Upgrade to V8 3.4

Merge 3.4.14.35

Simple merge required updates to makefiles only.

Bug: 568872
Change-Id: I403a38452c547e06fcfa951c12eca12a1bc40978
diff --git a/AUTHORS b/AUTHORS
index 60d5998..d4e35fe 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -7,6 +7,7 @@
 Sigma Designs Inc.
 ARM Ltd.
 Hewlett-Packard Development Company, LP
+Igalia, S.L.
 
 Akinori MUSHA <knu@FreeBSD.org>
 Alexander Botero-Lowry <alexbl@FreeBSD.org>
@@ -35,6 +36,7 @@
 Peter Varga <pvarga@inf.u-szeged.hu>
 Rafal Krypa <rafal@krypa.net>
 Rene Rebe <rene@exactcode.de>
+Robert Mustacchi <rm@fingolfin.org>
 Rodolph Perfetta <rodolph.perfetta@arm.com>
 Ryan Dahl <coldredlemur@gmail.com>
 Sanjoy Das <sanjoy@playingwithpointers.com>
diff --git a/Android.libv8.mk b/Android.libv8.mk
index 067fb39..e2978c7 100644
--- a/Android.libv8.mk
+++ b/Android.libv8.mk
@@ -41,7 +41,7 @@
 $(GEN1): $(LOCAL_JS_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $(GEN1) CORE $(LOCAL_JS_LIBRARY_FILES)
+	python $(SCRIPT) $(GEN1) CORE off $(LOCAL_JS_LIBRARY_FILES)
 V8_GENERATED_LIBRARIES := $(intermediates)/libraries.cc
 
 # Generate experimental-libraries.cc
@@ -50,7 +50,7 @@
 $(GEN2): $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating experimental-libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $(GEN2) EXPERIMENTAL $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
+	python $(SCRIPT) $(GEN2) EXPERIMENTAL off $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
 V8_GENERATED_LIBRARIES += $(intermediates)/experimental-libraries.cc
 
 LOCAL_GENERATED_SOURCES += $(V8_GENERATED_LIBRARIES)
diff --git a/Android.mksnapshot.mk b/Android.mksnapshot.mk
index 4d01116..8f54be7 100644
--- a/Android.mksnapshot.mk
+++ b/Android.mksnapshot.mk
@@ -48,7 +48,7 @@
 $(GEN3): $(LOCAL_JS_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $(GEN3) CORE $(LOCAL_JS_LIBRARY_FILES)
+	python $(SCRIPT) $(GEN3) CORE off $(LOCAL_JS_LIBRARY_FILES)
 LOCAL_GENERATED_SOURCES := $(intermediates)/libraries.cc
 
 # Generate experimental-libraries.cc
@@ -57,7 +57,7 @@
 $(GEN4): $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating experimental-libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $(GEN4) EXPERIMENTAL $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
+	python $(SCRIPT) $(GEN4) EXPERIMENTAL off $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
 LOCAL_GENERATED_SOURCES += $(intermediates)/experimental-libraries.cc
 
 LOCAL_CFLAGS := \
diff --git a/Android.v8common.mk b/Android.v8common.mk
index 83e2a97..d318f0a 100644
--- a/Android.v8common.mk
+++ b/Android.v8common.mk
@@ -49,7 +49,6 @@
 	src/ic.cc \
 	src/interpreter-irregexp.cc \
 	src/isolate.cc \
-	src/json-parser.cc \
 	src/jsregexp.cc \
 	src/lithium.cc \
 	src/lithium-allocator.cc \
@@ -89,6 +88,8 @@
 	src/utils.cc \
 	src/v8-counters.cc \
 	src/v8.cc \
+	src/v8conversions.cc \
+	src/v8utils.cc \
 	src/v8threads.cc \
 	src/variables.cc \
 	src/version.cc \
diff --git a/ChangeLog b/ChangeLog
index 49063d1..6901729 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,261 @@
+2011-07-20: Version 3.4.14
+
+        Fix the debugger for strict-mode functions. (Chromium issue 89236)
+
+        Add GetPropertyAttribute method for Object in the API. (Patch by Peter Varga)
+
+        Fix -Wunused-but-set-variable for gcc-4.6 on x64. (Issue 1291)
+
+
+2011-07-18: Version 3.4.13
+
+        Improved debugger support to allow inspection of optimized frames (issue
+        1140).
+
+        Fixed a bug in prototype transitions cache clearing introduced by r8165.
+
+        Fixed shortcutting bug in HInferRepresentation. Patch by Andy Wingo.
+
+        Fixed a memory leak in sample/shell.cc (dispose semaphores).
+
+        Simplified HClampToUint8. Patch by Andy Wingo.
+
+        Exposed APIs for detecting boxed primitives, native errors. Patch by
+        Luke Zarko.
+
+        Added map check for COW elements to crankshaft array handling code
+        (issue 1560).
+
+        Sample shell and (a light version of) D8 links against a shared library
+        now.
+
+        Fixed bug in array filter and reduce functions (issue 1559).
+
+        Avoid TLS load in AstNode constructor.
+
+        Introduced a random entropy source which can optionally be provided at
+        initialization. (Chromium issue 89462).
+
+
+2011-07-13: Version 3.4.12
+
+        Added --prof profiling option to d8 shell.
+
+        Fixed a bug where reading a directory in d8 shell hangs (issue 1533).
+
+        Fixed a potential assertion failure in const declarations.
+
+        Fixed an assertion failure in descriptor arrays (issue 1526).
+
+        Enabled fast thread-local storage by default on supported platforms.
+
+        Improved reporting of source position for global variable loads
+        (issue 1527).
+
+
+2011-07-11: Version 3.4.11
+
+        Fixed MinGW32 build.
+
+        Fixed a GC bug with RegExp code flushing.
+
+        Implemented Object.defineProperty for proxies.
+
+        Fixed a bug in for/in iteration of arguments objects (issue 1531).
+
+        Added debugger support for inspecting optimized frames (issue 1140).
+
+        Allowed JSObject::PreventExtensions to work for arguments objects.
+
+        Bugfixes and performance work.
+
+
+2011-07-06: Version 3.4.10
+
+        Fixed debugger not breaking on certain "if" statements (issue 1523).
+
+        Fixed assertion failure in runtime profiler when running on IA32
+        without snapshot (issue 1522).
+
+        Fixed ABI for API calls on IA32 (for clang compatibility).
+
+        Introduced code flushing of RegExp code to free memory used by
+        RegExps sooner.
+
+        Fixed linux-tick-processor built wrong version of v8 (issue 1532).
+
+        Fixed assertion failure in v8::TryCache::StackTrace (issue 1529).
+
+        Performance improvements on all platforms.
+
+
+2011-07-04: Version 3.4.9
+
+        Added support for debugger inspection of locals in optimized frames
+        (issue 1140).
+
+        Fixed SConstruct to pass correct defines to samples/preparser when
+        building with library=shared.
+
+        Made date parser handle ES5 Date Time Strings correctly (issue 1498).
+
+        Fixed a bug in Object.defineProperty on the arguments object.
+
+        Performance improvements on all platforms.
+
+
+2011-06-29: Version 3.4.8
+
+        Ensure 16-byte stack alignment on Solaris (issue 1505).
+
+        Fix "illegal access" when calling parseInt with a radix
+        that is not a smi. (issue 1246).
+
+
+2011-06-27: Version 3.4.7
+
+        Fixed 64-bit build on FreeBSD.
+
+        Added API to set the property attributes for the prototype
+        property on functions created from FunctionTemplates.
+
+        Bugfixes and performance work.
+
+
+2011-06-22: Version 3.4.6
+
+        Lowered limit on code space for systems with low memory supply.
+
+        Allowed compiling v8_shell with the 'host' toolset (issue 82437).
+
+        Extended setBreakpoint API to accept partial script name (issue 1418).
+
+        Made multi-line comments not count when deciding whether the '-->'
+        comment starter is first on a line. This matches Safari.
+
+        Made handling of non-array recievers in Array length setter correct
+        (issue 1491).
+
+        Added ability to heap profiler to iterate over snapshot's node
+        (issue 1481).
+
+
+2011-06-20: Version 3.4.5
+
+        Fixed issues 794, 1097, 1215(partial), 1417, 1435, 1472, 1473,
+        1476, and 1477.
+
+        Improved code generation for !0 and !1.
+
+        Reduced memory usage for regular expressions with nested qualifiers.
+        (issue 1472)
+
+        Fixed V8 to count line terminators in multi-line comments.
+        (Chromium issue 86431)
+
+        Fixed disassembler=on option for release-mode builds. (issue 1473)
+
+        Performance improvements on all platforms.
+
+
+2011-06-15: Version 3.4.4
+
+        Added snapshot compression support and --stress-opt flag to d8.
+
+        Improved performance of try/catch.
+
+        Several GYP-related changes: Added support for building Xcode project
+        files. Make the ARM simulator build with GYP again. Generate Makefiles
+        for all architectures on Linux.
+
+        Fixed Array.prototype.{reduce,reduceRight} to pass undefined as the
+        receiver for strict mode callbacks. (issue 1436)
+
+        Fixed a bug where an array load was incorrectly hoisted by GVN.
+
+        Handle 'undefined' correctly when === has been specialized for doubles.
+        (issue 1434)
+
+        Corrected the limit of local variables in an optimized function from 64
+        to 63.
+
+        Correctly set ReadOnly flag on indexed properties when using the API Set
+        method. (issue 1470)
+
+        Give the correct error message when Object.isExtensible is called on a
+        non-object. (issue 1452)
+
+        Added GetOwnPropertyNames method for Object in the API. Patch by Peter
+        Varga.
+
+        Do not redefine properties unneccesarily in seal and freeze. (issue
+        1447)
+
+        IsExecutionTerminating has an Isolate parameter now.
+
+        Distinguish keyed loads with a symbol key from fast elements loads,
+        avoiding some useless deoptimizations. (issue 1471)
+
+
+2011-06-08: Version 3.4.3
+
+        Clear the global thread table when an isolate is disposed
+        (issue 1433).
+
+        Converted time zone name to UTF8 on Windows (issue 1290).
+
+        Limited the number of arguments in a function call to 32766
+        (issue 1413).
+
+        Compress sources of JS libraries in addition to the snapshot.
+
+        Fixed a bug in Lithium environment iteration.
+
+        Performance improvements on all platforms.
+
+
+2011-06-06: Version 3.4.2
+
+        More work on ES-Harmony proxies.  Still hidden behind a flag.
+
+        Fixed some crash bugs and improved performance.
+
+        Fixed building with gdb debugging support.
+
+        Do not install SIGPROF handler until it is needed.
+
+        Added DateTimeFormat to i18n API.
+
+        Fixed compilation on OpenBSD.
+
+        Take the ulimit into account when sizing the heap.  OpenBSD users
+        may still have to increase the default ulimit to run heavy pages in
+        the browser.
+
+
+2011-06-01: Version 3.4.1
+
+        Fixed JSON stringify issue with arrays.
+
+        Changed calls to JS builtins to be passed undefined when called with
+        implicit receiver.
+
+        Implemented the set trap for Harmony proxies. Proxies still need to
+        be enabled with the --harmony-proxies flag.
+
+
+2011-05-30: Version 3.4.0
+
+        Changed calls to undefined property setters to not throw (issue 1355).
+
+        Made RegExp objects not callable.
+
+        Fixed issues on special case large JSON strings in new json parser
+        (issues http://crbug.com/83877 and http://crbug.com/84186).
+
+        Performance improvements on all platforms.
+
+
 2011-05-25: Version 3.3.10
 
         Fixed calls of strict mode function with an implicit receiver.
@@ -2837,3 +3095,6 @@
 
         Initial export.
 
+# Local Variables:
+# mode:text
+# End:
diff --git a/SConstruct b/SConstruct
index 4a7e182..8e16a78 100644
--- a/SConstruct
+++ b/SConstruct
@@ -60,26 +60,17 @@
     'mode:debug': {
       'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT']
     },
-    'vmstate:on': {
-      'CPPDEFINES':   ['ENABLE_VMSTATE_TRACKING'],
-    },
     'objectprint:on': {
       'CPPDEFINES':   ['OBJECT_PRINT'],
     },
-    'protectheap:on': {
-      'CPPDEFINES':   ['ENABLE_VMSTATE_TRACKING', 'ENABLE_HEAP_PROTECTION'],
-    },
-    'profilingsupport:on': {
-      'CPPDEFINES':   ['ENABLE_VMSTATE_TRACKING', 'ENABLE_LOGGING_AND_PROFILING'],
-    },
     'debuggersupport:on': {
       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT'],
     },
     'inspector:on': {
       'CPPDEFINES':   ['INSPECTOR'],
     },
-    'fasttls:on': {
-      'CPPDEFINES':   ['V8_FAST_TLS'],
+    'fasttls:off': {
+      'CPPDEFINES':   ['V8_NO_FAST_TLS'],
     },
     'liveobjectlist:on': {
       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR',
@@ -89,7 +80,7 @@
   'gcc': {
     'all': {
       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
-      'CXXFLAGS':     ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
+      'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
     },
     'visibility:hidden': {
       # Use visibility=default to disable this.
@@ -230,7 +221,7 @@
   'msvc': {
     'all': {
       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
-      'CXXFLAGS':     ['$CCFLAGS', '/GR-', '/Gy'],
+      'CXXFLAGS':     ['/GR-', '/Gy'],
       'CPPDEFINES':   ['WIN32'],
       'LINKFLAGS':    ['/INCREMENTAL:NO', '/NXCOMPAT', '/IGNORE:4221'],
       'CCPDBFLAGS':   ['/Zi']
@@ -400,16 +391,20 @@
 CCTEST_EXTRA_FLAGS = {
   'all': {
     'CPPPATH': [join(root_dir, 'src')],
+    'library:shared': {
+      'CPPDEFINES': ['USING_V8_SHARED']
+    },
   },
   'gcc': {
     'all': {
       'LIBPATH':      [abspath('.')],
       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
-      'CXXFLAGS':     ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
+      'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
       'LINKFLAGS':    ['$CCFLAGS'],
     },
     'os:linux': {
       'LIBS':         ['pthread'],
+      'CCFLAGS':      ['-Wno-unused-but-set-variable'],
     },
     'os:macos': {
       'LIBS':         ['pthread'],
@@ -436,9 +431,6 @@
       'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
       'LIBS': ['winmm', 'ws2_32']
     },
-    'library:shared': {
-      'CPPDEFINES': ['USING_V8_SHARED']
-    },
     'arch:ia32': {
       'CPPDEFINES': ['V8_TARGET_ARCH_IA32']
     },
@@ -453,12 +445,15 @@
 SAMPLE_FLAGS = {
   'all': {
     'CPPPATH': [join(abspath('.'), 'include')],
+    'library:shared': {
+      'CPPDEFINES': ['USING_V8_SHARED']
+    },
   },
   'gcc': {
     'all': {
       'LIBPATH':      ['.'],
       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
-      'CXXFLAGS':     ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
+      'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
       'LINKFLAGS':    ['$CCFLAGS'],
     },
     'os:linux': {
@@ -472,6 +467,9 @@
       'LIBS':         ['execinfo', 'pthread']
     },
     'os:solaris': {
+      # On Solaris, to get isinf, INFINITY, fpclassify and other macros one
+      # needs to define __C99FEATURES__.
+      'CPPDEFINES': ['__C99FEATURES__'],
       'LIBPATH' :     ['/usr/local/lib'],
       'LIBS':         ['m', 'pthread', 'socket', 'nsl', 'rt'],
       'LINKFLAGS':    ['-mt']
@@ -572,9 +570,6 @@
     'verbose:on': {
       'LINKFLAGS': ['/VERBOSE']
     },
-    'library:shared': {
-      'CPPDEFINES': ['USING_V8_SHARED']
-    },
     'prof:on': {
       'LINKFLAGS': ['/MAP']
     },
@@ -625,13 +620,16 @@
 
 PREPARSER_FLAGS = {
   'all': {
-    'CPPPATH': [join(abspath('.'), 'include'), join(abspath('.'), 'src')]
+    'CPPPATH': [join(abspath('.'), 'include'), join(abspath('.'), 'src')],
+    'library:shared': {
+      'CPPDEFINES': ['USING_V8_SHARED']
+    },
   },
   'gcc': {
     'all': {
       'LIBPATH':      ['.'],
       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
-      'CXXFLAGS':     ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
+      'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
       'LINKFLAGS':    ['$CCFLAGS'],
     },
     'os:win32': {
@@ -712,6 +710,9 @@
       'CCFLAGS':      ['-g', '-O0'],
       'CPPDEFINES':   ['DEBUG']
     },
+    'os:freebsd': {
+      'LIBPATH' : ['/usr/local/lib'],
+    },
   },
   'msvc': {
     'all': {
@@ -724,9 +725,6 @@
     'verbose:on': {
       'LINKFLAGS': ['/VERBOSE']
     },
-    'library:shared': {
-      'CPPDEFINES': ['USING_V8_SHARED']
-    },
     'prof:on': {
       'LINKFLAGS': ['/MAP']
     },
@@ -776,10 +774,17 @@
 
 
 D8_FLAGS = {
+  'all': {
+    'library:shared': {
+      'CPPDEFINES': ['V8_SHARED'],
+      'LIBS': ['v8'],
+      'LIBPATH': ['.']
+    },
+  },
   'gcc': {
     'all': {
       'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
-      'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
+      'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'],
       'LINKFLAGS': ['$CCFLAGS'],
     },
     'console:readline': {
@@ -807,6 +812,12 @@
     'arch:arm': {
       'LINKFLAGS':   ARM_LINK_FLAGS
     },
+    'compress_startup_data:bz2': {
+      'CPPDEFINES':   ['COMPRESS_STARTUP_DATA_BZ2'],
+      'os:linux': {
+        'LIBS': ['bz2']
+      }
+    }
   },
   'msvc': {
     'all': {
@@ -917,21 +928,11 @@
     'default': 'static',
     'help': 'the type of library to produce'
   },
-  'vmstate': {
-    'values': ['on', 'off'],
-    'default': 'off',
-    'help': 'enable VM state tracking'
-  },
   'objectprint': {
     'values': ['on', 'off'],
     'default': 'off',
     'help': 'enable object printing'
   },
-  'protectheap': {
-    'values': ['on', 'off'],
-    'default': 'off',
-    'help': 'enable heap protection'
-  },
   'profilingsupport': {
     'values': ['on', 'off'],
     'default': 'on',
@@ -1146,8 +1147,8 @@
     return False
   if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on':
     Abort("Profiling on windows only supported for static library.")
-  if env['gdbjit'] == 'on' and (env['os'] != 'linux' or (env['arch'] != 'ia32' and env['arch'] != 'x64' and env['arch'] != 'arm')):
-    Abort("GDBJIT interface is supported only for Intel-compatible (ia32 or x64) Linux target.")
+  if env['gdbjit'] == 'on' and ((env['os'] != 'linux' and env['os'] != 'macos') or (env['arch'] != 'ia32' and env['arch'] != 'x64' and env['arch'] != 'arm')):
+    Abort("GDBJIT interface is supported only for Intel-compatible (ia32 or x64) Linux/OSX target.")
   if env['os'] == 'win32' and env['soname'] == 'on':
     Abort("Shared Object soname not applicable for Windows.")
   if env['soname'] == 'on' and env['library'] == 'static':
@@ -1366,16 +1367,22 @@
     pdb_name = library_name + '.dll.pdb'
     library = env.SharedLibrary(library_name, object_files, PDB=pdb_name)
     preparser_pdb_name = preparser_library_name + '.dll.pdb';
+    preparser_soname = 'lib' + preparser_library_name + '.so';
     preparser_library = env.SharedLibrary(preparser_library_name,
                                           preparser_files,
-                                          PDB=preparser_pdb_name)
+                                          PDB=preparser_pdb_name,
+                                          SONAME=preparser_soname)
   context.library_targets.append(library)
   context.library_targets.append(preparser_library)
 
   d8_env = Environment(tools=tools)
   d8_env.Replace(**context.flags['d8'])
   context.ApplyEnvOverrides(d8_env)
-  shell = d8_env.Program('d8' + suffix, object_files + shell_files)
+  if context.options['library'] == 'static':
+    shell = d8_env.Program('d8' + suffix, object_files + shell_files)
+  else:
+    shell = d8_env.Program('d8' + suffix, shell_files)
+    d8_env.Depends(shell, library)
   context.d8_targets.append(shell)
 
   for sample in context.samples:
@@ -1411,7 +1418,7 @@
   preparser_object = preparser_env.SConscript(
     join('preparser', 'SConscript'),
     build_dir=join('obj', 'preparser', target_id),
-    exports='context',
+    exports='context tools',
     duplicate=False
   )
   preparser_name = join('obj', 'preparser', target_id, 'preparser')
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index 88a1a79..ff5fd5d 100644
--- a/V8_MERGE_REVISION
+++ b/V8_MERGE_REVISION
@@ -1,2 +1,2 @@
-V8 3.3.10.39
-http://v8.googlecode.com/svn/branches/3.3@9793
+V8 3.4.14.35
+http://v8.googlecode.com/svn/branches/3.4@9839
diff --git a/build/README.txt b/build/README.txt
index f6b9255..c74b520 100644
--- a/build/README.txt
+++ b/build/README.txt
@@ -9,23 +9,40 @@
 
 $ svn co http://gyp.googlecode.com/svn/trunk build/gyp
 
-To generate Makefiles and build 32-bit version on Linux:
---------------------------------------------------------
+Note for the command lines below that Debug is the default configuration,
+so specifying that on the command lines is not required.
 
-$ GYP_DEFINES=target_arch=ia32 build/gyp_v8
-$ make
 
-To generate Makefiles and build 64-bit version on Linux:
---------------------------------------------------------
+To generate Makefiles on Linux:
+-------------------------------
 
-$ GYP_DEFINES=target_arch=x64 build/gyp_v8
-$ make
+$ build/gyp_v8
 
-To generate Makefiles and build for the arm simulator on Linux:
----------------------------------------------------------------
+This will build makefiles for ia32, x64 and the ARM simulator with names
+Makefile-ia32, Makefile-x64 and Makefile-armu respectively.
 
-$ build/gyp_v8 -I build/arm.gypi
-$ make
+To build and run for ia32 in debug and release version do:
+
+$ make -f Makefile-ia32
+$ out/Debug/shell
+$ make -f Makefile-ia32 BUILDTYPE=Release
+$ out/Release/shell
+
+Change the makefile to build and run for the other architectures.
+
+
+To generate Xcode project files on Mac OS:
+------------------------------------------
+
+$ build/gyp_v8
+
+This will make an Xcode project for the ia32 architecture. To build and run do:
+
+$ xcodebuild -project build/all.xcodeproj
+$ samples/build/Debug/shell
+$ xcodebuild -project build/all.xcodeproj -configuration Release
+$ samples/build/Release/shell
+
 
 To generate Visual Studio solution and project files on Windows:
 ----------------------------------------------------------------
@@ -42,8 +59,8 @@
 
 > svn co http://src.chromium.org/svn/trunk/tools/third_party/python_26@70627 third_party/python_26
 
-Now generate Visual Studio solution and project files:
+Now generate Visual Studio solution and project files for the ia32 architecture:
 
-> third_party\python_26\python build/gyp_v8 -D target_arch=ia32
+> third_party\python_26\python build/gyp_v8
 
 Now open build\All.sln in Visual Studio.
diff --git a/build/all.gyp b/build/all.gyp
index 544e2c2..38287e3 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -9,9 +9,15 @@
       'type': 'none',
       'dependencies': [
         '../samples/samples.gyp:*',
-        '../test/cctest/cctest.gyp:*',
-        '../src/d8.gyp:*',
-      ]
+        '../src/d8.gyp:d8',
+      ],
+      'conditions': [
+        [ 'component!="shared_library"', {
+          'dependencies': [
+            '../test/cctest/cctest.gyp:*',
+          ],
+        }]
+      ],
     }
   ]
 }
diff --git a/build/armu.gypi b/build/armu.gypi
index 72eb4d1..3f874c0 100644
--- a/build/armu.gypi
+++ b/build/armu.gypi
@@ -1,4 +1,4 @@
-# Copyright 2010 the V8 project authors. All rights reserved.
+# Copyright 2011 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
@@ -27,6 +27,10 @@
 
 {
   'variables': {
+    'target_arch': 'ia32',
     'v8_target_arch': 'arm',
+    'armv7': 1,
+    'arm_neon': 0,
+    'arm_fpu': 'vfpv3',
   }
 }
diff --git a/build/common.gypi b/build/common.gypi
index 19b4dc2..7020495 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -139,6 +139,45 @@
           },
         },
       },
-    }]
+    }],  # OS=="win"
+    ['OS=="mac"', {
+      'target_defaults': {
+        'xcode_settings': {
+          'ALWAYS_SEARCH_USER_PATHS': 'NO',
+          'GCC_C_LANGUAGE_STANDARD': 'ansi',        # -ansi
+          'GCC_CW_ASM_SYNTAX': 'NO',                # No -fasm-blocks
+          'GCC_DYNAMIC_NO_PIC': 'NO',               # No -mdynamic-no-pic
+                                                    # (Equivalent to -fPIC)
+          'GCC_ENABLE_CPP_EXCEPTIONS': 'NO',        # -fno-exceptions
+          'GCC_ENABLE_CPP_RTTI': 'NO',              # -fno-rtti
+          'GCC_ENABLE_PASCAL_STRINGS': 'NO',        # No -mpascal-strings
+          # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
+          'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
+          'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES',      # -fvisibility=hidden
+          'GCC_THREADSAFE_STATICS': 'NO',           # -fno-threadsafe-statics
+          'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES',    # -Werror
+          'GCC_VERSION': '4.2',
+          'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES',  # -Wnewline-eof
+          'MACOSX_DEPLOYMENT_TARGET': '10.4',       # -mmacosx-version-min=10.4
+          'PREBINDING': 'NO',                       # No -Wl,-prebind
+          'USE_HEADERMAP': 'NO',
+          'OTHER_CFLAGS': [
+            '-fno-strict-aliasing',
+          ],
+          'WARNING_CFLAGS': [
+            '-Wall',
+            '-Wendif-labels',
+            '-W',
+            '-Wno-unused-parameter',
+            '-Wnon-virtual-dtor',
+          ],
+        },
+        'target_conditions': [
+          ['_type!="static_library"', {
+            'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
+          }],
+        ],  # target_conditions
+      },  # target_defaults
+    }],  # OS=="mac"
   ],
 }
diff --git a/build/gyp_v8 b/build/gyp_v8
index 0c2221e..61b54c2 100755
--- a/build/gyp_v8
+++ b/build/gyp_v8
@@ -38,9 +38,13 @@
 script_dir = os.path.dirname(__file__)
 v8_root = os.path.normpath(os.path.join(script_dir, os.pardir))
 
+sys.path.insert(0, os.path.join(v8_root, 'tools'))
+import utils
+
 sys.path.insert(0, os.path.join(v8_root, 'build', 'gyp', 'pylib'))
 import gyp
 
+
 def apply_gyp_environment(file_path=None):
   """
   Reads in a *.gyp_env file and applies the valid keys to os.environ.
@@ -68,6 +72,7 @@
       else:
         os.environ[var] = val
 
+
 def additional_include_files(args=[]):
   """
   Returns a list of additional (.gypi) files to include, without
@@ -97,6 +102,14 @@
 
   return result
 
+
+def run_gyp(args):
+  rc = gyp.main(args)
+  if rc != 0:
+    print 'Error running GYP'
+    sys.exit(rc)
+
+
 if __name__ == '__main__':
   args = sys.argv[1:]
 
@@ -141,5 +154,20 @@
   print 'Updating projects from gyp files...'
   sys.stdout.flush()
 
-  # Off we go...
-  sys.exit(gyp.main(args))
+  # Generate for the architectures supported on the given platform.
+  gyp_args = list(args)
+  gyp_args.append('-Dtarget_arch=ia32')
+  if utils.GuessOS() == 'linux':
+    gyp_args.append('-S-ia32')
+  run_gyp(gyp_args)
+
+  if utils.GuessOS() == 'linux':
+    gyp_args = list(args)
+    gyp_args.append('-Dtarget_arch=x64')
+    gyp_args.append('-S-x64')
+    run_gyp(gyp_args)
+
+    gyp_args = list(args)
+    gyp_args.append('-I' + v8_root + '/build/armu.gypi')
+    gyp_args.append('-S-armu')
+    run_gyp(gyp_args)
diff --git a/build/v8-features.gypi b/build/v8-features.gypi
new file mode 100644
index 0000000..4037452
--- /dev/null
+++ b/build/v8-features.gypi
@@ -0,0 +1,125 @@
+# Copyright 2011 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# TODO(sgjesse): This is currently copied from v8.gyp, should probably
+# be refactored.
+{
+  'variables': {
+    'use_system_v8%': 0,
+    'msvs_use_common_release': 0,
+    'gcc_version%': 'unknown',
+    'v8_compress_startup_data%': 'off',
+    'v8_target_arch%': '<(target_arch)',
+
+    # Setting 'v8_can_use_unaligned_accesses' to 'true' will allow the code
+    # generated by V8 to do unaligned memory access, and setting it to 'false'
+    # will ensure that the generated code will always do aligned memory
+    # accesses. The default value of 'default' will try to determine the correct
+    # setting. Note that for Intel architectures (ia32 and x64) unaligned memory
+    # access is allowed for all CPUs.
+    'v8_can_use_unaligned_accesses%': 'default',
+
+    # Setting 'v8_can_use_vfp_instructions' to 'true' will enable use of ARM VFP
+    # instructions in the V8 generated code. VFP instructions will be enabled
+    # both for the snapshot and for the ARM target. Leaving the default value
+    # of 'false' will avoid VFP instructions in the snapshot and use CPU feature
+    # probing when running on the target.
+    'v8_can_use_vfp_instructions%': 'false',
+
+    # Setting v8_use_arm_eabi_hardfloat to true will turn on V8 support for ARM
+    # EABI calling convention where double arguments are passed in VFP
+    # registers. Note that the GCC flag '-mfloat-abi=hard' should be used as
+    # well when compiling for the ARM target.
+    'v8_use_arm_eabi_hardfloat%': 'false',
+
+    'v8_use_snapshot%': 'true',
+    'host_os%': '<(OS)',
+    'v8_use_liveobjectlist%': 'false',
+  },
+  'target_defaults': {
+    'conditions': [
+      ['OS!="mac"', {
+        'conditions': [
+          ['v8_target_arch=="arm"', {
+            'defines': [
+              'V8_TARGET_ARCH_ARM',
+            ],
+            'conditions': [
+              [ 'v8_can_use_unaligned_accesses=="true"', {
+                'defines': [
+                  'CAN_USE_UNALIGNED_ACCESSES=1',
+                ],
+              }],
+              [ 'v8_can_use_unaligned_accesses=="false"', {
+                'defines': [
+                  'CAN_USE_UNALIGNED_ACCESSES=0',
+                ],
+              }],
+              [ 'v8_can_use_vfp_instructions=="true"', {
+                'defines': [
+                  'CAN_USE_VFP_INSTRUCTIONS',
+                ],
+              }],
+              [ 'v8_use_arm_eabi_hardfloat=="true"', {
+                'defines': [
+                  'USE_EABI_HARDFLOAT=1',
+                  'CAN_USE_VFP_INSTRUCTIONS',
+                ],
+              }],
+            ],
+          }],
+          ['v8_target_arch=="ia32"', {
+            'defines': [
+              'V8_TARGET_ARCH_IA32',
+            ],
+          }],
+          ['v8_target_arch=="mips"', {
+            'defines': [
+              'V8_TARGET_ARCH_MIPS',
+            ],
+          }],
+          ['v8_target_arch=="x64"', {
+            'defines': [
+              'V8_TARGET_ARCH_X64',
+            ],
+          }],
+        ],
+      }],
+    ],
+    'configurations': {
+      'Debug': {
+        'defines': [
+          'DEBUG',
+          '_DEBUG',
+          'ENABLE_DISASSEMBLER',
+          'V8_ENABLE_CHECKS',
+          'OBJECT_PRINT',
+        ],
+      }
+    }
+  }
+}
diff --git a/include/v8-profiler.h b/include/v8-profiler.h
index 940a35c..4febcb9 100644
--- a/include/v8-profiler.h
+++ b/include/v8-profiler.h
@@ -269,17 +269,10 @@
 
   /**
    * Returns node id. For the same heap object, the id remains the same
-   * across all snapshots. Not applicable to aggregated heap snapshots
-   * as they only contain aggregated instances.
+   * across all snapshots.
    */
   uint64_t GetId() const;
 
-  /**
-   * Returns the number of instances. Only applicable to aggregated
-   * heap snapshots.
-   */
-  int GetInstancesCount() const;
-
   /** Returns node's own size, in bytes. */
   int GetSelfSize() const;
 
@@ -323,9 +316,7 @@
 class V8EXPORT HeapSnapshot {
  public:
   enum Type {
-    kFull = 0,       // Heap snapshot with all instances and references.
-    kAggregated = 1  // Snapshot doesn't contain individual heap entries,
-                     // instead they are grouped by constructor name.
+    kFull = 0  // Heap snapshot with all instances and references.
   };
   enum SerializationFormat {
     kJSON = 0  // See format description near 'Serialize' method.
@@ -346,6 +337,12 @@
   /** Returns a node by its id. */
   const HeapGraphNode* GetNodeById(uint64_t id) const;
 
+  /** Returns total nodes count in the snapshot. */
+  int GetNodesCount() const;
+
+  /** Returns a node by index. */
+  const HeapGraphNode* GetNode(int index) const;
+
   /**
    * Deletes the snapshot and removes it from HeapProfiler's list.
    * All pointers to nodes, edges and paths previously returned become
diff --git a/include/v8.h b/include/v8.h
index b4598c6..f4f81e4 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -80,9 +80,11 @@
 
 class Context;
 class String;
+class StringObject;
 class Value;
 class Utils;
 class Number;
+class NumberObject;
 class Object;
 class Array;
 class Int32;
@@ -90,6 +92,7 @@
 class External;
 class Primitive;
 class Boolean;
+class BooleanObject;
 class Integer;
 class Function;
 class Date;
@@ -165,7 +168,6 @@
  */
 template <class T> class Handle {
  public:
-
   /**
    * Creates an empty handle.
    */
@@ -312,7 +314,6 @@
  */
 template <class T> class Persistent : public Handle<T> {
  public:
-
   /**
    * Creates an empty persistent handle that doesn't point to any
    * storage cell.
@@ -586,7 +587,6 @@
  */
 class V8EXPORT Script {
  public:
-
   /**
    * Compiles the specified script (context-independent).
    *
@@ -858,7 +858,6 @@
  */
 class Value : public Data {
  public:
-
   /**
    * Returns true if this value is the undefined value.  See ECMA-262
    * 4.3.10.
@@ -933,6 +932,26 @@
   V8EXPORT bool IsDate() const;
 
   /**
+   * Returns true if this value is a Boolean object.
+   */
+  V8EXPORT bool IsBooleanObject() const;
+
+  /**
+   * Returns true if this value is a Number object.
+   */
+  V8EXPORT bool IsNumberObject() const;
+
+  /**
+   * Returns true if this value is a String object.
+   */
+  V8EXPORT bool IsStringObject() const;
+
+  /**
+   * Returns true if this value is a NativeError.
+   */
+  V8EXPORT bool IsNativeError() const;
+
+  /**
    * Returns true if this value is a RegExp.
    */
   V8EXPORT bool IsRegExp() const;
@@ -990,7 +1009,6 @@
  */
 class String : public Primitive {
  public:
-
   /**
    * Returns the number of characters in this string.
    */
@@ -1440,6 +1458,13 @@
 
   V8EXPORT Local<Value> Get(uint32_t index);
 
+  /**
+   * Gets the property attributes of a property which can be None or
+   * any combination of ReadOnly, DontEnum and DontDelete. Returns
+   * None when the property doesn't exist.
+   */
+  V8EXPORT PropertyAttribute GetPropertyAttributes(Handle<Value> key);
+
   // TODO(1245389): Replace the type-specific versions of these
   // functions with generic ones that accept a Handle<Value> key.
   V8EXPORT bool Has(Handle<String> key);
@@ -1470,6 +1495,13 @@
   V8EXPORT Local<Array> GetPropertyNames();
 
   /**
+   * This function has the same functionality as GetPropertyNames but
+   * the returned array doesn't contain the names of properties from
+   * prototype objects.
+   */
+  V8EXPORT Local<Array> GetOwnPropertyNames();
+
+  /**
    * Get the prototype object.  This does not skip objects marked to
    * be skipped by __proto__ and it does not consult the security
    * handler.
@@ -1640,6 +1672,7 @@
 
   V8EXPORT static Local<Object> New();
   static inline Object* Cast(Value* obj);
+
  private:
   V8EXPORT Object();
   V8EXPORT static void CheckCast(Value* obj);
@@ -1742,6 +1775,63 @@
 
 
 /**
+ * A Number object (ECMA-262, 4.3.21).
+ */
+class NumberObject : public Object {
+ public:
+  V8EXPORT static Local<Value> New(double value);
+
+  /**
+   * Returns the Number held by the object.
+   */
+  V8EXPORT double NumberValue() const;
+
+  static inline NumberObject* Cast(v8::Value* obj);
+
+ private:
+  V8EXPORT static void CheckCast(v8::Value* obj);
+};
+
+
+/**
+ * A Boolean object (ECMA-262, 4.3.15).
+ */
+class BooleanObject : public Object {
+ public:
+  V8EXPORT static Local<Value> New(bool value);
+
+  /**
+   * Returns the Boolean held by the object.
+   */
+  V8EXPORT bool BooleanValue() const;
+
+  static inline BooleanObject* Cast(v8::Value* obj);
+
+ private:
+  V8EXPORT static void CheckCast(v8::Value* obj);
+};
+
+
+/**
+ * A String object (ECMA-262, 4.3.18).
+ */
+class StringObject : public Object {
+ public:
+  V8EXPORT static Local<Value> New(Handle<String> value);
+
+  /**
+   * Returns the String held by the object.
+   */
+  V8EXPORT Local<String> StringValue() const;
+
+  static inline StringObject* Cast(v8::Value* obj);
+
+ private:
+  V8EXPORT static void CheckCast(v8::Value* obj);
+};
+
+
+/**
  * An instance of the built-in RegExp constructor (ECMA-262, 15.10).
  */
 class RegExp : public Object {
@@ -2141,6 +2231,13 @@
   void SetHiddenPrototype(bool value);
 
   /**
+   * Sets the property attributes of the 'prototype' property of functions
+   * created from this FunctionTemplate. Can be any combination of ReadOnly,
+   * DontEnum and DontDelete.
+   */
+  void SetPrototypeAttributes(int attributes);
+
+  /**
    * Returns true if the given object is an instance of this function
    * template.
    */
@@ -2548,23 +2645,6 @@
 
 
 /**
- * Profiler modules.
- *
- * In V8, profiler consists of several modules: CPU profiler, and different
- * kinds of heap profiling. Each can be turned on / off independently.
- * When PROFILER_MODULE_HEAP_SNAPSHOT flag is passed to ResumeProfilerEx,
- * modules are enabled only temporarily for making a snapshot of the heap.
- */
-enum ProfilerModules {
-  PROFILER_MODULE_NONE            = 0,
-  PROFILER_MODULE_CPU             = 1,
-  PROFILER_MODULE_HEAP_STATS      = 1 << 1,
-  PROFILER_MODULE_JS_CONSTRUCTORS = 1 << 2,
-  PROFILER_MODULE_HEAP_SNAPSHOT   = 1 << 16
-};
-
-
-/**
  * Collection of V8 heap information.
  *
  * Instances of this class can be passed to v8::V8::HeapStatistics to
@@ -2682,7 +2762,6 @@
   void* GetData();
 
  private:
-
   Isolate();
   Isolate(const Isolate&);
   ~Isolate();
@@ -2704,6 +2783,38 @@
   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 V8EXPORT 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.
+ */
+typedef bool (*EntropySource)(unsigned char* buffer, size_t length);
+
 /**
  * Container class for static utility functions.
  */
@@ -2753,6 +2864,10 @@
    *   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();
@@ -2925,6 +3040,12 @@
   static bool Initialize();
 
   /**
+   * Allows the host application to provide a callback which can be used
+   * as a source of entropy for random number generators.
+   */
+  static void SetEntropySource(EntropySource source);
+
+  /**
    * 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
@@ -2963,65 +3084,6 @@
   static bool IsProfilerPaused();
 
   /**
-   * Resumes specified profiler modules. Can be called several times to
-   * mark the opening of a profiler events block with the given tag.
-   *
-   * "ResumeProfiler" is equivalent to "ResumeProfilerEx(PROFILER_MODULE_CPU)".
-   * See ProfilerModules enum.
-   *
-   * \param flags Flags specifying profiler modules.
-   * \param tag Profile tag.
-   */
-  static void ResumeProfilerEx(int flags, int tag = 0);
-
-  /**
-   * Pauses specified profiler modules. Each call to "PauseProfilerEx" closes
-   * a block of profiler events opened by a call to "ResumeProfilerEx" with the
-   * same tag value. There is no need for blocks to be properly nested.
-   * The profiler is paused when the last opened block is closed.
-   *
-   * "PauseProfiler" is equivalent to "PauseProfilerEx(PROFILER_MODULE_CPU)".
-   * See ProfilerModules enum.
-   *
-   * \param flags Flags specifying profiler modules.
-   * \param tag Profile tag.
-   */
-  static void PauseProfilerEx(int flags, int tag = 0);
-
-  /**
-   * Returns active (resumed) profiler modules.
-   * See ProfilerModules enum.
-   *
-   * \returns active profiler modules.
-   */
-  static int GetActiveProfilerModules();
-
-  /**
-   * If logging is performed into a memory buffer (via --logfile=*), allows to
-   * retrieve previously written messages. This can be used for retrieving
-   * profiler log data in the application. This function is thread-safe.
-   *
-   * Caller provides a destination buffer that must exist during GetLogLines
-   * call. Only whole log lines are copied into the buffer.
-   *
-   * \param from_pos specified a point in a buffer to read from, 0 is the
-   *   beginning of a buffer. It is assumed that caller updates its current
-   *   position using returned size value from the previous call.
-   * \param dest_buf destination buffer for log data.
-   * \param max_size size of the destination buffer.
-   * \returns actual size of log data copied into buffer.
-   */
-  static int GetLogLines(int from_pos, char* dest_buf, int max_size);
-
-  /**
-   * The minimum allowed size for a log lines buffer.  If the size of
-   * the buffer given will not be enough to hold a line of the maximum
-   * length, an attempt to find a log line end in GetLogLines will
-   * fail, and an empty result will be returned.
-   */
-  static const int kMinimumSizeForLogLinesBuffer = 2048;
-
-  /**
    * Retrieve the V8 thread id of the calling thread.
    *
    * The thread id for a thread should only be retrieved after the V8
@@ -3074,8 +3136,10 @@
    * because of a call to TerminateExecution.  In that case there are
    * still JavaScript frames on the stack and the termination
    * exception is still active.
+   *
+   * \param isolate The isolate in which to check.
    */
-  static bool IsExecutionTerminating();
+  static bool IsExecutionTerminating(Isolate* isolate = NULL);
 
   /**
    * Releases any resources used by v8 and stops any utility threads
@@ -3144,7 +3208,6 @@
  */
 class V8EXPORT TryCatch {
  public:
-
   /**
    * Creates a new try/catch block and registers it with v8.
    */
@@ -3236,6 +3299,7 @@
   void SetCaptureMessage(bool value);
 
  private:
+  v8::internal::Isolate* isolate_;
   void* next_;
   void* exception_;
   void* message_;
@@ -3690,7 +3754,6 @@
  */
 class Internals {
  public:
-
   // These values match non-compiler-dependent values defined within
   // the implementation of v8.
   static const int kHeapObjectMapOffset = 0;
@@ -3703,7 +3766,7 @@
   static const int kFullStringRepresentationMask = 0x07;
   static const int kExternalTwoByteRepresentationTag = 0x02;
 
-  static const int kJSObjectType = 0xa2;
+  static const int kJSObjectType = 0xa3;
   static const int kFirstNonstringType = 0x80;
   static const int kForeignType = 0x85;
 
@@ -4047,6 +4110,30 @@
 }
 
 
+StringObject* StringObject::Cast(v8::Value* value) {
+#ifdef V8_ENABLE_CHECKS
+  CheckCast(value);
+#endif
+  return static_cast<StringObject*>(value);
+}
+
+
+NumberObject* NumberObject::Cast(v8::Value* value) {
+#ifdef V8_ENABLE_CHECKS
+  CheckCast(value);
+#endif
+  return static_cast<NumberObject*>(value);
+}
+
+
+BooleanObject* BooleanObject::Cast(v8::Value* value) {
+#ifdef V8_ENABLE_CHECKS
+  CheckCast(value);
+#endif
+  return static_cast<BooleanObject*>(value);
+}
+
+
 RegExp* RegExp::Cast(v8::Value* value) {
 #ifdef V8_ENABLE_CHECKS
   CheckCast(value);
diff --git a/preparser/SConscript b/preparser/SConscript
index 1d51e82..10b3953 100644
--- a/preparser/SConscript
+++ b/preparser/SConscript
@@ -26,10 +26,10 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 from os.path import join
-Import('context')
+Import('context tools')
 
 def ConfigureObjectFiles():
-  env = Environment()
+  env = Environment(tools=tools)
   env.Replace(**context.flags['preparser'])
   context.ApplyEnvOverrides(env)
   return env.Object('preparser-process.cc')
diff --git a/preparser/preparser-process.cc b/preparser/preparser-process.cc
index a19c66b..e67851c 100644
--- a/preparser/preparser-process.cc
+++ b/preparser/preparser-process.cc
@@ -208,7 +208,7 @@
     fflush(stderr);
   }
   exit(EXIT_FAILURE);
-};
+}
 
 
 bool IsFlag(const char* arg) {
@@ -290,12 +290,12 @@
         arg_index++;
       } while (argc > arg_index && IsFlag(argv[arg_index]));
       if (argc > arg_index) {
-        expects.beg_pos = atoi(argv[arg_index]);
+        expects.beg_pos = atoi(argv[arg_index]);  // NOLINT
         do {
           arg_index++;
         } while (argc > arg_index && IsFlag(argv[arg_index]));
         if (argc > arg_index) {
-          expects.end_pos = atoi(argv[arg_index]);
+          expects.end_pos = atoi(argv[arg_index]);  // NOLINT
         }
       }
     }
diff --git a/samples/SConscript b/samples/SConscript
index 31990b6..84c48c9 100644
--- a/samples/SConscript
+++ b/samples/SConscript
@@ -26,10 +26,10 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 from os.path import join
-Import('sample context')
+Import('sample context tools')
 
 def ConfigureObjectFiles():
-  env = Environment()
+  env = Environment(tools=tools)
   env.Replace(**context.flags['sample'])
   context.ApplyEnvOverrides(env)
   return env.Object(sample + '.cc')
diff --git a/samples/process.cc b/samples/process.cc
index 4a873b7..07c4805 100644
--- a/samples/process.cc
+++ b/samples/process.cc
@@ -535,7 +535,7 @@
                   string* file) {
   for (int i = 1; i < argc; i++) {
     string arg = argv[i];
-    int index = arg.find('=', 0);
+    size_t index = arg.find('=', 0);
     if (index == string::npos) {
       *file = arg;
     } else {
diff --git a/samples/shell.cc b/samples/shell.cc
index 342031d..f37e731 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -41,7 +41,7 @@
 // #ifndef USING_V8_SHARED/#endif is a hack until we can resolve whether to
 // still use the shell sample for testing or change to use the developer
 // shell d8 TODO(1272).
-#ifndef USING_V8_SHARED
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
 #include "../src/v8.h"
 #endif  // USING_V8_SHARED
 
@@ -86,7 +86,7 @@
 class SourceGroup {
  public:
   SourceGroup() :
-#ifndef USING_V8_SHARED
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
                   next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
                   done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
                   thread_(NULL),
@@ -95,6 +95,13 @@
                   begin_offset_(0),
                   end_offset_(0) { }
 
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
+  ~SourceGroup() {
+    delete next_semaphore_;
+    delete done_semaphore_;
+  }
+#endif  // USING_V8_SHARED
+
   void Begin(char** argv, int offset) {
     argv_ = const_cast<const char**>(argv);
     begin_offset_ = offset;
@@ -134,7 +141,7 @@
     }
   }
 
-#ifndef USING_V8_SHARED
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
   void StartExecuteInThread() {
     if (thread_ == NULL) {
       thread_ = new IsolateThread(this);
@@ -155,7 +162,7 @@
 #endif  // USING_V8_SHARED
 
  private:
-#ifndef USING_V8_SHARED
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
   static v8::internal::Thread::Options GetThreadOptions() {
     v8::internal::Thread::Options options;
     options.name = "IsolateThread";
@@ -170,7 +177,7 @@
   class IsolateThread : public v8::internal::Thread {
    public:
     explicit IsolateThread(SourceGroup* group)
-        : v8::internal::Thread(NULL, GetThreadOptions()), group_(group) {}
+        : v8::internal::Thread(GetThreadOptions()), group_(group) {}
 
     virtual void Run() {
       group_->ExecuteInThread();
@@ -213,6 +220,34 @@
 static SourceGroup* isolate_sources = NULL;
 
 
+#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) {
+    ASSERT_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
+
+
 int RunMain(int argc, char* argv[]) {
   v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
   v8::HandleScope handle_scope;
@@ -228,7 +263,7 @@
   int num_isolates = 1;
   for (int i = 1; i < argc; i++) {
     if (strcmp(argv[i], "--isolate") == 0) {
-#ifndef USING_V8_SHARED
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
       ++num_isolates;
 #else  // USING_V8_SHARED
       printf("Error: --isolate not supported when linked with shared "
@@ -259,14 +294,14 @@
     }
     current->End(argc);
   }
-#ifndef USING_V8_SHARED
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
   for (int i = 1; i < num_isolates; ++i) {
     isolate_sources[i].StartExecuteInThread();
   }
 #endif  // USING_V8_SHARED
   isolate_sources[0].Execute();
   if (run_shell) RunShell(context);
-#ifndef USING_V8_SHARED
+#if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
   for (int i = 1; i < num_isolates; ++i) {
     isolate_sources[i].WaitForThread();
   }
@@ -303,29 +338,13 @@
   }
 
 #ifdef COMPRESS_STARTUP_DATA_BZ2
-  ASSERT_EQ(v8::StartupData::kBZip2,
-            v8::V8::GetCompressedStartupDataAlgorithm());
-  int compressed_data_count = v8::V8::GetCompressedStartupDataCount();
-  v8::StartupData* compressed_data = new v8::StartupData[compressed_data_count];
-  v8::V8::GetCompressedStartupData(compressed_data);
-  for (int i = 0; i < compressed_data_count; ++i) {
-    char* decompressed = new char[compressed_data[i].raw_size];
-    unsigned int decompressed_size = compressed_data[i].raw_size;
-    int result =
-        BZ2_bzBuffToBuffDecompress(decompressed,
-                                   &decompressed_size,
-                                   const_cast<char*>(compressed_data[i].data),
-                                   compressed_data[i].compressed_size,
-                                   0, 1);
-    if (result != BZ_OK) {
-      fprintf(stderr, "bzip error code: %d\n", result);
-      exit(1);
-    }
-    compressed_data[i].data = decompressed;
-    compressed_data[i].raw_size = decompressed_size;
+  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);
   }
-  v8::V8::SetDecompressedStartupData(compressed_data);
-#endif  // COMPRESS_STARTUP_DATA_BZ2
+#endif
 
   v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
   int result = 0;
@@ -348,13 +367,6 @@
   }
   v8::V8::Dispose();
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  for (int i = 0; i < compressed_data_count; ++i) {
-    delete[] compressed_data[i].data;
-  }
-  delete[] compressed_data;
-#endif  // COMPRESS_STARTUP_DATA_BZ2
-
   return result;
 }
 
@@ -492,14 +504,42 @@
 
 v8::Handle<v8::Value> CreateExternalArray(const v8::Arguments& args,
                                           v8::ExternalArrayType type,
-                                          int element_size) {
+                                          size_t element_size) {
+  assert(element_size == 1 ||
+         element_size == 2 ||
+         element_size == 4 ||
+         element_size == 8);
   if (args.Length() != 1) {
     return v8::ThrowException(
         v8::String::New("Array constructor needs one parameter."));
   }
-  int length = args[0]->Int32Value();
-  void* data = malloc(length * element_size);
-  memset(data, 0, length * element_size);
+  static const int kMaxLength = 0x3fffffff;
+  size_t length = 0;
+  if (args[0]->IsUint32()) {
+    length = args[0]->Uint32Value();
+  } else if (args[0]->IsNumber()) {
+    double raw_length = args[0]->NumberValue();
+    if (raw_length < 0) {
+      return v8::ThrowException(
+          v8::String::New("Array length must not be negative."));
+    }
+    if (raw_length > kMaxLength) {
+      return v8::ThrowException(
+          v8::String::New("Array length exceeds maximum length."));
+    }
+    length = static_cast<size_t>(raw_length);
+  } else {
+    return v8::ThrowException(
+        v8::String::New("Array length must be a number."));
+  }
+  if (length > static_cast<size_t>(kMaxLength)) {
+    return v8::ThrowException(
+        v8::String::New("Array length exceeds maximum length."));
+  }
+  void* data = calloc(length, element_size);
+  if (data == NULL) {
+    return v8::ThrowException(v8::String::New("Memory allocation failed."));
+  }
   v8::Handle<v8::Object> array = v8::Object::New();
   v8::Persistent<v8::Object> persistent_array =
       v8::Persistent<v8::Object>::New(array);
diff --git a/src/SConscript b/src/SConscript
index fe21d02..b45a567 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -85,7 +85,6 @@
     inspector.cc
     interpreter-irregexp.cc
     isolate.cc
-    json-parser.cc
     jsregexp.cc
     lithium-allocator.cc
     lithium.cc
@@ -127,7 +126,9 @@
     utils.cc
     v8-counters.cc
     v8.cc
+    v8conversions.cc
     v8threads.cc
+    v8utils.cc
     variables.cc
     version.cc
     zone.cc
@@ -237,11 +238,19 @@
     scanner-base.cc
     token.cc
     unicode.cc
+    utils.cc
     """)
 }
 
 
-D8_FILES = {
+D8_LIGHT_FILES = {
+  'all': [
+    'd8.cc'
+  ]
+}
+
+
+D8_FULL_FILES = {
   'all': [
     'd8.cc', 'd8-debug.cc'
   ],
@@ -313,26 +322,39 @@
   env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C)
   env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions')
 
+  def BuildJS2CEnv(type):
+    js2c_env = { 'TYPE': type, 'COMPRESSION': 'off' }
+    if 'COMPRESS_STARTUP_DATA_BZ2' in env['CPPDEFINES']:
+      js2c_env['COMPRESSION'] = 'bz2'
+    return js2c_env
+
   # Build the standard platform-independent source files.
   source_files = context.GetRelevantSources(SOURCES)
-
-  d8_files = context.GetRelevantSources(D8_FILES)
-  d8_js = env.JS2C('d8-js.cc', 'd8.js', TYPE='D8')
+  d8_js = env.JS2C('d8-js.cc', 'd8.js', **{'TYPE': 'D8', 'COMPRESSION': 'off'})
   d8_js_obj = context.ConfigureObject(env, d8_js, CPPPATH=['.'])
-  d8_objs = [context.ConfigureObject(env, [d8_files]), d8_js_obj]
+  if context.options['library'] == 'shared':
+    d8_files = context.GetRelevantSources(D8_LIGHT_FILES)
+    d8_objs = []
+  else:
+    d8_files = context.GetRelevantSources(D8_FULL_FILES)
+    d8_objs = [d8_js_obj]
+  d8_objs.append(context.ConfigureObject(env, [d8_files]))
 
   # Combine the JavaScript library files into a single C++ file and
   # compile it.
   library_files = [s for s in LIBRARY_FILES]
   library_files.append('macros.py')
-  libraries_src = env.JS2C(['libraries.cc'], library_files, TYPE='CORE')
+  libraries_src = env.JS2C(
+    ['libraries.cc'], library_files, **BuildJS2CEnv('CORE'))
   libraries_obj = context.ConfigureObject(env, libraries_src, CPPPATH=['.'])
 
   # Combine the experimental JavaScript library files into a C++ file
   # and compile it.
   experimental_library_files = [ s for s in EXPERIMENTAL_LIBRARY_FILES ]
   experimental_library_files.append('macros.py')
-  experimental_libraries_src = env.JS2C(['experimental-libraries.cc'], experimental_library_files, TYPE='EXPERIMENTAL')
+  experimental_libraries_src = env.JS2C(['experimental-libraries.cc'],
+                                        experimental_library_files,
+                                        **BuildJS2CEnv('EXPERIMENTAL'))
   experimental_libraries_obj = context.ConfigureObject(env, experimental_libraries_src, CPPPATH=['.'])
 
   source_objs = context.ConfigureObject(env, source_files)
diff --git a/src/accessors.cc b/src/accessors.cc
index 255e3dd..e7d6aa0 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -688,7 +688,6 @@
         index_(0) {
     GetFunctions();
   }
-
   JSFunction* next() {
     if (functions_.length() == 0) return NULL;
     JSFunction* next_function = functions_[index_];
diff --git a/src/api.cc b/src/api.cc
index 5980854..b0e9775 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -38,6 +38,7 @@
 #include "global-handles.h"
 #include "heap-profiler.h"
 #include "messages.h"
+#include "natives.h"
 #include "parser.h"
 #include "platform.h"
 #include "profile-generator-inl.h"
@@ -53,16 +54,11 @@
 
 #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
 
-#ifdef ENABLE_VMSTATE_TRACKING
 #define ENTER_V8(isolate)                                        \
   ASSERT((isolate)->IsInitialized());                           \
   i::VMState __state__((isolate), i::OTHER)
 #define LEAVE_V8(isolate) \
   i::VMState __state__((isolate), i::EXTERNAL)
-#else
-#define ENTER_V8(isolate) ((void) 0)
-#define LEAVE_V8(isolate) ((void) 0)
-#endif
 
 namespace v8 {
 
@@ -97,13 +93,11 @@
     }                                                                          \
   } while (false)
 
-// TODO(isolates): Add a parameter to this macro for an isolate.
 
-#define API_ENTRY_CHECK(msg)                                                   \
+#define API_ENTRY_CHECK(isolate, msg)                                          \
   do {                                                                         \
     if (v8::Locker::IsActive()) {                                              \
-      ApiCheck(i::Isolate::Current()->thread_manager()->                       \
-                  IsLockedByCurrentThread(),                                   \
+      ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(),           \
                msg,                                                            \
                "Entering the V8 API without proper locking in place");         \
     }                                                                          \
@@ -115,9 +109,7 @@
 
 static void DefaultFatalErrorHandler(const char* location,
                                      const char* message) {
-#ifdef ENABLE_VMSTATE_TRACKING
   i::VMState __state__(i::Isolate::Current(), i::OTHER);
-#endif
   API_Fatal(location, message);
 }
 
@@ -176,8 +168,8 @@
   heap_stats.pending_global_handle_count = &pending_global_handle_count;
   int near_death_global_handle_count;
   heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
-  int destroyed_global_handle_count;
-  heap_stats.destroyed_global_handle_count = &destroyed_global_handle_count;
+  int free_global_handle_count;
+  heap_stats.free_global_handle_count = &free_global_handle_count;
   intptr_t memory_allocator_size;
   heap_stats.memory_allocator_size = &memory_allocator_size;
   intptr_t memory_allocator_capacity;
@@ -311,6 +303,46 @@
 }
 
 
+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 {
+      ASSERT_EQ(0, compressed_data[i].raw_size);
+    }
+    compressed_data[i].data = decompressed;
+  }
+  V8::SetDecompressedStartupData(compressed_data);
+  return 0;
+}
+
+
 StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
 #ifdef COMPRESS_STARTUP_DATA_BZ2
   return StartupData::kBZip2;
@@ -323,6 +355,8 @@
 enum CompressedStartupDataItems {
   kSnapshot = 0,
   kSnapshotContext,
+  kLibraries,
+  kExperimentalLibraries,
   kCompressedStartupDataCount
 };
 
@@ -347,6 +381,21 @@
   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
 }
 
@@ -362,6 +411,20 @@
   i::Snapshot::set_context_raw_data(
       reinterpret_cast<const i::byte*>(
           decompressed_data[kSnapshotContext].data));
+
+  ASSERT_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);
+
+  ASSERT_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
 }
 
@@ -573,8 +636,8 @@
 
 
 HandleScope::HandleScope() {
-  API_ENTRY_CHECK("HandleScope::HandleScope");
   i::Isolate* isolate = i::Isolate::Current();
+  API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
   v8::ImplementationUtilities::HandleScopeData* current =
       isolate->handle_scope_data();
   isolate_ = isolate;
@@ -630,12 +693,11 @@
 
 
 void Context::Enter() {
-  // TODO(isolates): Context should have a pointer to isolate.
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Handle<i::Context> env = Utils::OpenHandle(this);
+  i::Isolate* isolate = env->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
   ENTER_V8(isolate);
 
-  i::Handle<i::Context> env = Utils::OpenHandle(this);
   isolate->handle_scope_implementer()->EnterContext(env);
 
   isolate->handle_scope_implementer()->SaveContext(isolate->context());
@@ -644,7 +706,9 @@
 
 
 void Context::Exit() {
-  // TODO(isolates): Context should have a pointer to isolate.
+  // Exit is essentially a static function and doesn't use the
+  // receiver, so we have to get the current isolate from the thread
+  // local.
   i::Isolate* isolate = i::Isolate::Current();
   if (!isolate->IsInitialized()) return;
 
@@ -662,41 +726,31 @@
 
 
 void Context::SetData(v8::Handle<String> data) {
-  // TODO(isolates): Context should have a pointer to isolate.
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Handle<i::Context> env = Utils::OpenHandle(this);
+  i::Isolate* isolate = env->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
-  ENTER_V8(isolate);
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::Context> env = Utils::OpenHandle(this);
-    i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
-    ASSERT(env->IsGlobalContext());
-    if (env->IsGlobalContext()) {
-      env->set_data(*raw_data);
-    }
+  i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
+  ASSERT(env->IsGlobalContext());
+  if (env->IsGlobalContext()) {
+    env->set_data(*raw_data);
   }
 }
 
 
 v8::Local<v8::Value> Context::GetData() {
-  // TODO(isolates): Context should have a pointer to isolate.
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Handle<i::Context> env = Utils::OpenHandle(this);
+  i::Isolate* isolate = env->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
     return v8::Local<Value>();
   }
-  ENTER_V8(isolate);
   i::Object* raw_result = NULL;
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::Context> env = Utils::OpenHandle(this);
-    ASSERT(env->IsGlobalContext());
-    if (env->IsGlobalContext()) {
-      raw_result = env->data();
-    } else {
-      return Local<Value>();
-    }
+  ASSERT(env->IsGlobalContext());
+  if (env->IsGlobalContext()) {
+    raw_result = env->data();
+  } else {
+    return Local<Value>();
   }
-  i::Handle<i::Object> result(raw_result);
+  i::Handle<i::Object> result(raw_result, isolate);
   return Utils::ToLocal(result);
 }
 
@@ -823,6 +877,7 @@
       i::Handle<i::FunctionTemplateInfo> info) {
   info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
   info->set_flag(0);
+  info->set_prototype_attributes(i::Smi::FromInt(v8::None));
 }
 
 
@@ -925,6 +980,7 @@
 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);
   i::FixedArray* types = i::FixedArray::cast(info->types());
@@ -1044,6 +1100,17 @@
 }
 
 
+void FunctionTemplate::SetPrototypeAttributes(int attributes) {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
+    return;
+  }
+  ENTER_V8(isolate);
+  Utils::OpenHandle(this)->set_prototype_attributes(
+      i::Smi::FromInt(attributes));
+}
+
+
 void FunctionTemplate::SetNamedInstancePropertyHandler(
       NamedPropertyGetter getter,
       NamedPropertySetter setter,
@@ -1545,26 +1612,27 @@
 
 
 v8::TryCatch::TryCatch()
-    : next_(i::Isolate::Current()->try_catch_handler_address()),
-      exception_(HEAP->the_hole_value()),
+    : isolate_(i::Isolate::Current()),
+      next_(isolate_->try_catch_handler_address()),
+      exception_(isolate_->heap()->the_hole_value()),
       message_(i::Smi::FromInt(0)),
       is_verbose_(false),
       can_continue_(true),
       capture_message_(true),
       rethrow_(false) {
-  i::Isolate::Current()->RegisterTryCatchHandler(this);
+  isolate_->RegisterTryCatchHandler(this);
 }
 
 
 v8::TryCatch::~TryCatch() {
-  i::Isolate* isolate = i::Isolate::Current();
+  ASSERT(isolate_ == i::Isolate::Current());
   if (rethrow_) {
     v8::HandleScope scope;
     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
-    isolate->UnregisterTryCatchHandler(this);
+    isolate_->UnregisterTryCatchHandler(this);
     v8::ThrowException(exc);
   } else {
-    isolate->UnregisterTryCatchHandler(this);
+    isolate_->UnregisterTryCatchHandler(this);
   }
 }
 
@@ -1587,10 +1655,11 @@
 
 
 v8::Local<Value> v8::TryCatch::Exception() const {
+  ASSERT(isolate_ == i::Isolate::Current());
   if (HasCaught()) {
     // Check for out of memory exception.
     i::Object* exception = reinterpret_cast<i::Object*>(exception_);
-    return v8::Utils::ToLocal(i::Handle<i::Object>(exception));
+    return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
   } else {
     return v8::Local<Value>();
   }
@@ -1598,15 +1667,17 @@
 
 
 v8::Local<Value> v8::TryCatch::StackTrace() const {
+  ASSERT(isolate_ == i::Isolate::Current());
   if (HasCaught()) {
     i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
     if (!raw_obj->IsJSObject()) return v8::Local<Value>();
-    v8::HandleScope scope;
-    i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj));
-    i::Handle<i::String> name = FACTORY->LookupAsciiSymbol("stack");
-    if (!obj->HasProperty(*name))
-      return v8::Local<Value>();
-    return scope.Close(v8::Utils::ToLocal(i::GetProperty(obj, name)));
+    i::HandleScope scope(isolate_);
+    i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
+    i::Handle<i::String> name = isolate_->factory()->LookupAsciiSymbol("stack");
+    if (!obj->HasProperty(*name)) return v8::Local<Value>();
+    i::Handle<i::Object> value = i::GetProperty(obj, name);
+    if (value.is_null()) return v8::Local<Value>();
+    return v8::Utils::ToLocal(scope.CloseAndEscape(value));
   } else {
     return v8::Local<Value>();
   }
@@ -1614,9 +1685,10 @@
 
 
 v8::Local<v8::Message> v8::TryCatch::Message() const {
+  ASSERT(isolate_ == i::Isolate::Current());
   if (HasCaught() && message_ != i::Smi::FromInt(0)) {
     i::Object* message = reinterpret_cast<i::Object*>(message_);
-    return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
+    return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
   } else {
     return v8::Local<v8::Message>();
   }
@@ -1624,7 +1696,8 @@
 
 
 void v8::TryCatch::Reset() {
-  exception_ = HEAP->the_hole_value();
+  ASSERT(isolate_ == i::Isolate::Current());
+  exception_ = isolate_->heap()->the_hole_value();
   message_ = i::Smi::FromInt(0);
 }
 
@@ -2094,6 +2167,65 @@
 }
 
 
+bool Value::IsStringObject() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Value::IsStringObject()")) return false;
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  return obj->HasSpecificClassOf(isolate->heap()->String_symbol());
+}
+
+
+bool Value::IsNumberObject() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Value::IsNumberObject()")) return false;
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  return obj->HasSpecificClassOf(isolate->heap()->Number_symbol());
+}
+
+
+static i::Object* LookupBuiltin(i::Isolate* isolate,
+                                const char* builtin_name) {
+  i::Handle<i::String> symbol =
+      isolate->factory()->LookupAsciiSymbol(builtin_name);
+  i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
+  return builtins->GetPropertyNoExceptionThrown(*symbol);
+}
+
+
+static bool CheckConstructor(i::Isolate* isolate,
+                             i::Handle<i::JSObject> obj,
+                             const char* class_name) {
+  return obj->map()->constructor() == LookupBuiltin(isolate, class_name);
+}
+
+
+bool Value::IsNativeError() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Value::IsNativeError()")) return false;
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  if (obj->IsJSObject()) {
+    i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
+    return CheckConstructor(isolate, js_obj, "$Error") ||
+        CheckConstructor(isolate, js_obj, "$EvalError") ||
+        CheckConstructor(isolate, js_obj, "$RangeError") ||
+        CheckConstructor(isolate, js_obj, "$ReferenceError") ||
+        CheckConstructor(isolate, js_obj, "$SyntaxError") ||
+        CheckConstructor(isolate, js_obj, "$TypeError") ||
+        CheckConstructor(isolate, js_obj, "$URIError");
+  } else {
+    return false;
+  }
+}
+
+
+bool Value::IsBooleanObject() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Value::IsBooleanObject()")) return false;
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  return obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol());
+}
+
+
 bool Value::IsRegExp() const {
   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsRegExp()")) return false;
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
@@ -2289,6 +2421,36 @@
 }
 
 
+void v8::StringObject::CheckCast(v8::Value* that) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::StringObject::Cast()")) return;
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_symbol()),
+           "v8::StringObject::Cast()",
+           "Could not convert to StringObject");
+}
+
+
+void v8::NumberObject::CheckCast(v8::Value* that) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::NumberObject::Cast()")) return;
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_symbol()),
+           "v8::NumberObject::Cast()",
+           "Could not convert to NumberObject");
+}
+
+
+void v8::BooleanObject::CheckCast(v8::Value* that) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::BooleanObject::Cast()")) return;
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_symbol()),
+           "v8::BooleanObject::Cast()",
+           "Could not convert to BooleanObject");
+}
+
+
 void v8::RegExp::CheckCast(v8::Value* that) {
   if (IsDeadCheck(i::Isolate::Current(), "v8::RegExp::Cast()")) return;
   i::Handle<i::Object> obj = Utils::OpenHandle(that);
@@ -2632,6 +2794,26 @@
 }
 
 
+PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::GetPropertyAttribute()",
+             return static_cast<PropertyAttribute>(NONE));
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
+  if (!key_obj->IsString()) {
+    EXCEPTION_PREAMBLE(isolate);
+    key_obj = i::Execution::ToString(key_obj, &has_pending_exception);
+    EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
+  }
+  i::Handle<i::String> key_string = i::Handle<i::String>::cast(key_obj);
+  PropertyAttributes result = self->GetPropertyAttribute(*key_string);
+  if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
+  return static_cast<PropertyAttribute>(result);
+}
+
+
 Local<Value> v8::Object::GetPrototype() {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
@@ -2697,6 +2879,25 @@
 }
 
 
+Local<Array> v8::Object::GetOwnPropertyNames() {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
+             return Local<v8::Array>());
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  i::Handle<i::FixedArray> value =
+      i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY);
+  // Because we use caching to speed up enumeration it is important
+  // to never change the result of the basic enumeration function so
+  // we clone the result.
+  i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
+  i::Handle<i::JSArray> result =
+      isolate->factory()->NewJSArrayWithElements(elms);
+  return Utils::ToLocal(scope.CloseAndEscape(result));
+}
+
+
 Local<String> v8::Object::ObjectProtoToString() {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
@@ -3392,6 +3593,7 @@
 void Function::SetName(v8::Handle<v8::String> name) {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
+  USE(isolate);
   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   func->shared()->set_name(*Utils::OpenHandle(*name));
 }
@@ -3751,6 +3953,11 @@
 }
 
 
+void v8::V8::SetEntropySource(EntropySource source) {
+  i::V8::SetEntropySource(source);
+}
+
+
 bool v8::V8::Dispose() {
   i::Isolate* isolate = i::Isolate::Current();
   if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
@@ -4262,6 +4469,9 @@
   if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
     return false;
   }
+  if (isolate->heap()->IsInGCPostProcessing()) {
+    return false;
+  }
   bool result = obj->MakeExternal(resource);
   if (result && !obj->IsSymbol()) {
     isolate->heap()->external_string_table()->AddString(*obj);
@@ -4294,6 +4504,9 @@
   if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
     return false;
   }
+  if (isolate->heap()->IsInGCPostProcessing()) {
+    return false;
+  }
   bool result = obj->MakeExternal(resource);
   if (result && !obj->IsSymbol()) {
     isolate->heap()->external_string_table()->AddString(*obj);
@@ -4328,6 +4541,73 @@
 }
 
 
+Local<v8::Value> v8::NumberObject::New(double value) {
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
+  LOG_API(isolate, "NumberObject::New");
+  ENTER_V8(isolate);
+  i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
+  i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
+  return Utils::ToLocal(obj);
+}
+
+
+double v8::NumberObject::NumberValue() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::NumberObject::NumberValue()")) return 0;
+  LOG_API(isolate, "NumberObject::NumberValue");
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+  return jsvalue->value()->Number();
+}
+
+
+Local<v8::Value> v8::BooleanObject::New(bool value) {
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
+  LOG_API(isolate, "BooleanObject::New");
+  ENTER_V8(isolate);
+  i::Handle<i::Object> boolean(value ? isolate->heap()->true_value()
+                                     : isolate->heap()->false_value());
+  i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
+  return Utils::ToLocal(obj);
+}
+
+
+bool v8::BooleanObject::BooleanValue() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::BooleanObject::BooleanValue()")) return 0;
+  LOG_API(isolate, "BooleanObject::BooleanValue");
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+  return jsvalue->value()->IsTrue();
+}
+
+
+Local<v8::Value> v8::StringObject::New(Handle<String> value) {
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
+  LOG_API(isolate, "StringObject::New");
+  ENTER_V8(isolate);
+  i::Handle<i::Object> obj =
+      isolate->factory()->ToObject(Utils::OpenHandle(*value));
+  return Utils::ToLocal(obj);
+}
+
+
+Local<v8::String> v8::StringObject::StringValue() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::StringObject::StringValue()")) {
+    return Local<v8::String>();
+  }
+  LOG_API(isolate, "StringObject::StringValue");
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+  return Utils::ToLocal(
+      i::Handle<i::String>(i::String::cast(jsvalue->value())));
+}
+
+
 Local<v8::Value> v8::Date::New(double time) {
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Date::New()");
@@ -4726,73 +5006,20 @@
 
 
 void V8::PauseProfiler() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  PauseProfilerEx(PROFILER_MODULE_CPU);
-#endif
+  i::Isolate* isolate = i::Isolate::Current();
+  isolate->logger()->PauseProfiler();
 }
 
 
 void V8::ResumeProfiler() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  ResumeProfilerEx(PROFILER_MODULE_CPU);
-#endif
+  i::Isolate* isolate = i::Isolate::Current();
+  isolate->logger()->ResumeProfiler();
 }
 
 
 bool V8::IsProfilerPaused() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  return LOGGER->GetActiveProfilerModules() & PROFILER_MODULE_CPU;
-#else
-  return true;
-#endif
-}
-
-
-void V8::ResumeProfilerEx(int flags, int tag) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
-  if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
-    // Snapshot mode: resume modules, perform GC, then pause only
-    // those modules which haven't been started prior to making a
-    // snapshot.
-
-    // Make a GC prior to taking a snapshot.
-    isolate->heap()->CollectAllGarbage(false);
-    // Reset snapshot flag and CPU module flags.
-    flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
-    const int current_flags = isolate->logger()->GetActiveProfilerModules();
-    isolate->logger()->ResumeProfiler(flags, tag);
-    isolate->heap()->CollectAllGarbage(false);
-    isolate->logger()->PauseProfiler(~current_flags & flags, tag);
-  } else {
-    isolate->logger()->ResumeProfiler(flags, tag);
-  }
-#endif
-}
-
-
-void V8::PauseProfilerEx(int flags, int tag) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  LOGGER->PauseProfiler(flags, tag);
-#endif
-}
-
-
-int V8::GetActiveProfilerModules() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  return LOGGER->GetActiveProfilerModules();
-#else
-  return PROFILER_MODULE_NONE;
-#endif
-}
-
-
-int V8::GetLogLines(int from_pos, char* dest_buf, int max_size) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  ASSERT(max_size >= kMinimumSizeForLogLinesBuffer);
-  return LOGGER->GetLogLines(from_pos, dest_buf, max_size);
-#endif
-  return 0;
+  return isolate->logger()->IsProfilerPaused();
 }
 
 
@@ -4806,7 +5033,7 @@
 void V8::TerminateExecution(int thread_id) {
   i::Isolate* isolate = i::Isolate::Current();
   if (!isolate->IsInitialized()) return;
-  API_ENTRY_CHECK("V8::TerminateExecution()");
+  API_ENTRY_CHECK(isolate, "V8::TerminateExecution()");
   // If the thread_id identifies the current thread just terminate
   // execution right away.  Otherwise, ask the thread manager to
   // terminate the thread with the given id if any.
@@ -4829,9 +5056,10 @@
 }
 
 
-bool V8::IsExecutionTerminating() {
-  i::Isolate* isolate = i::Isolate::Current();
-  return IsExecutionTerminatingCheck(isolate);
+bool V8::IsExecutionTerminating(Isolate* isolate) {
+  i::Isolate* i_isolate = isolate != NULL ?
+      reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
+  return IsExecutionTerminatingCheck(i_isolate);
 }
 
 
@@ -5255,8 +5483,6 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 Handle<String> CpuProfileNode::GetFunctionName() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
@@ -5443,6 +5669,7 @@
       reinterpret_cast<const i::HeapGraphEdge*>(edge));
 }
 
+
 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
@@ -5511,19 +5738,10 @@
 uint64_t HeapGraphNode::GetId() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
-  ASSERT(ToInternal(this)->snapshot()->type() != i::HeapSnapshot::kAggregated);
   return ToInternal(this)->id();
 }
 
 
-int HeapGraphNode::GetInstancesCount() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  IsDeadCheck(isolate, "v8::HeapGraphNode::GetInstancesCount");
-  ASSERT(ToInternal(this)->snapshot()->type() == i::HeapSnapshot::kAggregated);
-  return static_cast<int>(ToInternal(this)->id());
-}
-
-
 int HeapGraphNode::GetSelfSize() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
@@ -5630,6 +5848,21 @@
 }
 
 
+int HeapSnapshot::GetNodesCount() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
+  return ToInternal(this)->entries()->length();
+}
+
+
+const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
+  i::Isolate* isolate = i::Isolate::Current();
+  IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
+  return reinterpret_cast<const HeapGraphNode*>(
+      ToInternal(this)->entries()->at(index));
+}
+
+
 void HeapSnapshot::Serialize(OutputStream* stream,
                              HeapSnapshot::SerializationFormat format) const {
   i::Isolate* isolate = i::Isolate::Current();
@@ -5681,9 +5914,6 @@
     case HeapSnapshot::kFull:
       internal_type = i::HeapSnapshot::kFull;
       break;
-    case HeapSnapshot::kAggregated:
-      internal_type = i::HeapSnapshot::kAggregated;
-      break;
     default:
       UNREACHABLE();
   }
@@ -5706,7 +5936,6 @@
                                                              callback);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 
 v8::Testing::StressType internal::Testing::stress_type_ =
diff --git a/src/api.h b/src/api.h
index 5846414..8d2e778 100644
--- a/src/api.h
+++ b/src/api.h
@@ -398,7 +398,6 @@
 // data.
 class HandleScopeImplementer {
  public:
-
   explicit HandleScopeImplementer(Isolate* isolate)
       : isolate_(isolate),
         blocks_(0),
diff --git a/src/apinatives.js b/src/apinatives.js
index ca2bbf5..193863f 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -73,7 +73,15 @@
       if (name) %FunctionSetName(fun, name);
       cache[serialNumber] = fun;
       var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
-      fun.prototype = prototype ? Instantiate(prototype) : {};
+      var attributes = %GetTemplateField(data, kApiPrototypeAttributesOffset);
+      if (attributes != NONE) {
+        %IgnoreAttributesAndSetProperty(
+            fun, "prototype",
+            prototype ? Instantiate(prototype) : {},
+            attributes);
+      } else {
+        fun.prototype = prototype ? Instantiate(prototype) : {};
+      }
       %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
       var parent = %GetTemplateField(data, kApiParentTemplateOffset);
       if (parent) {
diff --git a/src/arguments.h b/src/arguments.h
index a080581..72bbe1d 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -63,6 +63,14 @@
     return Handle<S>(reinterpret_cast<S**>(value));
   }
 
+  int smi_at(int index) {
+    return Smi::cast((*this)[index])->value();
+  }
+
+  double number_at(int index) {
+    return (*this)[index]->Number();
+  }
+
   // Get the total number of arguments including the receiver.
   int length() const { return length_; }
 
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index c7050a7..89df079 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -320,13 +320,13 @@
   ASSERT(buffer_ != NULL);
   pc_ = buffer_;
   reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
-  num_prinfo_ = 0;
+  num_pending_reloc_info_ = 0;
   next_buffer_check_ = 0;
   const_pool_blocked_nesting_ = 0;
   no_const_pool_before_ = 0;
-  last_const_pool_end_ = 0;
+  first_const_pool_use_ = -1;
   last_bound_pos_ = 0;
-  ast_id_for_reloc_info_ = kNoASTId;
+  ClearRecordedAstId();
 }
 
 
@@ -346,7 +346,7 @@
 void Assembler::GetCode(CodeDesc* desc) {
   // Emit constant pool if necessary.
   CheckConstPool(true, false);
-  ASSERT(num_prinfo_ == 0);
+  ASSERT(num_pending_reloc_info_ == 0);
 
   // Setup code descriptor.
   desc->buffer = buffer_;
@@ -873,7 +873,7 @@
   emit(instr | rn.code()*B16 | rd.code()*B12);
   if (rn.is(pc) || x.rm_.is(pc)) {
     // Block constant pool emission for one instruction after reading pc.
-    BlockConstPoolBefore(pc_offset() + kInstrSize);
+    BlockConstPoolFor(1);
   }
 }
 
@@ -997,7 +997,7 @@
 
   // Block the emission of the constant pool, since the branch instruction must
   // be emitted at the pc offset recorded by the label.
-  BlockConstPoolBefore(pc_offset() + kInstrSize);
+  BlockConstPoolFor(1);
   return target_pos - (pc_offset() + kPcLoadDelta);
 }
 
@@ -1493,15 +1493,17 @@
 void Assembler::stop(const char* msg, Condition cond, int32_t code) {
 #ifndef __arm__
   ASSERT(code >= kDefaultStopCode);
-  // The Simulator will handle the stop instruction and get the message address.
-  // It expects to find the address just after the svc instruction.
-  BlockConstPoolFor(2);
-  if (code >= 0) {
-    svc(kStopCode + code, cond);
-  } else {
-    svc(kStopCode + kMaxStopCode, cond);
+  {
+    // The Simulator will handle the stop instruction and get the message
+    // address. It expects to find the address just after the svc instruction.
+    BlockConstPoolScope block_const_pool(this);
+    if (code >= 0) {
+      svc(kStopCode + code, cond);
+    } else {
+      svc(kStopCode + kMaxStopCode, cond);
+    }
+    emit(reinterpret_cast<Instr>(msg));
   }
-  emit(reinterpret_cast<Instr>(msg));
 #else  // def __arm__
 #ifdef CAN_USE_ARMV5_INSTRUCTIONS
   if (cond != al) {
@@ -2406,11 +2408,6 @@
 }
 
 
-void Assembler::BlockConstPoolFor(int instructions) {
-  BlockConstPoolBefore(pc_offset() + instructions * kInstrSize);
-}
-
-
 // Debugging.
 void Assembler::RecordJSReturn() {
   positions_recorder()->WriteRecordedPositions();
@@ -2474,8 +2471,8 @@
   // to relocate any emitted relocation entries.
 
   // Relocate pending relocation entries.
-  for (int i = 0; i < num_prinfo_; i++) {
-    RelocInfo& rinfo = prinfo_[i];
+  for (int i = 0; i < num_pending_reloc_info_; i++) {
+    RelocInfo& rinfo = pending_reloc_info_[i];
     ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
            rinfo.rmode() != RelocInfo::POSITION);
     if (rinfo.rmode() != RelocInfo::JS_RETURN) {
@@ -2489,7 +2486,7 @@
   // No relocation info should be pending while using db. db is used
   // to write pure data with no pointers and the constant pool should
   // be emitted before using db.
-  ASSERT(num_prinfo_ == 0);
+  ASSERT(num_pending_reloc_info_ == 0);
   CheckBuffer();
   *reinterpret_cast<uint8_t*>(pc_) = data;
   pc_ += sizeof(uint8_t);
@@ -2500,7 +2497,7 @@
   // No relocation info should be pending while using dd. dd is used
   // to write pure data with no pointers and the constant pool should
   // be emitted before using dd.
-  ASSERT(num_prinfo_ == 0);
+  ASSERT(num_pending_reloc_info_ == 0);
   CheckBuffer();
   *reinterpret_cast<uint32_t*>(pc_) = data;
   pc_ += sizeof(uint32_t);
@@ -2517,11 +2514,14 @@
            || RelocInfo::IsPosition(rmode));
     // These modes do not need an entry in the constant pool.
   } else {
-    ASSERT(num_prinfo_ < kMaxNumPRInfo);
-    prinfo_[num_prinfo_++] = rinfo;
+    ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo);
+    if (num_pending_reloc_info_ == 0) {
+      first_const_pool_use_ = pc_offset();
+    }
+    pending_reloc_info_[num_pending_reloc_info_++] = rinfo;
     // Make sure the constant pool is not emitted in place of the next
     // instruction for which we just recorded relocation info.
-    BlockConstPoolBefore(pc_offset() + kInstrSize);
+    BlockConstPoolFor(1);
   }
   if (rinfo.rmode() != RelocInfo::NONE) {
     // Don't record external references unless the heap will be serialized.
@@ -2537,9 +2537,8 @@
     }
     ASSERT(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
     if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
-      ASSERT(ast_id_for_reloc_info_ != kNoASTId);
-      RelocInfo reloc_info_with_ast_id(pc_, rmode, ast_id_for_reloc_info_);
-      ast_id_for_reloc_info_ = kNoASTId;
+      RelocInfo reloc_info_with_ast_id(pc_, rmode, RecordedAstId());
+      ClearRecordedAstId();
       reloc_info_writer.Write(&reloc_info_with_ast_id);
     } else {
       reloc_info_writer.Write(&rinfo);
@@ -2548,111 +2547,112 @@
 }
 
 
-void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
-  // Calculate the offset of the next check. It will be overwritten
-  // when a const pool is generated or when const pools are being
-  // blocked for a specific range.
-  next_buffer_check_ = pc_offset() + kCheckConstInterval;
-
-  // There is nothing to do if there are no pending relocation info entries.
-  if (num_prinfo_ == 0) return;
-
-  // We emit a constant pool at regular intervals of about kDistBetweenPools
-  // or when requested by parameter force_emit (e.g. after each function).
-  // We prefer not to emit a jump unless the max distance is reached or if we
-  // are running low on slots, which can happen if a lot of constants are being
-  // emitted (e.g. --debug-code and many static references).
-  int dist = pc_offset() - last_const_pool_end_;
-  if (!force_emit && dist < kMaxDistBetweenPools &&
-      (require_jump || dist < kDistBetweenPools) &&
-      // TODO(1236125): Cleanup the "magic" number below. We know that
-      // the code generation will test every kCheckConstIntervalInst.
-      // Thus we are safe as long as we generate less than 7 constant
-      // entries per instruction.
-      (num_prinfo_ < (kMaxNumPRInfo - (7 * kCheckConstIntervalInst)))) {
-    return;
+void Assembler::BlockConstPoolFor(int instructions) {
+  int pc_limit = pc_offset() + instructions * kInstrSize;
+  if (no_const_pool_before_ < pc_limit) {
+    // If there are some pending entries, the constant pool cannot be blocked
+    // further than first_const_pool_use_ + kMaxDistToPool
+    ASSERT((num_pending_reloc_info_ == 0) ||
+           (pc_limit < (first_const_pool_use_ + kMaxDistToPool)));
+    no_const_pool_before_ = pc_limit;
   }
 
-  // If we did not return by now, we need to emit the constant pool soon.
+  if (next_buffer_check_ < no_const_pool_before_) {
+    next_buffer_check_ = no_const_pool_before_;
+  }
+}
 
-  // However, some small sequences of instructions must not be broken up by the
-  // insertion of a constant pool; such sequences are protected by setting
-  // either const_pool_blocked_nesting_ or no_const_pool_before_, which are
-  // both checked here. Also, recursive calls to CheckConstPool are blocked by
-  // no_const_pool_before_.
-  if (const_pool_blocked_nesting_ > 0 || pc_offset() < no_const_pool_before_) {
-    // Emission is currently blocked; make sure we try again as soon as
-    // possible.
-    if (const_pool_blocked_nesting_ > 0) {
-      next_buffer_check_ = pc_offset() + kInstrSize;
-    } else {
-      next_buffer_check_ = no_const_pool_before_;
-    }
 
+void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
+  // Some short sequence of instruction mustn't be broken up by constant pool
+  // emission, such sequences are protected by calls to BlockConstPoolFor and
+  // BlockConstPoolScope.
+  if (is_const_pool_blocked()) {
     // Something is wrong if emission is forced and blocked at the same time.
     ASSERT(!force_emit);
     return;
   }
 
-  int jump_instr = require_jump ? kInstrSize : 0;
+  // There is nothing to do if there are no pending constant pool entries.
+  if (num_pending_reloc_info_ == 0)  {
+    // Calculate the offset of the next check.
+    next_buffer_check_ = pc_offset() + kCheckPoolInterval;
+    return;
+  }
+
+  // We emit a constant pool when:
+  //  * requested to do so by parameter force_emit (e.g. after each function).
+  //  * the distance to the first instruction accessing the constant pool is
+  //    kAvgDistToPool or more.
+  //  * no jump is required and the distance to the first instruction accessing
+  //    the constant pool is at least kMaxDistToPool / 2.
+  ASSERT(first_const_pool_use_ >= 0);
+  int dist = pc_offset() - first_const_pool_use_;
+  if (!force_emit && dist < kAvgDistToPool &&
+      (require_jump || (dist < (kMaxDistToPool / 2)))) {
+    return;
+  }
 
   // Check that the code buffer is large enough before emitting the constant
-  // pool and relocation information (include the jump over the pool and the
-  // constant pool marker).
-  int max_needed_space =
-      jump_instr + kInstrSize + num_prinfo_*(kInstrSize + kMaxRelocSize);
-  while (buffer_space() <= (max_needed_space + kGap)) GrowBuffer();
+  // pool (include the jump over the pool and the constant pool marker and
+  // the gap to the relocation information).
+  int jump_instr = require_jump ? kInstrSize : 0;
+  int needed_space = jump_instr + kInstrSize +
+                     num_pending_reloc_info_ * kInstrSize + kGap;
+  while (buffer_space() <= needed_space) GrowBuffer();
 
-  // Block recursive calls to CheckConstPool.
-  BlockConstPoolBefore(pc_offset() + jump_instr + kInstrSize +
-                       num_prinfo_*kInstrSize);
-  // Don't bother to check for the emit calls below.
-  next_buffer_check_ = no_const_pool_before_;
+  {
+    // Block recursive calls to CheckConstPool.
+    BlockConstPoolScope block_const_pool(this);
 
-  // Emit jump over constant pool if necessary.
-  Label after_pool;
-  if (require_jump) b(&after_pool);
-
-  RecordComment("[ Constant Pool");
-
-  // Put down constant pool marker "Undefined instruction" as specified by
-  // A5.6 (ARMv7) Instruction set encoding.
-  emit(kConstantPoolMarker | num_prinfo_);
-
-  // Emit constant pool entries.
-  for (int i = 0; i < num_prinfo_; i++) {
-    RelocInfo& rinfo = prinfo_[i];
-    ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
-           rinfo.rmode() != RelocInfo::POSITION &&
-           rinfo.rmode() != RelocInfo::STATEMENT_POSITION);
-    Instr instr = instr_at(rinfo.pc());
-
-    // Instruction to patch must be a ldr/str [pc, #offset].
-    // P and U set, B and W clear, Rn == pc, offset12 still 0.
-    ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | kOff12Mask)) ==
-           (2*B25 | P | U | pc.code()*B16));
-    int delta = pc_ - rinfo.pc() - 8;
-    ASSERT(delta >= -4);  // instr could be ldr pc, [pc, #-4] followed by targ32
-    if (delta < 0) {
-      instr &= ~U;
-      delta = -delta;
+    // Emit jump over constant pool if necessary.
+    Label after_pool;
+    if (require_jump) {
+      b(&after_pool);
     }
-    ASSERT(is_uint12(delta));
-    instr_at_put(rinfo.pc(), instr + delta);
-    emit(rinfo.data());
-  }
-  num_prinfo_ = 0;
-  last_const_pool_end_ = pc_offset();
 
-  RecordComment("]");
+    RecordComment("[ Constant Pool");
 
-  if (after_pool.is_linked()) {
-    bind(&after_pool);
+    // Put down constant pool marker "Undefined instruction" as specified by
+    // A5.6 (ARMv7) Instruction set encoding.
+    emit(kConstantPoolMarker | num_pending_reloc_info_);
+
+    // Emit constant pool entries.
+    for (int i = 0; i < num_pending_reloc_info_; i++) {
+      RelocInfo& rinfo = pending_reloc_info_[i];
+      ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
+             rinfo.rmode() != RelocInfo::POSITION &&
+             rinfo.rmode() != RelocInfo::STATEMENT_POSITION);
+
+      Instr instr = instr_at(rinfo.pc());
+      // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0.
+      ASSERT(IsLdrPcImmediateOffset(instr) &&
+             GetLdrRegisterImmediateOffset(instr) == 0);
+
+      int delta = pc_ - rinfo.pc() - kPcLoadDelta;
+      // 0 is the smallest delta:
+      //   ldr rd, [pc, #0]
+      //   constant pool marker
+      //   data
+      ASSERT(is_uint12(delta));
+
+      instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta));
+      emit(rinfo.data());
+    }
+
+    num_pending_reloc_info_ = 0;
+    first_const_pool_use_ = -1;
+
+    RecordComment("]");
+
+    if (after_pool.is_linked()) {
+      bind(&after_pool);
+    }
   }
 
   // Since a constant pool was just emitted, move the check offset forward by
   // the standard interval.
-  next_buffer_check_ = pc_offset() + kCheckConstInterval;
+  next_buffer_check_ = pc_offset() + kCheckPoolInterval;
 }
 
 
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 2ab46b3..97d4226 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -167,13 +167,14 @@
 
 // Double word VFP register.
 struct DwVfpRegister {
-  // d0 has been excluded from allocation. This is following ia32
-  // where xmm0 is excluded. This should be revisited.
-  // Currently d0 is used as a scratch register.
-  // d1 has also been excluded from allocation to be used as a scratch
-  // register as well.
   static const int kNumRegisters = 16;
-  static const int kNumAllocatableRegisters = 15;
+  // A few double registers are reserved: one as a scratch register and one to
+  // hold 0.0, that does not fit in the immediate field of vmov instructions.
+  //  d14: 0.0
+  //  d15: scratch register.
+  static const int kNumReservedRegisters = 2;
+  static const int kNumAllocatableRegisters = kNumRegisters -
+      kNumReservedRegisters;
 
   static int ToAllocationIndex(DwVfpRegister reg) {
     ASSERT(reg.code() != 0);
@@ -188,6 +189,7 @@
   static const char* AllocationIndexToString(int index) {
     ASSERT(index >= 0 && index < kNumAllocatableRegisters);
     const char* const names[] = {
+      "d0",
       "d1",
       "d2",
       "d3",
@@ -200,9 +202,7 @@
       "d10",
       "d11",
       "d12",
-      "d13",
-      "d14",
-      "d15"
+      "d13"
     };
     return names[index];
   }
@@ -306,6 +306,7 @@
 // Aliases for double registers.
 const DwVfpRegister kFirstCalleeSavedDoubleReg = d8;
 const DwVfpRegister kLastCalleeSavedDoubleReg = d15;
+const DwVfpRegister kDoubleRegZero = d14;
 
 
 // Coprocessor register
@@ -377,7 +378,6 @@
   INLINE(explicit Operand(int32_t immediate,
          RelocInfo::Mode rmode = RelocInfo::NONE));
   INLINE(explicit Operand(const ExternalReference& f));
-  INLINE(explicit Operand(const char* s));
   explicit Operand(Handle<Object> handle);
   INLINE(explicit Operand(Smi* value));
 
@@ -455,6 +455,7 @@
 
   Register rn() const { return rn_; }
   Register rm() const { return rm_; }
+  AddrMode am() const { return am_; }
 
   bool OffsetIsUint12Encodable() const {
     return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_);
@@ -504,6 +505,7 @@
   // Enable a specified feature within a scope.
   class Scope BASE_EMBEDDED {
 #ifdef DEBUG
+
    public:
     explicit Scope(CpuFeature f) {
       unsigned mask = 1u << f;
@@ -523,10 +525,12 @@
         isolate_->set_enabled_cpu_features(old_enabled_);
       }
     }
+
    private:
     Isolate* isolate_;
     unsigned old_enabled_;
 #else
+
    public:
     explicit Scope(CpuFeature f) {}
 #endif
@@ -1136,8 +1140,13 @@
   void jmp(Label* L) { b(L, al); }
 
   // Check the code size generated from label to here.
-  int InstructionsGeneratedSince(Label* l) {
-    return (pc_offset() - l->pos()) / kInstrSize;
+  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;
   }
 
   // Check whether an immediate fits an addressing mode 1 instruction.
@@ -1159,10 +1168,6 @@
     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
   };
 
-  // Postpone the generation of the constant pool for the specified number of
-  // instructions.
-  void BlockConstPoolFor(int instructions);
-
   // Debugging
 
   // Mark address of the ExitJSFrame code.
@@ -1173,7 +1178,17 @@
 
   // Record the AST id of the CallIC being compiled, so that it can be placed
   // in the relocation information.
-  void RecordAstId(unsigned ast_id) { ast_id_for_reloc_info_ = ast_id; }
+  void SetRecordedAstId(unsigned ast_id) {
+    ASSERT(recorded_ast_id_ == kNoASTId);
+    recorded_ast_id_ = ast_id;
+  }
+
+  unsigned RecordedAstId() {
+    ASSERT(recorded_ast_id_ != kNoASTId);
+    return recorded_ast_id_;
+  }
+
+  void ClearRecordedAstId() { recorded_ast_id_ = kNoASTId; }
 
   // Record a comment relocation entry that can be used by a disassembler.
   // Use --code-comments to enable.
@@ -1222,24 +1237,24 @@
   static int GetCmpImmediateRawImmediate(Instr instr);
   static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
 
-  // Buffer size and constant pool distance are checked together at regular
-  // intervals of kBufferCheckInterval emitted bytes
-  static const int kBufferCheckInterval = 1*KB/2;
   // Constants in pools are accessed via pc relative addressing, which can
   // reach +/-4KB thereby defining a maximum distance between the instruction
-  // and the accessed constant. We satisfy this constraint by limiting the
-  // distance between pools.
-  static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval;
-  static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrSize;
+  // and the accessed constant.
+  static const int kMaxDistToPool = 4*KB;
+  static const int kMaxNumPendingRelocInfo = kMaxDistToPool/kInstrSize;
 
-  // Check if is time to emit a constant pool for pending reloc info entries
+  // Postpone the generation of the constant pool for the specified number of
+  // instructions.
+  void BlockConstPoolFor(int instructions);
+
+  // Check if is time to emit a constant pool.
   void CheckConstPool(bool force_emit, bool require_jump);
 
  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.
-  unsigned ast_id_for_reloc_info_;
+  unsigned recorded_ast_id_;
 
   bool emit_debug_code() const { return emit_debug_code_; }
 
@@ -1257,18 +1272,37 @@
   // Patch branch instruction at pos to branch to given branch target pos
   void target_at_put(int pos, int target_pos);
 
-  // Block the emission of the constant pool before pc_offset
-  void BlockConstPoolBefore(int pc_offset) {
-    if (no_const_pool_before_ < pc_offset) no_const_pool_before_ = pc_offset;
+  // Prevent contant pool emission until EndBlockConstPool is called.
+  // Call to this function can be nested but must be followed by an equal
+  // number of call to EndBlockConstpool.
+  void StartBlockConstPool() {
+    if (const_pool_blocked_nesting_++ == 0) {
+      // Prevent constant pool checks happening by setting the next check to
+      // the biggest possible offset.
+      next_buffer_check_ = kMaxInt;
+    }
   }
 
-  void StartBlockConstPool() {
-    const_pool_blocked_nesting_++;
-  }
+  // Resume constant pool emission. Need to be called as many time as
+  // StartBlockConstPool to have an effect.
   void EndBlockConstPool() {
-    const_pool_blocked_nesting_--;
+    if (--const_pool_blocked_nesting_ == 0) {
+      // Check the constant pool hasn't been blocked for too long.
+      ASSERT((num_pending_reloc_info_ == 0) ||
+             (pc_offset() < (first_const_pool_use_ + kMaxDistToPool)));
+      // Two cases:
+      //  * no_const_pool_before_ >= next_buffer_check_ and the emission is
+      //    still blocked
+      //  * no_const_pool_before_ < next_buffer_check_ and the next emit will
+      //    trigger a check.
+      next_buffer_check_ = no_const_pool_before_;
+    }
   }
-  bool is_const_pool_blocked() const { return const_pool_blocked_nesting_ > 0; }
+
+  bool is_const_pool_blocked() const {
+    return (const_pool_blocked_nesting_ > 0) ||
+           (pc_offset() < no_const_pool_before_);
+  }
 
  private:
   // Code buffer:
@@ -1302,33 +1336,41 @@
   // expensive. By default we only check again once a number of instructions
   // has been generated. That also means that the sizing of the buffers is not
   // an exact science, and that we rely on some slop to not overrun buffers.
-  static const int kCheckConstIntervalInst = 32;
-  static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize;
+  static const int kCheckPoolIntervalInst = 32;
+  static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
 
 
-  // Pools are emitted after function return and in dead code at (more or less)
-  // regular intervals of kDistBetweenPools bytes
-  static const int kDistBetweenPools = 1*KB;
+  // Average distance beetween a constant pool and the first instruction
+  // accessing the constant pool. Longer distance should result in less I-cache
+  // pollution.
+  // In practice the distance will be smaller since constant pool emission is
+  // forced after function return and sometimes after unconditional branches.
+  static const int kAvgDistToPool = kMaxDistToPool - kCheckPoolInterval;
 
   // Emission of the constant pool may be blocked in some code sequences.
   int const_pool_blocked_nesting_;  // Block emission if this is not zero.
   int no_const_pool_before_;  // Block emission before this pc offset.
 
-  // Keep track of the last emitted pool to guarantee a maximal distance
-  int last_const_pool_end_;  // pc offset following the last constant pool
+  // Keep track of the first instruction requiring a constant pool entry
+  // since the previous constant pool was emitted.
+  int first_const_pool_use_;
 
   // Relocation info generation
   // Each relocation is encoded as a variable size value
   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
   RelocInfoWriter reloc_info_writer;
+
   // Relocation info records are also used during code generation as temporary
   // containers for constants and code target addresses until they are emitted
   // to the constant pool. These pending relocation info records are temporarily
   // stored in a separate buffer until a constant pool is emitted.
   // If every instruction in a long sequence is accessing the pool, we need one
   // pending relocation entry per instruction.
-  RelocInfo prinfo_[kMaxNumPRInfo];  // the buffer of pending relocation info
-  int num_prinfo_;  // number of pending reloc info entries in the buffer
+
+  // the buffer of pending relocation info
+  RelocInfo pending_reloc_info_[kMaxNumPendingRelocInfo];
+  // number of pending reloc info entries in the buffer
+  int num_pending_reloc_info_;
 
   // The bound position, before this we cannot do instruction elimination.
   int last_bound_pos_;
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 794b370..328102b 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -619,8 +619,7 @@
 
   Label non_function_call;
   // Check that the function is not a smi.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, &non_function_call);
+  __ JumpIfSmi(r1, &non_function_call);
   // Check that the function is a JSFunction.
   __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
   __ b(ne, &non_function_call);
@@ -675,8 +674,7 @@
     // Load the initial map and verify that it is in fact a map.
     // r1: constructor function
     __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
-    __ tst(r2, Operand(kSmiTagMask));
-    __ b(eq, &rt_call);
+    __ JumpIfSmi(r2, &rt_call);
     __ CompareObjectType(r2, r3, r4, MAP_TYPE);
     __ b(ne, &rt_call);
 
@@ -946,12 +944,11 @@
   // sp[0]: receiver (newly allocated object)
   // sp[1]: constructor function
   // sp[2]: number of arguments (smi-tagged)
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &use_receiver);
+  __ JumpIfSmi(r0, &use_receiver);
 
   // If the type of the result (stored in its map) is less than
-  // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
-  __ CompareObjectType(r0, r3, r3, FIRST_JS_OBJECT_TYPE);
+  // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
+  __ CompareObjectType(r0, r3, r3, FIRST_SPEC_OBJECT_TYPE);
   __ b(ge, &exit);
 
   // Throw away the result of the constructor invocation and use the
@@ -1047,8 +1044,7 @@
   // Invoke the code and pass argc as r0.
   __ mov(r0, Operand(r3));
   if (is_construct) {
-    __ Call(masm->isolate()->builtins()->JSConstructCall(),
-            RelocInfo::CODE_TARGET);
+    __ Call(masm->isolate()->builtins()->JSConstructCall());
   } else {
     ParameterCount actual(r0);
     __ InvokeFunction(r1, actual, CALL_FUNCTION,
@@ -1236,8 +1232,7 @@
   // r0: actual number of arguments
   Label non_function;
   __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, &non_function);
+  __ JumpIfSmi(r1, &non_function);
   __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
   __ b(ne, &non_function);
 
@@ -1257,8 +1252,7 @@
     __ b(ne, &shift_arguments);
 
     // Do not transform the receiver for native (Compilerhints already in r3).
-    __ tst(r3, Operand(1 << (SharedFunctionInfo::kES5Native +
-                             kSmiTagSize)));
+    __ tst(r3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
     __ b(ne, &shift_arguments);
 
     // Compute the receiver in non-strict mode.
@@ -1267,8 +1261,7 @@
     // r0: actual number of arguments
     // r1: function
     // r2: first argument
-    __ tst(r2, Operand(kSmiTagMask));
-    __ b(eq, &convert_to_object);
+    __ JumpIfSmi(r2, &convert_to_object);
 
     __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
     __ cmp(r2, r3);
@@ -1277,9 +1270,8 @@
     __ cmp(r2, r3);
     __ b(eq, &use_global_receiver);
 
-    STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-    STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-    __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE);
+    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+    __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE);
     __ b(ge, &shift_arguments);
 
     __ bind(&convert_to_object);
@@ -1443,13 +1435,11 @@
   __ b(ne, &push_receiver);
 
   // Do not transform the receiver for strict mode functions.
-  __ tst(r2, Operand(1 << (SharedFunctionInfo::kES5Native +
-                           kSmiTagSize)));
+  __ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
   __ b(ne, &push_receiver);
 
   // Compute the receiver in non-strict mode.
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &call_to_object);
+  __ JumpIfSmi(r0, &call_to_object);
   __ LoadRoot(r1, Heap::kNullValueRootIndex);
   __ cmp(r0, r1);
   __ b(eq, &use_global_receiver);
@@ -1459,9 +1449,8 @@
 
   // Check if the receiver is already a JavaScript object.
   // r0: receiver
-  STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-  STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
+  STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+  __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
   __ b(ge, &push_receiver);
 
   // Convert the receiver to a regular object.
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 5e6c0c3..eaad9f2 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -69,8 +69,7 @@
 void ToNumberStub::Generate(MacroAssembler* masm) {
   // The ToNumber stub takes one argument in eax.
   Label check_heap_number, call_builtin;
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(ne, &check_heap_number);
+  __ JumpIfNotSmi(r0, &check_heap_number);
   __ Ret();
 
   __ bind(&check_heap_number);
@@ -158,7 +157,7 @@
   __ ldr(r3, MemOperand(sp, 0));
 
   // Setup the object header.
-  __ LoadRoot(r2, Heap::kContextMapRootIndex);
+  __ LoadRoot(r2, Heap::kFunctionContextMapRootIndex);
   __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
   __ mov(r2, Operand(Smi::FromInt(length)));
   __ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
@@ -166,11 +165,10 @@
   // Setup the fixed slots.
   __ mov(r1, Operand(Smi::FromInt(0)));
   __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX)));
-  __ str(r0, MemOperand(r0, Context::SlotOffset(Context::FCONTEXT_INDEX)));
-  __ str(r1, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
+  __ str(cp, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
   __ str(r1, MemOperand(r0, Context::SlotOffset(Context::EXTENSION_INDEX)));
 
-  // Copy the global object from the surrounding context.
+  // Copy the global object from the previous context.
   __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
 
@@ -187,7 +185,7 @@
 
   // Need to collect. Call into runtime system.
   __ bind(&gc);
-  __ TailCallRuntime(Runtime::kNewContext, 1, 1);
+  __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1);
 }
 
 
@@ -306,12 +304,6 @@
   }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "ConvertToDoubleStub"; }
-
-#ifdef DEBUG
-  void Print() { PrintF("ConvertToDoubleStub\n"); }
-#endif
 };
 
 
@@ -394,11 +386,11 @@
     __ mov(scratch1, Operand(r0));
     ConvertToDoubleStub stub1(r3, r2, scratch1, scratch2);
     __ push(lr);
-    __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub1.GetCode());
     // Write Smi from r1 to r1 and r0 in double format.
     __ mov(scratch1, Operand(r1));
     ConvertToDoubleStub stub2(r1, r0, scratch1, scratch2);
-    __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub2.GetCode());
     __ pop(lr);
   }
 }
@@ -475,7 +467,7 @@
     __ mov(scratch1, Operand(object));
     ConvertToDoubleStub stub(dst2, dst1, scratch1, scratch2);
     __ push(lr);
-    __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub.GetCode());
     __ pop(lr);
   }
 
@@ -931,14 +923,14 @@
     // 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(r0, r4, r4, FIRST_JS_OBJECT_TYPE);
+      __ CompareObjectType(r0, r4, r4, FIRST_SPEC_OBJECT_TYPE);
       __ b(ge, slow);
     } else {
       __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
       __ b(eq, &heap_number);
       // Comparing JS objects with <=, >= is complicated.
       if (cond != eq) {
-        __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
+        __ cmp(r4, Operand(FIRST_SPEC_OBJECT_TYPE));
         __ b(ge, slow);
         // Normally here we fall through to return_equal, but undefined is
         // special: (undefined == undefined) == true, but
@@ -1029,8 +1021,7 @@
          (lhs.is(r1) && rhs.is(r0)));
 
   Label rhs_is_smi;
-  __ tst(rhs, Operand(kSmiTagMask));
-  __ b(eq, &rhs_is_smi);
+  __ JumpIfSmi(rhs, &rhs_is_smi);
 
   // Lhs is a Smi.  Check whether the rhs is a heap number.
   __ CompareObjectType(rhs, r4, r4, HEAP_NUMBER_TYPE);
@@ -1061,7 +1052,7 @@
     // Convert lhs to a double in r2, r3.
     __ mov(r7, Operand(lhs));
     ConvertToDoubleStub stub1(r3, r2, r7, r6);
-    __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub1.GetCode());
     // Load rhs to a double in r0, r1.
     __ Ldrd(r0, r1, FieldMemOperand(rhs, HeapNumber::kValueOffset));
     __ pop(lr);
@@ -1103,7 +1094,7 @@
     // Convert rhs to a double in r0, r1.
     __ mov(r7, Operand(rhs));
     ConvertToDoubleStub stub2(r1, r0, r7, r6);
-    __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub2.GetCode());
     __ pop(lr);
   }
   // Fall through to both_loaded_as_doubles.
@@ -1220,14 +1211,14 @@
     ASSERT((lhs.is(r0) && rhs.is(r1)) ||
            (lhs.is(r1) && rhs.is(r0)));
 
-    // If either operand is a JSObject or an oddball value, then they are
+    // 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 == JS_FUNCTION_TYPE);
+    STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
     Label first_non_object;
     // Get the type of the first operand into r2 and compare it with
-    // FIRST_JS_OBJECT_TYPE.
-    __ CompareObjectType(rhs, r2, r2, FIRST_JS_OBJECT_TYPE);
+    // FIRST_SPEC_OBJECT_TYPE.
+    __ CompareObjectType(rhs, r2, r2, FIRST_SPEC_OBJECT_TYPE);
     __ b(lt, &first_non_object);
 
     // Return non-zero (r0 is not zero)
@@ -1240,7 +1231,7 @@
     __ cmp(r2, Operand(ODDBALL_TYPE));
     __ b(eq, &return_not_equal);
 
-    __ CompareObjectType(lhs, r3, r3, FIRST_JS_OBJECT_TYPE);
+    __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE);
     __ b(ge, &return_not_equal);
 
     // Check for oddballs: true, false, null, undefined.
@@ -1317,9 +1308,9 @@
   __ Ret();
 
   __ bind(&object_test);
-  __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE));
+  __ cmp(r2, Operand(FIRST_SPEC_OBJECT_TYPE));
   __ b(lt, not_both_strings);
-  __ CompareObjectType(lhs, r2, r3, FIRST_JS_OBJECT_TYPE);
+  __ CompareObjectType(lhs, r2, r3, FIRST_SPEC_OBJECT_TYPE);
   __ b(lt, 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
@@ -1458,8 +1449,7 @@
   if (include_smi_compare_) {
     Label not_two_smis, smi_done;
     __ orr(r2, r1, r0);
-    __ tst(r2, Operand(kSmiTagMask));
-    __ b(ne, &not_two_smis);
+    __ JumpIfNotSmi(r2, &not_two_smis);
     __ mov(r1, Operand(r1, ASR, 1));
     __ sub(r0, r1, Operand(r0, ASR, 1));
     __ Ret();
@@ -1482,8 +1472,7 @@
   STATIC_ASSERT(kSmiTag == 0);
   ASSERT_EQ(0, Smi::FromInt(0));
   __ and_(r2, lhs_, Operand(rhs_));
-  __ tst(r2, Operand(kSmiTagMask));
-  __ b(ne, &not_smis);
+  __ JumpIfNotSmi(r2, &not_smis);
   // One operand is a smi.  EmitSmiNonsmiComparison generates code that can:
   // 1) Return the answer.
   // 2) Go to slow.
@@ -1614,15 +1603,13 @@
 }
 
 
-// This stub does not handle the inlined cases (Smis, Booleans, undefined).
 // The stub returns zero for false, and a non-zero value for true.
 void ToBooleanStub::Generate(MacroAssembler* masm) {
   // This stub uses VFP3 instructions.
   CpuFeatures::Scope scope(VFP3);
 
-  Label false_result;
-  Label not_heap_number;
-  Register scratch = r9.is(tos_) ? r7 : r9;
+  Label false_result, true_result, not_string;
+  const Register map = r9.is(tos_) ? r7 : r9;
 
   // undefined -> false
   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
@@ -1652,11 +1639,31 @@
   __ cmp(tos_, ip);
   __ b(eq, &false_result);
 
-  // HeapNumber => false iff +0, -0, or NaN.
-  __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
-  __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
-  __ cmp(scratch, ip);
-  __ b(&not_heap_number, ne);
+  // Get the map of the heap object.
+  __ ldr(map, FieldMemOperand(tos_, HeapObject::kMapOffset));
+
+  // Undetectable -> false.
+  __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
+  __ tst(ip, Operand(1 << Map::kIsUndetectable));
+  __ b(&false_result, ne);
+
+  // JavaScript object -> true.
+  __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
+  // "tos_" is a register and contains a non-zero value. Hence we implicitly
+  // return true if the greater than condition is satisfied.
+  __ Ret(ge);
+
+  // String value -> false iff empty.
+  __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
+  __ b(&not_string, ge);
+  __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset));
+  // Return string length as boolean value, i.e. return false iff length is 0.
+  __ Ret();
+
+  __ bind(&not_string);
+  // HeapNumber -> false iff +0, -0, or NaN.
+  __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
+  __ b(&true_result, ne);
   __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset));
   __ VFPCompareAndSetFlags(d1, 0.0);
   // "tos_" is a register, and contains a non zero value by default.
@@ -1666,72 +1673,27 @@
   __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs);  // for FP_NAN
   __ Ret();
 
-  __ bind(&not_heap_number);
-
-  // It can be an undetectable object.
-  // Undetectable => false.
-  __ ldr(ip, FieldMemOperand(tos_, HeapObject::kMapOffset));
-  __ ldrb(scratch, FieldMemOperand(ip, Map::kBitFieldOffset));
-  __ and_(scratch, scratch, Operand(1 << Map::kIsUndetectable));
-  __ cmp(scratch, Operand(1 << Map::kIsUndetectable));
-  __ b(&false_result, eq);
-
-  // JavaScript object => true.
-  __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
-  __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
-  __ cmp(scratch, Operand(FIRST_JS_OBJECT_TYPE));
-  // "tos_" is a register and contains a non-zero value.
-  // Hence we implicitly return true if the greater than
-  // condition is satisfied.
-  __ Ret(gt);
-
-  // Check for string
-  __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
-  __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
-  __ cmp(scratch, Operand(FIRST_NONSTRING_TYPE));
-  // "tos_" is a register and contains a non-zero value.
-  // Hence we implicitly return true if the greater than
-  // condition is satisfied.
-  __ Ret(gt);
-
-  // String value => false iff empty, i.e., length is zero
-  __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset));
-  // If length is zero, "tos_" contains zero ==> false.
-  // If length is not zero, "tos_" contains a non-zero value ==> true.
+  // Return 1/0 for true/false in tos_.
+  __ bind(&true_result);
+  __ mov(tos_, Operand(1, RelocInfo::NONE));
   __ Ret();
-
-  // Return 0 in "tos_" for false .
   __ bind(&false_result);
   __ mov(tos_, Operand(0, RelocInfo::NONE));
   __ Ret();
 }
 
 
-Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
-  UnaryOpStub stub(key, type_info);
-  return stub.GetCode();
-}
-
-
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -1755,22 +1717,14 @@
 
 
 void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
-  // Prepare to push argument.
-  __ mov(r3, Operand(r0));
-
-  // Push this stub's key. Although the operation and the type info are
-  // encoded into the key, the encoding is opaque, so push them too.
-  __ mov(r2, Operand(Smi::FromInt(MinorKey())));
-  __ mov(r1, Operand(Smi::FromInt(op_)));
+  __ mov(r3, Operand(r0));  // the operand
+  __ mov(r2, Operand(Smi::FromInt(op_)));
+  __ mov(r1, Operand(Smi::FromInt(mode_)));
   __ mov(r0, Operand(Smi::FromInt(operand_type_)));
-
   __ Push(r3, r2, r1, r0);
 
   __ TailCallExternalReference(
-      ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
-                        masm->isolate()),
-      4,
-      1);
+      ExternalReference(IC_Utility(IC::kUnaryOp_Patch), masm->isolate()), 4, 1);
 }
 
 
@@ -1903,6 +1857,8 @@
 
 void UnaryOpStub::GenerateHeapNumberCodeBitNot(
     MacroAssembler* masm, Label* slow) {
+  Label impossible;
+
   EmitCheckForHeapNumber(masm, r0, r1, r6, slow);
   // Convert the heap number is r0 to an untagged integer in r1.
   __ ConvertToInt32(r0, r1, r2, r3, d0, slow);
@@ -1921,17 +1877,27 @@
   __ bind(&try_float);
   if (mode_ == UNARY_NO_OVERWRITE) {
     Label slow_allocate_heapnumber, heapnumber_allocated;
-    __ AllocateHeapNumber(r0, r2, r3, r6, &slow_allocate_heapnumber);
+    // Allocate a new heap number without zapping r0, which we need if it fails.
+    __ AllocateHeapNumber(r2, r3, r4, r6, &slow_allocate_heapnumber);
     __ jmp(&heapnumber_allocated);
 
     __ bind(&slow_allocate_heapnumber);
     __ EnterInternalFrame();
-    __ push(r1);
-      __ CallRuntime(Runtime::kNumberAlloc, 0);
-    __ pop(r1);
+    __ push(r0);  // Push the heap number, not the untagged int32.
+    __ CallRuntime(Runtime::kNumberAlloc, 0);
+    __ mov(r2, r0);  // Move the new heap number into r2.
+    // Get the heap number into r0, now that the new heap number is in r2.
+    __ pop(r0);
     __ LeaveInternalFrame();
 
+    // Convert the heap number in r0 to an untagged integer in r1.
+    // This can't go slow-case because it's the same number we already
+    // converted once again.
+    __ ConvertToInt32(r0, r1, r3, r4, d0, &impossible);
+    __ mvn(r1, Operand(r1));
+
     __ bind(&heapnumber_allocated);
+    __ mov(r0, r2);  // Move newly allocated heap number to r0.
   }
 
   if (CpuFeatures::IsSupported(VFP3)) {
@@ -1948,6 +1914,11 @@
     WriteInt32ToHeapNumberStub stub(r1, r0, r2);
     __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
   }
+
+  __ bind(&impossible);
+  if (FLAG_debug_code) {
+    __ stop("Incorrect assumption in bit-not stub");
+  }
 }
 
 
@@ -2002,14 +1973,6 @@
 }
 
 
-Handle<Code> GetBinaryOpStub(int key,
-                             BinaryOpIC::TypeInfo type_info,
-                             BinaryOpIC::TypeInfo result_type_info) {
-  BinaryOpStub stub(key, type_info, result_type_info);
-  return stub.GetCode();
-}
-
-
 void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
   Label get_result;
 
@@ -2066,12 +2029,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -2080,13 +2038,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -2444,8 +2399,7 @@
   // Perform combined smi check on both operands.
   __ orr(scratch1, left, Operand(right));
   STATIC_ASSERT(kSmiTag == 0);
-  __ tst(scratch1, Operand(kSmiTagMask));
-  __ b(ne, &not_smis);
+  __ JumpIfNotSmi(scratch1, &not_smis);
 
   // If the smi-smi operation results in a smi return is generated.
   GenerateSmiSmiOperation(masm);
@@ -2558,37 +2512,36 @@
     case Token::MUL:
     case Token::DIV:
     case Token::MOD: {
-    // Load both operands and check that they are 32-bit integer.
-    // Jump to type transition if they are not. The registers r0 and r1 (right
-    // and left) are preserved for the runtime call.
-    FloatingPointHelper::Destination destination =
-        CpuFeatures::IsSupported(VFP3) &&
-        op_ != Token::MOD ?
-        FloatingPointHelper::kVFPRegisters :
-        FloatingPointHelper::kCoreRegisters;
+      // Load both operands and check that they are 32-bit integer.
+      // Jump to type transition if they are not. The registers r0 and r1 (right
+      // and left) are preserved for the runtime call.
+      FloatingPointHelper::Destination destination =
+          (CpuFeatures::IsSupported(VFP3) && op_ != Token::MOD)
+              ? FloatingPointHelper::kVFPRegisters
+              : FloatingPointHelper::kCoreRegisters;
 
-    FloatingPointHelper::LoadNumberAsInt32Double(masm,
-                                                 right,
-                                                 destination,
-                                                 d7,
-                                                 r2,
-                                                 r3,
-                                                 heap_number_map,
-                                                 scratch1,
-                                                 scratch2,
-                                                 s0,
-                                                 &transition);
-    FloatingPointHelper::LoadNumberAsInt32Double(masm,
-                                                 left,
-                                                 destination,
-                                                 d6,
-                                                 r4,
-                                                 r5,
-                                                 heap_number_map,
-                                                 scratch1,
-                                                 scratch2,
-                                                 s0,
-                                                 &transition);
+      FloatingPointHelper::LoadNumberAsInt32Double(masm,
+                                                   right,
+                                                   destination,
+                                                   d7,
+                                                   r2,
+                                                   r3,
+                                                   heap_number_map,
+                                                   scratch1,
+                                                   scratch2,
+                                                   s0,
+                                                   &transition);
+      FloatingPointHelper::LoadNumberAsInt32Double(masm,
+                                                   left,
+                                                   destination,
+                                                   d6,
+                                                   r4,
+                                                   r5,
+                                                   heap_number_map,
+                                                   scratch1,
+                                                   scratch2,
+                                                   s0,
+                                                   &transition);
 
       if (destination == FloatingPointHelper::kVFPRegisters) {
         CpuFeatures::Scope scope(VFP3);
@@ -2649,9 +2602,11 @@
           // DIV just falls through to allocating a heap number.
         }
 
-        if (result_type_ >= (op_ == Token::DIV) ? BinaryOpIC::HEAP_NUMBER
-                                                : BinaryOpIC::INT32) {
-          __ bind(&return_heap_number);
+        __ bind(&return_heap_number);
+        // Return a heap number, or fall through to type transition or runtime
+        // call if we can't.
+        if (result_type_ >= ((op_ == Token::DIV) ? BinaryOpIC::HEAP_NUMBER
+                                                 : BinaryOpIC::INT32)) {
           // We are using vfp registers so r5 is available.
           heap_number_result = r5;
           GenerateHeapResultAllocation(masm,
@@ -2825,7 +2780,11 @@
       UNREACHABLE();
   }
 
-  if (transition.is_linked()) {
+  // We never expect DIV to yield an integer result, so we always generate
+  // type transition code for DIV operations expecting an integer result: the
+  // code will fall through to this type transition.
+  if (transition.is_linked() ||
+      ((op_ == Token::DIV) && (result_type_ <= BinaryOpIC::INT32))) {
     __ bind(&transition);
     GenerateTypeTransition(masm);
   }
@@ -3394,15 +3353,10 @@
 
   __ mov(r2, Operand(ExternalReference::isolate_address()));
 
-
-  // TODO(1242173): To let the GC traverse the return address of the exit
-  // frames, we need to know where the return address is. Right now,
-  // we store it on the stack to be able to find it again, but we never
-  // restore from it in case of changes, which makes it impossible to
-  // support moving the C entry code stub. This should be fixed, but currently
-  // this is OK because the CEntryStub gets generated so early in the V8 boot
-  // sequence that it is not moving ever.
-
+  // 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.
@@ -3556,6 +3510,8 @@
     CpuFeatures::Scope scope(VFP3);
     // Save callee-saved vfp registers.
     __ vstm(db_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
+    // Set up the reserved register for 0.0.
+    __ vmov(kDoubleRegZero, 0.0);
   }
 
   // Get address of argv, see stm above.
@@ -3590,7 +3546,6 @@
   // Setup frame pointer for the frame to be pushed.
   __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If this is the outermost JS call, set js_entry_sp value.
   Label non_outermost_js;
   ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
@@ -3606,7 +3561,6 @@
   __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
   __ bind(&cont);
   __ push(ip);
-#endif
 
   // Call a faked try-block that does the invoke.
   __ bl(&invoke);
@@ -3667,7 +3621,6 @@
   __ PopTryHandler();
 
   __ bind(&exit);  // r0 holds result
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Check if the current stack frame is marked as the outermost JS frame.
   Label non_outermost_js_2;
   __ pop(r5);
@@ -3677,7 +3630,6 @@
   __ mov(r5, Operand(ExternalReference(js_entry_sp)));
   __ str(r6, MemOperand(r5));
   __ bind(&non_outermost_js_2);
-#endif
 
   // Restore the top frame descriptors from the stack.
   __ pop(r3);
@@ -3940,12 +3892,233 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewNonStrictSlow(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 runtime;
+  __ ldr(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ ldr(r2, MemOperand(r3, StandardFrameConstants::kContextOffset));
+  __ cmp(r2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ b(ne, &runtime);
+
+  // Patch the arguments.length and the parameters pointer in the current frame.
+  __ ldr(r2, MemOperand(r3, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ str(r2, MemOperand(sp, 0 * kPointerSize));
+  __ add(r3, r3, Operand(r2, LSL, 1));
+  __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
+  __ str(r3, MemOperand(sp, 1 * kPointerSize));
+
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+  // Stack layout:
+  //  sp[0] : number of parameters (tagged)
+  //  sp[4] : address of receiver argument
+  //  sp[8] : function
+  // Registers used over whole function:
+  //  r6 : allocated object (tagged)
+  //  r9 : mapped parameter count (tagged)
+
+  __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
+  // r1 = parameter count (tagged)
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label runtime;
+  Label adaptor_frame, try_allocate;
+  __ ldr(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ ldr(r2, MemOperand(r3, StandardFrameConstants::kContextOffset));
+  __ cmp(r2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ b(eq, &adaptor_frame);
+
+  // No adaptor, parameter count = argument count.
+  __ mov(r2, r1);
+  __ b(&try_allocate);
+
+  // We have an adaptor frame. Patch the parameters pointer.
+  __ bind(&adaptor_frame);
+  __ ldr(r2, MemOperand(r3, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ add(r3, r3, Operand(r2, LSL, 1));
+  __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
+  __ str(r3, MemOperand(sp, 1 * kPointerSize));
+
+  // r1 = parameter count (tagged)
+  // r2 = argument count (tagged)
+  // Compute the mapped parameter count = min(r1, r2) in r1.
+  __ cmp(r1, Operand(r2));
+  __ mov(r1, Operand(r2), LeaveCC, gt);
+
+  __ 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.
+  __ cmp(r1, Operand(Smi::FromInt(0)));
+  __ mov(r9, Operand(0), LeaveCC, eq);
+  __ mov(r9, Operand(r1, LSL, 1), LeaveCC, ne);
+  __ add(r9, r9, Operand(kParameterMapHeaderSize), LeaveCC, ne);
+
+  // 2. Backing store.
+  __ add(r9, r9, Operand(r2, LSL, 1));
+  __ add(r9, r9, Operand(FixedArray::kHeaderSize));
+
+  // 3. Arguments object.
+  __ add(r9, r9, Operand(Heap::kArgumentsObjectSize));
+
+  // Do the allocation of all three objects in one go.
+  __ AllocateInNewSpace(r9, r0, r3, r4, &runtime, TAG_OBJECT);
+
+  // r0 = address of new object(s) (tagged)
+  // r2 = argument count (tagged)
+  // Get the arguments boilerplate from the current (global) context into r4.
+  const int kNormalOffset =
+      Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
+  const int kAliasedOffset =
+      Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
+
+  __ ldr(r4, MemOperand(r8, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
+  __ cmp(r1, Operand(0));
+  __ ldr(r4, MemOperand(r4, kNormalOffset), eq);
+  __ ldr(r4, MemOperand(r4, kAliasedOffset), ne);
+
+  // r0 = address of new object (tagged)
+  // r1 = mapped parameter count (tagged)
+  // r2 = argument count (tagged)
+  // r4 = address of boilerplate object (tagged)
+  // Copy the JS object part.
+  for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
+    __ ldr(r3, FieldMemOperand(r4, i));
+    __ str(r3, FieldMemOperand(r0, i));
+  }
+
+  // Setup the callee in-object property.
+  STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
+  __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
+  const int kCalleeOffset = JSObject::kHeaderSize +
+      Heap::kArgumentsCalleeIndex * kPointerSize;
+  __ str(r3, FieldMemOperand(r0, kCalleeOffset));
+
+  // Use the length (smi tagged) and set that as an in-object property too.
+  STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
+  const int kLengthOffset = JSObject::kHeaderSize +
+      Heap::kArgumentsLengthIndex * kPointerSize;
+  __ str(r2, FieldMemOperand(r0, kLengthOffset));
+
+  // Setup the elements pointer in the allocated arguments object.
+  // If we allocated a parameter map, r4 will point there, otherwise
+  // it will point to the backing store.
+  __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
+  __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
+
+  // r0 = address of new object (tagged)
+  // r1 = mapped parameter count (tagged)
+  // r2 = argument count (tagged)
+  // r4 = address of parameter map or backing store (tagged)
+  // Initialize parameter map. If there are no mapped arguments, we're done.
+  Label skip_parameter_map;
+  __ cmp(r1, Operand(Smi::FromInt(0)));
+  // Move backing store address to r3, because it is
+  // expected there when filling in the unmapped arguments.
+  __ mov(r3, r4, LeaveCC, eq);
+  __ b(eq, &skip_parameter_map);
+
+  __ LoadRoot(r6, Heap::kNonStrictArgumentsElementsMapRootIndex);
+  __ str(r6, FieldMemOperand(r4, FixedArray::kMapOffset));
+  __ add(r6, r1, Operand(Smi::FromInt(2)));
+  __ str(r6, FieldMemOperand(r4, FixedArray::kLengthOffset));
+  __ str(r8, FieldMemOperand(r4, FixedArray::kHeaderSize + 0 * kPointerSize));
+  __ add(r6, r4, Operand(r1, LSL, 1));
+  __ add(r6, r6, Operand(kParameterMapHeaderSize));
+  __ str(r6, FieldMemOperand(r4, FixedArray::kHeaderSize + 1 * kPointerSize));
+
+  // 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;
+  __ mov(r6, r1);
+  __ ldr(r9, MemOperand(sp, 0 * kPointerSize));
+  __ add(r9, r9, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
+  __ sub(r9, r9, Operand(r1));
+  __ LoadRoot(r7, Heap::kTheHoleValueRootIndex);
+  __ add(r3, r4, Operand(r6, LSL, 1));
+  __ add(r3, r3, Operand(kParameterMapHeaderSize));
+
+  // r6 = loop variable (tagged)
+  // r1 = mapping index (tagged)
+  // r3 = address of backing store (tagged)
+  // r4 = address of parameter map (tagged)
+  // r5 = temporary scratch (a.o., for address calculation)
+  // r7 = the hole value
+  __ jmp(&parameters_test);
+
+  __ bind(&parameters_loop);
+  __ sub(r6, r6, Operand(Smi::FromInt(1)));
+  __ mov(r5, Operand(r6, LSL, 1));
+  __ add(r5, r5, Operand(kParameterMapHeaderSize - kHeapObjectTag));
+  __ str(r9, MemOperand(r4, r5));
+  __ sub(r5, r5, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
+  __ str(r7, MemOperand(r3, r5));
+  __ add(r9, r9, Operand(Smi::FromInt(1)));
+  __ bind(&parameters_test);
+  __ cmp(r6, Operand(Smi::FromInt(0)));
+  __ b(ne, &parameters_loop);
+
+  __ bind(&skip_parameter_map);
+  // r2 = argument count (tagged)
+  // r3 = address of backing store (tagged)
+  // r5 = scratch
+  // Copy arguments header and remaining slots (if there are any).
+  __ LoadRoot(r5, Heap::kFixedArrayMapRootIndex);
+  __ str(r5, FieldMemOperand(r3, FixedArray::kMapOffset));
+  __ str(r2, FieldMemOperand(r3, FixedArray::kLengthOffset));
+
+  Label arguments_loop, arguments_test;
+  __ mov(r9, r1);
+  __ ldr(r4, MemOperand(sp, 1 * kPointerSize));
+  __ sub(r4, r4, Operand(r9, LSL, 1));
+  __ jmp(&arguments_test);
+
+  __ bind(&arguments_loop);
+  __ sub(r4, r4, Operand(kPointerSize));
+  __ ldr(r6, MemOperand(r4, 0));
+  __ add(r5, r3, Operand(r9, LSL, 1));
+  __ str(r6, FieldMemOperand(r5, FixedArray::kHeaderSize));
+  __ add(r9, r9, Operand(Smi::FromInt(1)));
+
+  __ bind(&arguments_test);
+  __ cmp(r9, Operand(r2));
+  __ b(lt, &arguments_loop);
+
+  // Return and remove the on-stack parameters.
+  __ add(sp, sp, Operand(3 * kPointerSize));
+  __ Ret();
+
+  // Do the runtime call to allocate the arguments object.
+  // r2 = argument count (taggged)
+  __ bind(&runtime);
+  __ str(r2, MemOperand(sp, 0 * kPointerSize));  // Patch argument count.
+  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+}
+
+
+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;
   __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
@@ -3973,40 +4146,31 @@
   __ mov(r1, Operand(r1, LSR, kSmiTagSize));
   __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
   __ bind(&add_arguments_object);
-  __ add(r1, r1, Operand(GetArgumentsObjectSize() / kPointerSize));
+  __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
 
   // Do the allocation of both objects in one go.
-  __ AllocateInNewSpace(
-      r1,
-      r0,
-      r2,
-      r3,
-      &runtime,
-      static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
+  __ AllocateInNewSpace(r1,
+                        r0,
+                        r2,
+                        r3,
+                        &runtime,
+                        static_cast<AllocationFlags>(TAG_OBJECT |
+                                                     SIZE_IN_WORDS));
 
   // Get the arguments boilerplate from the current (global) context.
   __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
-  __ ldr(r4, MemOperand(r4,
-                        Context::SlotOffset(GetArgumentsBoilerplateIndex())));
+  __ ldr(r4, MemOperand(r4, Context::SlotOffset(
+      Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
 
   // Copy the JS object part.
   __ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize);
 
-  if (type_ == NEW_NON_STRICT) {
-    // Setup the callee in-object property.
-    STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
-    __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
-    const int kCalleeOffset = JSObject::kHeaderSize +
-                              Heap::kArgumentsCalleeIndex * kPointerSize;
-    __ str(r3, FieldMemOperand(r0, kCalleeOffset));
-  }
-
   // Get the length (smi tagged) and set that as an in-object property too.
   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
   __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
   __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize +
-                                 Heap::kArgumentsLengthIndex * kPointerSize));
+      Heap::kArgumentsLengthIndex * kPointerSize));
 
   // If there are no actual arguments, we're done.
   Label done;
@@ -4018,12 +4182,13 @@
 
   // Setup the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ add(r4, r0, Operand(GetArgumentsObjectSize()));
+  __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict));
   __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
   __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
   __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
   __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
-  __ mov(r1, Operand(r1, LSR, kSmiTagSize));  // Untag the length for the loop.
+  // Untag the length for the loop.
+  __ mov(r1, Operand(r1, LSR, kSmiTagSize));
 
   // Copy the fixed array slots.
   Label loop;
@@ -4046,7 +4211,7 @@
 
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+  __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
 }
 
 
@@ -4098,8 +4263,7 @@
   // Check that the first argument is a JSRegExp object.
   __ ldr(r0, MemOperand(sp, kJSRegExpOffset));
   STATIC_ASSERT(kSmiTag == 0);
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &runtime);
+  __ JumpIfSmi(r0, &runtime);
   __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
   __ b(ne, &runtime);
 
@@ -4135,8 +4299,7 @@
   // regexp_data: RegExp data (FixedArray)
   // Check that the second argument is a string.
   __ ldr(subject, MemOperand(sp, kSubjectOffset));
-  __ tst(subject, Operand(kSmiTagMask));
-  __ b(eq, &runtime);
+  __ JumpIfSmi(subject, &runtime);
   Condition is_string = masm->IsObjectStringType(subject, r0);
   __ b(NegateCondition(is_string), &runtime);
   // Get the length of the string to r3.
@@ -4149,8 +4312,7 @@
   // Check that the third argument is a positive smi less than the subject
   // string length. A negative value will be greater (unsigned comparison).
   __ ldr(r0, MemOperand(sp, kPreviousIndexOffset));
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(ne, &runtime);
+  __ JumpIfNotSmi(r0, &runtime);
   __ cmp(r3, Operand(r0));
   __ b(ls, &runtime);
 
@@ -4159,8 +4321,7 @@
   // regexp_data: RegExp data (FixedArray)
   // Check that the fourth object is a JSArray object.
   __ ldr(r0, MemOperand(sp, kLastMatchInfoOffset));
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &runtime);
+  __ JumpIfSmi(r0, &runtime);
   __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
   __ b(ne, &runtime);
   // Check that the JSArray is in fast case.
@@ -4419,8 +4580,7 @@
   __ ldr(r1, MemOperand(sp, kPointerSize * 2));
   STATIC_ASSERT(kSmiTag == 0);
   STATIC_ASSERT(kSmiTagSize == 1);
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(ne, &slowcase);
+  __ JumpIfNotSmi(r1, &slowcase);
   __ cmp(r1, Operand(Smi::FromInt(kMaxInlineLength)));
   __ b(hi, &slowcase);
   // Smi-tagging is equivalent to multiplying by 2.
@@ -4562,6 +4722,7 @@
   __ mov(r0, Operand(argc_));  // Setup the number of arguments.
   __ mov(r2, Operand(0, RelocInfo::NONE));
   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
+  __ SetCallKind(r5, CALL_AS_METHOD);
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
 }
@@ -4569,16 +4730,9 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT((lhs_.is(r0) && rhs_.is(r1)) ||
          (lhs_.is(r1) && rhs_.is(r0)));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case lt: cc_name = "LT"; break;
@@ -4589,40 +4743,14 @@
     case ne: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* lhs_name = lhs_.is(r0) ? "_r0" : "_r1";
-  const char* rhs_name = rhs_.is(r0) ? "_r0" : "_r1";
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == eq || cc_ == ne)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s%s%s",
-               cc_name,
-               lhs_name,
-               rhs_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == eq || cc_ == ne;
+  stream->Add("CompareStub_%s", cc_name);
+  stream->Add(lhs_.is(r0) ? "_r0" : "_r1");
+  stream->Add(rhs_.is(r0) ? "_r0" : "_r1");
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
@@ -5301,8 +5429,7 @@
   // Make sure first argument is a sequential (or flat) string.
   __ ldr(r5, MemOperand(sp, kStringOffset));
   STATIC_ASSERT(kSmiTag == 0);
-  __ tst(r5, Operand(kSmiTagMask));
-  __ b(eq, &runtime);
+  __ JumpIfSmi(r5, &runtime);
   Condition is_string = masm->IsObjectStringType(r5, r1);
   __ b(NegateCondition(is_string), &runtime);
 
@@ -5939,8 +6066,7 @@
   ASSERT(state_ == CompareIC::SMIS);
   Label miss;
   __ orr(r2, r1, r0);
-  __ tst(r2, Operand(kSmiTagMask));
-  __ b(ne, &miss);
+  __ JumpIfNotSmi(r2, &miss);
 
   if (GetCondition() == eq) {
     // For equality we do not care about the sign of the result.
@@ -5964,8 +6090,7 @@
   Label unordered;
   Label miss;
   __ and_(r2, r1, Operand(r0));
-  __ tst(r2, Operand(kSmiTagMask));
-  __ b(eq, &generic_stub);
+  __ JumpIfSmi(r2, &generic_stub);
 
   __ CompareObjectType(r0, r2, r2, HEAP_NUMBER_TYPE);
   __ b(ne, &miss);
@@ -6114,8 +6239,7 @@
   ASSERT(state_ == CompareIC::OBJECTS);
   Label miss;
   __ and_(r2, r1, Operand(r0));
-  __ tst(r2, Operand(kSmiTagMask));
-  __ b(eq, &miss);
+  __ JumpIfSmi(r2, &miss);
 
   __ CompareObjectType(r0, r2, r2, JS_OBJECT_TYPE);
   __ b(ne, &miss);
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index fb05cd2..557f7e6 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -58,35 +58,14 @@
 };
 
 
-class ToBooleanStub: public CodeStub {
- public:
-  explicit ToBooleanStub(Register tos) : tos_(tos) { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  Register tos_;
-  Major MajorKey() { return ToBoolean; }
-  int MinorKey() { return tos_.code(); }
-};
-
-
 class UnaryOpStub: public CodeStub {
  public:
-  UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
+  UnaryOpStub(Token::Value op,
+              UnaryOverwriteMode mode,
+              UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(UnaryOpIC::UNINITIALIZED),
-        name_(NULL) {
-  }
-
-  UnaryOpStub(
-      int key,
-      UnaryOpIC::TypeInfo operand_type)
-      : op_(OpBits::decode(key)),
-        mode_(ModeBits::decode(key)),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -96,20 +75,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("UnaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -163,8 +129,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     use_vfp3_ = CpuFeatures::IsSupported(VFP3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -177,8 +142,7 @@
         mode_(ModeBits::decode(key)),
         use_vfp3_(VFP3Bits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -194,20 +158,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
@@ -391,12 +342,6 @@
   }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "WriteInt32ToHeapNumberStub"; }
-
-#ifdef DEBUG
-  void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); }
-#endif
 };
 
 
@@ -423,8 +368,6 @@
   int MinorKey() { return 0; }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "NumberToStringStub"; }
 };
 
 
@@ -442,8 +385,6 @@
   int MinorKey() { return 0; }
 
   bool NeedsImmovableCode() { return true; }
-
-  const char* GetName() { return "RegExpCEntryStub"; }
 };
 
 
@@ -464,14 +405,11 @@
   int MinorKey() { return 0; }
 
   bool NeedsImmovableCode() { return true; }
-
-  const char* GetName() { return "DirectCEntryStub"; }
 };
 
 
 class FloatingPointHelper : public AllStatic {
  public:
-
   enum Destination {
     kVFPRegisters,
     kCoreRegisters
@@ -649,13 +587,6 @@
       StringDictionary::kHeaderSize +
       StringDictionary::kElementsStartIndex * kPointerSize;
 
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("StringDictionaryLookupStub\n");
-  }
-#endif
-
   Major MajorKey() { return StringDictionaryNegativeLookup; }
 
   int MinorKey() {
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 01aa805..d27982a 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -58,9 +58,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static void SetFunctionInfo(Handle<JSFunction> fun,
                               FunctionLiteral* lit,
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index 5b62d82..4b994e5 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -270,6 +270,9 @@
   output_ = new FrameDescription*[1];
   output_[0] = new(output_frame_size) FrameDescription(
       output_frame_size, function_);
+#ifdef DEBUG
+  output_[0]->SetKind(Code::OPTIMIZED_FUNCTION);
+#endif
 
   // Clear the incoming parameters in the optimized frame to avoid
   // confusing the garbage collector.
@@ -385,6 +388,9 @@
   // Allocate and store the output frame description.
   FrameDescription* output_frame =
       new(output_frame_size) FrameDescription(output_frame_size, function);
+#ifdef DEBUG
+  output_frame->SetKind(Code::FUNCTION);
+#endif
 
   bool is_bottommost = (0 == frame_index);
   bool is_topmost = (output_count_ - 1 == frame_index);
@@ -519,7 +525,7 @@
 
 
   // Set the continuation for the topmost frame.
-  if (is_topmost) {
+  if (is_topmost && bailout_type_ != DEBUGGER) {
     Builtins* builtins = isolate_->builtins();
     Code* continuation = (bailout_type_ == EAGER)
         ? builtins->builtin(Builtins::kNotifyDeoptimized)
@@ -532,8 +538,28 @@
 }
 
 
-#define __ masm()->
+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::kNumAllocatableRegisters; 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, Memory::uint32_at(tos + i));
+  }
+}
+
+
+#define __ masm()->
 
 // This code tries to be close to ia32 code so that any changes can be
 // easily ported.
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 6116513..c3440eb 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -92,17 +92,19 @@
   }
 
   void EmitPatchInfo() {
-    int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
-    Register reg;
-    reg.set_code(delta_to_patch_site / kOff12Mask);
-    __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
+    if (patch_site_.is_bound()) {
+      int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
+      Register reg;
+      reg.set_code(delta_to_patch_site / kOff12Mask);
+      __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
 #ifdef DEBUG
-    info_emitted_ = true;
+      info_emitted_ = true;
 #endif
+    } else {
+      __ nop();  // Signals no inlined code.
+    }
   }
 
-  bool is_bound() const { return patch_site_.is_bound(); }
-
  private:
   MacroAssembler* masm_;
   Label patch_site_;
@@ -129,6 +131,7 @@
 void FullCodeGenerator::Generate(CompilationInfo* info) {
   ASSERT(info_ == NULL);
   info_ = info;
+  scope_ = info->scope();
   SetFunctionPosition(function());
   Comment cmnt(masm_, "[ function compiled by full code generator");
 
@@ -139,21 +142,21 @@
   }
 #endif
 
-  // Strict mode functions need to replace the receiver with undefined
-  // when called as functions (without an explicit receiver
-  // object). r5 is zero for method calls and non-zero for function
-  // calls.
-  if (info->is_strict_mode()) {
+  // Strict mode functions and builtins need to replace the receiver
+  // with undefined when called as functions (without an explicit
+  // receiver object). r5 is zero for method calls and non-zero for
+  // function calls.
+  if (info->is_strict_mode() || info->is_native()) {
     Label ok;
     __ cmp(r5, Operand(0));
     __ b(eq, &ok);
-    int receiver_offset = scope()->num_parameters() * kPointerSize;
+    int receiver_offset = info->scope()->num_parameters() * kPointerSize;
     __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
     __ str(r2, MemOperand(sp, receiver_offset));
     __ bind(&ok);
   }
 
-  int locals_count = scope()->num_stack_slots();
+  int locals_count = info->scope()->num_stack_slots();
 
   __ Push(lr, fp, cp, r1);
   if (locals_count > 0) {
@@ -173,7 +176,7 @@
   bool function_in_register = true;
 
   // Possibly allocate a local context.
-  int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   if (heap_slots > 0) {
     Comment cmnt(masm_, "[ Allocate local context");
     // Argument to NewContext is the function, which is in r1.
@@ -182,14 +185,14 @@
       FastNewContextStub stub(heap_slots);
       __ CallStub(&stub);
     } else {
-      __ CallRuntime(Runtime::kNewContext, 1);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
     }
     function_in_register = false;
     // Context is returned in both r0 and cp.  It replaces the context
     // passed to us.  It's saved in the stack and kept live in cp.
     __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
     // Copy any necessary parameters into the context.
-    int num_parameters = scope()->num_parameters();
+    int num_parameters = info->scope()->num_parameters();
     for (int i = 0; i < num_parameters; i++) {
       Slot* slot = scope()->parameter(i)->AsSlot();
       if (slot != NULL && slot->type() == Slot::CONTEXT) {
@@ -220,27 +223,28 @@
       __ mov(r3, r1);
     }
     // Receiver is just before the parameters on the caller's stack.
-    int offset = scope()->num_parameters() * kPointerSize;
+    int num_parameters = info->scope()->num_parameters();
+    int offset = num_parameters * kPointerSize;
     __ add(r2, fp,
            Operand(StandardFrameConstants::kCallerSPOffset + offset));
-    __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters())));
+    __ mov(r1, Operand(Smi::FromInt(num_parameters)));
     __ Push(r3, r2, r1);
 
     // 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 stub(
-        is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT
-                         : ArgumentsAccessStub::NEW_NON_STRICT);
+    ArgumentsAccessStub::Type type;
+    if (is_strict_mode()) {
+      type = ArgumentsAccessStub::NEW_STRICT;
+    } else if (function()->has_duplicate_parameters()) {
+      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+    } else {
+      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+    }
+    ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
 
-    Variable* arguments_shadow = scope()->arguments_shadow();
-    if (arguments_shadow != NULL) {
-      // Duplicate the value; move-to-slot operation might clobber registers.
-      __ mov(r3, r0);
-      Move(arguments_shadow->AsSlot(), r3, r1, r2);
-    }
     Move(arguments->AsSlot(), r0, r1, r2);
   }
 
@@ -345,7 +349,7 @@
     { Assembler::BlockConstPoolScope block_const_pool(masm_);
       // Here we use masm_-> instead of the __ macro to avoid the code coverage
       // tool from instrumenting as we rely on the code size here.
-      int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
+      int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
       CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
       __ RecordJSReturn();
       masm_->mov(sp, fp);
@@ -383,7 +387,7 @@
   // For simplicity we always test the accumulator register.
   codegen()->Move(result_register(), slot);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -417,7 +421,7 @@
     if (true_label_ != fall_through_) __ b(true_label_);
   } else {
     __ LoadRoot(result_register(), index);
-    codegen()->DoTest(true_label_, false_label_, fall_through_);
+    codegen()->DoTest(this);
   }
 }
 
@@ -464,7 +468,7 @@
   } else {
     // For simplicity we always test the accumulator register.
     __ mov(result_register(), Operand(lit));
-    codegen()->DoTest(true_label_, false_label_, fall_through_);
+    codegen()->DoTest(this);
   }
 }
 
@@ -500,7 +504,7 @@
   __ Drop(count);
   __ Move(result_register(), reg);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -578,7 +582,8 @@
 }
 
 
-void FullCodeGenerator::DoTest(Label* if_true,
+void FullCodeGenerator::DoTest(Expression* condition,
+                               Label* if_true,
                                Label* if_false,
                                Label* fall_through) {
   if (CpuFeatures::IsSupported(VFP3)) {
@@ -712,10 +717,12 @@
         // context.
         ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
         if (FLAG_debug_code) {
-          // Check that we're not inside a 'with'.
-          __ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX));
-          __ cmp(r1, cp);
-          __ Check(eq, "Unexpected declaration in current context.");
+          // Check that we're not inside a with or catch context.
+          __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
+          __ CompareRoot(r1, Heap::kWithContextMapRootIndex);
+          __ Check(ne, "Declaration in with context.");
+          __ CompareRoot(r1, Heap::kCatchContextMapRootIndex);
+          __ Check(ne, "Declaration in catch context.");
         }
         if (mode == Variable::CONST) {
           __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
@@ -769,7 +776,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
 
       __ push(r0);
@@ -783,7 +790,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ Call(ic);
       // Value in r0 is ignored (declarations are statements).
     }
   }
@@ -857,7 +864,8 @@
     // Record position before stub call for type feedback.
     SetSourcePosition(clause->position());
     Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
-    EmitCallIC(ic, &patch_site, clause->CompareId());
+    __ Call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
+    patch_site.EmitPatchInfo();
 
     __ cmp(r0, Operand(0));
     __ b(ne, &next_test);
@@ -912,8 +920,8 @@
   // Convert the object to a JS object.
   Label convert, done_convert;
   __ JumpIfSmi(r0, &convert);
-  __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
-  __ b(hs, &done_convert);
+  __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
+  __ b(ge, &done_convert);
   __ bind(&convert);
   __ push(r0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
@@ -1105,7 +1113,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1127,8 +1135,7 @@
         __ b(ne, slow);
       }
       // Load next context in chain.
-      __ ldr(next, ContextOperand(current, Context::CLOSURE_INDEX));
-      __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
+      __ ldr(next, ContextOperand(current, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering cp.
       current = next;
     }
@@ -1154,8 +1161,7 @@
     __ tst(temp, temp);
     __ b(ne, slow);
     // Load next context in chain.
-    __ ldr(next, ContextOperand(next, Context::CLOSURE_INDEX));
-    __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
+    __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX));
     __ b(&loop);
     __ bind(&fast);
   }
@@ -1166,7 +1172,7 @@
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  EmitCallIC(ic, mode, AstNode::kNoNumber);
+  __ Call(ic, mode);
 }
 
 
@@ -1186,8 +1192,7 @@
         __ tst(temp, temp);
         __ b(ne, slow);
       }
-      __ ldr(next, ContextOperand(context, Context::CLOSURE_INDEX));
-      __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
+      __ ldr(next, ContextOperand(context, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering cp.
       context = next;
     }
@@ -1248,7 +1253,7 @@
           __ mov(r0, Operand(key_literal->handle()));
           Handle<Code> ic =
               isolate()->builtins()->KeyedLoadIC_Initialize();
-          EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
+          __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
           __ jmp(done);
         }
       }
@@ -1257,24 +1262,27 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
-  // Four cases: non-this global variables, lookup slots, all other
-  // types of slots, and parameters that rewrite to explicit property
-  // accesses on the arguments object.
-  Slot* slot = var->AsSlot();
-  Property* property = var->AsProperty();
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
 
-  if (var->is_global() && !var->is_this()) {
+  // Three cases: non-this global variables, lookup slots, and all other
+  // types of slots.
+  Slot* slot = var->AsSlot();
+  ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
+
+  if (slot == NULL) {
     Comment cmnt(masm_, "Global variable");
     // Use inline caching. Variable name is passed in r2 and the global
     // object (receiver) in r0.
     __ ldr(r0, GlobalObjectOperand());
     __ mov(r2, Operand(var->name()));
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
     context()->Plug(r0);
 
-  } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
+  } else if (slot->type() == Slot::LOOKUP) {
     Label done, slow;
 
     // Generate code for loading from variables potentially shadowed
@@ -1290,7 +1298,7 @@
 
     context()->Plug(r0);
 
-  } else if (slot != NULL) {
+  } else {
     Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
                             ? "Context slot"
                             : "Stack slot");
@@ -1306,32 +1314,6 @@
     } else {
       context()->Plug(slot);
     }
-  } else {
-    Comment cmnt(masm_, "Rewritten parameter");
-    ASSERT_NOT_NULL(property);
-    // Rewritten parameter accesses are of the form "slot[literal]".
-
-    // Assert that the object is in a slot.
-    Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
-    ASSERT_NOT_NULL(object_var);
-    Slot* object_slot = object_var->AsSlot();
-    ASSERT_NOT_NULL(object_slot);
-
-    // Load the object.
-    Move(r1, object_slot);
-
-    // Assert that the key is a smi.
-    Literal* key_literal = property->key()->AsLiteral();
-    ASSERT_NOT_NULL(key_literal);
-    ASSERT(key_literal->handle()->IsSmi());
-
-    // Load the key.
-    __ mov(r0, Operand(key_literal->handle()));
-
-    // Call keyed load IC. It has arguments key and receiver in r0 and r1.
-    Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
-    context()->Plug(r0);
   }
 }
 
@@ -1441,7 +1423,7 @@
             Handle<Code> ic = is_strict_mode()
                 ? isolate()->builtins()->StoreIC_Initialize_Strict()
                 : isolate()->builtins()->StoreIC_Initialize();
-            EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id());
+            __ Call(ic, RelocInfo::CODE_TARGET, key->id());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           } else {
             VisitForEffect(value);
@@ -1572,7 +1554,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
@@ -1598,27 +1580,13 @@
       break;
     case KEYED_PROPERTY:
       if (expr->is_compound()) {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          __ ldr(r0, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
-          __ push(r0);
-          __ mov(r0, Operand(property->key()->AsLiteral()->handle()));
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForAccumulatorValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForAccumulatorValue(property->key());
         __ ldr(r1, MemOperand(sp, 0));
         __ push(r0);
       } else {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          __ ldr(r1, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
-          __ mov(r0, Operand(property->key()->AsLiteral()->handle()));
-          __ Push(r1, r0);
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForStackValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForStackValue(property->key());
       }
       break;
   }
@@ -1629,7 +1597,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -1695,7 +1663,7 @@
   __ mov(r2, Operand(key->handle()));
   // Call load IC. It has arguments receiver and property name r0 and r2.
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
@@ -1703,7 +1671,7 @@
   SetSourcePosition(prop->position());
   // Call keyed load IC. It has arguments key and receiver in r0 and r1.
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
@@ -1730,7 +1698,8 @@
 
   __ bind(&stub_call);
   BinaryOpStub stub(op, mode);
-  EmitCallIC(stub.GetCode(), &patch_site, expr->id());
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   __ jmp(&done);
 
   __ bind(&smi_case);
@@ -1811,7 +1780,9 @@
                                      OverwriteMode mode) {
   __ pop(r1);
   BinaryOpStub stub(op, mode);
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code.
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   context()->Plug(r0);
 }
 
@@ -1825,7 +1796,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
@@ -1851,30 +1822,20 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ Call(ic);
       break;
     }
     case KEYED_PROPERTY: {
       __ push(r0);  // Preserve value.
-      if (prop->is_synthetic()) {
-        ASSERT(prop->obj()->AsVariableProxy() != NULL);
-        ASSERT(prop->key()->AsLiteral() != NULL);
-        { AccumulatorValueContext for_object(this);
-          EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
-        }
-        __ mov(r2, r0);
-        __ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
-      } else {
-        VisitForStackValue(prop->obj());
-        VisitForAccumulatorValue(prop->key());
-        __ mov(r1, r0);
-        __ pop(r2);
-      }
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
+      __ mov(r1, r0);
+      __ pop(r2);
       __ pop(r0);  // Restore value.
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ Call(ic);
       break;
     }
   }
@@ -1885,8 +1846,6 @@
 
 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
                                                Token::Value op) {
-  // Left-hand sides that rewrite to explicit property accesses do not reach
-  // here.
   ASSERT(var != NULL);
   ASSERT(var->is_global() || var->AsSlot() != NULL);
 
@@ -1900,7 +1859,7 @@
     Handle<Code> ic = is_strict_mode()
         ? isolate()->builtins()->StoreIC_Initialize_Strict()
         : isolate()->builtins()->StoreIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
 
   } else if (op == Token::INIT_CONST) {
     // Like var declarations, const declarations are hoisted to function
@@ -1922,18 +1881,7 @@
         __ b(ne, &skip);
         __ str(result_register(), MemOperand(fp, SlotOffset(slot)));
         break;
-      case Slot::CONTEXT: {
-        __ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX));
-        __ ldr(r2, ContextOperand(r1, slot->index()));
-        __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
-        __ cmp(r2, ip);
-        __ b(ne, &skip);
-        __ str(r0, ContextOperand(r1, slot->index()));
-        int offset = Context::SlotOffset(slot->index());
-        __ mov(r3, r0);  // Preserve the stored value in r0.
-        __ RecordWrite(r1, Operand(offset), r3, r2);
-        break;
-      }
+      case Slot::CONTEXT:
       case Slot::LOOKUP:
         __ push(r0);
         __ mov(r0, Operand(slot->var()->name()));
@@ -2009,7 +1957,7 @@
   Handle<Code> ic = is_strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2055,7 +2003,7 @@
   Handle<Code> ic = is_strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2107,7 +2055,7 @@
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
-  EmitCallIC(ic, mode, expr->id());
+  __ Call(ic, mode, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2141,7 +2089,7 @@
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
   __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize));  // Key.
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2181,7 +2129,8 @@
   __ push(r1);
 
   // Push the receiver of the enclosing function and do runtime call.
-  __ ldr(r1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize));
+  int receiver_offset = 2 + info_->scope()->num_parameters();
+  __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize));
   __ push(r1);
   // Push the strict mode flag.
   __ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
@@ -2300,9 +2249,9 @@
       __ bind(&done);
       // Push function.
       __ push(r0);
-      // Push global receiver.
-      __ ldr(r1, GlobalObjectOperand());
-      __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
       __ push(r1);
       __ bind(&call);
     }
@@ -2324,7 +2273,7 @@
     } else {
       // Call to a keyed property.
       // For a synthetic property use keyed load IC followed by function call,
-      // for a regular property use keyed EmitCallIC.
+      // for a regular property use EmitKeyedCallWithIC.
       if (prop->is_synthetic()) {
         // Do not visit the object and key subexpressions (they are shared
         // by all occurrences of the same rewritten parameter).
@@ -2342,7 +2291,7 @@
         SetSourcePosition(prop->position());
 
         Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-        EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+        __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
         __ ldr(r1, GlobalObjectOperand());
         __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
         __ Push(r0, r1);  // Function, receiver.
@@ -2468,9 +2417,9 @@
   __ tst(r1, Operand(1 << Map::kIsUndetectable));
   __ b(ne, if_false);
   __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset));
-  __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
+  __ cmp(r1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
   __ b(lt, if_false);
-  __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
+  __ cmp(r1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(le, if_true, if_false, fall_through);
 
@@ -2491,7 +2440,7 @@
                          &if_true, &if_false, &fall_through);
 
   __ JumpIfSmi(r0, if_false);
-  __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
+  __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(ge, if_true, if_false, fall_through);
 
@@ -2588,8 +2537,7 @@
   // If a valueOf property is not found on the object check that it's
   // prototype is the un-modified String prototype. If not result is false.
   __ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset));
-  __ tst(r2, Operand(kSmiTagMask));
-  __ b(eq, if_false);
+  __ JumpIfSmi(r2, if_false);
   __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
   __ ldr(r3, ContextOperand(cp, Context::GLOBAL_INDEX));
   __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset));
@@ -2734,7 +2682,7 @@
   // parameter count in r0.
   VisitForAccumulatorValue(args->at(0));
   __ mov(r1, r0);
-  __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
+  __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
   __ CallStub(&stub);
   context()->Plug(r0);
@@ -2746,7 +2694,7 @@
 
   Label exit;
   // Get the number of formal parameters.
-  __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
+  __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
 
   // Check if the calling frame is an arguments adaptor frame.
   __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
@@ -2774,16 +2722,18 @@
 
   // Check that the object is a JS object but take special care of JS
   // functions to make sure they have 'Function' as their class.
-  __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE);  // Map is now in r0.
+  __ CompareObjectType(r0, r0, r1, FIRST_SPEC_OBJECT_TYPE);
+  // Map is now in r0.
   __ b(lt, &null);
 
-  // As long as JS_FUNCTION_TYPE is the last instance type and it is
-  // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
-  // LAST_JS_OBJECT_TYPE.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
-  __ cmp(r1, Operand(JS_FUNCTION_TYPE));
-  __ b(eq, &function);
+  // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
+  // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
+  STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+  STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+                LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
+  __ cmp(r1, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE));
+  __ b(ge, &function);
 
   // Check if the constructor in the map is a function.
   __ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset));
@@ -2826,13 +2776,12 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
+
   // Finally, we're expected to leave a value on the top of the stack.
   __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
   context()->Plug(r0);
@@ -3343,8 +3292,7 @@
   __ b(eq, &ok);
   // Fail if either is a non-HeapObject.
   __ and_(tmp, left, Operand(right));
-  __ tst(tmp, Operand(kSmiTagMask));
-  __ b(eq, &fail);
+  __ JumpIfSmi(tmp, &fail);
   __ ldr(tmp, FieldMemOperand(left, HeapObject::kMapOffset));
   __ ldrb(tmp2, FieldMemOperand(tmp, Map::kInstanceTypeOffset));
   __ cmp(tmp2, Operand(JS_REGEXP_TYPE));
@@ -3434,9 +3382,7 @@
   __ b(ne, &bailout);
 
   // Check that the array has fast elements.
-  __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset));
-  __ tst(scratch2, Operand(1 << Map::kHasFastElements));
-  __ b(eq, &bailout);
+  __ CheckFastElements(scratch1, scratch2, &bailout);
 
   // If the array has length zero, return the empty string.
   __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
@@ -3634,6 +3580,39 @@
 }
 
 
+void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 1);
+
+  // Load the function into r0.
+  VisitForAccumulatorValue(args->at(0));
+
+  // Prepare for the test.
+  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);
+
+  // Test for strict mode function.
+  __ ldr(r1, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
+  __ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kCompilerHintsOffset));
+  __ tst(r1, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
+                           kSmiTagSize)));
+  __ b(ne, if_true);
+
+  // Test for native function.
+  __ tst(r1, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
+  __ b(ne, if_true);
+
+  // Not native or strict-mode function.
+  __ b(if_false);
+
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+  context()->Plug(if_true, if_false);
+}
+
+
 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   Handle<String> name = expr->name();
   if (name->length() > 0 && name->Get(0) == '_') {
@@ -3666,7 +3645,7 @@
         isolate()->stub_cache()->ComputeCallInitialize(arg_count,
                                                        NOT_IN_LOOP,
                                                        mode);
-    EmitCallIC(ic, mode, expr->id());
+    __ Call(ic, mode, expr->id());
     // Restore context register.
     __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
   } else {
@@ -3774,8 +3753,7 @@
       Comment cmt(masm_, "[ UnaryOperation (ADD)");
       VisitForAccumulatorValue(expr->expression());
       Label no_conversion;
-      __ tst(result_register(), Operand(kSmiTagMask));
-      __ b(eq, &no_conversion);
+      __ JumpIfSmi(result_register(), &no_conversion);
       ToNumberStub convert_stub;
       __ CallStub(&convert_stub);
       __ bind(&no_conversion);
@@ -3809,7 +3787,7 @@
   // accumulator register r0.
   VisitForAccumulatorValue(expr->expression());
   SetSourcePosition(expr->position());
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
   context()->Plug(r0);
 }
 
@@ -3826,7 +3804,7 @@
   }
 
   // Expression can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
@@ -3841,7 +3819,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
@@ -3854,15 +3832,8 @@
       __ push(r0);
       EmitNamedPropertyLoad(prop);
     } else {
-      if (prop->is_arguments_access()) {
-        VariableProxy* obj_proxy = prop->obj()->AsVariableProxy();
-        __ ldr(r0, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
-        __ push(r0);
-        __ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
-      } else {
-        VisitForStackValue(prop->obj());
-        VisitForAccumulatorValue(prop->key());
-      }
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
       __ ldr(r1, MemOperand(sp, 0));
       __ push(r0);
       EmitKeyedPropertyLoad(prop);
@@ -3927,7 +3898,8 @@
   SetSourcePosition(expr->position());
 
   BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
-  EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+  patch_site.EmitPatchInfo();
   __ bind(&done);
 
   // Store the value returned in r0.
@@ -3958,7 +3930,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -3975,7 +3947,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -4001,7 +3973,7 @@
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+    __ Call(ic);
     PrepareForBailout(expr, TOS_REG);
     context()->Plug(r0);
   } else if (proxy != NULL &&
@@ -4024,30 +3996,18 @@
     context()->Plug(r0);
   } else {
     // This expression cannot throw a reference error at the top level.
-    context()->HandleExpression(expr);
+    VisitInCurrentContext(expr);
   }
 }
 
 
-bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
-                                          Expression* left,
-                                          Expression* right,
-                                          Label* if_true,
-                                          Label* if_false,
-                                          Label* fall_through) {
-  if (op != Token::EQ && op != Token::EQ_STRICT) return false;
-
-  // Check for the pattern: typeof <expression> == <string literal>.
-  Literal* right_literal = right->AsLiteral();
-  if (right_literal == NULL) return false;
-  Handle<Object> right_literal_value = right_literal->handle();
-  if (!right_literal_value->IsString()) return false;
-  UnaryOperation* left_unary = left->AsUnaryOperation();
-  if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
-  Handle<String> check = Handle<String>::cast(right_literal_value);
-
+void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
+                                                 Handle<String> check,
+                                                 Label* if_true,
+                                                 Label* if_false,
+                                                 Label* fall_through) {
   { AccumulatorValueContext context(this);
-    VisitForTypeofValue(left_unary->expression());
+    VisitForTypeofValue(expr);
   }
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
 
@@ -4082,7 +4042,7 @@
 
   } else if (check->Equals(isolate()->heap()->function_symbol())) {
     __ JumpIfSmi(r0, if_false);
-    __ CompareObjectType(r0, r1, r0, FIRST_FUNCTION_CLASS_TYPE);
+    __ CompareObjectType(r0, r1, r0, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
     Split(ge, if_true, if_false, fall_through);
 
   } else if (check->Equals(isolate()->heap()->object_symbol())) {
@@ -4090,10 +4050,10 @@
     __ CompareRoot(r0, Heap::kNullValueRootIndex);
     __ b(eq, if_true);
     // Check for JS objects => true.
-    __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE);
-    __ b(lo, if_false);
-    __ CompareInstanceType(r0, r1, FIRST_FUNCTION_CLASS_TYPE);
-    __ b(hs, if_false);
+    __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ b(lt, if_false);
+    __ CompareInstanceType(r0, r1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ b(gt, if_false);
     // Check for undetectable objects => false.
     __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
     __ tst(r1, Operand(1 << Map::kIsUndetectable));
@@ -4101,8 +4061,18 @@
   } else {
     if (if_false != fall_through) __ jmp(if_false);
   }
+}
 
-  return true;
+
+void FullCodeGenerator::EmitLiteralCompareUndefined(Expression* expr,
+                                                    Label* if_true,
+                                                    Label* if_false,
+                                                    Label* fall_through) {
+  VisitForAccumulatorValue(expr);
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+
+  __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
+  Split(eq, if_true, if_false, fall_through);
 }
 
 
@@ -4122,14 +4092,12 @@
 
   // First we try a fast inlined version of the compare when one of
   // the operands is a literal.
-  Token::Value op = expr->op();
-  Expression* left = expr->left();
-  Expression* right = expr->right();
-  if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) {
+  if (TryLiteralCompare(expr, if_true, if_false, fall_through)) {
     context()->Plug(if_true, if_false);
     return;
   }
 
+  Token::Value op = expr->op();
   VisitForStackValue(expr->left());
   switch (op) {
     case Token::IN:
@@ -4204,7 +4172,8 @@
       // Record position and call the compare IC.
       SetSourcePosition(expr->position());
       Handle<Code> ic = CompareIC::GetUninitialized(op);
-      EmitCallIC(ic, &patch_site, expr->id());
+      __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
+      patch_site.EmitPatchInfo();
       PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
       __ cmp(r0, Operand(0));
       Split(cond, if_true, if_false, fall_through);
@@ -4237,8 +4206,7 @@
     __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
     __ cmp(r0, r1);
     __ b(eq, if_true);
-    __ tst(r0, Operand(kSmiTagMask));
-    __ b(eq, if_false);
+    __ JumpIfSmi(r0, if_false);
     // It can be an undetectable object.
     __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
     __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
@@ -4266,70 +4234,6 @@
 }
 
 
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   RelocInfo::Mode mode,
-                                   unsigned ast_id) {
-  ASSERT(mode == RelocInfo::CODE_TARGET ||
-         mode == RelocInfo::CODE_TARGET_CONTEXT);
-  Counters* counters = isolate()->counters();
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
-    default:
-      break;
-  }
-  if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) {
-    __ Call(ic, mode);
-  } else {
-    ASSERT(mode == RelocInfo::CODE_TARGET);
-    mode = RelocInfo::CODE_TARGET_WITH_ID;
-    __ CallWithAstId(ic, mode, ast_id);
-  }
-}
-
-
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   JumpPatchSite* patch_site,
-                                   unsigned ast_id) {
-  Counters* counters = isolate()->counters();
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
-    default:
-      break;
-  }
-
-  if (ast_id == kNoASTId) {
-    __ Call(ic, RelocInfo::CODE_TARGET);
-  } else {
-    __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
-  }
-  if (patch_site != NULL && patch_site->is_bound()) {
-    patch_site->EmitPatchInfo();
-  } else {
-    __ nop();  // Signals no inlined code.
-  }
-}
-
-
 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
   ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
   __ str(value, MemOperand(fp, frame_offset));
@@ -4341,6 +4245,27 @@
 }
 
 
+void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
+  Scope* declaration_scope = scope()->DeclarationScope();
+  if (declaration_scope->is_global_scope()) {
+    // Contexts nested in the global context have a canonical empty function
+    // as their closure, not the anonymous closure containing the global
+    // code.  Pass a smi sentinel and let the runtime look up the empty
+    // function.
+    __ mov(ip, Operand(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.
+    __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX));
+  } else {
+    ASSERT(declaration_scope->is_function_scope());
+    __ ldr(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  }
+  __ push(ip);
+}
+
+
 // ----------------------------------------------------------------------------
 // Non-local control flow support.
 
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 2123163..6038153 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -79,15 +79,14 @@
   //       elements map.
 
   // Check that the receiver isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check that the receiver is a valid JS object.
-  __ CompareObjectType(receiver, t0, t1, FIRST_JS_OBJECT_TYPE);
+  __ CompareObjectType(receiver, t0, t1, FIRST_SPEC_OBJECT_TYPE);
   __ b(lt, miss);
 
   // If this assert fails, we have to check upper bound too.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
 
   GenerateGlobalInstanceTypeCheck(masm, t1, miss);
 
@@ -213,101 +212,6 @@
 }
 
 
-static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
-                                         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;
-
-  // Compute the hash code from the untagged key.  This must be kept in sync
-  // with ComputeIntegerHash in utils.h.
-  //
-  // hash = ~hash + (hash << 15);
-  __ mvn(t1, Operand(t0));
-  __ add(t0, t1, Operand(t0, LSL, 15));
-  // hash = hash ^ (hash >> 12);
-  __ eor(t0, t0, Operand(t0, LSR, 12));
-  // hash = hash + (hash << 2);
-  __ add(t0, t0, Operand(t0, LSL, 2));
-  // hash = hash ^ (hash >> 4);
-  __ eor(t0, t0, Operand(t0, LSR, 4));
-  // hash = hash * 2057;
-  __ mov(t1, Operand(2057));
-  __ mul(t0, t0, t1);
-  // hash = hash ^ (hash >> 16);
-  __ eor(t0, t0, Operand(t0, LSR, 16));
-
-  // Compute the capacity mask.
-  __ ldr(t1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
-  __ mov(t1, Operand(t1, ASR, kSmiTagSize));  // convert smi to int
-  __ sub(t1, t1, Operand(1));
-
-  // Generate an unrolled loop that performs a few probes before giving up.
-  static const int kProbes = 4;
-  for (int i = 0; i < kProbes; i++) {
-    // Use t2 for index calculations and keep the hash intact in t0.
-    __ mov(t2, t0);
-    // Compute the masked index: (hash + i + i * i) & mask.
-    if (i > 0) {
-      __ add(t2, t2, Operand(NumberDictionary::GetProbeOffset(i)));
-    }
-    __ and_(t2, t2, Operand(t1));
-
-    // Scale the index by multiplying by the element size.
-    ASSERT(NumberDictionary::kEntrySize == 3);
-    __ add(t2, t2, Operand(t2, LSL, 1));  // t2 = t2 * 3
-
-    // Check if the key is identical to the name.
-    __ add(t2, elements, Operand(t2, LSL, kPointerSizeLog2));
-    __ ldr(ip, FieldMemOperand(t2, NumberDictionary::kElementsStartOffset));
-    __ cmp(key, Operand(ip));
-    if (i != kProbes - 1) {
-      __ b(eq, &done);
-    } else {
-      __ b(ne, miss);
-    }
-  }
-
-  __ bind(&done);
-  // Check that the value is a normal property.
-  // t2: elements + (index * kPointerSize)
-  const int kDetailsOffset =
-      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
-  __ ldr(t1, FieldMemOperand(t2, kDetailsOffset));
-  __ tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
-  __ b(ne, miss);
-
-  // Get the value at the masked, scaled index and return.
-  const int kValueOffset =
-      NumberDictionary::kElementsStartOffset + kPointerSize;
-  __ ldr(result, FieldMemOperand(t2, kValueOffset));
-}
-
-
 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r2    : name
@@ -503,8 +407,7 @@
   // to probe.
   //
   // Check for number.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, &number);
+  __ JumpIfSmi(r1, &number);
   __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE);
   __ b(ne, &non_number);
   __ bind(&number);
@@ -548,8 +451,7 @@
   // r1: function
 
   // Check that the value isn't a smi.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, miss);
+  __ JumpIfSmi(r1, miss);
 
   // Check that the value is a JSFunction.
   __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE);
@@ -624,8 +526,7 @@
   if (id == IC::kCallIC_Miss) {
     Label invoke, global;
     __ ldr(r2, MemOperand(sp, argc * kPointerSize));  // receiver
-    __ tst(r2, Operand(kSmiTagMask));
-    __ b(eq, &invoke);
+    __ JumpIfSmi(r2, &invoke);
     __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE);
     __ b(eq, &global);
     __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE));
@@ -742,7 +643,7 @@
   __ b(ne, &slow_load);
   __ mov(r0, Operand(r2, ASR, kSmiTagSize));
   // r0: untagged index
-  GenerateNumberDictionaryLoad(masm, &slow_load, r4, r2, r1, r0, r3, r5);
+  __ LoadFromNumberDictionary(&slow_load, r4, r2, r1, r0, r3, r5);
   __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3);
   __ jmp(&do_call);
 
@@ -812,8 +713,7 @@
 
   // Check if the name is a string.
   Label miss;
-  __ tst(r2, Operand(kSmiTagMask));
-  __ b(eq, &miss);
+  __ JumpIfSmi(r2, &miss);
   __ IsObjectJSStringType(r2, r0, &miss);
 
   GenerateCallNormal(masm, argc);
@@ -887,6 +787,174 @@
 }
 
 
+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);
+  __ b(lt, slow_case);
+
+  // Check that the key is a positive smi.
+  __ tst(key, Operand(0x8000001));
+  __ b(ne, slow_case);
+
+  // Load the elements into scratch1 and check its map.
+  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  __ ldr(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.
+  __ ldr(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset));
+  __ sub(scratch2, scratch2, Operand(Smi::FromInt(2)));
+  __ cmp(key, Operand(scratch2));
+  __ b(cs, unmapped_case);
+
+  // Load element index and check whether it is the hole.
+  const int kOffset =
+      FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag;
+
+  __ mov(scratch3, Operand(kPointerSize >> 1));
+  __ mul(scratch3, key, scratch3);
+  __ add(scratch3, scratch3, Operand(kOffset));
+
+  __ ldr(scratch2, MemOperand(scratch1, scratch3));
+  __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex);
+  __ cmp(scratch2, scratch3);
+  __ b(eq, 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).
+  __ ldr(scratch1, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
+  __ mov(scratch3, Operand(kPointerSize >> 1));
+  __ mul(scratch3, scratch2, scratch3);
+  __ add(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;
+  __ ldr(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);
+  __ ldr(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
+  __ cmp(key, Operand(scratch));
+  __ b(cs, slow_case);
+  __ mov(scratch, Operand(kPointerSize >> 1));
+  __ mul(scratch, key, scratch);
+  __ add(scratch,
+         scratch,
+         Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  return MemOperand(backing_store, scratch);
+}
+
+
+void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- lr     : return address
+  //  -- r0     : key
+  //  -- r1     : receiver
+  // -----------------------------------
+  Label slow, notin;
+  MemOperand mapped_location =
+      GenerateMappedArgumentsLookup(masm, r1, r0, r2, r3, r4, &notin, &slow);
+  __ ldr(r0, mapped_location);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in r2.
+  MemOperand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, r0, r2, r3, &slow);
+  __ ldr(r2, unmapped_location);
+  __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
+  __ cmp(r2, r3);
+  __ b(eq, &slow);
+  __ mov(r0, r2);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
+void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- r0     : value
+  //  -- r1     : key
+  //  -- r2     : receiver
+  //  -- lr     : return address
+  // -----------------------------------
+  Label slow, notin;
+  MemOperand mapped_location =
+      GenerateMappedArgumentsLookup(masm, r2, r1, r3, r4, r5, &notin, &slow);
+  __ str(r0, mapped_location);
+  __ add(r6, r3, r5);
+  __ RecordWrite(r3, r6, r9);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in r3.
+  MemOperand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, r1, r3, r4, &slow);
+  __ str(r0, unmapped_location);
+  __ add(r6, r3, r4);
+  __ RecordWrite(r3, r6, r9);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
+void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
+                                             int argc) {
+  // ----------- S t a t e -------------
+  //  -- r2    : name
+  //  -- lr    : return address
+  // -----------------------------------
+  Label slow, notin;
+  // Load receiver.
+  __ ldr(r1, MemOperand(sp, argc * kPointerSize));
+  MemOperand mapped_location =
+      GenerateMappedArgumentsLookup(masm, r1, r2, r3, r4, r5, &notin, &slow);
+  __ ldr(r1, mapped_location);
+  GenerateFunctionTailCall(masm, argc, &slow, r3);
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in r3.
+  MemOperand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, r2, r3, r4, &slow);
+  __ ldr(r1, unmapped_location);
+  __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
+  __ cmp(r1, r3);
+  __ b(eq, &slow);
+  GenerateFunctionTailCall(masm, argc, &slow, r3);
+  __ bind(&slow);
+  GenerateMiss(masm, argc);
+}
+
+
+Object* KeyedLoadIC_Miss(Arguments args);
+
+
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
@@ -944,11 +1012,8 @@
   GenerateKeyedLoadReceiverCheck(
       masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow);
 
-  // Check the "has fast elements" bit in the receiver's map which is
-  // now in r2.
-  __ ldrb(r3, FieldMemOperand(r2, Map::kBitField2Offset));
-  __ tst(r3, Operand(1 << Map::kHasFastElements));
-  __ b(eq, &check_number_dictionary);
+  // Check the receiver's map to see if it has fast elements.
+  __ CheckFastElements(r2, r3, &check_number_dictionary);
 
   GenerateFastArrayLoad(
       masm, receiver, key, r4, r3, r2, r0, NULL, &slow);
@@ -967,7 +1032,7 @@
   __ cmp(r3, ip);
   __ b(ne, &slow);
   __ mov(r2, Operand(r0, ASR, kSmiTagSize));
-  GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r0, r2, r3, r5);
+  __ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5);
   __ Ret();
 
   // Slow case, key and receiver still in r0 and r1.
@@ -1214,11 +1279,9 @@
   // r4 and r5 are used as general scratch registers.
 
   // Check that the key is a smi.
-  __ tst(key, Operand(kSmiTagMask));
-  __ b(ne, &slow);
+  __ JumpIfNotSmi(key, &slow);
   // Check that the object isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, &slow);
+  __ JumpIfSmi(receiver, &slow);
   // Get the map of the object.
   __ ldr(r4, FieldMemOperand(receiver, HeapObject::kMapOffset));
   // Check that the receiver does not require access checks.  We need
@@ -1230,9 +1293,13 @@
   __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
   __ cmp(r4, Operand(JS_ARRAY_TYPE));
   __ b(eq, &array);
-  // Check that the object is some kind of JS object.
-  __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
+  // Check that the object is some kind of JSObject.
+  __ cmp(r4, Operand(FIRST_JS_RECEIVER_TYPE));
   __ b(lt, &slow);
+  __ cmp(r4, Operand(JS_PROXY_TYPE));
+  __ b(eq, &slow);
+  __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
+  __ b(eq, &slow);
 
   // Object case: Check key against length in the elements array.
   __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index e32cd0c..b96805e 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -68,13 +68,13 @@
   ASSERT(Output() == NULL ||
          LUnallocated::cast(Output())->HasFixedPolicy() ||
          !LUnallocated::cast(Output())->HasRegisterPolicy());
-  for (UseIterator it(this); it.HasNext(); it.Advance()) {
-    LUnallocated* operand = LUnallocated::cast(it.Next());
+  for (UseIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
     ASSERT(operand->HasFixedPolicy() ||
            operand->IsUsedAtStart());
   }
-  for (TempIterator it(this); it.HasNext(); it.Advance()) {
-    LUnallocated* operand = LUnallocated::cast(it.Next());
+  for (TempIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
     ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
   }
 }
@@ -111,21 +111,18 @@
 template<int R, int I, int T>
 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
   stream->Add("= ");
-  inputs_.PrintOperandsTo(stream);
+  for (int i = 0; i < inputs_.length(); i++) {
+    if (i > 0) stream->Add(" ");
+    inputs_[i]->PrintTo(stream);
+  }
 }
 
 
 template<int R, int I, int T>
 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
-  results_.PrintOperandsTo(stream);
-}
-
-
-template<typename T, int N>
-void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
-  for (int i = 0; i < N; i++) {
+  for (int i = 0; i < results_.length(); i++) {
     if (i > 0) stream->Add(" ");
-    elems_[i]->PrintTo(stream);
+    results_[i]->PrintTo(stream);
   }
 }
 
@@ -268,12 +265,6 @@
 }
 
 
-void LTypeofIs::PrintDataTo(StringStream* stream) {
-  InputAt(0)->PrintTo(stream);
-  stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
-}
-
-
 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
   stream->Add("if typeof ");
   InputAt(0)->PrintTo(stream);
@@ -343,13 +334,6 @@
 }
 
 
-void LClassOfTest::PrintDataTo(StringStream* stream) {
-  stream->Add("= class_of_test(");
-  InputAt(0)->PrintTo(stream);
-  stream->Add(", \"%o\")", *hydrogen()->class_name());
-}
-
-
 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
   arguments()->PrintTo(stream);
 
@@ -388,6 +372,15 @@
 }
 
 
+void LStoreKeyedFastDoubleElement::PrintDataTo(StringStream* stream) {
+  elements()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  stream->Add("] <- ");
+  value()->PrintTo(stream);
+}
+
+
 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add("[");
@@ -436,8 +429,7 @@
     LLabel* label = LLabel::cast(first_instr);
     if (last_instr->IsGoto()) {
       LGoto* goto_instr = LGoto::cast(last_instr);
-      if (!goto_instr->include_stack_check() &&
-          label->IsRedundant() &&
+      if (label->IsRedundant() &&
           !label->is_loop_header()) {
         bool can_eliminate = true;
         for (int i = first + 1; i < last && can_eliminate; ++i) {
@@ -718,7 +710,9 @@
 
 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
   HEnvironment* hydrogen_env = current_block_->last_environment();
-  instr->set_environment(CreateEnvironment(hydrogen_env));
+  int argument_index_accumulator = 0;
+  instr->set_environment(CreateEnvironment(hydrogen_env,
+                                           &argument_index_accumulator));
   return instr;
 }
 
@@ -808,6 +802,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
+  return AssignEnvironment(new LDeoptimize);
+}
+
+
 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
   return AssignEnvironment(new LDeoptimize);
 }
@@ -821,7 +820,7 @@
 
     LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
     LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
-    return DefineSameAsFirst(new LBitI(op, left, right));
+    return DefineAsRegister(new LBitI(op, left, right));
   } else {
     ASSERT(instr->representation().IsTagged());
     ASSERT(instr->left()->representation().IsTagged());
@@ -848,11 +847,11 @@
   }
 
   ASSERT(instr->representation().IsInteger32());
-  ASSERT(instr->OperandAt(0)->representation().IsInteger32());
-  ASSERT(instr->OperandAt(1)->representation().IsInteger32());
-  LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
+  ASSERT(instr->left()->representation().IsInteger32());
+  ASSERT(instr->right()->representation().IsInteger32());
+  LOperand* left = UseRegisterAtStart(instr->left());
 
-  HValue* right_value = instr->OperandAt(1);
+  HValue* right_value = instr->right();
   LOperand* right = NULL;
   int constant_value = 0;
   if (right_value->IsConstant()) {
@@ -860,7 +859,7 @@
     right = chunk_->DefineConstantOperand(constant);
     constant_value = constant->Integer32Value() & 0x1f;
   } else {
-    right = UseRegister(right_value);
+    right = UseRegisterAtStart(right_value);
   }
 
   // Shift operations can only deoptimize if we do a logical shift
@@ -877,7 +876,7 @@
   }
 
   LInstruction* result =
-      DefineSameAsFirst(new LShiftI(op, left, right, does_deopt));
+      DefineAsRegister(new LShiftI(op, left, right, does_deopt));
   return does_deopt ? AssignEnvironment(result) : result;
 }
 
@@ -891,7 +890,7 @@
   LOperand* left = UseRegisterAtStart(instr->left());
   LOperand* right = UseRegisterAtStart(instr->right());
   LArithmeticD* result = new LArithmeticD(op, left, right);
-  return DefineSameAsFirst(result);
+  return DefineAsRegister(result);
 }
 
 
@@ -989,28 +988,20 @@
     if (FLAG_stress_environments && !instr->HasEnvironment()) {
       instr = AssignEnvironment(instr);
     }
-    if (current->IsTest() && !instr->IsGoto()) {
-      ASSERT(instr->IsControl());
-      HTest* test = HTest::cast(current);
-      instr->set_hydrogen_value(test->value());
-      HBasicBlock* first = test->FirstSuccessor();
-      HBasicBlock* second = test->SecondSuccessor();
-      ASSERT(first != NULL && second != NULL);
-      instr->SetBranchTargets(first->block_id(), second->block_id());
-    } else {
-      instr->set_hydrogen_value(current);
-    }
-
+    instr->set_hydrogen_value(current);
     chunk_->AddInstruction(instr, current_block_);
   }
   current_instruction_ = old_current;
 }
 
 
-LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
+LEnvironment* LChunkBuilder::CreateEnvironment(
+    HEnvironment* hydrogen_env,
+    int* argument_index_accumulator) {
   if (hydrogen_env == NULL) return NULL;
 
-  LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
+  LEnvironment* outer =
+      CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
   int ast_id = hydrogen_env->ast_id();
   ASSERT(ast_id != AstNode::kNoNumber);
   int value_count = hydrogen_env->length();
@@ -1020,7 +1011,6 @@
                                           argument_count_,
                                           value_count,
                                           outer);
-  int argument_index = 0;
   for (int i = 0; i < value_count; ++i) {
     if (hydrogen_env->is_special_index(i)) continue;
 
@@ -1029,7 +1019,7 @@
     if (value->IsArgumentsObject()) {
       op = NULL;
     } else if (value->IsPushArgument()) {
-      op = new LArgument(argument_index++);
+      op = new LArgument((*argument_index_accumulator)++);
     } else {
       op = UseAny(value);
     }
@@ -1041,102 +1031,19 @@
 
 
 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
-  LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(),
-                                   instr->include_stack_check());
-  if (instr->include_stack_check())  result = AssignPointerMap(result);
-  return result;
+  return new LGoto(instr->FirstSuccessor()->block_id());
 }
 
 
-LInstruction* LChunkBuilder::DoTest(HTest* instr) {
+LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
   HValue* v = instr->value();
-  if (!v->EmitAtUses()) {
-    return new LBranch(UseRegisterAtStart(v));
-  } else if (v->IsClassOfTest()) {
-    HClassOfTest* compare = HClassOfTest::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
-                                     TempRegister());
-  } else if (v->IsCompare()) {
-    HCompare* compare = HCompare::cast(v);
-    Token::Value op = compare->token();
-    HValue* left = compare->left();
-    HValue* right = compare->right();
-    Representation r = compare->GetInputRepresentation();
-    if (r.IsInteger32()) {
-      ASSERT(left->representation().IsInteger32());
-      ASSERT(right->representation().IsInteger32());
-      return new LCmpIDAndBranch(UseRegisterAtStart(left),
-                                 UseRegisterAtStart(right));
-    } else if (r.IsDouble()) {
-      ASSERT(left->representation().IsDouble());
-      ASSERT(right->representation().IsDouble());
-      return new LCmpIDAndBranch(UseRegisterAtStart(left),
-                                 UseRegisterAtStart(right));
-    } else {
-      ASSERT(left->representation().IsTagged());
-      ASSERT(right->representation().IsTagged());
-      bool reversed = op == Token::GT || op == Token::LTE;
-      LOperand* left_operand = UseFixed(left, reversed ? r0 : r1);
-      LOperand* right_operand = UseFixed(right, reversed ? r1 : r0);
-      LInstruction* result = new LCmpTAndBranch(left_operand, right_operand);
-      return MarkAsCall(result, instr);
-    }
-  } else if (v->IsIsSmi()) {
-    HIsSmi* compare = HIsSmi::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsSmiAndBranch(Use(compare->value()));
-  } else if (v->IsIsUndetectable()) {
-    HIsUndetectable* compare = HIsUndetectable::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()),
-                                        TempRegister());
-  } else if (v->IsHasInstanceType()) {
-    HHasInstanceType* compare = HHasInstanceType::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()));
-  } else if (v->IsHasCachedArrayIndex()) {
-    HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LHasCachedArrayIndexAndBranch(
-        UseRegisterAtStart(compare->value()));
-  } else if (v->IsIsNull()) {
-    HIsNull* compare = HIsNull::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsNullAndBranch(UseRegisterAtStart(compare->value()));
-  } else if (v->IsIsObject()) {
-    HIsObject* compare = HIsObject::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    LOperand* temp = TempRegister();
-    return new LIsObjectAndBranch(UseRegister(compare->value()), temp);
-  } else if (v->IsCompareJSObjectEq()) {
-    HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
-    return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
-                                       UseRegisterAtStart(compare->right()));
-  } else if (v->IsCompareSymbolEq()) {
-    HCompareSymbolEq* compare = HCompareSymbolEq::cast(v);
-    return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()),
-                                     UseRegisterAtStart(compare->right()));
-  } else if (v->IsInstanceOf()) {
-    HInstanceOf* instance_of = HInstanceOf::cast(v);
-    LInstruction* result =
-        new LInstanceOfAndBranch(UseFixed(instance_of->left(), r0),
-                                 UseFixed(instance_of->right(), r1));
-    return MarkAsCall(result, instr);
-  } else if (v->IsTypeofIs()) {
-    HTypeofIs* typeof_is = HTypeofIs::cast(v);
-    return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
-  } else if (v->IsIsConstructCall()) {
-    return new LIsConstructCallAndBranch(TempRegister());
-  } else if (v->IsConstant()) {
+  if (v->EmitAtUses()) {
     HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
     return new LGoto(successor->block_id());
-  } else {
-    Abort("Undefined compare before branch");
-    return NULL;
   }
+  return new LBranch(UseRegisterAtStart(v));
 }
 
 
@@ -1170,7 +1077,7 @@
 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
     HInstanceOfKnownGlobal* instr) {
   LInstanceOfKnownGlobal* result =
-      new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4));
+      new LInstanceOfKnownGlobal(UseFixed(instr->left(), r0), FixedTemp(r4));
   return MarkAsCall(DefineFixed(result, r0), instr);
 }
 
@@ -1195,6 +1102,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
+  return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction);
+}
+
+
 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
   return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext);
 }
@@ -1245,15 +1157,15 @@
     LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
     switch (op) {
       case kMathAbs:
-        return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
+        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
       case kMathFloor:
         return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
       case kMathSqrt:
-        return DefineSameAsFirst(result);
+        return DefineAsRegister(result);
       case kMathRound:
         return AssignEnvironment(DefineAsRegister(result));
       case kMathPowHalf:
-        return DefineSameAsFirst(result);
+        return DefineAsRegister(result);
       default:
         UNREACHABLE();
         return NULL;
@@ -1331,7 +1243,7 @@
 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
   ASSERT(instr->value()->representation().IsInteger32());
   ASSERT(instr->representation().IsInteger32());
-  return DefineSameAsFirst(new LBitNotI(UseRegisterAtStart(instr->value())));
+  return DefineAsRegister(new LBitNotI(UseRegisterAtStart(instr->value())));
 }
 
 
@@ -1376,15 +1288,20 @@
       mod = new LModI(value, UseOrConstant(instr->right()));
     } else {
       LOperand* dividend = UseRegister(instr->left());
-      LOperand* divisor = UseRegisterAtStart(instr->right());
+      LOperand* divisor = UseRegister(instr->right());
       mod = new LModI(dividend,
                       divisor,
                       TempRegister(),
-                      FixedTemp(d1),
-                      FixedTemp(d2));
+                      FixedTemp(d10),
+                      FixedTemp(d11));
     }
 
-    return AssignEnvironment(DefineSameAsFirst(mod));
+    if (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+        instr->CheckFlag(HValue::kCanBeDivByZero)) {
+      return AssignEnvironment(DefineAsRegister(mod));
+    } else {
+      return DefineAsRegister(mod);
+    }
   } else if (instr->representation().IsTagged()) {
     return DoArithmeticT(Token::MOD, instr);
   } else {
@@ -1404,16 +1321,22 @@
   if (instr->representation().IsInteger32()) {
     ASSERT(instr->left()->representation().IsInteger32());
     ASSERT(instr->right()->representation().IsInteger32());
-    LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
+    LOperand* left;
     LOperand* right = UseOrConstant(instr->MostConstantOperand());
     LOperand* temp = NULL;
-    if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    if (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
+        (instr->CheckFlag(HValue::kCanOverflow) ||
+        !right->IsConstantOperand())) {
+      left = UseRegister(instr->LeastConstantOperand());
       temp = TempRegister();
+    } else {
+      left = UseRegisterAtStart(instr->LeastConstantOperand());
     }
-    LMulI* mul = new LMulI(left, right, temp);
-    return AssignEnvironment(DefineSameAsFirst(mul));
+    return AssignEnvironment(DefineAsRegister(new LMulI(left, right, temp)));
+
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::MUL, instr);
+
   } else {
     return DoArithmeticT(Token::MUL, instr);
   }
@@ -1427,7 +1350,7 @@
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseOrConstantAtStart(instr->right());
     LSubI* sub = new LSubI(left, right);
-    LInstruction* result = DefineSameAsFirst(sub);
+    LInstruction* result = DefineAsRegister(sub);
     if (instr->CheckFlag(HValue::kCanOverflow)) {
       result = AssignEnvironment(result);
     }
@@ -1447,7 +1370,7 @@
     LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
     LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
     LAddI* add = new LAddI(left, right);
-    LInstruction* result = DefineSameAsFirst(add);
+    LInstruction* result = DefineAsRegister(add);
     if (instr->CheckFlag(HValue::kCanOverflow)) {
       result = AssignEnvironment(result);
     }
@@ -1478,88 +1401,84 @@
 }
 
 
-LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
+LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
   Token::Value op = instr->token();
   Representation r = instr->GetInputRepresentation();
+  ASSERT(instr->left()->representation().IsTagged());
+  ASSERT(instr->right()->representation().IsTagged());
+  bool reversed = (op == Token::GT || op == Token::LTE);
+  LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1);
+  LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0);
+  LCmpT* result = new LCmpT(left, right);
+  return MarkAsCall(DefineFixed(result, r0), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCompareIDAndBranch(
+    HCompareIDAndBranch* instr) {
+  Representation r = instr->GetInputRepresentation();
   if (r.IsInteger32()) {
     ASSERT(instr->left()->representation().IsInteger32());
     ASSERT(instr->right()->representation().IsInteger32());
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseRegisterAtStart(instr->right());
-    return DefineAsRegister(new LCmpID(left, right));
-  } else if (r.IsDouble()) {
+    return new LCmpIDAndBranch(left, right);
+  } else {
+    ASSERT(r.IsDouble());
     ASSERT(instr->left()->representation().IsDouble());
     ASSERT(instr->right()->representation().IsDouble());
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseRegisterAtStart(instr->right());
-    return DefineAsRegister(new LCmpID(left, right));
-  } else {
-    ASSERT(instr->left()->representation().IsTagged());
-    ASSERT(instr->right()->representation().IsTagged());
-    bool reversed = (op == Token::GT || op == Token::LTE);
-    LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1);
-    LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0);
-    LCmpT* result = new LCmpT(left, right);
-    return MarkAsCall(DefineFixed(result, r0), instr);
+    return new LCmpIDAndBranch(left, right);
   }
 }
 
 
-LInstruction* LChunkBuilder::DoCompareJSObjectEq(
-    HCompareJSObjectEq* instr) {
+LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
+    HCompareObjectEqAndBranch* instr) {
   LOperand* left = UseRegisterAtStart(instr->left());
   LOperand* right = UseRegisterAtStart(instr->right());
-  LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right);
-  return DefineAsRegister(result);
+  return new LCmpObjectEqAndBranch(left, right);
 }
 
 
-LInstruction* LChunkBuilder::DoCompareSymbolEq(
-    HCompareSymbolEq* instr) {
-  LOperand* left = UseRegisterAtStart(instr->left());
-  LOperand* right = UseRegisterAtStart(instr->right());
-  LCmpSymbolEq* result = new LCmpSymbolEq(left, right);
-  return DefineAsRegister(result);
+LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
+    HCompareConstantEqAndBranch* instr) {
+  return new LCmpConstantEqAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
+LInstruction* LChunkBuilder::DoIsNullAndBranch(HIsNullAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LIsNull(value));
+  return new LIsNullAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
+LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LIsObject(value));
+  LOperand* temp = TempRegister();
+  return new LIsObjectAndBranch(UseRegisterAtStart(instr->value()), temp);
 }
 
 
-LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) {
+LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseAtStart(instr->value());
-
-  return DefineAsRegister(new LIsSmi(value));
+  return new LIsSmiAndBranch(Use(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) {
+LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
+    HIsUndetectableAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LIsUndetectable(value));
+  return new LIsUndetectableAndBranch(UseRegisterAtStart(instr->value()),
+                                      TempRegister());
 }
 
 
-LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
+LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
+    HHasInstanceTypeAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LHasInstanceType(value));
+  return new LHasInstanceTypeAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
@@ -1572,19 +1491,19 @@
 }
 
 
-LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
-    HHasCachedArrayIndex* instr) {
+LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
+    HHasCachedArrayIndexAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegister(instr->value());
-
-  return DefineAsRegister(new LHasCachedArrayIndex(value));
+  return new LHasCachedArrayIndexAndBranch(
+      UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
+LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
+    HClassOfTestAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseTempRegister(instr->value());
-  return DefineSameAsFirst(new LClassOfTest(value));
+  return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
+                                   TempRegister());
 }
 
 
@@ -1607,10 +1526,16 @@
 }
 
 
+LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
+  LOperand* object = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LElementsKind(object));
+}
+
+
 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
   LOperand* object = UseRegister(instr->value());
   LValueOf* result = new LValueOf(object, TempRegister());
-  return AssignEnvironment(DefineSameAsFirst(result));
+  return AssignEnvironment(DefineAsRegister(result));
 }
 
 
@@ -1633,6 +1558,11 @@
 }
 
 
+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.
@@ -1660,7 +1590,7 @@
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
                                                       : NULL;
-        LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d3)
+        LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d11)
                                                       : NULL;
         res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3));
         res = AssignEnvironment(res);
@@ -1754,19 +1684,44 @@
   Representation input_rep = value->representation();
   LOperand* reg = UseRegister(value);
   if (input_rep.IsDouble()) {
-    return DefineAsRegister(new LClampDToUint8(reg, FixedTemp(d1)));
+    return DefineAsRegister(new LClampDToUint8(reg, FixedTemp(d11)));
   } else if (input_rep.IsInteger32()) {
     return DefineAsRegister(new LClampIToUint8(reg));
   } else {
     ASSERT(input_rep.IsTagged());
     // Register allocator doesn't (yet) support allocation of double
     // temps. Reserve d1 explicitly.
-    LClampTToUint8* result = new LClampTToUint8(reg, FixedTemp(d1));
+    LClampTToUint8* result = new LClampTToUint8(reg, FixedTemp(d11));
     return AssignEnvironment(DefineAsRegister(result));
   }
 }
 
 
+LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
+  HValue* value = instr->value();
+  Representation input_rep = value->representation();
+  LOperand* reg = UseRegister(value);
+  if (input_rep.IsDouble()) {
+    LOperand* temp1 = TempRegister();
+    LOperand* temp2 = TempRegister();
+    LDoubleToI* res = new LDoubleToI(reg, temp1, temp2);
+    return AssignEnvironment(DefineAsRegister(res));
+  } else if (input_rep.IsInteger32()) {
+    // Canonicalization should already have removed the hydrogen instruction in
+    // this case, since it is a noop.
+    UNREACHABLE();
+    return NULL;
+  } else {
+    ASSERT(input_rep.IsTagged());
+    LOperand* temp1 = TempRegister();
+    LOperand* temp2 = TempRegister();
+    LOperand* temp3 = FixedTemp(d11);
+    LTaggedToI* res = new LTaggedToI(reg, temp1, temp2, temp3);
+    return AssignEnvironment(DefineSameAsFirst(res));
+  }
+}
+
+
 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
   return new LReturn(UseFixed(instr->value(), r0));
 }
@@ -1898,19 +1853,33 @@
   LOperand* obj = UseRegisterAtStart(instr->object());
   LOperand* key = UseRegisterAtStart(instr->key());
   LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
-  return AssignEnvironment(DefineSameAsFirst(result));
+  return AssignEnvironment(DefineAsRegister(result));
+}
+
+
+LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
+    HLoadKeyedFastDoubleElement* instr) {
+  ASSERT(instr->representation().IsDouble());
+  ASSERT(instr->key()->representation().IsInteger32());
+  LOperand* elements = UseTempRegister(instr->elements());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+  LLoadKeyedFastDoubleElement* result =
+      new LLoadKeyedFastDoubleElement(elements, key);
+  return AssignEnvironment(DefineAsRegister(result));
 }
 
 
 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
     HLoadKeyedSpecializedArrayElement* instr) {
-  ExternalArrayType array_type = instr->array_type();
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
   Representation representation(instr->representation());
   ASSERT(
-      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
-                                        array_type != kExternalDoubleArray)) ||
-      (representation.IsDouble() && (array_type == kExternalFloatArray ||
-                                     array_type == kExternalDoubleArray)));
+      (representation.IsInteger32() &&
+       (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
+      (representation.IsDouble() &&
+       ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
+       (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->key()->representation().IsInteger32());
   LOperand* external_pointer = UseRegister(instr->external_pointer());
   LOperand* key = UseRegisterOrConstant(instr->key());
@@ -1919,7 +1888,7 @@
   LInstruction* load_instr = DefineAsRegister(result);
   // An unsigned int array load might overflow and cause a deopt, make sure it
   // has an environment.
-  return (array_type == kExternalUnsignedIntArray) ?
+  return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ?
       AssignEnvironment(load_instr) : load_instr;
 }
 
@@ -1953,21 +1922,38 @@
 }
 
 
+LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
+    HStoreKeyedFastDoubleElement* instr) {
+  ASSERT(instr->value()->representation().IsDouble());
+  ASSERT(instr->elements()->representation().IsTagged());
+  ASSERT(instr->key()->representation().IsInteger32());
+
+  LOperand* elements = UseRegisterAtStart(instr->elements());
+  LOperand* val = UseTempRegister(instr->value());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+
+  return new LStoreKeyedFastDoubleElement(elements, key, val);
+}
+
+
 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
     HStoreKeyedSpecializedArrayElement* instr) {
   Representation representation(instr->value()->representation());
-  ExternalArrayType array_type = instr->array_type();
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
   ASSERT(
-      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
-                                        array_type != kExternalDoubleArray)) ||
-      (representation.IsDouble() && (array_type == kExternalFloatArray ||
-                                     array_type == kExternalDoubleArray)));
+      (representation.IsInteger32() &&
+       (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
+      (representation.IsDouble() &&
+       ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
+       (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->external_pointer()->representation().IsExternal());
   ASSERT(instr->key()->representation().IsInteger32());
 
   LOperand* external_pointer = UseRegister(instr->external_pointer());
-  bool val_is_temp_register = array_type == kExternalPixelArray ||
-      array_type == kExternalFloatArray;
+  bool val_is_temp_register =
+      elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS ||
+      elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS;
   LOperand* val = val_is_temp_register
       ? UseTempRegister(instr->value())
       : UseRegister(instr->value());
@@ -2132,13 +2118,14 @@
 }
 
 
-LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
-  return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
+LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
+  return new LTypeofIsAndBranch(UseTempRegister(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
-  return DefineAsRegister(new LIsConstructCall());
+LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
+    HIsConstructCallAndBranch* instr) {
+  return new LIsConstructCallAndBranch(TempRegister());
 }
 
 
@@ -2174,7 +2161,12 @@
 
 
 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
-  return MarkAsCall(new LStackCheck, instr);
+  if (instr->is_function_entry()) {
+    return MarkAsCall(new LStackCheck, instr);
+  } else {
+    ASSERT(instr->is_backwards_branch());
+    return AssignEnvironment(AssignPointerMap(new LStackCheck));
+  }
 }
 
 
@@ -2183,7 +2175,6 @@
   HConstant* undefined = graph()->GetConstantUndefined();
   HEnvironment* inner = outer->CopyForInlining(instr->closure(),
                                                instr->function(),
-                                               HEnvironment::LITHIUM,
                                                undefined,
                                                instr->call_kind());
   current_block_->UpdateEnvironment(inner);
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 73c4a87..b477e99 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -32,6 +32,7 @@
 #include "lithium-allocator.h"
 #include "lithium.h"
 #include "safepoint-table.h"
+#include "utils.h"
 
 namespace v8 {
 namespace internal {
@@ -76,17 +77,12 @@
   V(ClampDToUint8)                              \
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
-  V(ClassOfTest)                                \
   V(ClassOfTestAndBranch)                       \
-  V(CmpID)                                      \
+  V(CmpConstantEqAndBranch)                     \
   V(CmpIDAndBranch)                             \
-  V(CmpJSObjectEq)                              \
-  V(CmpJSObjectEqAndBranch)                     \
+  V(CmpObjectEqAndBranch)                       \
   V(CmpMapAndBranch)                            \
-  V(CmpSymbolEq)                                \
-  V(CmpSymbolEqAndBranch)                       \
   V(CmpT)                                       \
-  V(CmpTAndBranch)                              \
   V(ConstantD)                                  \
   V(ConstantI)                                  \
   V(ConstantT)                                  \
@@ -95,6 +91,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(ElementsKind)                               \
   V(ExternalArrayLength)                        \
   V(FixedArrayLength)                           \
   V(FunctionLiteral)                            \
@@ -102,26 +99,18 @@
   V(GlobalObject)                               \
   V(GlobalReceiver)                             \
   V(Goto)                                       \
-  V(HasCachedArrayIndex)                        \
   V(HasCachedArrayIndexAndBranch)               \
-  V(HasInstanceType)                            \
   V(HasInstanceTypeAndBranch)                   \
   V(In)                                         \
   V(InstanceOf)                                 \
-  V(InstanceOfAndBranch)                        \
   V(InstanceOfKnownGlobal)                      \
   V(InstructionGap)                             \
   V(Integer32ToDouble)                          \
   V(InvokeFunction)                             \
-  V(IsConstructCall)                            \
   V(IsConstructCallAndBranch)                   \
-  V(IsNull)                                     \
   V(IsNullAndBranch)                            \
-  V(IsObject)                                   \
   V(IsObjectAndBranch)                          \
-  V(IsSmi)                                      \
   V(IsSmiAndBranch)                             \
-  V(IsUndetectable)                             \
   V(IsUndetectableAndBranch)                    \
   V(JSArrayLength)                              \
   V(Label)                                      \
@@ -132,6 +121,7 @@
   V(LoadFunctionPrototype)                      \
   V(LoadGlobalCell)                             \
   V(LoadGlobalGeneric)                          \
+  V(LoadKeyedFastDoubleElement)                 \
   V(LoadKeyedFastElement)                       \
   V(LoadKeyedGeneric)                           \
   V(LoadKeyedSpecializedArrayElement)           \
@@ -158,6 +148,7 @@
   V(StoreContextSlot)                           \
   V(StoreGlobalCell)                            \
   V(StoreGlobalGeneric)                         \
+  V(StoreKeyedFastDoubleElement)                \
   V(StoreKeyedFastElement)                      \
   V(StoreKeyedGeneric)                          \
   V(StoreKeyedSpecializedArrayElement)          \
@@ -169,10 +160,10 @@
   V(StringLength)                               \
   V(SubI)                                       \
   V(TaggedToI)                                  \
+  V(ThisFunction)                               \
   V(Throw)                                      \
   V(ToFastProperties)                           \
   V(Typeof)                                     \
-  V(TypeofIs)                                   \
   V(TypeofIsAndBranch)                          \
   V(UnaryMathOperation)                         \
   V(UnknownOSRValue)                            \
@@ -231,7 +222,6 @@
   virtual bool IsGap() const { return false; }
 
   virtual bool IsControl() const { return false; }
-  virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
 
   void set_environment(LEnvironment* env) { environment_ = env; }
   LEnvironment* environment() const { return environment_; }
@@ -286,37 +276,6 @@
 };
 
 
-template<typename ElementType, int NumElements>
-class OperandContainer {
- public:
-  OperandContainer() {
-    for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
-  }
-  int length() { return NumElements; }
-  ElementType& operator[](int i) {
-    ASSERT(i < length());
-    return elems_[i];
-  }
-  void PrintOperandsTo(StringStream* stream);
-
- private:
-  ElementType elems_[NumElements];
-};
-
-
-template<typename ElementType>
-class OperandContainer<ElementType, 0> {
- public:
-  int length() { return 0; }
-  void PrintOperandsTo(StringStream* stream) { }
-  ElementType& operator[](int i) {
-    UNREACHABLE();
-    static ElementType t = 0;
-    return t;
-  }
-};
-
-
 // R = number of result operands (0 or 1).
 // I = number of input operands.
 // T = number of temporary operands.
@@ -339,9 +298,9 @@
   virtual void PrintOutputOperandTo(StringStream* stream);
 
  protected:
-  OperandContainer<LOperand*, R> results_;
-  OperandContainer<LOperand*, I> inputs_;
-  OperandContainer<LOperand*, T> temps_;
+  EmbeddedContainer<LOperand*, R> results_;
+  EmbeddedContainer<LOperand*, I> inputs_;
+  EmbeddedContainer<LOperand*, T> temps_;
 };
 
 
@@ -401,19 +360,16 @@
 
 class LGoto: public LTemplateInstruction<0, 0, 0> {
  public:
-  LGoto(int block_id, bool include_stack_check = false)
-    : block_id_(block_id), include_stack_check_(include_stack_check) { }
+  explicit LGoto(int block_id) : block_id_(block_id) { }
 
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
   virtual void PrintDataTo(StringStream* stream);
   virtual bool IsControl() const { return true; }
 
   int block_id() const { return block_id_; }
-  bool include_stack_check() const { return include_stack_check_; }
 
  private:
   int block_id_;
-  bool include_stack_check_;
 };
 
 
@@ -489,16 +445,15 @@
  public:
   virtual bool IsControl() const { return true; }
 
-  int true_block_id() const { return true_block_id_; }
-  int false_block_id() const { return false_block_id_; }
-  void SetBranchTargets(int true_block_id, int false_block_id) {
-    true_block_id_ = true_block_id;
-    false_block_id_ = false_block_id;
-  }
+  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
+  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
+  int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); }
+  int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); }
 
  private:
-  int true_block_id_;
-  int false_block_id_;
+  HControlInstruction* hydrogen() {
+    return HControlInstruction::cast(this->hydrogen_value());
+  }
 };
 
 
@@ -614,23 +569,6 @@
 };
 
 
-class LCmpID: public LTemplateInstruction<1, 2, 0> {
- public:
-  LCmpID(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
-
-  Token::Value op() const { return hydrogen()->token(); }
-  bool is_double() const {
-    return hydrogen()->GetInputRepresentation().IsDouble();
-  }
-};
-
-
 class LCmpIDAndBranch: public LControlInstruction<2, 0> {
  public:
   LCmpIDAndBranch(LOperand* left, LOperand* right) {
@@ -639,7 +577,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
+  DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
 
   Token::Value op() const { return hydrogen()->token(); }
   bool is_double() const {
@@ -665,63 +603,31 @@
 };
 
 
-class LCmpJSObjectEq: public LTemplateInstruction<1, 2, 0> {
+class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
  public:
-  LCmpJSObjectEq(LOperand* left, LOperand* right) {
+  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
     inputs_[0] = left;
     inputs_[1] = right;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
+  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
+                               "cmp-object-eq-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
 };
 
 
-class LCmpJSObjectEqAndBranch: public LControlInstruction<2, 0> {
+class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> {
  public:
-  LCmpJSObjectEqAndBranch(LOperand* left, LOperand* right) {
+  explicit LCmpConstantEqAndBranch(LOperand* left) {
     inputs_[0] = left;
-    inputs_[1] = right;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
-                               "cmp-jsobject-eq-and-branch")
+  DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
+                               "cmp-constant-eq-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
 };
 
 
-class LCmpSymbolEq: public LTemplateInstruction<1, 2, 0> {
- public:
-  LCmpSymbolEq(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpSymbolEq, "cmp-symbol-eq")
-};
-
-
-class LCmpSymbolEqAndBranch: public LControlInstruction<2, 0> {
- public:
-  LCmpSymbolEqAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpSymbolEqAndBranch, "cmp-symbol-eq-and-branch")
-};
-
-
-class LIsNull: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsNull(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
-  DECLARE_HYDROGEN_ACCESSOR(IsNull)
-
-  bool is_strict() const { return hydrogen()->is_strict(); }
-};
-
 class LIsNullAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LIsNullAndBranch(LOperand* value) {
@@ -729,7 +635,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(IsNull)
+  DECLARE_HYDROGEN_ACCESSOR(IsNullAndBranch)
 
   bool is_strict() const { return hydrogen()->is_strict(); }
 
@@ -737,17 +643,7 @@
 };
 
 
-class LIsObject: public LTemplateInstruction<1, 1, 1> {
- public:
-  explicit LIsObject(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
-};
-
-
-class LIsObjectAndBranch: public LControlInstruction<1, 2> {
+class LIsObjectAndBranch: public LControlInstruction<1, 1> {
  public:
   LIsObjectAndBranch(LOperand* value, LOperand* temp) {
     inputs_[0] = value;
@@ -755,22 +651,12 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LIsSmi: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsSmi(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
-  DECLARE_HYDROGEN_ACCESSOR(IsSmi)
-};
-
-
 class LIsSmiAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LIsSmiAndBranch(LOperand* value) {
@@ -778,22 +664,12 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LIsUndetectable: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsUndetectable(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsUndetectable, "is-undetectable")
-  DECLARE_HYDROGEN_ACCESSOR(IsUndetectable)
-};
-
-
 class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
  public:
   explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
@@ -803,22 +679,12 @@
 
   DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
                                "is-undetectable-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LHasInstanceType: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LHasInstanceType(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
-  DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
-};
-
-
 class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LHasInstanceTypeAndBranch(LOperand* value) {
@@ -827,7 +693,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
                                "has-instance-type-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
+  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -844,17 +710,6 @@
 };
 
 
-class LHasCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LHasCachedArrayIndex(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
-  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
-};
-
-
 class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
@@ -863,18 +718,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
                                "has-cached-array-index-and-branch")
-  virtual void PrintDataTo(StringStream* stream);
-};
-
-
-class LClassOfTest: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LClassOfTest(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
-  DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
+  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -889,7 +733,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
                                "class-of-test-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
+  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -903,21 +747,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
-
-  Token::Value op() const { return hydrogen()->token(); }
-};
-
-
-class LCmpTAndBranch: public LControlInstruction<2, 0> {
- public:
-  LCmpTAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
+  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
 
   Token::Value op() const { return hydrogen()->token(); }
 };
@@ -934,17 +764,6 @@
 };
 
 
-class LInstanceOfAndBranch: public LControlInstruction<2, 0> {
- public:
-  LInstanceOfAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
-};
-
-
 class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
  public:
   LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
@@ -1057,7 +876,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
-  DECLARE_HYDROGEN_ACCESSOR(Value)
+  DECLARE_HYDROGEN_ACCESSOR(Branch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -1118,6 +937,17 @@
 };
 
 
+class LElementsKind: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LElementsKind(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
+  DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
+};
+
+
 class LValueOf: public LTemplateInstruction<1, 1, 1> {
  public:
   LValueOf(LOperand* value, LOperand* temp) {
@@ -1309,6 +1139,22 @@
 };
 
 
+class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
+ public:
+  LLoadKeyedFastDoubleElement(LOperand* elements, LOperand* key) {
+    inputs_[0] = elements;
+    inputs_[1] = key;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
+                               "load-keyed-fast-double-element")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
+
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+};
+
+
 class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
  public:
   LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
@@ -1323,8 +1169,8 @@
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
-  ExternalArrayType array_type() const {
-    return hydrogen()->array_type();
+  JSObject::ElementsKind elements_kind() const {
+    return hydrogen()->elements_kind();
   }
 };
 
@@ -1440,6 +1286,11 @@
 };
 
 
+class LThisFunction: public LTemplateInstruction<1, 0, 0> {
+  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
+};
+
+
 class LContext: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(Context, "context")
@@ -1639,7 +1490,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -1659,7 +1510,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -1764,6 +1615,28 @@
 };
 
 
+class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
+ public:
+  LStoreKeyedFastDoubleElement(LOperand* elements,
+                               LOperand* key,
+                               LOperand* val) {
+    inputs_[0] = elements;
+    inputs_[1] = key;
+    inputs_[2] = val;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
+                               "store-keyed-fast-double-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  LOperand* value() { return inputs_[2]; }
+};
+
+
 class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
  public:
   LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val) {
@@ -1800,8 +1673,8 @@
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
-  ExternalArrayType array_type() const {
-    return hydrogen()->array_type();
+  JSObject::ElementsKind elements_kind() const {
+    return hydrogen()->elements_kind();
   }
 };
 
@@ -2020,21 +1893,6 @@
 };
 
 
-class LTypeofIs: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LTypeofIs(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
-  DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
-
-  Handle<String> type_literal() { return hydrogen()->type_literal(); }
-
-  virtual void PrintDataTo(StringStream* stream);
-};
-
-
 class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LTypeofIsAndBranch(LOperand* value) {
@@ -2042,7 +1900,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
+  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
@@ -2050,13 +1908,6 @@
 };
 
 
-class LIsConstructCall: public LTemplateInstruction<1, 0, 0> {
- public:
-  DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is-construct-call")
-  DECLARE_HYDROGEN_ACCESSOR(IsConstructCall)
-};
-
-
 class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
  public:
   explicit LIsConstructCallAndBranch(LOperand* temp) {
@@ -2108,6 +1959,12 @@
 class LStackCheck: public LTemplateInstruction<0, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
+  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
+
+  Label* done_label() { return &done_label_; }
+
+ private:
+  Label done_label_;
 };
 
 
@@ -2313,7 +2170,8 @@
       LInstruction* instr, int ast_id);
   void ClearInstructionPendingDeoptimizationEnvironment();
 
-  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
+  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
+                                  int* argument_index_accumulator);
 
   void VisitInstruction(HInstruction* current);
 
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index d25ca49..ad8091b 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -146,11 +146,11 @@
   // fp: Caller's frame pointer.
   // lr: Caller's pc.
 
-  // Strict mode functions need to replace the receiver with undefined
-  // when called as functions (without an explicit receiver
-  // object). r5 is zero for method calls and non-zero for function
-  // calls.
-  if (info_->is_strict_mode()) {
+  // Strict mode functions and builtins need to replace the receiver
+  // with undefined when called as functions (without an explicit
+  // receiver object). r5 is zero for method calls and non-zero for
+  // function calls.
+  if (info_->is_strict_mode() || info_->is_native()) {
     Label ok;
     __ cmp(r5, Operand(0));
     __ b(eq, &ok);
@@ -189,7 +189,7 @@
       FastNewContextStub stub(heap_slots);
       __ CallStub(&stub);
     } else {
-      __ CallRuntime(Runtime::kNewContext, 1);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
     }
     RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
     // Context is returned in both r0 and cp.  It replaces the context
@@ -257,11 +257,20 @@
 
 bool LCodeGen::GenerateDeferredCode() {
   ASSERT(is_generating());
-  for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
-    LDeferredCode* code = deferred_[i];
-    __ bind(code->entry());
-    code->Generate();
-    __ jmp(code->exit());
+  if (deferred_.length() > 0) {
+    for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
+      LDeferredCode* code = deferred_[i];
+      __ bind(code->entry());
+      code->Generate();
+      __ jmp(code->exit());
+    }
+
+    // Pad code to ensure that the last piece of deferred code have
+    // room for lazy bailout.
+    while ((masm()->pc_offset() - LastSafepointEnd())
+           < Deoptimizer::patch_size()) {
+      __ nop();
+    }
   }
 
   // Force constant pool emission at the end of the deferred code to make
@@ -777,7 +786,7 @@
 
 
 void LCodeGen::RecordPosition(int position) {
-  if (!FLAG_debug_info || position == RelocInfo::kNoPosition) return;
+  if (position == RelocInfo::kNoPosition) return;
   masm()->positions_recorder()->RecordPosition(position);
 }
 
@@ -880,6 +889,7 @@
 void LCodeGen::DoModI(LModI* instr) {
   if (instr->hydrogen()->HasPowerOf2Divisor()) {
     Register dividend = ToRegister(instr->InputAt(0));
+    Register result = ToRegister(instr->result());
 
     int32_t divisor =
         HConstant::cast(instr->hydrogen()->right())->Integer32Value();
@@ -889,17 +899,15 @@
     Label positive_dividend, done;
     __ cmp(dividend, Operand(0));
     __ b(pl, &positive_dividend);
-    __ rsb(dividend, dividend, Operand(0));
-    __ and_(dividend, dividend, Operand(divisor - 1));
-    __ rsb(dividend, dividend, Operand(0), SetCC);
+    __ rsb(result, dividend, Operand(0));
+    __ and_(result, result, Operand(divisor - 1), SetCC);
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      __ b(ne, &done);
-      DeoptimizeIf(al, instr->environment());
-    } else {
-      __ b(&done);
+      DeoptimizeIf(eq, instr->environment());
     }
+    __ rsb(result, result, Operand(0));
+    __ b(&done);
     __ bind(&positive_dividend);
-    __ and_(dividend, dividend, Operand(divisor - 1));
+    __ and_(result, dividend, Operand(divisor - 1));
     __ bind(&done);
     return;
   }
@@ -915,8 +923,6 @@
   DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
   DwVfpRegister quotient = double_scratch0();
 
-  ASSERT(result.is(left));
-
   ASSERT(!dividend.is(divisor));
   ASSERT(!dividend.is(quotient));
   ASSERT(!divisor.is(quotient));
@@ -932,6 +938,8 @@
     DeoptimizeIf(eq, instr->environment());
   }
 
+  __ Move(result, left);
+
   // (0 % x) must yield 0 (if x is finite, which is the case here).
   __ cmp(left, Operand(0));
   __ b(eq, &done);
@@ -1128,68 +1136,125 @@
 
 void LCodeGen::DoMulI(LMulI* instr) {
   Register scratch = scratch0();
+  Register result = ToRegister(instr->result());
+  // Note that result may alias left.
   Register left = ToRegister(instr->InputAt(0));
-  Register right = EmitLoadRegister(instr->InputAt(1), scratch);
+  LOperand* right_op = instr->InputAt(1);
 
-  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      !instr->InputAt(1)->IsConstantOperand()) {
-    __ orr(ToRegister(instr->TempAt(0)), left, right);
-  }
+  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+  bool bailout_on_minus_zero =
+    instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
 
-  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
-    // scratch:left = left * right.
-    __ smull(left, scratch, left, right);
-    __ mov(ip, Operand(left, ASR, 31));
-    __ cmp(ip, Operand(scratch));
-    DeoptimizeIf(ne, instr->environment());
+  if (right_op->IsConstantOperand() && !can_overflow) {
+    // Use optimized code for specific constants.
+    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.
+      __ cmp(left, Operand(0));
+      DeoptimizeIf(eq, instr->environment());
+    }
+
+    switch (constant) {
+      case -1:
+        __ rsb(result, left, Operand(0));
+        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.
+          __ cmp(left, Operand(0));
+          DeoptimizeIf(mi, instr->environment());
+        }
+        __ mov(result, Operand(0));
+        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 (IsPowerOf2(constant_abs) ||
+            IsPowerOf2(constant_abs - 1) ||
+            IsPowerOf2(constant_abs + 1)) {
+          if (IsPowerOf2(constant_abs)) {
+            int32_t shift = WhichPowerOf2(constant_abs);
+            __ mov(result, Operand(left, LSL, shift));
+          } else if (IsPowerOf2(constant_abs - 1)) {
+            int32_t shift = WhichPowerOf2(constant_abs - 1);
+            __ add(result, left, Operand(left, LSL, shift));
+          } else if (IsPowerOf2(constant_abs + 1)) {
+            int32_t shift = WhichPowerOf2(constant_abs + 1);
+            __ rsb(result, left, Operand(left, LSL, shift));
+          }
+
+          // Correct the sign of the result is the constant is negative.
+          if (constant < 0)  __ rsb(result, result, Operand(0));
+
+        } else {
+          // Generate standard code.
+          __ mov(ip, Operand(constant));
+          __ mul(result, left, ip);
+        }
+    }
+
   } else {
-    __ mul(left, left, right);
-  }
+    Register right = EmitLoadRegister(right_op, scratch);
+    if (bailout_on_minus_zero) {
+      __ orr(ToRegister(instr->TempAt(0)), left, right);
+    }
 
-  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    // Bail out if the result is supposed to be negative zero.
-    Label done;
-    __ cmp(left, Operand(0));
-    __ b(ne, &done);
-    if (instr->InputAt(1)->IsConstantOperand()) {
-      if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) {
-        DeoptimizeIf(al, instr->environment());
-      }
+    if (can_overflow) {
+      // scratch:result = left * right.
+      __ smull(result, scratch, left, right);
+      __ cmp(scratch, Operand(result, ASR, 31));
+      DeoptimizeIf(ne, instr->environment());
     } else {
-      // Test the non-zero operand for negative sign.
+      __ mul(result, left, right);
+    }
+
+    if (bailout_on_minus_zero) {
+      // Bail out if the result is supposed to be negative zero.
+      Label done;
+      __ cmp(result, Operand(0));
+      __ b(ne, &done);
       __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
       DeoptimizeIf(mi, instr->environment());
+      __ bind(&done);
     }
-    __ bind(&done);
   }
 }
 
 
 void LCodeGen::DoBitI(LBitI* instr) {
-  LOperand* left = instr->InputAt(0);
-  LOperand* right = instr->InputAt(1);
-  ASSERT(left->Equals(instr->result()));
-  ASSERT(left->IsRegister());
-  Register result = ToRegister(left);
-  Operand right_operand(no_reg);
+  LOperand* left_op = instr->InputAt(0);
+  LOperand* right_op = instr->InputAt(1);
+  ASSERT(left_op->IsRegister());
+  Register left = ToRegister(left_op);
+  Register result = ToRegister(instr->result());
+  Operand right(no_reg);
 
-  if (right->IsStackSlot() || right->IsArgument()) {
-    Register right_reg = EmitLoadRegister(right, ip);
-    right_operand = Operand(right_reg);
+  if (right_op->IsStackSlot() || right_op->IsArgument()) {
+    right = Operand(EmitLoadRegister(right_op, ip));
   } else {
-    ASSERT(right->IsRegister() || right->IsConstantOperand());
-    right_operand = ToOperand(right);
+    ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
+    right = ToOperand(right_op);
   }
 
   switch (instr->op()) {
     case Token::BIT_AND:
-      __ and_(result, ToRegister(left), right_operand);
+      __ and_(result, left, right);
       break;
     case Token::BIT_OR:
-      __ orr(result, ToRegister(left), right_operand);
+      __ orr(result, left, right);
       break;
     case Token::BIT_XOR:
-      __ eor(result, ToRegister(left), right_operand);
+      __ eor(result, left, right);
       break;
     default:
       UNREACHABLE();
@@ -1199,54 +1264,62 @@
 
 
 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->InputAt(1);
+  Register left = ToRegister(instr->InputAt(0));
+  Register result = ToRegister(instr->result());
   Register scratch = scratch0();
-  LOperand* left = instr->InputAt(0);
-  LOperand* right = instr->InputAt(1);
-  ASSERT(left->Equals(instr->result()));
-  ASSERT(left->IsRegister());
-  Register result = ToRegister(left);
-  if (right->IsRegister()) {
-    // Mask the right operand.
-    __ and_(scratch, ToRegister(right), Operand(0x1F));
+  if (right_op->IsRegister()) {
+    // Mask the right_op operand.
+    __ and_(scratch, ToRegister(right_op), Operand(0x1F));
     switch (instr->op()) {
       case Token::SAR:
-        __ mov(result, Operand(result, ASR, scratch));
+        __ mov(result, Operand(left, ASR, scratch));
         break;
       case Token::SHR:
         if (instr->can_deopt()) {
-          __ mov(result, Operand(result, LSR, scratch), SetCC);
+          __ mov(result, Operand(left, LSR, scratch), SetCC);
           DeoptimizeIf(mi, instr->environment());
         } else {
-          __ mov(result, Operand(result, LSR, scratch));
+          __ mov(result, Operand(left, LSR, scratch));
         }
         break;
       case Token::SHL:
-        __ mov(result, Operand(result, LSL, scratch));
+        __ mov(result, Operand(left, LSL, scratch));
         break;
       default:
         UNREACHABLE();
         break;
     }
   } else {
-    int value = ToInteger32(LConstantOperand::cast(right));
+    // 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::SAR:
         if (shift_count != 0) {
-          __ mov(result, Operand(result, ASR, shift_count));
+          __ mov(result, Operand(left, ASR, shift_count));
+        } else {
+          __ Move(result, left);
         }
         break;
       case Token::SHR:
-        if (shift_count == 0 && instr->can_deopt()) {
-          __ tst(result, Operand(0x80000000));
-          DeoptimizeIf(ne, instr->environment());
+        if (shift_count != 0) {
+          __ mov(result, Operand(left, LSR, shift_count));
         } else {
-          __ mov(result, Operand(result, LSR, shift_count));
+          if (instr->can_deopt()) {
+            __ tst(left, Operand(0x80000000));
+            DeoptimizeIf(ne, instr->environment());
+          }
+          __ Move(result, left);
         }
         break;
       case Token::SHL:
         if (shift_count != 0) {
-          __ mov(result, Operand(result, LSL, shift_count));
+          __ mov(result, Operand(left, LSL, shift_count));
+        } else {
+          __ Move(result, left);
         }
         break;
       default:
@@ -1260,16 +1333,16 @@
 void LCodeGen::DoSubI(LSubI* instr) {
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
-  ASSERT(left->Equals(instr->result()));
+  LOperand* result = instr->result();
   bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
   SBit set_cond = can_overflow ? SetCC : LeaveCC;
 
   if (right->IsStackSlot() || right->IsArgument()) {
     Register right_reg = EmitLoadRegister(right, ip);
-    __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
+    __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
   } else {
     ASSERT(right->IsRegister() || right->IsConstantOperand());
-    __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
+    __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
   }
 
   if (can_overflow) {
@@ -1288,7 +1361,7 @@
   ASSERT(instr->result()->IsDoubleRegister());
   DwVfpRegister result = ToDoubleRegister(instr->result());
   double v = instr->value();
-  __ vmov(result, v);
+  __ Vmov(result, v);
 }
 
 
@@ -1319,19 +1392,34 @@
 }
 
 
+void LCodeGen::DoElementsKind(LElementsKind* instr) {
+  Register result = ToRegister(instr->result());
+  Register input = ToRegister(instr->InputAt(0));
+
+  // Load map into |result|.
+  __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
+  // Load the map's "bit field 2" into |result|. We only need the first byte,
+  // but the following bit field extraction takes care of that anyway.
+  __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset));
+  // Retrieve elements_kind from bit field 2.
+  __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
+}
+
+
 void LCodeGen::DoValueOf(LValueOf* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register result = ToRegister(instr->result());
   Register map = ToRegister(instr->TempAt(0));
-  ASSERT(input.is(result));
   Label done;
 
   // If the object is a smi return the object.
   __ tst(input, Operand(kSmiTagMask));
+  __ Move(result, input, eq);
   __ b(eq, &done);
 
   // If the object is not a value type, return the object.
   __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
+  __ Move(result, input, ne);
   __ b(ne, &done);
   __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
 
@@ -1340,9 +1428,9 @@
 
 
 void LCodeGen::DoBitNotI(LBitNotI* instr) {
-  LOperand* input = instr->InputAt(0);
-  ASSERT(input->Equals(instr->result()));
-  __ mvn(ToRegister(input), Operand(ToRegister(input)));
+  Register input = ToRegister(instr->InputAt(0));
+  Register result = ToRegister(instr->result());
+  __ mvn(result, Operand(input));
 }
 
 
@@ -1360,16 +1448,16 @@
 void LCodeGen::DoAddI(LAddI* instr) {
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
-  ASSERT(left->Equals(instr->result()));
+  LOperand* result = instr->result();
   bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
   SBit set_cond = can_overflow ? SetCC : LeaveCC;
 
   if (right->IsStackSlot() || right->IsArgument()) {
     Register right_reg = EmitLoadRegister(right, ip);
-    __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
+    __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
   } else {
     ASSERT(right->IsRegister() || right->IsConstantOperand());
-    __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
+    __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
   }
 
   if (can_overflow) {
@@ -1381,18 +1469,19 @@
 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
   DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
   DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
+  DoubleRegister result = ToDoubleRegister(instr->result());
   switch (instr->op()) {
     case Token::ADD:
-      __ vadd(left, left, right);
+      __ vadd(result, left, right);
       break;
     case Token::SUB:
-      __ vsub(left, left, right);
+      __ vsub(result, left, right);
       break;
     case Token::MUL:
-      __ vmul(left, left, right);
+      __ vmul(result, left, right);
       break;
     case Token::DIV:
-      __ vdiv(left, left, right);
+      __ vdiv(result, left, right);
       break;
     case Token::MOD: {
       // Save r0-r3 on the stack.
@@ -1404,7 +1493,7 @@
           ExternalReference::double_fp_operation(Token::MOD, isolate()),
           0, 2);
       // Move the result in the double result register.
-      __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result()));
+      __ GetCFunctionDoubleResult(result);
 
       // Restore r0-r3.
       __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
@@ -1459,7 +1548,7 @@
   int true_block = chunk_->LookupDestination(instr->true_block_id());
   int false_block = chunk_->LookupDestination(instr->false_block_id());
 
-  Representation r = instr->hydrogen()->representation();
+  Representation r = instr->hydrogen()->value()->representation();
   if (r.IsInteger32()) {
     Register reg = ToRegister(instr->InputAt(0));
     __ cmp(reg, Operand(0));
@@ -1475,7 +1564,7 @@
   } else {
     ASSERT(r.IsTagged());
     Register reg = ToRegister(instr->InputAt(0));
-    if (instr->hydrogen()->type().IsBoolean()) {
+    if (instr->hydrogen()->value()->type().IsBoolean()) {
       __ LoadRoot(ip, Heap::kTrueValueRootIndex);
       __ cmp(reg, ip);
       EmitBranch(true_block, false_block, eq);
@@ -1494,12 +1583,11 @@
       __ b(eq, false_label);
       __ cmp(reg, Operand(0));
       __ b(eq, false_label);
-      __ tst(reg, Operand(kSmiTagMask));
-      __ b(eq, true_label);
+      __ JumpIfSmi(reg, true_label);
 
       // Test double values. Zero and NaN are false.
       Label call_stub;
-      DoubleRegister dbl_scratch = d0;
+      DoubleRegister dbl_scratch = double_scratch0();
       Register scratch = scratch0();
       __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
       __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
@@ -1527,45 +1615,17 @@
 }
 
 
-void LCodeGen::EmitGoto(int block, LDeferredCode* deferred_stack_check) {
+void LCodeGen::EmitGoto(int block) {
   block = chunk_->LookupDestination(block);
   int next_block = GetNextEmittedBlock(current_block_);
   if (block != next_block) {
-    // Perform stack overflow check if this goto needs it before jumping.
-    if (deferred_stack_check != NULL) {
-      __ LoadRoot(ip, Heap::kStackLimitRootIndex);
-      __ cmp(sp, Operand(ip));
-      __ b(hs, chunk_->GetAssemblyLabel(block));
-      __ jmp(deferred_stack_check->entry());
-      deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block));
-    } else {
-      __ jmp(chunk_->GetAssemblyLabel(block));
-    }
+    __ jmp(chunk_->GetAssemblyLabel(block));
   }
 }
 
 
-void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
-  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
-  CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr);
-}
-
-
 void LCodeGen::DoGoto(LGoto* instr) {
-  class DeferredStackCheck: public LDeferredCode {
-   public:
-    DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
-   private:
-    LGoto* instr_;
-  };
-
-  DeferredStackCheck* deferred = NULL;
-  if (instr->include_stack_check()) {
-    deferred = new DeferredStackCheck(this, instr);
-  }
-  EmitGoto(instr->block_id(), deferred);
+  EmitGoto(instr->block_id());
 }
 
 
@@ -1602,34 +1662,6 @@
 }
 
 
-void LCodeGen::DoCmpID(LCmpID* instr) {
-  LOperand* left = instr->InputAt(0);
-  LOperand* right = instr->InputAt(1);
-  LOperand* result = instr->result();
-  Register scratch = scratch0();
-
-  Label unordered, done;
-  if (instr->is_double()) {
-    // Compare left and right as doubles and load the
-    // resulting flags into the normal status register.
-    __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right));
-    // If a NaN is involved, i.e. the result is unordered (V set),
-    // jump to unordered to return false.
-    __ b(vs, &unordered);
-  } else {
-    EmitCmpI(left, right);
-  }
-
-  Condition cc = TokenToCondition(instr->op(), instr->is_double());
-  __ LoadRoot(ToRegister(result), Heap::kTrueValueRootIndex);
-  __ b(cc, &done);
-
-  __ bind(&unordered);
-  __ LoadRoot(ToRegister(result), Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
@@ -1652,18 +1684,7 @@
 }
 
 
-void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
-  Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  Register result = ToRegister(instr->result());
-
-  __ cmp(left, Operand(right));
-  __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
-}
-
-
-void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
+void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
   Register left = ToRegister(instr->InputAt(0));
   Register right = ToRegister(instr->InputAt(1));
   int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1674,62 +1695,16 @@
 }
 
 
-void LCodeGen::DoCmpSymbolEq(LCmpSymbolEq* instr) {
+void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
   Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  Register result = ToRegister(instr->result());
-
-  __ cmp(left, Operand(right));
-  __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
-}
-
-
-void LCodeGen::DoCmpSymbolEqAndBranch(LCmpSymbolEqAndBranch* instr) {
-  Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
   int true_block = chunk_->LookupDestination(instr->true_block_id());
+  int false_block = chunk_->LookupDestination(instr->false_block_id());
 
-  __ cmp(left, Operand(right));
+  __ cmp(left, Operand(instr->hydrogen()->right()));
   EmitBranch(true_block, false_block, eq);
 }
 
 
-void LCodeGen::DoIsNull(LIsNull* instr) {
-  Register reg = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  __ LoadRoot(ip, Heap::kNullValueRootIndex);
-  __ cmp(reg, ip);
-  if (instr->is_strict()) {
-    __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
-    __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
-  } else {
-    Label true_value, false_value, done;
-    __ b(eq, &true_value);
-    __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
-    __ cmp(ip, reg);
-    __ b(eq, &true_value);
-    __ tst(reg, Operand(kSmiTagMask));
-    __ b(eq, &false_value);
-    // Check for undetectable objects by looking in the bit field in
-    // the map. The object has already been smi checked.
-    Register scratch = result;
-    __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
-    __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
-    __ tst(scratch, Operand(1 << Map::kIsUndetectable));
-    __ b(ne, &true_value);
-    __ bind(&false_value);
-    __ LoadRoot(result, Heap::kFalseValueRootIndex);
-    __ jmp(&done);
-    __ bind(&true_value);
-    __ LoadRoot(result, Heap::kTrueValueRootIndex);
-    __ bind(&done);
-  }
-}
-
-
 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
   Register scratch = scratch0();
   Register reg = ToRegister(instr->InputAt(0));
@@ -1751,8 +1726,7 @@
     __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
     __ cmp(reg, ip);
     __ b(eq, true_label);
-    __ tst(reg, Operand(kSmiTagMask));
-    __ b(eq, false_label);
+    __ JumpIfSmi(reg, false_label);
     // Check for undetectable objects by looking in the bit field in
     // the map. The object has already been smi checked.
     __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
@@ -1765,13 +1739,13 @@
 
 Condition LCodeGen::EmitIsObject(Register input,
                                  Register temp1,
-                                 Register temp2,
                                  Label* is_not_object,
                                  Label* is_object) {
+  Register temp2 = scratch0();
   __ JumpIfSmi(input, is_not_object);
 
-  __ LoadRoot(temp1, Heap::kNullValueRootIndex);
-  __ cmp(input, temp1);
+  __ LoadRoot(temp2, Heap::kNullValueRootIndex);
+  __ cmp(input, temp2);
   __ b(eq, is_object);
 
   // Load map.
@@ -1783,33 +1757,13 @@
 
   // Load instance type and check that it is in object type range.
   __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
-  __ cmp(temp2, Operand(FIRST_JS_OBJECT_TYPE));
+  __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
   __ b(lt, is_not_object);
-  __ cmp(temp2, Operand(LAST_JS_OBJECT_TYPE));
+  __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
   return le;
 }
 
 
-void LCodeGen::DoIsObject(LIsObject* instr) {
-  Register reg = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  Register temp = scratch0();
-  Label is_false, is_true, done;
-
-  Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
-  __ b(true_cond, &is_true);
-
-  __ bind(&is_false);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ b(&done);
-
-  __ bind(&is_true);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
   Register reg = ToRegister(instr->InputAt(0));
   Register temp1 = ToRegister(instr->TempAt(0));
@@ -1821,25 +1775,12 @@
   Label* false_label = chunk_->GetAssemblyLabel(false_block);
 
   Condition true_cond =
-      EmitIsObject(reg, temp1, temp2, false_label, true_label);
+      EmitIsObject(reg, temp1, false_label, true_label);
 
   EmitBranch(true_block, false_block, true_cond);
 }
 
 
-void LCodeGen::DoIsSmi(LIsSmi* instr) {
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  Register result = ToRegister(instr->result());
-  Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
-  __ tst(input_reg, Operand(kSmiTagMask));
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  Label done;
-  __ b(eq, &done);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
   int true_block = chunk_->LookupDestination(instr->true_block_id());
   int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1850,25 +1791,6 @@
 }
 
 
-void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  Label false_label, done;
-  __ JumpIfSmi(input, &false_label);
-  __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
-  __ ldrb(result, FieldMemOperand(result, Map::kBitFieldOffset));
-  __ tst(result, Operand(1 << Map::kIsUndetectable));
-  __ b(eq, &false_label);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ jmp(&done);
-  __ bind(&false_label);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register temp = ToRegister(instr->TempAt(0));
@@ -1884,7 +1806,7 @@
 }
 
 
-static InstanceType TestType(HHasInstanceType* instr) {
+static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
   InstanceType from = instr->from();
   InstanceType to = instr->to();
   if (from == FIRST_TYPE) return to;
@@ -1893,7 +1815,7 @@
 }
 
 
-static Condition BranchCondition(HHasInstanceType* instr) {
+static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
   InstanceType from = instr->from();
   InstanceType to = instr->to();
   if (from == to) return eq;
@@ -1904,23 +1826,6 @@
 }
 
 
-void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  Label done;
-  __ tst(input, Operand(kSmiTagMask));
-  __ LoadRoot(result, Heap::kFalseValueRootIndex, eq);
-  __ b(eq, &done);
-  __ CompareObjectType(input, result, result, TestType(instr->hydrogen()));
-  Condition cond = BranchCondition(instr->hydrogen());
-  __ LoadRoot(result, Heap::kTrueValueRootIndex, cond);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex, NegateCondition(cond));
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
   Register scratch = scratch0();
   Register input = ToRegister(instr->InputAt(0));
@@ -1930,8 +1835,7 @@
 
   Label* false_label = chunk_->GetAssemblyLabel(false_block);
 
-  __ tst(input, Operand(kSmiTagMask));
-  __ b(eq, false_label);
+  __ JumpIfSmi(input, false_label);
 
   __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
   EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
@@ -1951,20 +1855,6 @@
 }
 
 
-void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  Register scratch = scratch0();
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  __ ldr(scratch,
-         FieldMemOperand(input, String::kHashFieldOffset));
-  __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask));
-  __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
-}
-
-
 void LCodeGen::DoHasCachedArrayIndexAndBranch(
     LHasCachedArrayIndexAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
@@ -1990,28 +1880,28 @@
                                Register temp2) {
   ASSERT(!input.is(temp));
   ASSERT(!temp.is(temp2));  // But input and temp2 may be the same register.
-  __ tst(input, Operand(kSmiTagMask));
-  __ b(eq, is_false);
-  __ CompareObjectType(input, temp, temp2, FIRST_JS_OBJECT_TYPE);
+  __ JumpIfSmi(input, is_false);
+  __ CompareObjectType(input, temp, temp2, FIRST_SPEC_OBJECT_TYPE);
   __ b(lt, is_false);
 
   // Map is now in temp.
   // Functions have class 'Function'.
-  __ CompareInstanceType(temp, temp2, JS_FUNCTION_TYPE);
+  __ CompareInstanceType(temp, temp2, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
   if (class_name->IsEqualTo(CStrVector("Function"))) {
-    __ b(eq, is_true);
+    __ b(ge, is_true);
   } else {
-    __ b(eq, is_false);
+    __ b(ge, is_false);
   }
 
   // Check if the constructor in the map is a function.
   __ ldr(temp, FieldMemOperand(temp, Map::kConstructorOffset));
 
-  // As long as JS_FUNCTION_TYPE is the last instance type and it is
-  // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
-  // LAST_JS_OBJECT_TYPE.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
+  // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type and
+  // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
+  STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+  STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+                LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
 
   // Objects with a non-function constructor have class 'Object'.
   __ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE);
@@ -2037,27 +1927,6 @@
 }
 
 
-void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  ASSERT(input.is(result));
-  Handle<String> class_name = instr->hydrogen()->class_name();
-
-  Label done, is_true, is_false;
-
-  EmitClassOfTest(&is_true, &is_false, class_name, input, scratch0(), input);
-  __ b(ne, &is_false);
-
-  __ bind(&is_true);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ jmp(&done);
-
-  __ bind(&is_false);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register temp = scratch0();
@@ -2101,20 +1970,6 @@
 }
 
 
-void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
-  ASSERT(ToRegister(instr->InputAt(0)).is(r0));  // Object is in r0.
-  ASSERT(ToRegister(instr->InputAt(1)).is(r1));  // Function is in r1.
-
-  int true_block = chunk_->LookupDestination(instr->true_block_id());
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
-
-  InstanceofStub stub(InstanceofStub::kArgsInRegisters);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-  __ cmp(r0, Operand(0));
-  EmitBranch(true_block, false_block, eq);
-}
-
-
 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
   class DeferredInstanceOfKnownGlobal: public LDeferredCode {
    public:
@@ -2269,25 +2124,6 @@
 }
 
 
-void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) {
-  Token::Value op = instr->op();
-  int true_block = chunk_->LookupDestination(instr->true_block_id());
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
-
-  Handle<Code> ic = CompareIC::GetUninitialized(op);
-  CallCode(ic, RelocInfo::CODE_TARGET, instr);
-
-  // The compare stub expects compare condition and the input operands
-  // reversed for GT and LTE.
-  Condition condition = ComputeCompareCondition(op);
-  if (op == Token::GT || op == Token::LTE) {
-    condition = ReverseCondition(condition);
-  }
-  __ cmp(r0, Operand(0));
-  EmitBranch(true_block, false_block, condition);
-}
-
-
 void LCodeGen::DoReturn(LReturn* instr) {
   if (FLAG_trace) {
     // Push the return value on the stack as the parameter.
@@ -2526,7 +2362,7 @@
 
   __ ldr(result, FieldMemOperand(input, JSObject::kElementsOffset));
   if (FLAG_debug_code) {
-    Label done;
+    Label done, fail;
     __ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
     __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
     __ cmp(scratch, ip);
@@ -2534,11 +2370,18 @@
     __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
     __ cmp(scratch, ip);
     __ b(eq, &done);
-    __ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
-    __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
-    __ sub(scratch, scratch, Operand(FIRST_EXTERNAL_ARRAY_TYPE));
-    __ cmp(scratch, Operand(kExternalArrayTypeCount));
-    __ Check(cc, "Check for fast elements failed.");
+    // |scratch| still contains |input|'s map.
+    __ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset));
+    __ ubfx(scratch, scratch, Map::kElementsKindShift,
+            Map::kElementsKindBitCount);
+    __ cmp(scratch, Operand(JSObject::FAST_ELEMENTS));
+    __ b(eq, &done);
+    __ cmp(scratch, Operand(JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND));
+    __ b(lt, &fail);
+    __ cmp(scratch, Operand(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND));
+    __ b(le, &done);
+    __ bind(&fail);
+    __ Abort("Check for fast or external elements failed.");
     __ bind(&done);
   }
 }
@@ -2576,7 +2419,6 @@
   Register key = EmitLoadRegister(instr->key(), scratch0());
   Register result = ToRegister(instr->result());
   Register scratch = scratch0();
-  ASSERT(result.is(elements));
 
   // Load the result.
   __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
@@ -2591,11 +2433,53 @@
 }
 
 
+void LCodeGen::DoLoadKeyedFastDoubleElement(
+    LLoadKeyedFastDoubleElement* instr) {
+  Register elements = ToRegister(instr->elements());
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  Register key = no_reg;
+  DwVfpRegister result = ToDoubleRegister(instr->result());
+  Register scratch = scratch0();
+
+  int shift_size =
+      ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS);
+  int constant_key = 0;
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort("array index constant value too big.");
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+
+  Operand operand = key_is_constant
+      ? Operand(constant_key * (1 << shift_size) +
+                FixedDoubleArray::kHeaderSize - kHeapObjectTag)
+      : Operand(key, LSL, shift_size);
+  __ add(elements, elements, operand);
+  if (!key_is_constant) {
+    __ add(elements, elements,
+           Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+  }
+
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    // TODO(danno): If no hole check is required, there is no need to allocate
+    // elements into a temporary register, instead scratch can be used.
+    __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
+    __ cmp(scratch, Operand(kHoleNanUpper32));
+    DeoptimizeIf(eq, instr->environment());
+  }
+
+  __ vldr(result, elements, 0);
+}
+
+
 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
     LLoadKeyedSpecializedArrayElement* instr) {
   Register external_pointer = ToRegister(instr->external_pointer());
   Register key = no_reg;
-  ExternalArrayType array_type = instr->array_type();
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
   bool key_is_constant = instr->key()->IsConstantOperand();
   int constant_key = 0;
   if (key_is_constant) {
@@ -2606,43 +2490,45 @@
   } else {
     key = ToRegister(instr->key());
   }
-  int shift_size = ExternalArrayTypeToShiftSize(array_type);
+  int shift_size = ElementsKindToShiftSize(elements_kind);
 
-  if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) {
+  if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+      elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     CpuFeatures::Scope scope(VFP3);
-    DwVfpRegister result(ToDoubleRegister(instr->result()));
-    Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
-                                    : Operand(key, LSL, shift_size));
+    DwVfpRegister result = ToDoubleRegister(instr->result());
+    Operand operand = key_is_constant
+        ? Operand(constant_key * (1 << shift_size))
+        : Operand(key, LSL, shift_size);
     __ add(scratch0(), external_pointer, operand);
-    if (array_type == kExternalFloatArray) {
+    if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
       __ vldr(result.low(), scratch0(), 0);
       __ vcvt_f64_f32(result, result.low());
-    } else  {  // i.e. array_type == kExternalDoubleArray
+    } else  {  // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS
       __ vldr(result, scratch0(), 0);
     }
   } else {
-    Register result(ToRegister(instr->result()));
+    Register result = ToRegister(instr->result());
     MemOperand mem_operand(key_is_constant
         ? MemOperand(external_pointer, constant_key * (1 << shift_size))
         : MemOperand(external_pointer, key, LSL, shift_size));
-    switch (array_type) {
-      case kExternalByteArray:
+    switch (elements_kind) {
+      case JSObject::EXTERNAL_BYTE_ELEMENTS:
         __ ldrsb(result, mem_operand);
         break;
-      case kExternalUnsignedByteArray:
-      case kExternalPixelArray:
+      case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
         __ ldrb(result, mem_operand);
         break;
-      case kExternalShortArray:
+      case JSObject::EXTERNAL_SHORT_ELEMENTS:
         __ ldrsh(result, mem_operand);
         break;
-      case kExternalUnsignedShortArray:
+      case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
         __ ldrh(result, mem_operand);
         break;
-      case kExternalIntArray:
+      case JSObject::EXTERNAL_INT_ELEMENTS:
         __ ldr(result, mem_operand);
         break;
-      case kExternalUnsignedIntArray:
+      case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
         __ ldr(result, mem_operand);
         __ cmp(result, Operand(0x80000000));
         // TODO(danno): we could be more clever here, perhaps having a special
@@ -2650,8 +2536,12 @@
         // happens, and generate code that returns a double rather than int.
         DeoptimizeIf(cs, instr->environment());
         break;
-      case kExternalFloatArray:
-      case kExternalDoubleArray:
+      case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+      case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+      case JSObject::FAST_DOUBLE_ELEMENTS:
+      case JSObject::FAST_ELEMENTS:
+      case JSObject::DICTIONARY_ELEMENTS:
+      case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -2717,12 +2607,26 @@
   ASSERT(function.is(r1));  // Required by InvokeFunction.
   ASSERT(ToRegister(instr->result()).is(r0));
 
-  // TODO(1412): This is not correct if the called function is a
-  // strict mode function or a native.
-  //
-  // If the receiver is null or undefined, we have to pass the global object
-  // as a receiver.
+  // 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, receiver_ok;
+
+  // Do not transform the receiver to object for strict mode
+  // functions.
+  __ ldr(scratch,
+         FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
+  __ ldr(scratch,
+         FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
+  __ tst(scratch,
+         Operand(1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize)));
+  __ b(ne, &receiver_ok);
+
+  // Do not transform the receiver to object for builtins.
+  __ tst(scratch, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
+  __ b(ne, &receiver_ok);
+
+  // Normal function. Replace undefined or null with global receiver.
   __ LoadRoot(scratch, Heap::kNullValueRootIndex);
   __ cmp(receiver, scratch);
   __ b(eq, &global_object);
@@ -2733,8 +2637,8 @@
   // Deoptimize if the receiver is not a JS object.
   __ tst(receiver, Operand(kSmiTagMask));
   DeoptimizeIf(eq, instr->environment());
-  __ CompareObjectType(receiver, scratch, scratch, FIRST_JS_OBJECT_TYPE);
-  DeoptimizeIf(lo, instr->environment());
+  __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE);
+  DeoptimizeIf(lt, instr->environment());
   __ jmp(&receiver_ok);
 
   __ bind(&global_object);
@@ -2797,6 +2701,12 @@
 }
 
 
+void LCodeGen::DoThisFunction(LThisFunction* instr) {
+  Register result = ToRegister(instr->result());
+  __ ldr(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+}
+
+
 void LCodeGen::DoContext(LContext* instr) {
   Register result = ToRegister(instr->result());
   __ mov(result, cp);
@@ -2807,8 +2717,7 @@
   Register context = ToRegister(instr->context());
   Register result = ToRegister(instr->result());
   __ ldr(result,
-         MemOperand(context, Context::SlotOffset(Context::CLOSURE_INDEX)));
-  __ ldr(result, FieldMemOperand(result, JSFunction::kContextOffset));
+         MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
 }
 
 
@@ -2872,8 +2781,8 @@
 
 
 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
-  ASSERT(instr->InputAt(0)->Equals(instr->result()));
   Register input = ToRegister(instr->InputAt(0));
+  Register result = ToRegister(instr->result());
   Register scratch = scratch0();
 
   // Deoptimize if not a heap number.
@@ -2887,10 +2796,10 @@
   scratch = no_reg;
   __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
   // Check the sign of the argument. If the argument is positive, just
-  // return it. We do not need to patch the stack since |input| and
-  // |result| are the same register and |input| would be restored
-  // unchanged by popping safepoint registers.
+  // return it.
   __ tst(exponent, Operand(HeapNumber::kSignMask));
+  // Move the input to the result if necessary.
+  __ Move(result, input);
   __ b(eq, &done);
 
   // Input is negative. Reverse its sign.
@@ -2930,7 +2839,7 @@
     __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
     __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
 
-    __ StoreToSafepointRegisterSlot(tmp1, input);
+    __ StoreToSafepointRegisterSlot(tmp1, result);
   }
 
   __ bind(&done);
@@ -2939,11 +2848,13 @@
 
 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
   Register input = ToRegister(instr->InputAt(0));
+  Register result = ToRegister(instr->result());
   __ cmp(input, Operand(0));
+  __ Move(result, input, pl);
   // We can make rsb conditional because the previous cmp instruction
   // will clear the V (overflow) flag and rsb won't set this flag
   // if input is positive.
-  __ rsb(input, input, Operand(0), SetCC, mi);
+  __ rsb(result, input, Operand(0), SetCC, mi);
   // Deoptimize on overflow.
   DeoptimizeIf(vs, instr->environment());
 }
@@ -2963,11 +2874,11 @@
     LUnaryMathOperation* instr_;
   };
 
-  ASSERT(instr->InputAt(0)->Equals(instr->result()));
   Representation r = instr->hydrogen()->value()->representation();
   if (r.IsDouble()) {
     DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
-    __ vabs(input, input);
+    DwVfpRegister result = ToDoubleRegister(instr->result());
+    __ vabs(result, input);
   } else if (r.IsInteger32()) {
     EmitIntegerMathAbs(instr);
   } else {
@@ -3045,7 +2956,7 @@
   // Save the original sign for later comparison.
   __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask));
 
-  __ vmov(double_scratch0(), 0.5);
+  __ Vmov(double_scratch0(), 0.5);
   __ vadd(input, input, double_scratch0());
 
   // Check sign of the result: if the sign changed, the input
@@ -3082,24 +2993,17 @@
 
 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
   DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
-  ASSERT(ToDoubleRegister(instr->result()).is(input));
-  __ vsqrt(input, input);
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  __ vsqrt(result, input);
 }
 
 
 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
   DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
-  Register scratch = scratch0();
-  SwVfpRegister single_scratch = double_scratch0().low();
-  DoubleRegister double_scratch = double_scratch0();
-  ASSERT(ToDoubleRegister(instr->result()).is(input));
-
+  DoubleRegister result = ToDoubleRegister(instr->result());
   // Add +0 to convert -0 to +0.
-  __ mov(scratch, Operand(0));
-  __ vmov(single_scratch, scratch);
-  __ vcvt_f64_s32(double_scratch, single_scratch);
-  __ vadd(input, input, double_scratch);
-  __ vsqrt(input, input);
+  __ vadd(result, input, kDoubleRegZero);
+  __ vsqrt(result, result);
 }
 
 
@@ -3382,12 +3286,54 @@
 }
 
 
+void LCodeGen::DoStoreKeyedFastDoubleElement(
+    LStoreKeyedFastDoubleElement* instr) {
+  DwVfpRegister value = ToDoubleRegister(instr->value());
+  Register elements = ToRegister(instr->elements());
+  Register key = no_reg;
+  Register scratch = scratch0();
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  int constant_key = 0;
+  Label not_nan;
+
+  // Calculate the effective address of the slot in the array to store the
+  // double value.
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort("array index constant value too big.");
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+  int shift_size = ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS);
+  Operand operand = key_is_constant
+      ? Operand(constant_key * (1 << shift_size) +
+                FixedDoubleArray::kHeaderSize - kHeapObjectTag)
+      : Operand(key, LSL, shift_size);
+  __ add(scratch, elements, operand);
+  if (!key_is_constant) {
+    __ add(scratch, scratch,
+           Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+  }
+
+  // Check for NaN. All NaNs must be canonicalized.
+  __ VFPCompareAndSetFlags(value, value);
+
+  // Only load canonical NaN if the comparison above set the overflow.
+  __ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(), vs);
+
+  __ bind(&not_nan);
+  __ vstr(value, scratch, 0);
+}
+
+
 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
     LStoreKeyedSpecializedArrayElement* instr) {
 
   Register external_pointer = ToRegister(instr->external_pointer());
   Register key = no_reg;
-  ExternalArrayType array_type = instr->array_type();
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
   bool key_is_constant = instr->key()->IsConstantOperand();
   int constant_key = 0;
   if (key_is_constant) {
@@ -3398,18 +3344,19 @@
   } else {
     key = ToRegister(instr->key());
   }
-  int shift_size = ExternalArrayTypeToShiftSize(array_type);
+  int shift_size = ElementsKindToShiftSize(elements_kind);
 
-  if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) {
+  if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+      elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     CpuFeatures::Scope scope(VFP3);
     DwVfpRegister value(ToDoubleRegister(instr->value()));
     Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
                                     : Operand(key, LSL, shift_size));
     __ add(scratch0(), external_pointer, operand);
-    if (array_type == kExternalFloatArray) {
+    if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
       __ vcvt_f32_f64(double_scratch0().low(), value);
       __ vstr(double_scratch0().low(), scratch0(), 0);
-    } else {  // i.e. array_type == kExternalDoubleArray
+    } else {  // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS
       __ vstr(value, scratch0(), 0);
     }
   } else {
@@ -3417,22 +3364,26 @@
     MemOperand mem_operand(key_is_constant
         ? MemOperand(external_pointer, constant_key * (1 << shift_size))
         : MemOperand(external_pointer, key, LSL, shift_size));
-    switch (array_type) {
-      case kExternalPixelArray:
-      case kExternalByteArray:
-      case kExternalUnsignedByteArray:
+    switch (elements_kind) {
+      case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+      case JSObject::EXTERNAL_BYTE_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
         __ strb(value, mem_operand);
         break;
-      case kExternalShortArray:
-      case kExternalUnsignedShortArray:
+      case JSObject::EXTERNAL_SHORT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
         __ strh(value, mem_operand);
         break;
-      case kExternalIntArray:
-      case kExternalUnsignedIntArray:
+      case JSObject::EXTERNAL_INT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
         __ str(value, mem_operand);
         break;
-      case kExternalFloatArray:
-      case kExternalDoubleArray:
+      case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+      case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+      case JSObject::FAST_DOUBLE_ELEMENTS:
+      case JSObject::FAST_ELEMENTS:
+      case JSObject::DICTIONARY_ELEMENTS:
+      case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -3693,8 +3644,8 @@
 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
   Label slow;
   Register reg = ToRegister(instr->InputAt(0));
-  DoubleRegister dbl_scratch = d0;
-  SwVfpRegister flt_scratch = s0;
+  DoubleRegister dbl_scratch = double_scratch0();
+  SwVfpRegister flt_scratch = dbl_scratch.low();
 
   // Preserve the value of all registers.
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
@@ -3803,14 +3754,13 @@
                                 bool deoptimize_on_undefined,
                                 LEnvironment* env) {
   Register scratch = scratch0();
-  SwVfpRegister flt_scratch = s0;
-  ASSERT(!result_reg.is(d0));
+  SwVfpRegister flt_scratch = double_scratch0().low();
+  ASSERT(!result_reg.is(double_scratch0()));
 
   Label load_smi, heap_number, done;
 
   // Smi check.
-  __ tst(input_reg, Operand(kSmiTagMask));
-  __ b(eq, &load_smi);
+  __ JumpIfSmi(input_reg, &load_smi);
 
   // Heap number map check.
   __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
@@ -4316,29 +4266,6 @@
 }
 
 
-void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  Label true_label;
-  Label false_label;
-  Label done;
-
-  Condition final_branch_condition = EmitTypeofIs(&true_label,
-                                                  &false_label,
-                                                  input,
-                                                  instr->type_literal());
-  __ b(final_branch_condition, &true_label);
-  __ bind(&false_label);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ b(&done);
-
-  __ bind(&true_label);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -4394,17 +4321,19 @@
 
   } else if (type_name->Equals(heap()->function_symbol())) {
     __ JumpIfSmi(input, false_label);
-    __ CompareObjectType(input, input, scratch, FIRST_FUNCTION_CLASS_TYPE);
+    __ CompareObjectType(input, input, scratch,
+                         FIRST_CALLABLE_SPEC_OBJECT_TYPE);
     final_branch_condition = ge;
 
   } else if (type_name->Equals(heap()->object_symbol())) {
     __ JumpIfSmi(input, false_label);
     __ CompareRoot(input, Heap::kNullValueRootIndex);
     __ b(eq, true_label);
-    __ CompareObjectType(input, input, scratch, FIRST_JS_OBJECT_TYPE);
-    __ b(lo, false_label);
-    __ CompareInstanceType(input, scratch, FIRST_FUNCTION_CLASS_TYPE);
-    __ b(hs, false_label);
+    __ CompareObjectType(input, input, scratch,
+                         FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ b(lt, false_label);
+    __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ b(gt, false_label);
     // Check for undetectable objects => false.
     __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
     __ tst(ip, Operand(1 << Map::kIsUndetectable));
@@ -4420,26 +4349,6 @@
 }
 
 
-void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
-  Register result = ToRegister(instr->result());
-  Label true_label;
-  Label false_label;
-  Label done;
-
-  EmitIsConstructCall(result, scratch0());
-  __ b(eq, &true_label);
-
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ b(&done);
-
-
-  __ bind(&true_label);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
   Register temp1 = ToRegister(instr->TempAt(0));
   int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -4514,15 +4423,50 @@
 }
 
 
+void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
+  {
+    PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+    __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
+    RegisterLazyDeoptimization(
+        instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
+  }
+
+  // The gap code includes the restoring of the safepoint registers.
+  int pc = masm()->pc_offset();
+  safepoints_.SetPcAfterGap(pc);
+}
+
+
 void LCodeGen::DoStackCheck(LStackCheck* instr) {
-  // Perform stack overflow check.
-  Label ok;
-  __ LoadRoot(ip, Heap::kStackLimitRootIndex);
-  __ cmp(sp, Operand(ip));
-  __ b(hs, &ok);
-  StackCheckStub stub;
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-  __ bind(&ok);
+  class DeferredStackCheck: public LDeferredCode {
+   public:
+    DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
+        : LDeferredCode(codegen), instr_(instr) { }
+    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
+   private:
+    LStackCheck* instr_;
+  };
+
+  if (instr->hydrogen()->is_function_entry()) {
+    // Perform stack overflow check.
+    Label done;
+    __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+    __ cmp(sp, Operand(ip));
+    __ b(hs, &done);
+    StackCheckStub stub;
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+    __ bind(&done);
+  } else {
+    ASSERT(instr->hydrogen()->is_backwards_branch());
+    // Perform stack overflow check if this goto needs it before jumping.
+    DeferredStackCheck* deferred_stack_check =
+        new DeferredStackCheck(this, instr);
+    __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+    __ cmp(sp, Operand(ip));
+    __ b(lo, deferred_stack_check->entry());
+    __ bind(instr->done_label());
+    deferred_stack_check->SetExit(instr->done_label());
+  }
 }
 
 
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index 8253c17..ead8489 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -108,7 +108,7 @@
   void DoDeferredNumberTagI(LNumberTagI* instr);
   void DoDeferredTaggedToI(LTaggedToI* instr);
   void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
-  void DoDeferredStackCheck(LGoto* instr);
+  void DoDeferredStackCheck(LStackCheck* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
@@ -148,7 +148,7 @@
   HGraph* graph() const { return chunk_->graph(); }
 
   Register scratch0() { return r9; }
-  DwVfpRegister double_scratch0() { return d0; }
+  DwVfpRegister double_scratch0() { return d15; }
 
   int GetNextEmittedBlock(int block);
   LInstruction* GetNextInstruction();
@@ -261,7 +261,7 @@
   }
 
   static Condition TokenToCondition(Token::Value op, bool is_unsigned);
-  void EmitGoto(int block, LDeferredCode* deferred_stack_check = NULL);
+  void EmitGoto(int block);
   void EmitBranch(int left_block, int right_block, Condition cc);
   void EmitCmpI(LOperand* left, LOperand* right);
   void EmitNumberUntagD(Register input,
@@ -280,7 +280,6 @@
   // true and false label should be made, to optimize fallthrough.
   Condition EmitIsObject(Register input,
                          Register temp1,
-                         Register temp2,
                          Label* is_not_object,
                          Label* is_object);
 
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index c227b13..c34a579 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -91,7 +91,7 @@
 }
 
 
-void MacroAssembler::Jump(byte* target, RelocInfo::Mode rmode,
+void MacroAssembler::Jump(Address target, RelocInfo::Mode rmode,
                           Condition cond) {
   ASSERT(!RelocInfo::IsCodeTarget(rmode));
   Jump(reinterpret_cast<intptr_t>(target), rmode, cond);
@@ -118,10 +118,8 @@
 void MacroAssembler::Call(Register target, Condition cond) {
   // Block constant pool for the call instruction sequence.
   BlockConstPoolScope block_const_pool(this);
-#ifdef DEBUG
-  int pre_position = pc_offset();
-#endif
-
+  Label start;
+  bind(&start);
 #if USE_BLX
   blx(target, cond);
 #else
@@ -129,34 +127,29 @@
   mov(lr, Operand(pc), LeaveCC, cond);
   mov(pc, Operand(target), LeaveCC, cond);
 #endif
-
-#ifdef DEBUG
-  int post_position = pc_offset();
-  CHECK_EQ(pre_position + CallSize(target, cond), post_position);
-#endif
+  ASSERT_EQ(CallSize(target, cond), SizeOfCodeGeneratedSince(&start));
 }
 
 
 int MacroAssembler::CallSize(
-    intptr_t target, RelocInfo::Mode rmode, Condition cond) {
+    Address target, RelocInfo::Mode rmode, Condition cond) {
   int size = 2 * kInstrSize;
   Instr mov_instr = cond | MOV | LeaveCC;
-  if (!Operand(target, rmode).is_single_instruction(mov_instr)) {
+  intptr_t immediate = reinterpret_cast<intptr_t>(target);
+  if (!Operand(immediate, rmode).is_single_instruction(mov_instr)) {
     size += kInstrSize;
   }
   return size;
 }
 
 
-void MacroAssembler::Call(intptr_t target,
+void MacroAssembler::Call(Address target,
                           RelocInfo::Mode rmode,
                           Condition cond) {
   // Block constant pool for the call instruction sequence.
   BlockConstPoolScope block_const_pool(this);
-#ifdef DEBUG
-  int pre_position = pc_offset();
-#endif
-
+  Label start;
+  bind(&start);
 #if USE_BLX
   // On ARMv5 and after the recommended call sequence is:
   //  ldr ip, [pc, #...]
@@ -168,7 +161,7 @@
   // we have to do it explicitly.
   positions_recorder()->WriteRecordedPositions();
 
-  mov(ip, Operand(target, rmode));
+  mov(ip, Operand(reinterpret_cast<int32_t>(target), rmode));
   blx(ip, cond);
 
   ASSERT(kCallTargetAddressOffset == 2 * kInstrSize);
@@ -176,82 +169,36 @@
   // Set lr for return at current pc + 8.
   mov(lr, Operand(pc), LeaveCC, cond);
   // Emit a ldr<cond> pc, [pc + offset of target in constant pool].
-  mov(pc, Operand(target, rmode), LeaveCC, cond);
+  mov(pc, Operand(reinterpret_cast<int32_t>(target), rmode), LeaveCC, cond);
   ASSERT(kCallTargetAddressOffset == kInstrSize);
 #endif
-
-#ifdef DEBUG
-  int post_position = pc_offset();
-  CHECK_EQ(pre_position + CallSize(target, rmode, cond), post_position);
-#endif
+  ASSERT_EQ(CallSize(target, rmode, cond), SizeOfCodeGeneratedSince(&start));
 }
 
 
-int MacroAssembler::CallSize(
-    byte* target, RelocInfo::Mode rmode, Condition cond) {
-  return CallSize(reinterpret_cast<intptr_t>(target), rmode);
-}
-
-
-void MacroAssembler::Call(
-    byte* target, RelocInfo::Mode rmode, Condition cond) {
-#ifdef DEBUG
-  int pre_position = pc_offset();
-#endif
-
-  ASSERT(!RelocInfo::IsCodeTarget(rmode));
-  Call(reinterpret_cast<intptr_t>(target), rmode, cond);
-
-#ifdef DEBUG
-  int post_position = pc_offset();
-  CHECK_EQ(pre_position + CallSize(target, rmode, cond), post_position);
-#endif
-}
-
-
-int MacroAssembler::CallSize(
-    Handle<Code> code, RelocInfo::Mode rmode, Condition cond) {
-  return CallSize(reinterpret_cast<intptr_t>(code.location()), rmode, cond);
-}
-
-
-void MacroAssembler::CallWithAstId(Handle<Code> code,
-                                   RelocInfo::Mode rmode,
-                                   unsigned ast_id,
-                                   Condition cond) {
-#ifdef DEBUG
-  int pre_position = pc_offset();
-#endif
-
-  ASSERT(rmode == RelocInfo::CODE_TARGET_WITH_ID);
-  ASSERT(ast_id != kNoASTId);
-  ASSERT(ast_id_for_reloc_info_ == kNoASTId);
-  ast_id_for_reloc_info_ = ast_id;
-  // 'code' is always generated ARM code, never THUMB code
-  Call(reinterpret_cast<intptr_t>(code.location()), rmode, cond);
-
-#ifdef DEBUG
-  int post_position = pc_offset();
-  CHECK_EQ(pre_position + CallSize(code, rmode, cond), post_position);
-#endif
+int MacroAssembler::CallSize(Handle<Code> code,
+                             RelocInfo::Mode rmode,
+                             unsigned ast_id,
+                             Condition cond) {
+  return CallSize(reinterpret_cast<Address>(code.location()), rmode, cond);
 }
 
 
 void MacroAssembler::Call(Handle<Code> code,
                           RelocInfo::Mode rmode,
+                          unsigned ast_id,
                           Condition cond) {
-#ifdef DEBUG
-  int pre_position = pc_offset();
-#endif
-
+  Label start;
+  bind(&start);
   ASSERT(RelocInfo::IsCodeTarget(rmode));
+  if (rmode == RelocInfo::CODE_TARGET && ast_id != kNoASTId) {
+    SetRecordedAstId(ast_id);
+    rmode = RelocInfo::CODE_TARGET_WITH_ID;
+  }
   // 'code' is always generated ARM code, never THUMB code
-  Call(reinterpret_cast<intptr_t>(code.location()), rmode, cond);
-
-#ifdef DEBUG
-  int post_position = pc_offset();
-  CHECK_EQ(pre_position + CallSize(code, rmode, cond), post_position);
-#endif
+  Call(reinterpret_cast<Address>(code.location()), rmode, cond);
+  ASSERT_EQ(CallSize(code, rmode, ast_id, cond),
+            SizeOfCodeGeneratedSince(&start));
 }
 
 
@@ -298,14 +245,20 @@
 }
 
 
+void MacroAssembler::Push(Handle<Object> handle) {
+  mov(ip, Operand(handle));
+  push(ip);
+}
+
+
 void MacroAssembler::Move(Register dst, Handle<Object> value) {
   mov(dst, Operand(value));
 }
 
 
-void MacroAssembler::Move(Register dst, Register src) {
+void MacroAssembler::Move(Register dst, Register src, Condition cond) {
   if (!dst.is(src)) {
-    mov(dst, src);
+    mov(dst, src, LeaveCC, cond);
   }
 }
 
@@ -330,7 +283,8 @@
              !src2.must_use_constant_pool() &&
              CpuFeatures::IsSupported(ARMv7) &&
              IsPowerOf2(src2.immediate() + 1)) {
-    ubfx(dst, src1, 0, WhichPowerOf2(src2.immediate() + 1), cond);
+    ubfx(dst, src1, 0,
+        WhichPowerOf2(static_cast<uint32_t>(src2.immediate()) + 1), cond);
 
   } else {
     and_(dst, src1, src2, LeaveCC, cond);
@@ -438,20 +392,6 @@
 }
 
 
-void MacroAssembler::SmiJumpTable(Register index, Vector<Label*> targets) {
-  // Empty the const pool.
-  CheckConstPool(true, true);
-  add(pc, pc, Operand(index,
-                      LSL,
-                      Instruction::kInstrSizeLog2 - kSmiTagSize));
-  BlockConstPoolBefore(pc_offset() + (targets.length() + 1) * kInstrSize);
-  nop();  // Jump table alignment.
-  for (int i = 0; i < targets.length(); i++) {
-    b(targets[i]);
-  }
-}
-
-
 void MacroAssembler::LoadRoot(Register destination,
                               Heap::RootListIndex index,
                               Condition cond) {
@@ -654,19 +594,36 @@
   ASSERT_EQ(0, dst1.code() % 2);
   ASSERT_EQ(dst1.code() + 1, dst2.code());
 
+  // V8 does not use this addressing mode, so the fallback code
+  // below doesn't support it yet.
+  ASSERT((src.am() != PreIndex) && (src.am() != NegPreIndex));
+
   // Generate two ldr instructions if ldrd is not available.
   if (CpuFeatures::IsSupported(ARMv7)) {
     CpuFeatures::Scope scope(ARMv7);
     ldrd(dst1, dst2, src, cond);
   } else {
-    MemOperand src2(src);
-    src2.set_offset(src2.offset() + 4);
-    if (dst1.is(src.rn())) {
-      ldr(dst2, src2, cond);
-      ldr(dst1, src, cond);
-    } else {
-      ldr(dst1, src, cond);
-      ldr(dst2, src2, cond);
+    if ((src.am() == Offset) || (src.am() == NegOffset)) {
+      MemOperand src2(src);
+      src2.set_offset(src2.offset() + 4);
+      if (dst1.is(src.rn())) {
+        ldr(dst2, src2, cond);
+        ldr(dst1, src, cond);
+      } else {
+        ldr(dst1, src, cond);
+        ldr(dst2, src2, cond);
+      }
+    } else {  // PostIndex or NegPostIndex.
+      ASSERT((src.am() == PostIndex) || (src.am() == NegPostIndex));
+      if (dst1.is(src.rn())) {
+        ldr(dst2, MemOperand(src.rn(), 4, Offset), cond);
+        ldr(dst1, src, cond);
+      } else {
+        MemOperand src2(src);
+        src2.set_offset(src2.offset() - 4);
+        ldr(dst1, MemOperand(src.rn(), 4, PostIndex), cond);
+        ldr(dst2, src2, cond);
+      }
     }
   }
 }
@@ -679,15 +636,26 @@
   ASSERT_EQ(0, src1.code() % 2);
   ASSERT_EQ(src1.code() + 1, src2.code());
 
+  // V8 does not use this addressing mode, so the fallback code
+  // below doesn't support it yet.
+  ASSERT((dst.am() != PreIndex) && (dst.am() != NegPreIndex));
+
   // Generate two str instructions if strd is not available.
   if (CpuFeatures::IsSupported(ARMv7)) {
     CpuFeatures::Scope scope(ARMv7);
     strd(src1, src2, dst, cond);
   } else {
     MemOperand dst2(dst);
-    dst2.set_offset(dst2.offset() + 4);
-    str(src1, dst, cond);
-    str(src2, dst2, cond);
+    if ((dst.am() == Offset) || (dst.am() == NegOffset)) {
+      dst2.set_offset(dst2.offset() + 4);
+      str(src1, dst, cond);
+      str(src2, dst2, cond);
+    } else {  // PostIndex or NegPostIndex.
+      ASSERT((dst.am() == PostIndex) || (dst.am() == NegPostIndex));
+      dst2.set_offset(dst2.offset() - 4);
+      str(src1, MemOperand(dst.rn(), 4, PostIndex), cond);
+      str(src2, dst2, cond);
+    }
   }
 }
 
@@ -734,6 +702,23 @@
   vmrs(fpscr_flags, cond);
 }
 
+void MacroAssembler::Vmov(const DwVfpRegister dst,
+                          const double imm,
+                          const Condition cond) {
+  ASSERT(CpuFeatures::IsEnabled(VFP3));
+  static const DoubleRepresentation minus_zero(-0.0);
+  static const DoubleRepresentation zero(0.0);
+  DoubleRepresentation value(imm);
+  // Handle special values first.
+  if (value.bits == zero.bits) {
+    vmov(dst, kDoubleRegZero, cond);
+  } else if (value.bits == minus_zero.bits) {
+    vneg(dst, kDoubleRegZero, cond);
+  } else {
+    vmov(dst, imm, cond);
+  }
+}
+
 
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   // r0-r3: preserved
@@ -956,9 +941,9 @@
     Handle<Code> adaptor =
         isolate()->builtins()->ArgumentsAdaptorTrampoline();
     if (flag == CALL_FUNCTION) {
-      call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
+      call_wrapper.BeforeCall(CallSize(adaptor));
       SetCallKind(r5, call_kind);
-      Call(adaptor, RelocInfo::CODE_TARGET);
+      Call(adaptor);
       call_wrapper.AfterCall();
       b(done);
     } else {
@@ -1084,9 +1069,9 @@
                                             Register scratch,
                                             Label* fail) {
   ldrb(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
-  cmp(scratch, Operand(FIRST_JS_OBJECT_TYPE));
+  cmp(scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
   b(lt, fail);
-  cmp(scratch, Operand(LAST_JS_OBJECT_TYPE));
+  cmp(scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
   b(gt, fail);
 }
 
@@ -1358,6 +1343,100 @@
 }
 
 
+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;
+
+  // Compute the hash code from the untagged key.  This must be kept in sync
+  // with ComputeIntegerHash in utils.h.
+  //
+  // hash = ~hash + (hash << 15);
+  mvn(t1, Operand(t0));
+  add(t0, t1, Operand(t0, LSL, 15));
+  // hash = hash ^ (hash >> 12);
+  eor(t0, t0, Operand(t0, LSR, 12));
+  // hash = hash + (hash << 2);
+  add(t0, t0, Operand(t0, LSL, 2));
+  // hash = hash ^ (hash >> 4);
+  eor(t0, t0, Operand(t0, LSR, 4));
+  // hash = hash * 2057;
+  mov(t1, Operand(2057));
+  mul(t0, t0, t1);
+  // hash = hash ^ (hash >> 16);
+  eor(t0, t0, Operand(t0, LSR, 16));
+
+  // Compute the capacity mask.
+  ldr(t1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
+  mov(t1, Operand(t1, ASR, kSmiTagSize));  // convert smi to int
+  sub(t1, t1, Operand(1));
+
+  // Generate an unrolled loop that performs a few probes before giving up.
+  static const int kProbes = 4;
+  for (int i = 0; i < kProbes; i++) {
+    // Use t2 for index calculations and keep the hash intact in t0.
+    mov(t2, t0);
+    // Compute the masked index: (hash + i + i * i) & mask.
+    if (i > 0) {
+      add(t2, t2, Operand(NumberDictionary::GetProbeOffset(i)));
+    }
+    and_(t2, t2, Operand(t1));
+
+    // Scale the index by multiplying by the element size.
+    ASSERT(NumberDictionary::kEntrySize == 3);
+    add(t2, t2, Operand(t2, LSL, 1));  // t2 = t2 * 3
+
+    // Check if the key is identical to the name.
+    add(t2, elements, Operand(t2, LSL, kPointerSizeLog2));
+    ldr(ip, FieldMemOperand(t2, NumberDictionary::kElementsStartOffset));
+    cmp(key, Operand(ip));
+    if (i != kProbes - 1) {
+      b(eq, &done);
+    } else {
+      b(ne, miss);
+    }
+  }
+
+  bind(&done);
+  // Check that the value is a normal property.
+  // t2: elements + (index * kPointerSize)
+  const int kDetailsOffset =
+      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+  ldr(t1, FieldMemOperand(t2, kDetailsOffset));
+  tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
+  b(ne, miss);
+
+  // Get the value at the masked, scaled index and return.
+  const int kValueOffset =
+      NumberDictionary::kElementsStartOffset + kPointerSize;
+  ldr(result, FieldMemOperand(t2, kValueOffset));
+}
+
+
 void MacroAssembler::AllocateInNewSpace(int object_size,
                                         Register result,
                                         Register scratch1,
@@ -1677,6 +1756,16 @@
 }
 
 
+void MacroAssembler::CheckFastElements(Register map,
+                                       Register scratch,
+                                       Label* fail) {
+  STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0);
+  ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
+  cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue));
+  b(hi, fail);
+}
+
+
 void MacroAssembler::CheckMap(Register obj,
                               Register scratch,
                               Handle<Map> map,
@@ -1773,7 +1862,7 @@
 
 void MacroAssembler::CallStub(CodeStub* stub, Condition cond) {
   ASSERT(allow_stub_calls());  // Stub calls are not allowed in some stubs.
-  Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
+  Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond);
 }
 
 
@@ -1783,7 +1872,8 @@
   { MaybeObject* maybe_result = stub->TryGetCode();
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-  Call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, cond);
+  Handle<Code> code(Code::cast(result));
+  Call(code, RelocInfo::CODE_TARGET, kNoASTId, cond);
   return result;
 }
 
@@ -2459,6 +2549,9 @@
     LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
     cmp(elements, ip);
     b(eq, &ok);
+    LoadRoot(ip, Heap::kFixedDoubleArrayMapRootIndex);
+    cmp(elements, ip);
+    b(eq, &ok);
     LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
     cmp(elements, ip);
     b(eq, &ok);
@@ -2521,12 +2614,9 @@
 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.
-    ldr(dst, MemOperand(cp, Context::SlotOffset(Context::CLOSURE_INDEX)));
-    // Load the function context (which is the incoming, outer context).
-    ldr(dst, FieldMemOperand(dst, JSFunction::kContextOffset));
+    ldr(dst, MemOperand(cp, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     for (int i = 1; i < context_chain_length; i++) {
-      ldr(dst, MemOperand(dst, Context::SlotOffset(Context::CLOSURE_INDEX)));
-      ldr(dst, FieldMemOperand(dst, JSFunction::kContextOffset));
+      ldr(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     }
   } else {
     // Slot is in the current function context.  Move it into the
@@ -2534,17 +2624,6 @@
     // cannot be allowed to destroy the context in esi).
     mov(dst, cp);
   }
-
-  // We should not have found a 'with' context by walking the context chain
-  // (i.e., the static scope chain and runtime context chain do not agree).
-  // A variable occurring in such a scope should have slot type LOOKUP and
-  // not CONTEXT.
-  if (emit_debug_code()) {
-    ldr(ip, MemOperand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
-    cmp(dst, ip);
-    Check(eq, "Yo dawg, I heard you liked function contexts "
-              "so I put function contexts in all your contexts");
-  }
 }
 
 
@@ -2692,8 +2771,7 @@
   // Check that neither is a smi.
   STATIC_ASSERT(kSmiTag == 0);
   and_(scratch1, first, Operand(second));
-  tst(scratch1, Operand(kSmiTagMask));
-  b(eq, failure);
+  JumpIfSmi(scratch1, failure);
   JumpIfNonSmisNotBothSequentialAsciiStrings(first,
                                              second,
                                              scratch1,
@@ -3085,7 +3163,7 @@
   Label done;
   Label in_bounds;
 
-  vmov(temp_double_reg, 0.0);
+  Vmov(temp_double_reg, 0.0);
   VFPCompareAndSetFlags(input_reg, temp_double_reg);
   b(gt, &above_zero);
 
@@ -3095,7 +3173,7 @@
 
   // Double value is >= 255, return 255.
   bind(&above_zero);
-  vmov(temp_double_reg, 255.0);
+  Vmov(temp_double_reg, 255.0);
   VFPCompareAndSetFlags(input_reg, temp_double_reg);
   b(le, &in_bounds);
   mov(result_reg, Operand(255));
@@ -3103,7 +3181,7 @@
 
   // In 0-255 range, round and truncate.
   bind(&in_bounds);
-  vmov(temp_double_reg, 0.5);
+  Vmov(temp_double_reg, 0.5);
   vadd(temp_double_reg, input_reg, temp_double_reg);
   vcvt_u32_f64(s0, temp_double_reg);
   vmov(result_reg, s0);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 1e2c9f4..9c653ad 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -90,21 +90,21 @@
 
   // Jump, Call, and Ret pseudo instructions implementing inter-working.
   void Jump(Register target, Condition cond = al);
-  void Jump(byte* target, RelocInfo::Mode rmode, Condition cond = al);
+  void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al);
   void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
   static int CallSize(Register target, Condition cond = al);
   void Call(Register target, Condition cond = al);
-  static int CallSize(byte* target, RelocInfo::Mode rmode, Condition cond = al);
-  void Call(byte* target, RelocInfo::Mode rmode, Condition cond = al);
-  static int CallSize(Handle<Code> code,
+  static int CallSize(Address target,
                       RelocInfo::Mode rmode,
                       Condition cond = al);
+  void Call(Address target, RelocInfo::Mode rmode, Condition cond = al);
+  static int CallSize(Handle<Code> code,
+                      RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+                      unsigned ast_id = kNoASTId,
+                      Condition cond = al);
   void Call(Handle<Code> code,
-            RelocInfo::Mode rmode,
-            Condition cond = al);
-  void CallWithAstId(Handle<Code> code,
-            RelocInfo::Mode rmode,
-            unsigned ast_id,
+            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+            unsigned ast_id = kNoASTId,
             Condition cond = al);
   void Ret(Condition cond = al);
 
@@ -145,11 +145,9 @@
 
   // Register move. May do nothing if the registers are identical.
   void Move(Register dst, Handle<Object> value);
-  void Move(Register dst, Register src);
+  void Move(Register dst, Register src, Condition cond = al);
   void Move(DoubleRegister dst, DoubleRegister src);
 
-  // Jumps to the label at the index given by the Smi in "index".
-  void SmiJumpTable(Register index, Vector<Label*> targets);
   // Load an object from the root table.
   void LoadRoot(Register destination,
                 Heap::RootListIndex index,
@@ -194,6 +192,9 @@
                    Register address,
                    Register scratch);
 
+  // Push a handle.
+  void Push(Handle<Object> handle);
+
   // Push two registers.  Pushes leftmost register first (to highest address).
   void Push(Register src1, Register src2, Condition cond = al) {
     ASSERT(!src1.is(src2));
@@ -313,6 +314,10 @@
                               const Register fpscr_flags,
                               const Condition cond = al);
 
+  void Vmov(const DwVfpRegister dst,
+            const double imm,
+            const Condition cond = al);
+
 
   // ---------------------------------------------------------------------------
   // Activation frames
@@ -430,6 +435,16 @@
                               Register scratch,
                               Label* miss);
 
+
+  void LoadFromNumberDictionary(Label* miss,
+                                Register elements,
+                                Register key,
+                                Register result,
+                                Register t0,
+                                Register t1,
+                                Register t2);
+
+
   inline void MarkCode(NopMarkerTypes type) {
     nop(type);
   }
@@ -579,6 +594,12 @@
                            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 the map of an object is equal to a specified map (either
   // given directly or as an index into the root list) and branch to
   // label if not. Skip the smi check if not required (object is known
@@ -1027,12 +1048,6 @@
                            int num_double_arguments);
 
   void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
-  static int CallSize(intptr_t target,
-                      RelocInfo::Mode rmode,
-                      Condition cond = al);
-  void Call(intptr_t target,
-            RelocInfo::Mode rmode,
-            Condition cond = al);
 
   // Helper functions for generating invokes.
   void InvokePrologue(const ParameterCount& expected,
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index 1c59823..983a528 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -899,13 +899,12 @@
       constant_offset - offset_of_pc_register_read;
     ASSERT(pc_offset_of_constant < 0);
     if (is_valid_memory_offset(pc_offset_of_constant)) {
-      masm_->BlockConstPoolBefore(masm_->pc_offset() + Assembler::kInstrSize);
+      Assembler::BlockConstPoolScope block_const_pool(masm_);
       __ ldr(r0, MemOperand(pc, pc_offset_of_constant));
     } else {
       // Not a 12-bit offset, so it needs to be loaded from the constant
       // pool.
-      masm_->BlockConstPoolBefore(
-          masm_->pc_offset() + 2 * Assembler::kInstrSize);
+      Assembler::BlockConstPoolScope block_const_pool(masm_);
       __ mov(r0, Operand(pc_offset_of_constant + Assembler::kInstrSize));
       __ ldr(r0, MemOperand(pc, r0));
     }
@@ -1185,8 +1184,7 @@
 
 void RegExpMacroAssemblerARM::EmitBacktrackConstantPool() {
   __ CheckConstPool(false, false);
-  __ BlockConstPoolBefore(
-      masm_->pc_offset() + kBacktrackConstantPoolSize * Assembler::kInstrSize);
+  Assembler::BlockConstPoolScope block_const_pool(masm_);
   backtrack_constant_pool_offset_ = masm_->pc_offset();
   for (int i = 0; i < kBacktrackConstantPoolSize; i++) {
     __ emit(0);
diff --git a/src/arm/regexp-macro-assembler-arm.h b/src/arm/regexp-macro-assembler-arm.h
index d771e40..0e65386 100644
--- a/src/arm/regexp-macro-assembler-arm.h
+++ b/src/arm/regexp-macro-assembler-arm.h
@@ -28,6 +28,9 @@
 #ifndef V8_ARM_REGEXP_MACRO_ASSEMBLER_ARM_H_
 #define V8_ARM_REGEXP_MACRO_ASSEMBLER_ARM_H_
 
+#include "arm/assembler-arm.h"
+#include "arm/assembler-arm-inl.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index be8b7d6..c2665f8 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -121,7 +121,7 @@
 
   // Check that receiver is a JSObject.
   __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
-  __ cmp(scratch0, Operand(FIRST_JS_OBJECT_TYPE));
+  __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
   __ b(lt, miss_label);
 
   // Load properties array.
@@ -189,8 +189,7 @@
   ASSERT(!extra2.is(no_reg));
 
   // Check that the receiver isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, &miss);
+  __ JumpIfSmi(receiver, &miss);
 
   // Get the map of the receiver and compute the hash.
   __ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset));
@@ -282,8 +281,7 @@
                                            Register scratch,
                                            Label* miss_label) {
   // Check that the receiver isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, miss_label);
+  __ JumpIfSmi(receiver, miss_label);
 
   // Check that the object is a JS array.
   __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE);
@@ -305,8 +303,7 @@
                                 Label* smi,
                                 Label* non_string_object) {
   // Check that the receiver isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, smi);
+  __ JumpIfSmi(receiver, smi);
 
   // Check that the object is a string.
   __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
@@ -381,8 +378,7 @@
   Label exit;
 
   // Check that the receiver isn't a smi.
-  __ tst(receiver_reg, Operand(kSmiTagMask));
-  __ b(eq, miss_label);
+  __ JumpIfSmi(receiver_reg, miss_label);
 
   // Check that the map of the receiver hasn't changed.
   __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
@@ -431,8 +427,7 @@
     __ str(r0, FieldMemOperand(receiver_reg, offset));
 
     // Skip updating write barrier if storing a smi.
-    __ tst(r0, Operand(kSmiTagMask));
-    __ b(eq, &exit);
+    __ JumpIfSmi(r0, &exit);
 
     // Update the write barrier for the array address.
     // Pass the now unused name_reg as a scratch register.
@@ -445,8 +440,7 @@
     __ str(r0, FieldMemOperand(scratch, offset));
 
     // Skip updating write barrier if storing a smi.
-    __ tst(r0, Operand(kSmiTagMask));
-    __ b(eq, &exit);
+    __ JumpIfSmi(r0, &exit);
 
     // Update the write barrier for the array address.
     // Ok to clobber receiver_reg and name_reg, since we return.
@@ -1165,8 +1159,7 @@
                                      String* name,
                                      Label* miss) {
   // Check that the receiver isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check that the maps haven't changed.
   Register reg =
@@ -1187,8 +1180,7 @@
                                         String* name,
                                         Label* miss) {
   // Check that the receiver isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check that the maps haven't changed.
   Register reg =
@@ -1212,8 +1204,7 @@
                                                 String* name,
                                                 Label* miss) {
   // Check that the receiver isn't a smi.
-  __ tst(receiver, Operand(kSmiTagMask));
-  __ b(eq, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check that the maps haven't changed.
   Register reg =
@@ -1426,8 +1417,7 @@
   // object which can only happen for contextual calls. In this case,
   // the receiver cannot be a smi.
   if (object != holder) {
-    __ tst(r0, Operand(kSmiTagMask));
-    __ b(eq, miss);
+    __ JumpIfSmi(r0, miss);
   }
 
   // Check that the maps haven't changed.
@@ -1449,8 +1439,7 @@
     // the nice side effect that multiple closures based on the same
     // function can all use this call IC. Before we load through the
     // function, we have to verify that it still is a function.
-    __ tst(r1, Operand(kSmiTagMask));
-    __ b(eq, miss);
+    __ JumpIfSmi(r1, miss);
     __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
     __ b(ne, miss);
 
@@ -1495,8 +1484,7 @@
   // Get the receiver of the function from the stack into r0.
   __ ldr(r0, MemOperand(sp, argc * kPointerSize));
   // Check that the receiver isn't a smi.
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &miss);
+  __ JumpIfSmi(r0, &miss);
 
   // Do the right check and compute the holder register.
   Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss);
@@ -1967,8 +1955,7 @@
     __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
 
     STATIC_ASSERT(kSmiTag == 0);
-    __ tst(r1, Operand(kSmiTagMask));
-    __ b(eq, &miss);
+    __ JumpIfSmi(r1, &miss);
 
     CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
                     &miss);
@@ -1985,8 +1972,7 @@
   // Check the code is a smi.
   Label slow;
   STATIC_ASSERT(kSmiTag == 0);
-  __ tst(code, Operand(kSmiTagMask));
-  __ b(ne, &slow);
+  __ JumpIfNotSmi(code, &slow);
 
   // Convert the smi code to uint16.
   __ and_(code, code, Operand(Smi::FromInt(0xffff)));
@@ -2188,8 +2174,7 @@
     __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
 
     STATIC_ASSERT(kSmiTag == 0);
-    __ tst(r1, Operand(kSmiTagMask));
-    __ b(eq, &miss);
+    __ JumpIfSmi(r1, &miss);
 
     CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
                     &miss);
@@ -2292,8 +2277,7 @@
   __ ldr(r1, MemOperand(sp, argc * kPointerSize));
 
   // Check that the receiver isn't a smi.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, &miss_before_stack_reserved);
+  __ JumpIfSmi(r1, &miss_before_stack_reserved);
 
   __ IncrementCounter(counters->call_const(), 1, r0, r3);
   __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3);
@@ -2347,8 +2331,7 @@
 
   // Check that the receiver isn't a smi.
   if (check != NUMBER_CHECK) {
-    __ tst(r1, Operand(kSmiTagMask));
-    __ b(eq, &miss);
+    __ JumpIfSmi(r1, &miss);
   }
 
   // Make sure that it's okay not to patch the on stack receiver
@@ -2381,7 +2364,7 @@
       } else {
         // Check that the object is a two-byte string or a symbol.
         __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE);
-        __ b(hs, &miss);
+        __ b(ge, &miss);
         // Check that the maps starting from the prototype haven't changed.
         GenerateDirectLoadGlobalFunctionPrototype(
             masm(), Context::STRING_FUNCTION_INDEX, r0, &miss);
@@ -2398,8 +2381,7 @@
       } else {
         Label fast;
         // Check that the object is a smi or a heap number.
-        __ tst(r1, Operand(kSmiTagMask));
-        __ b(eq, &fast);
+        __ JumpIfSmi(r1, &fast);
         __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE);
         __ b(ne, &miss);
         __ bind(&fast);
@@ -2619,8 +2601,7 @@
   Label miss;
 
   // Check that the object isn't a smi.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, &miss);
+  __ JumpIfSmi(r1, &miss);
 
   // Check that the map of the object hasn't changed.
   __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
@@ -2667,8 +2648,7 @@
   Label miss;
 
   // Check that the object isn't a smi.
-  __ tst(r1, Operand(kSmiTagMask));
-  __ b(eq, &miss);
+  __ JumpIfSmi(r1, &miss);
 
   // Check that the map of the object hasn't changed.
   __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
@@ -2759,8 +2739,7 @@
   Label miss;
 
   // Check that receiver is not a smi.
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &miss);
+  __ JumpIfSmi(r0, &miss);
 
   // Check the maps of the full prototype chain.
   CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss);
@@ -2904,8 +2883,7 @@
   // object which can only happen for contextual calls. In this case,
   // the receiver cannot be a smi.
   if (object != holder) {
-    __ tst(r0, Operand(kSmiTagMask));
-    __ b(eq, &miss);
+    __ JumpIfSmi(r0, &miss);
   }
 
   // Check that the map of the global has not changed.
@@ -3115,14 +3093,15 @@
 }
 
 
-MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) {
+MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- lr    : return address
   //  -- r0    : key
   //  -- r1    : receiver
   // -----------------------------------
-  MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode();
   Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
+  MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(r1,
                  r2,
@@ -3206,8 +3185,7 @@
 }
 
 
-MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement(
-    Map* receiver_map) {
+MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- r0    : value
   //  -- r1    : key
@@ -3215,10 +3193,11 @@
   //  -- lr    : return address
   //  -- r3    : scratch
   // -----------------------------------
+  Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
   bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
   MaybeObject* maybe_stub =
-      KeyedStoreFastElementStub(is_js_array).TryGetCode();
-  Code* stub;
+      KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(r2,
                  r3,
@@ -3292,8 +3271,7 @@
   // r1: constructor function
   // r7: undefined
   __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
-  __ tst(r2, Operand(kSmiTagMask));
-  __ b(eq, &generic_stub_call);
+  __ JumpIfSmi(r2, &generic_stub_call);
   __ CompareObjectType(r2, r3, r4, MAP_TYPE);
   __ b(ne, &generic_stub_call);
 
@@ -3410,82 +3388,86 @@
 }
 
 
-MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
-    JSObject*receiver, ExternalArrayType array_type) {
-  // ----------- S t a t e -------------
-  //  -- lr    : return address
-  //  -- r0    : key
-  //  -- r1    : receiver
-  // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedLoadExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(r1,
-                 r2,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
-
-  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode();
-}
-
-
-MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
-    JSObject* receiver, ExternalArrayType array_type) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : name
-  //  -- r2    : receiver
-  //  -- lr    : return address
-  // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedStoreExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(r2,
-                 r3,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
-
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  return GetCode();
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm)
 
 
-static bool IsElementTypeSigned(ExternalArrayType array_type) {
-  switch (array_type) {
-    case kExternalByteArray:
-    case kExternalShortArray:
-    case kExternalIntArray:
+void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- lr     : return address
+  //  -- r0     : key
+  //  -- r1     : receiver
+  // -----------------------------------
+  Label slow, miss_force_generic;
+
+  Register key = r0;
+  Register receiver = r1;
+
+  __ JumpIfNotSmi(key, &miss_force_generic);
+  __ mov(r2, Operand(key, ASR, kSmiTagSize));
+  __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ LoadFromNumberDictionary(&slow, r4, key, r0, r2, r3, r5);
+  __ Ret();
+
+  __ bind(&slow);
+  __ IncrementCounter(
+      masm->isolate()->counters()->keyed_load_external_array_slow(),
+      1, r2, r3);
+
+  // ---------- S t a t e --------------
+  //  -- lr     : return address
+  //  -- r0     : key
+  //  -- r1     : receiver
+  // -----------------------------------
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+
+  // Miss case, call the runtime.
+  __ bind(&miss_force_generic);
+
+  // ---------- S t a t e --------------
+  //  -- lr     : return address
+  //  -- r0     : key
+  //  -- r1     : receiver
+  // -----------------------------------
+
+  Handle<Code> miss_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+}
+
+
+static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) {
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
       return true;
 
-    case kExternalUnsignedByteArray:
-    case kExternalUnsignedShortArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       return false;
 
-    default:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       return false;
   }
+  return false;
 }
 
 
 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
   //  -- r0     : key
@@ -3519,25 +3501,25 @@
   ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
 
   Register value = r2;
-  switch (array_type) {
-    case kExternalByteArray:
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
       __ ldrsb(value, MemOperand(r3, key, LSR, 1));
       break;
-    case kExternalPixelArray:
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       __ ldrb(value, MemOperand(r3, key, LSR, 1));
       break;
-    case kExternalShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
       __ ldrsh(value, MemOperand(r3, key, LSL, 0));
       break;
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ ldrh(value, MemOperand(r3, key, LSL, 0));
       break;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       __ ldr(value, MemOperand(r3, key, LSL, 1));
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       if (CpuFeatures::IsSupported(VFP3)) {
         CpuFeatures::Scope scope(VFP3);
         __ add(r2, r3, Operand(key, LSL, 1));
@@ -3546,7 +3528,7 @@
         __ ldr(value, MemOperand(r3, key, LSL, 1));
       }
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       if (CpuFeatures::IsSupported(VFP3)) {
         CpuFeatures::Scope scope(VFP3);
         __ add(r2, r3, Operand(key, LSL, 2));
@@ -3558,7 +3540,10 @@
         __ ldr(r3, MemOperand(r4, Register::kSizeInBytes));
       }
       break;
-    default:
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       break;
   }
@@ -3572,7 +3557,7 @@
   // d0: value (if VFP3 is supported)
   // r2/r3: value (if VFP3 is not supported)
 
-  if (array_type == kExternalIntArray) {
+  if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
     // For the Int and UnsignedInt array types, we need to see whether
     // the value can be represented in a Smi. If not, we need to convert
     // it to a HeapNumber.
@@ -3616,7 +3601,7 @@
       __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
       __ Ret();
     }
-  } else if (array_type == kExternalUnsignedIntArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
     // The test is different for unsigned int values. Since we need
     // the value to be in the range of a positive smi, we can't
     // handle either of the top two bits being set in the value.
@@ -3681,7 +3666,7 @@
       __ mov(r0, r4);
       __ Ret();
     }
-  } else if (array_type == kExternalFloatArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
     // For the floating-point array type, we need to always allocate a
     // HeapNumber.
     if (CpuFeatures::IsSupported(VFP3)) {
@@ -3751,7 +3736,7 @@
       __ mov(r0, r3);
       __ Ret();
     }
-  } else if (array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     if (CpuFeatures::IsSupported(VFP3)) {
       CpuFeatures::Scope scope(VFP3);
       // Allocate a HeapNumber for the result. Don't use r0 and r1 as
@@ -3808,7 +3793,7 @@
 
 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ---------- S t a t e --------------
   //  -- r0     : value
   //  -- r1     : key
@@ -3842,7 +3827,7 @@
   // runtime for all other kinds of values.
   // r3: external array.
   // r4: key (integer).
-  if (array_type == kExternalPixelArray) {
+  if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     // Double to pixel conversion is only implemented in the runtime for now.
     __ JumpIfNotSmi(value, &slow);
   } else {
@@ -3854,29 +3839,29 @@
   // r3: base pointer of external storage.
   // r4: key (integer).
   // r5: value (integer).
-  switch (array_type) {
-    case kExternalPixelArray:
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       // Clamp the value to [0..255].
       __ Usat(r5, 8, Operand(r5));
       __ strb(r5, MemOperand(r3, r4, LSL, 0));
       break;
-    case kExternalByteArray:
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       __ strb(r5, MemOperand(r3, r4, LSL, 0));
       break;
-    case kExternalShortArray:
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ strh(r5, MemOperand(r3, r4, LSL, 1));
       break;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       __ str(r5, MemOperand(r3, r4, LSL, 2));
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       // Perform int-to-float conversion and store to memory.
       StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9);
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       __ add(r3, r3, Operand(r4, LSL, 3));
       // r3: effective address of the double element
       FloatingPointHelper::Destination destination;
@@ -3897,7 +3882,10 @@
         __ str(r7, MemOperand(r3, Register::kSizeInBytes));
       }
       break;
-    default:
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       break;
   }
@@ -3905,7 +3893,7 @@
   // Entry registers are intact, r0 holds the value which is the return value.
   __ Ret();
 
-  if (array_type != kExternalPixelArray) {
+  if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     // r3: external array.
     // r4: index (integer).
     __ bind(&check_heap_number);
@@ -3923,7 +3911,7 @@
     if (CpuFeatures::IsSupported(VFP3)) {
       CpuFeatures::Scope scope(VFP3);
 
-      if (array_type == kExternalFloatArray) {
+      if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
         // vldr requires offset to be a multiple of 4 so we can not
         // include -kHeapObjectTag into it.
         __ sub(r5, r0, Operand(kHeapObjectTag));
@@ -3931,48 +3919,38 @@
         __ add(r5, r3, Operand(r4, LSL, 2));
         __ vcvt_f32_f64(s0, d0);
         __ vstr(s0, r5, 0);
-      } else if (array_type == kExternalDoubleArray) {
+      } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
         __ sub(r5, r0, Operand(kHeapObjectTag));
         __ vldr(d0, r5, HeapNumber::kValueOffset);
         __ add(r5, r3, Operand(r4, LSL, 3));
         __ vstr(d0, r5, 0);
       } else {
-        // Need to perform float-to-int conversion.
-        // Test for NaN or infinity (both give zero).
-        __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset));
-
         // Hoisted load.  vldr requires offset to be a multiple of 4 so we can
         // not include -kHeapObjectTag into it.
         __ sub(r5, value, Operand(kHeapObjectTag));
         __ vldr(d0, r5, HeapNumber::kValueOffset);
+        __ EmitECMATruncate(r5, d0, s2, r6, r7, r9);
 
-        __ Sbfx(r6, r6, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
-        // NaNs and Infinities have all-one exponents so they sign extend to -1.
-        __ cmp(r6, Operand(-1));
-        __ mov(r5, Operand(0), LeaveCC, eq);
-
-        // Not infinity or NaN simply convert to int.
-        if (IsElementTypeSigned(array_type)) {
-          __ vcvt_s32_f64(s0, d0, kDefaultRoundToZero, ne);
-        } else {
-          __ vcvt_u32_f64(s0, d0, kDefaultRoundToZero, ne);
-        }
-        __ vmov(r5, s0, ne);
-
-        switch (array_type) {
-          case kExternalByteArray:
-          case kExternalUnsignedByteArray:
+        switch (elements_kind) {
+          case JSObject::EXTERNAL_BYTE_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
             __ strb(r5, MemOperand(r3, r4, LSL, 0));
             break;
-          case kExternalShortArray:
-          case kExternalUnsignedShortArray:
+          case JSObject::EXTERNAL_SHORT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
             __ strh(r5, MemOperand(r3, r4, LSL, 1));
             break;
-          case kExternalIntArray:
-          case kExternalUnsignedIntArray:
+          case JSObject::EXTERNAL_INT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
             __ str(r5, MemOperand(r3, r4, LSL, 2));
             break;
-          default:
+          case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+          case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+          case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+          case JSObject::FAST_ELEMENTS:
+          case JSObject::FAST_DOUBLE_ELEMENTS:
+          case JSObject::DICTIONARY_ELEMENTS:
+          case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
             UNREACHABLE();
             break;
         }
@@ -3986,7 +3964,7 @@
       __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
       __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
 
-      if (array_type == kExternalFloatArray) {
+      if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
         Label done, nan_or_infinity_or_zero;
         static const int kMantissaInHiWordShift =
             kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
@@ -4038,14 +4016,14 @@
         __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
         __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
         __ b(&done);
-      } else if (array_type == kExternalDoubleArray) {
+      } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
         __ add(r7, r3, Operand(r4, LSL, 3));
         // r7: effective address of destination element.
         __ str(r6, MemOperand(r7, 0));
         __ str(r5, MemOperand(r7, Register::kSizeInBytes));
         __ Ret();
       } else {
-        bool is_signed_type = IsElementTypeSigned(array_type);
+        bool is_signed_type = IsElementTypeSigned(elements_kind);
         int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
         int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
 
@@ -4092,20 +4070,26 @@
         __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne);
 
         __ bind(&done);
-        switch (array_type) {
-          case kExternalByteArray:
-          case kExternalUnsignedByteArray:
+        switch (elements_kind) {
+          case JSObject::EXTERNAL_BYTE_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
             __ strb(r5, MemOperand(r3, r4, LSL, 0));
             break;
-          case kExternalShortArray:
-          case kExternalUnsignedShortArray:
+          case JSObject::EXTERNAL_SHORT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
             __ strh(r5, MemOperand(r3, r4, LSL, 1));
             break;
-          case kExternalIntArray:
-          case kExternalUnsignedIntArray:
+          case JSObject::EXTERNAL_INT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
             __ str(r5, MemOperand(r3, r4, LSL, 2));
             break;
-          default:
+          case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+          case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+          case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+          case JSObject::FAST_ELEMENTS:
+          case JSObject::FAST_DOUBLE_ELEMENTS:
+          case JSObject::DICTIONARY_ELEMENTS:
+          case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
             UNREACHABLE();
             break;
         }
@@ -4184,6 +4168,77 @@
 }
 
 
+void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
+    MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- lr    : return address
+  //  -- r0    : key
+  //  -- r1    : receiver
+  // -----------------------------------
+  Label miss_force_generic, slow_allocate_heapnumber;
+
+  Register key_reg = r0;
+  Register receiver_reg = r1;
+  Register elements_reg = r2;
+  Register heap_number_reg = r2;
+  Register indexed_double_offset = r3;
+  Register scratch = r4;
+  Register scratch2 = r5;
+  Register scratch3 = r6;
+  Register heap_number_map = r7;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+  // Get the elements array.
+  __ ldr(elements_reg,
+         FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
+
+  // Check that the key is within bounds.
+  __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
+  __ cmp(key_reg, Operand(scratch));
+  __ b(hs, &miss_force_generic);
+
+  // Load the upper word of the double in the fixed array and test for NaN.
+  __ add(indexed_double_offset, elements_reg,
+         Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
+  uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32);
+  __ ldr(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset));
+  __ cmp(scratch, Operand(kHoleNanUpper32));
+  __ b(&miss_force_generic, eq);
+
+  // Non-NaN. Allocate a new heap number and copy the double value into it.
+  __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
+  __ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
+                        heap_number_map, &slow_allocate_heapnumber);
+
+  // Don't need to reload the upper 32 bits of the double, it's already in
+  // scratch.
+  __ str(scratch, FieldMemOperand(heap_number_reg,
+                                  HeapNumber::kExponentOffset));
+  __ ldr(scratch, FieldMemOperand(indexed_double_offset,
+                                  FixedArray::kHeaderSize));
+  __ str(scratch, FieldMemOperand(heap_number_reg,
+                                  HeapNumber::kMantissaOffset));
+
+  __ mov(r0, heap_number_reg);
+  __ Ret();
+
+  __ bind(&slow_allocate_heapnumber);
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+
+  __ bind(&miss_force_generic);
+  Handle<Code> miss_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+}
+
+
 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
                                                       bool is_js_array) {
   // ----------- S t a t e -------------
@@ -4206,7 +4261,7 @@
   // have been verified by the caller to not be a smi.
 
   // Check that the key is a smi.
-  __ JumpIfNotSmi(r0, &miss_force_generic);
+  __ JumpIfNotSmi(key_reg, &miss_force_generic);
 
   // Get the elements array and make sure it is a fast element array, not 'cow'.
   __ ldr(elements_reg,
@@ -4247,6 +4302,125 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
+    MacroAssembler* masm,
+    bool is_js_array) {
+  // ----------- S t a t e -------------
+  //  -- r0    : value
+  //  -- r1    : key
+  //  -- r2    : receiver
+  //  -- lr    : return address
+  //  -- r3    : scratch
+  //  -- r4    : scratch
+  //  -- r5    : scratch
+  // -----------------------------------
+  Label miss_force_generic, smi_value, is_nan, maybe_nan, have_double_value;
+
+  Register value_reg = r0;
+  Register key_reg = r1;
+  Register receiver_reg = r2;
+  Register scratch = r3;
+  Register elements_reg = r4;
+  Register mantissa_reg = r5;
+  Register exponent_reg = r6;
+  Register scratch4 = r7;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+  __ ldr(elements_reg,
+         FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
+
+  // Check that the key is within bounds.
+  if (is_js_array) {
+    __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+  } else {
+    __ ldr(scratch,
+           FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
+  }
+  // Compare smis, unsigned compare catches both negative and out-of-bound
+  // indexes.
+  __ cmp(key_reg, scratch);
+  __ b(hs, &miss_force_generic);
+
+  // Handle smi values specially.
+  __ JumpIfSmi(value_reg, &smi_value);
+
+  // Ensure that the object is a heap number
+  __ CheckMap(value_reg,
+              scratch,
+              masm->isolate()->factory()->heap_number_map(),
+              &miss_force_generic,
+              DONT_DO_SMI_CHECK);
+
+  // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000
+  // in the exponent.
+  __ mov(scratch, Operand(kNaNOrInfinityLowerBoundUpper32));
+  __ ldr(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset));
+  __ cmp(exponent_reg, scratch);
+  __ b(ge, &maybe_nan);
+
+  __ ldr(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
+
+  __ bind(&have_double_value);
+  __ add(scratch, elements_reg,
+         Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
+  __ str(mantissa_reg, FieldMemOperand(scratch, FixedDoubleArray::kHeaderSize));
+  uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
+  __ str(exponent_reg, FieldMemOperand(scratch, offset));
+  __ Ret();
+
+  __ bind(&maybe_nan);
+  // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
+  // it's an Infinity, and the non-NaN code path applies.
+  __ b(gt, &is_nan);
+  __ ldr(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
+  __ cmp(mantissa_reg, Operand(0));
+  __ b(eq, &have_double_value);
+  __ bind(&is_nan);
+  // Load canonical NaN for storing into the double array.
+  uint64_t nan_int64 = BitCast<uint64_t>(
+      FixedDoubleArray::canonical_not_the_hole_nan_as_double());
+  __ mov(mantissa_reg, Operand(static_cast<uint32_t>(nan_int64)));
+  __ mov(exponent_reg, Operand(static_cast<uint32_t>(nan_int64 >> 32)));
+  __ jmp(&have_double_value);
+
+  __ bind(&smi_value);
+  __ add(scratch, elements_reg,
+         Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+  __ add(scratch, scratch,
+         Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
+  // scratch is now effective address of the double element
+
+  FloatingPointHelper::Destination destination;
+  if (CpuFeatures::IsSupported(VFP3)) {
+    destination = FloatingPointHelper::kVFPRegisters;
+  } else {
+    destination = FloatingPointHelper::kCoreRegisters;
+  }
+  __ SmiUntag(value_reg, value_reg);
+  FloatingPointHelper::ConvertIntToDouble(
+      masm, value_reg, destination,
+      d0, mantissa_reg, exponent_reg,  // These are: double_dst, dst1, dst2.
+      scratch4, s2);  // These are: scratch2, single_scratch.
+  if (destination == FloatingPointHelper::kVFPRegisters) {
+    CpuFeatures::Scope scope(VFP3);
+    __ vstr(d0, scratch, 0);
+  } else {
+    __ str(mantissa_reg, MemOperand(scratch, 0));
+    __ str(exponent_reg, MemOperand(scratch, Register::kSizeInBytes));
+  }
+  __ Ret();
+
+  // Handle store cache miss, replacing the ic with the generic stub.
+  __ bind(&miss_force_generic);
+  Handle<Code> ic =
+      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
+  __ Jump(ic, RelocInfo::CODE_TARGET);
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/array.js b/src/array.js
index df080a7..e6c13d9 100644
--- a/src/array.js
+++ b/src/array.js
@@ -631,7 +631,9 @@
 
   if (end_i < start_i) return result;
 
-  if (IS_ARRAY(this)) {
+  if (IS_ARRAY(this) &&
+      (end_i > 1000) &&
+      (%EstimateNumberOfElements(this) < end_i)) {
     SmartSlice(this, start_i, end_i - start_i, len, result);
   } else {
     SimpleSlice(this, start_i, end_i - start_i, len, result);
@@ -740,14 +742,15 @@
       else return x < y ? -1 : 1;
     };
   }
-  var global_receiver = %GetGlobalReceiver();
+  var receiver =
+      %_IsNativeOrStrictMode(comparefn) ? void 0 : %GetGlobalReceiver();
 
   function InsertionSort(a, from, to) {
     for (var i = from + 1; i < to; i++) {
       var element = a[i];
       for (var j = i - 1; j >= from; j--) {
         var tmp = a[j];
-        var order = %_CallFunction(global_receiver, tmp, element, comparefn);
+        var order = %_CallFunction(receiver, tmp, element, comparefn);
         if (order > 0) {
           a[j + 1] = tmp;
         } else {
@@ -769,14 +772,14 @@
     var v1 = a[to - 1];
     var middle_index = from + ((to - from) >> 1);
     var v2 = a[middle_index];
-    var c01 = %_CallFunction(global_receiver, v0, v1, comparefn);
+    var c01 = %_CallFunction(receiver, v0, v1, comparefn);
     if (c01 > 0) {
       // v1 < v0, so swap them.
       var tmp = v0;
       v0 = v1;
       v1 = tmp;
     } // v0 <= v1.
-    var c02 = %_CallFunction(global_receiver, v0, v2, comparefn);
+    var c02 = %_CallFunction(receiver, v0, v2, comparefn);
     if (c02 >= 0) {
       // v2 <= v0 <= v1.
       var tmp = v0;
@@ -785,7 +788,7 @@
       v1 = tmp;
     } else {
       // v0 <= v1 && v0 < v2
-      var c12 = %_CallFunction(global_receiver, v1, v2, comparefn);
+      var c12 = %_CallFunction(receiver, v1, v2, comparefn);
       if (c12 > 0) {
         // v0 <= v2 < v1
         var tmp = v1;
@@ -806,7 +809,7 @@
     // From i to high_start are elements that haven't been compared yet.
     partition: for (var i = low_end + 1; i < high_start; i++) {
       var element = a[i];
-      var order = %_CallFunction(global_receiver, element, pivot, comparefn);
+      var order = %_CallFunction(receiver, element, pivot, comparefn);
       if (order < 0) {
         %_SwapElements(a, i, low_end);
         low_end++;
@@ -815,7 +818,7 @@
           high_start--;
           if (high_start == i) break partition;
           var top_elem = a[high_start];
-          order = %_CallFunction(global_receiver, top_elem, pivot, comparefn);
+          order = %_CallFunction(receiver, top_elem, pivot, comparefn);
         } while (order > 0);
         %_SwapElements(a, i, high_start);
         if (order < 0) {
@@ -996,7 +999,7 @@
   }
   // Pull out the length so that modifications to the length in the
   // loop will not affect the looping.
-  var length = this.length;
+  var length = ToUint32(this.length);
   var result = [];
   var result_length = 0;
   for (var i = 0; i < length; i++) {
@@ -1233,7 +1236,7 @@
   }
   // Pull out the length so that modifications to the length in the
   // loop will not affect the looping.
-  var length = this.length;
+  var length = ToUint32(this.length);
   var i = 0;
 
   find_initial: if (%_ArgumentsLength() < 2) {
@@ -1250,7 +1253,7 @@
   for (; i < length; i++) {
     var element = this[i];
     if (!IS_UNDEFINED(element) || i in this) {
-      current = callback.call(null, current, element, i, this);
+      current = callback.call(void 0, current, element, i, this);
     }
   }
   return current;
@@ -1265,7 +1268,7 @@
   if (!IS_FUNCTION(callback)) {
     throw MakeTypeError('called_non_callable', [callback]);
   }
-  var i = this.length - 1;
+  var i = ToUint32(this.length) - 1;
 
   find_initial: if (%_ArgumentsLength() < 2) {
     for (; i >= 0; i--) {
@@ -1281,7 +1284,7 @@
   for (; i >= 0; i--) {
     var element = this[i];
     if (!IS_UNDEFINED(element) || i in this) {
-      current = callback.call(null, current, element, i, this);
+      current = callback.call(void 0, current, element, i, this);
     }
   }
   return current;
diff --git a/src/assembler.cc b/src/assembler.cc
index 3c7fc1c..fbd8089 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 1994-2006 Sun Microsystems Inc.
+// Copyright (c) 2011 Sun Microsystems Inc.
 // All Rights Reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,8 @@
 const double DoubleConstant::minus_zero = -0.0;
 const double DoubleConstant::uint8_max_value = 255;
 const double DoubleConstant::zero = 0.0;
-const double DoubleConstant::nan = OS::nan_value();
+const double DoubleConstant::canonical_non_hole_nan = OS::nan_value();
+const double DoubleConstant::the_hole_nan = BitCast<double>(kHoleNanInt64);
 const double DoubleConstant::negative_infinity = -V8_INFINITY;
 const char* RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
 
@@ -921,9 +922,15 @@
 }
 
 
-ExternalReference ExternalReference::address_of_nan() {
+ExternalReference ExternalReference::address_of_canonical_non_hole_nan() {
   return ExternalReference(reinterpret_cast<void*>(
-      const_cast<double*>(&DoubleConstant::nan)));
+      const_cast<double*>(&DoubleConstant::canonical_non_hole_nan)));
+}
+
+
+ExternalReference ExternalReference::address_of_the_hole_nan() {
+  return ExternalReference(reinterpret_cast<void*>(
+      const_cast<double*>(&DoubleConstant::the_hole_nan)));
 }
 
 
diff --git a/src/assembler.h b/src/assembler.h
index 29f1ea9..2d14f06 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -70,7 +70,8 @@
   static const double zero;
   static const double uint8_max_value;
   static const double negative_infinity;
-  static const double nan;
+  static const double canonical_non_hole_nan;
+  static const double the_hole_nan;
 };
 
 
@@ -90,14 +91,18 @@
     Unuse();
     UnuseNear();
   }
-  INLINE(~Label())                { ASSERT(!is_linked()); }
 
-  INLINE(void Unuse())            { pos_ = 0; }
-  INLINE(void UnuseNear())        { near_link_pos_ = 0; }
+  INLINE(~Label()) {
+    ASSERT(!is_linked());
+    ASSERT(!is_near_linked());
+  }
 
-  INLINE(bool is_bound() const)  { return pos_ <  0; }
-  INLINE(bool is_unused() const)  { return pos_ == 0 && near_link_pos_ == 0; }
-  INLINE(bool is_linked() const)  { return pos_ >  0; }
+  INLINE(void Unuse()) { pos_ = 0; }
+  INLINE(void UnuseNear()) { near_link_pos_ = 0; }
+
+  INLINE(bool is_bound() const) { return pos_ <  0; }
+  INLINE(bool is_unused() const) { return pos_ == 0 && near_link_pos_ == 0; }
+  INLINE(bool is_linked() const) { return pos_ >  0; }
   INLINE(bool is_near_linked() const) { return near_link_pos_ > 0; }
 
   // Returns the position of bound or linked labels. Cannot be used
@@ -625,7 +630,8 @@
   static ExternalReference address_of_zero();
   static ExternalReference address_of_uint8_max_value();
   static ExternalReference address_of_negative_infinity();
-  static ExternalReference address_of_nan();
+  static ExternalReference address_of_canonical_non_hole_nan();
+  static ExternalReference address_of_the_hole_nan();
 
   static ExternalReference math_sin_double_function(Isolate* isolate);
   static ExternalReference math_cos_double_function(Isolate* isolate);
diff --git a/src/ast-inl.h b/src/ast-inl.h
index c2bd613..c750e6b 100644
--- a/src/ast-inl.h
+++ b/src/ast-inl.h
@@ -37,68 +37,76 @@
 namespace internal {
 
 
-SwitchStatement::SwitchStatement(ZoneStringList* labels)
-    : BreakableStatement(labels, TARGET_FOR_ANONYMOUS),
+SwitchStatement::SwitchStatement(Isolate* isolate,
+                                 ZoneStringList* labels)
+    : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
       tag_(NULL), cases_(NULL) {
 }
 
 
-Block::Block(ZoneStringList* labels, int capacity, bool is_initializer_block)
-    : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY),
+Block::Block(Isolate* isolate,
+             ZoneStringList* labels,
+             int capacity,
+             bool is_initializer_block)
+    : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
       statements_(capacity),
       is_initializer_block_(is_initializer_block) {
 }
 
 
-BreakableStatement::BreakableStatement(ZoneStringList* labels, Type type)
+BreakableStatement::BreakableStatement(Isolate* isolate,
+                                       ZoneStringList* labels,
+                                       Type type)
     : labels_(labels),
       type_(type),
-      entry_id_(GetNextId()),
-      exit_id_(GetNextId()) {
+      entry_id_(GetNextId(isolate)),
+      exit_id_(GetNextId(isolate)) {
   ASSERT(labels == NULL || labels->length() > 0);
 }
 
 
-IterationStatement::IterationStatement(ZoneStringList* labels)
-    : BreakableStatement(labels, TARGET_FOR_ANONYMOUS),
+IterationStatement::IterationStatement(Isolate* isolate, ZoneStringList* labels)
+    : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
       body_(NULL),
       continue_target_(),
-      osr_entry_id_(GetNextId()) {
+      osr_entry_id_(GetNextId(isolate)) {
 }
 
 
-DoWhileStatement::DoWhileStatement(ZoneStringList* labels)
-    : IterationStatement(labels),
+DoWhileStatement::DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
+    : IterationStatement(isolate, labels),
       cond_(NULL),
       condition_position_(-1),
-      continue_id_(GetNextId()),
-      back_edge_id_(GetNextId()) {
+      continue_id_(GetNextId(isolate)),
+      back_edge_id_(GetNextId(isolate)) {
 }
 
 
-WhileStatement::WhileStatement(ZoneStringList* labels)
-    : IterationStatement(labels),
+WhileStatement::WhileStatement(Isolate* isolate, ZoneStringList* labels)
+    : IterationStatement(isolate, labels),
       cond_(NULL),
       may_have_function_literal_(true),
-      body_id_(GetNextId()) {
+      body_id_(GetNextId(isolate)) {
 }
 
 
-ForStatement::ForStatement(ZoneStringList* labels)
-    : IterationStatement(labels),
+ForStatement::ForStatement(Isolate* isolate, ZoneStringList* labels)
+    : IterationStatement(isolate, labels),
       init_(NULL),
       cond_(NULL),
       next_(NULL),
       may_have_function_literal_(true),
       loop_variable_(NULL),
-      continue_id_(GetNextId()),
-      body_id_(GetNextId()) {
+      continue_id_(GetNextId(isolate)),
+      body_id_(GetNextId(isolate)) {
 }
 
 
-ForInStatement::ForInStatement(ZoneStringList* labels)
-    : IterationStatement(labels), each_(NULL), enumerable_(NULL),
-      assignment_id_(GetNextId()) {
+ForInStatement::ForInStatement(Isolate* isolate, ZoneStringList* labels)
+    : IterationStatement(isolate, labels),
+      each_(NULL),
+      enumerable_(NULL),
+      assignment_id_(GetNextId(isolate)) {
 }
 
 
diff --git a/src/ast.cc b/src/ast.cc
index b4abf54..2df62ee 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -37,11 +37,11 @@
 namespace internal {
 
 AstSentinels::AstSentinels()
-    : this_proxy_(true),
-      identifier_proxy_(false),
-      valid_left_hand_side_sentinel_(),
-      this_property_(&this_proxy_, NULL, 0),
-      call_sentinel_(NULL, NULL, 0) {
+    : this_proxy_(Isolate::Current(), true),
+      identifier_proxy_(Isolate::Current(), false),
+      valid_left_hand_side_sentinel_(Isolate::Current()),
+      this_property_(Isolate::Current(), &this_proxy_, NULL, 0),
+      call_sentinel_(Isolate::Current(), NULL, NULL, 0) {
 }
 
 
@@ -72,8 +72,9 @@
 }
 
 
-VariableProxy::VariableProxy(Variable* var)
-    : name_(var->name()),
+VariableProxy::VariableProxy(Isolate* isolate, Variable* var)
+    : Expression(isolate),
+      name_(var->name()),
       var_(NULL),  // Will be set by the call to BindTo.
       is_this_(var->is_this()),
       inside_with_(false),
@@ -83,26 +84,29 @@
 }
 
 
-VariableProxy::VariableProxy(Handle<String> name,
+VariableProxy::VariableProxy(Isolate* isolate,
+                             Handle<String> name,
                              bool is_this,
                              bool inside_with,
                              int position)
-  : name_(name),
-    var_(NULL),
-    is_this_(is_this),
-    inside_with_(inside_with),
-    is_trivial_(false),
-    position_(position) {
+    : Expression(isolate),
+      name_(name),
+      var_(NULL),
+      is_this_(is_this),
+      inside_with_(inside_with),
+      is_trivial_(false),
+      position_(position) {
   // Names must be canonicalized for fast equality checks.
   ASSERT(name->IsSymbol());
 }
 
 
-VariableProxy::VariableProxy(bool is_this)
-  : var_(NULL),
-    is_this_(is_this),
-    inside_with_(false),
-    is_trivial_(false) {
+VariableProxy::VariableProxy(Isolate* isolate, bool is_this)
+    : Expression(isolate),
+      var_(NULL),
+      is_this_(is_this),
+      inside_with_(false),
+      is_trivial_(false) {
 }
 
 
@@ -120,17 +124,19 @@
 }
 
 
-Assignment::Assignment(Token::Value op,
+Assignment::Assignment(Isolate* isolate,
+                       Token::Value op,
                        Expression* target,
                        Expression* value,
                        int pos)
-    : op_(op),
+    : Expression(isolate),
+      op_(op),
       target_(target),
       value_(value),
       pos_(pos),
       binary_operation_(NULL),
       compound_load_id_(kNoNumber),
-      assignment_id_(GetNextId()),
+      assignment_id_(GetNextId(isolate)),
       block_start_(false),
       block_end_(false),
       is_monomorphic_(false),
@@ -138,8 +144,12 @@
   ASSERT(Token::IsAssignmentOp(op));
   if (is_compound()) {
     binary_operation_ =
-        new BinaryOperation(binary_op(), target, value, pos + 1);
-    compound_load_id_ = GetNextId();
+        new(isolate->zone()) BinaryOperation(isolate,
+                                             binary_op(),
+                                             target,
+                                             value,
+                                             pos + 1);
+    compound_load_id_ = GetNextId(isolate);
   }
 }
 
@@ -186,8 +196,9 @@
 
 
 ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) {
+  Isolate* isolate = Isolate::Current();
   emit_store_ = true;
-  key_ = new Literal(value->name());
+  key_ = new(isolate->zone()) Literal(isolate, value->name());
   value_ = value;
   kind_ = is_getter ? GETTER : SETTER;
 }
@@ -293,11 +304,11 @@
 
 void TargetCollector::AddTarget(Label* target) {
   // Add the label to the collector, but discard duplicates.
-  int length = targets_->length();
+  int length = targets_.length();
   for (int i = 0; i < length; i++) {
-    if (targets_->at(i) == target) return;
+    if (targets_[i] == target) return;
   }
-  targets_->Add(target);
+  targets_.Add(target);
 }
 
 
@@ -337,12 +348,64 @@
 }
 
 
+bool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
+                                              Handle<String>* check) {
+  if (op_ != Token::EQ && op_ != Token::EQ_STRICT) return false;
+
+  UnaryOperation* left_unary = left_->AsUnaryOperation();
+  UnaryOperation* right_unary = right_->AsUnaryOperation();
+  Literal* left_literal = left_->AsLiteral();
+  Literal* right_literal = right_->AsLiteral();
+
+  // Check for the pattern: typeof <expression> == <string literal>.
+  if (left_unary != NULL && left_unary->op() == Token::TYPEOF &&
+      right_literal != NULL && right_literal->handle()->IsString()) {
+    *expr = left_unary->expression();
+    *check = Handle<String>::cast(right_literal->handle());
+    return true;
+  }
+
+  // Check for the pattern: <string literal> == typeof <expression>.
+  if (right_unary != NULL && right_unary->op() == Token::TYPEOF &&
+      left_literal != NULL && left_literal->handle()->IsString()) {
+    *expr = right_unary->expression();
+    *check = Handle<String>::cast(left_literal->handle());
+    return true;
+  }
+
+  return false;
+}
+
+
+bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) {
+  if (op_ != Token::EQ_STRICT) return false;
+
+  UnaryOperation* left_unary = left_->AsUnaryOperation();
+  UnaryOperation* right_unary = right_->AsUnaryOperation();
+
+  // Check for the pattern: <expression> === void <literal>.
+  if (right_unary != NULL && right_unary->op() == Token::VOID &&
+      right_unary->expression()->AsLiteral() != NULL) {
+    *expr = left_;
+    return true;
+  }
+
+  // Check for the pattern: void <literal> === <expression>.
+  if (left_unary != NULL && left_unary->op() == Token::VOID &&
+      left_unary->expression()->AsLiteral() != NULL) {
+    *expr = right_;
+    return true;
+  }
+
+  return false;
+}
+
+
 // ----------------------------------------------------------------------------
 // Inlining support
 
 bool Declaration::IsInlineable() const {
-  UNREACHABLE();
-  return false;
+  return proxy()->var()->IsStackAllocated() && fun() == NULL;
 }
 
 
@@ -363,12 +426,12 @@
 }
 
 
-bool WithEnterStatement::IsInlineable() const {
+bool EnterWithContextStatement::IsInlineable() const {
   return false;
 }
 
 
-bool WithExitStatement::IsInlineable() const {
+bool ExitContextStatement::IsInlineable() const {
   return false;
 }
 
@@ -393,11 +456,6 @@
 }
 
 
-bool CatchExtensionObject::IsInlineable() const {
-  return false;
-}
-
-
 bool DebuggerStatement::IsInlineable() const {
   return false;
 }
@@ -593,7 +651,7 @@
 
 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
   // Record type feedback from the oracle in the AST.
-  is_monomorphic_ = oracle->LoadIsMonomorphic(this);
+  is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
   if (key()->IsPropertyName()) {
     if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
       is_array_length_ = true;
@@ -613,9 +671,9 @@
     is_string_access_ = true;
   } else if (is_monomorphic_) {
     monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this);
-    if (monomorphic_receiver_type_->has_external_array_elements()) {
-      set_external_array_type(oracle->GetKeyedLoadExternalArrayType(this));
-    }
+  } else if (oracle->LoadIsMegamorphicWithTypeInfo(this)) {
+    receiver_types_ = new ZoneMapList(kMaxKeyedPolymorphism);
+    oracle->CollectKeyedReceiverTypes(this->id(), receiver_types_);
   }
 }
 
@@ -623,7 +681,7 @@
 void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
   Property* prop = target()->AsProperty();
   ASSERT(prop != NULL);
-  is_monomorphic_ = oracle->StoreIsMonomorphic(this);
+  is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
   if (prop->key()->IsPropertyName()) {
     Literal* lit_key = prop->key()->AsLiteral();
     ASSERT(lit_key != NULL && lit_key->handle()->IsString());
@@ -631,23 +689,23 @@
     ZoneMapList* types = oracle->StoreReceiverTypes(this, name);
     receiver_types_ = types;
   } else if (is_monomorphic_) {
-    // Record receiver type for monomorphic keyed loads.
+    // Record receiver type for monomorphic keyed stores.
     monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
-    if (monomorphic_receiver_type_->has_external_array_elements()) {
-      set_external_array_type(oracle->GetKeyedStoreExternalArrayType(this));
-    }
+  } else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
+    receiver_types_ = new ZoneMapList(kMaxKeyedPolymorphism);
+    oracle->CollectKeyedReceiverTypes(this->id(), receiver_types_);
   }
 }
 
 
 void CountOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
-  is_monomorphic_ = oracle->StoreIsMonomorphic(this);
+  is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
   if (is_monomorphic_) {
-    // Record receiver type for monomorphic keyed loads.
+    // Record receiver type for monomorphic keyed stores.
     monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
-    if (monomorphic_receiver_type_->has_external_array_elements()) {
-      set_external_array_type(oracle->GetKeyedStoreExternalArrayType(this));
-    }
+  } else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
+    receiver_types_ = new ZoneMapList(kMaxKeyedPolymorphism);
+    oracle->CollectKeyedReceiverTypes(this->id(), receiver_types_);
   }
 }
 
@@ -1143,15 +1201,16 @@
 }
 
 
-CaseClause::CaseClause(Expression* label,
+CaseClause::CaseClause(Isolate* isolate,
+                       Expression* label,
                        ZoneList<Statement*>* statements,
                        int pos)
     : label_(label),
       statements_(statements),
       position_(pos),
       compare_type_(NONE),
-      compare_id_(AstNode::GetNextId()),
-      entry_id_(AstNode::GetNextId()) {
+      compare_id_(AstNode::GetNextId(isolate)),
+      entry_id_(AstNode::GetNextId(isolate)) {
 }
 
 } }  // namespace v8::internal
diff --git a/src/ast.h b/src/ast.h
index 0ac1644..b4705f6 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -60,8 +60,8 @@
   V(ContinueStatement)                          \
   V(BreakStatement)                             \
   V(ReturnStatement)                            \
-  V(WithEnterStatement)                         \
-  V(WithExitStatement)                          \
+  V(EnterWithContextStatement)                  \
+  V(ExitContextStatement)                       \
   V(SwitchStatement)                            \
   V(DoWhileStatement)                           \
   V(WhileStatement)                             \
@@ -80,7 +80,6 @@
   V(RegExpLiteral)                              \
   V(ObjectLiteral)                              \
   V(ArrayLiteral)                               \
-  V(CatchExtensionObject)                       \
   V(Assignment)                                 \
   V(Throw)                                      \
   V(Property)                                   \
@@ -135,11 +134,15 @@
   static const int kNoNumber = -1;
   static const int kFunctionEntryId = 2;  // Using 0 could disguise errors.
 
-  AstNode() : id_(GetNextId()) {
-    Isolate* isolate = Isolate::Current();
+  // Override ZoneObject's new to count allocated AST nodes.
+  void* operator new(size_t size, Zone* zone) {
+    Isolate* isolate = zone->isolate();
     isolate->set_ast_node_count(isolate->ast_node_count() + 1);
+    return zone->New(static_cast<int>(size));
   }
 
+  AstNode() {}
+
   virtual ~AstNode() { }
 
   virtual void Accept(AstVisitor* v) = 0;
@@ -164,24 +167,22 @@
 
   static int Count() { return Isolate::Current()->ast_node_count(); }
   static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
-  unsigned id() const { return id_; }
 
  protected:
-  static unsigned GetNextId() {
-    Isolate* isolate = Isolate::Current();
-    unsigned tmp = isolate->ast_node_id();
-    isolate->set_ast_node_id(tmp + 1);
-    return tmp;
+  static unsigned GetNextId(Isolate* isolate) {
+    return ReserveIdRange(isolate, 1);
   }
-  static unsigned ReserveIdRange(int n) {
-    Isolate* isolate = Isolate::Current();
+
+  static unsigned ReserveIdRange(Isolate* isolate, int n) {
     unsigned tmp = isolate->ast_node_id();
     isolate->set_ast_node_id(tmp + n);
     return tmp;
   }
 
  private:
-  unsigned id_;
+  // Hidden to prevent accidental usage. It would have to load the
+  // current zone from the TLS.
+  void* operator new(size_t size);
 
   friend class CaseClause;  // Generates AST IDs.
 };
@@ -220,7 +221,9 @@
     kTest
   };
 
-  Expression() {}
+  explicit Expression(Isolate* isolate)
+      : id_(GetNextId(isolate)),
+        test_id_(GetNextId(isolate)) {}
 
   virtual int position() const {
     UNREACHABLE();
@@ -271,15 +274,12 @@
     return Handle<Map>();
   }
 
-  ExternalArrayType external_array_type() const {
-    return external_array_type_;
-  }
-  void set_external_array_type(ExternalArrayType array_type) {
-    external_array_type_ = array_type;
-  }
+  unsigned id() const { return id_; }
+  unsigned test_id() const { return test_id_; }
 
  private:
-  ExternalArrayType external_array_type_;
+  unsigned id_;
+  unsigned test_id_;
 };
 
 
@@ -290,6 +290,7 @@
  */
 class ValidLeftHandSideSentinel: public Expression {
  public:
+  explicit ValidLeftHandSideSentinel(Isolate* isolate) : Expression(isolate) {}
   virtual bool IsValidLeftHandSide() { return true; }
   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
   virtual bool IsInlineable() const;
@@ -321,7 +322,7 @@
   int ExitId() const { return exit_id_; }
 
  protected:
-  inline BreakableStatement(ZoneStringList* labels, Type type);
+  BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type);
 
  private:
   ZoneStringList* labels_;
@@ -334,7 +335,10 @@
 
 class Block: public BreakableStatement {
  public:
-  inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
+  inline Block(Isolate* isolate,
+               ZoneStringList* labels,
+               int capacity,
+               bool is_initializer_block);
 
   DECLARE_NODE_TYPE(Block)
 
@@ -396,12 +400,13 @@
   // Bailout support.
   int OsrEntryId() const { return osr_entry_id_; }
   virtual int ContinueId() const = 0;
+  virtual int StackCheckId() const = 0;
 
   // Code generation
   Label* continue_target()  { return &continue_target_; }
 
  protected:
-  explicit inline IterationStatement(ZoneStringList* labels);
+  inline IterationStatement(Isolate* isolate, ZoneStringList* labels);
 
   void Initialize(Statement* body) {
     body_ = body;
@@ -416,7 +421,7 @@
 
 class DoWhileStatement: public IterationStatement {
  public:
-  explicit inline DoWhileStatement(ZoneStringList* labels);
+  inline DoWhileStatement(Isolate* isolate, ZoneStringList* labels);
 
   DECLARE_NODE_TYPE(DoWhileStatement)
 
@@ -434,6 +439,7 @@
 
   // Bailout support.
   virtual int ContinueId() const { return continue_id_; }
+  virtual int StackCheckId() const { return back_edge_id_; }
   int BackEdgeId() const { return back_edge_id_; }
 
   virtual bool IsInlineable() const;
@@ -448,7 +454,7 @@
 
 class WhileStatement: public IterationStatement {
  public:
-  explicit inline WhileStatement(ZoneStringList* labels);
+  inline WhileStatement(Isolate* isolate, ZoneStringList* labels);
 
   DECLARE_NODE_TYPE(WhileStatement)
 
@@ -468,6 +474,7 @@
 
   // Bailout support.
   virtual int ContinueId() const { return EntryId(); }
+  virtual int StackCheckId() const { return body_id_; }
   int BodyId() const { return body_id_; }
 
  private:
@@ -480,7 +487,7 @@
 
 class ForStatement: public IterationStatement {
  public:
-  explicit inline ForStatement(ZoneStringList* labels);
+  inline ForStatement(Isolate* isolate, ZoneStringList* labels);
 
   DECLARE_NODE_TYPE(ForStatement)
 
@@ -507,6 +514,7 @@
 
   // Bailout support.
   virtual int ContinueId() const { return continue_id_; }
+  virtual int StackCheckId() const { return body_id_; }
   int BodyId() const { return body_id_; }
 
   bool is_fast_smi_loop() { return loop_variable_ != NULL; }
@@ -528,7 +536,7 @@
 
 class ForInStatement: public IterationStatement {
  public:
-  explicit inline ForInStatement(ZoneStringList* labels);
+  inline ForInStatement(Isolate* isolate, ZoneStringList* labels);
 
   DECLARE_NODE_TYPE(ForInStatement)
 
@@ -545,6 +553,7 @@
   // Bailout support.
   int AssignmentId() const { return assignment_id_; }
   virtual int ContinueId() const { return EntryId(); }
+  virtual int StackCheckId() const { return EntryId(); }
 
  private:
   Expression* each_;
@@ -618,37 +627,36 @@
 };
 
 
-class WithEnterStatement: public Statement {
+class EnterWithContextStatement: public Statement {
  public:
-  explicit WithEnterStatement(Expression* expression, bool is_catch_block)
-      : expression_(expression), is_catch_block_(is_catch_block) { }
+  explicit EnterWithContextStatement(Expression* expression)
+      : expression_(expression) { }
 
-  DECLARE_NODE_TYPE(WithEnterStatement)
+  DECLARE_NODE_TYPE(EnterWithContextStatement)
 
   Expression* expression() const { return expression_; }
 
-  bool is_catch_block() const { return is_catch_block_; }
   virtual bool IsInlineable() const;
 
  private:
   Expression* expression_;
-  bool is_catch_block_;
 };
 
 
-class WithExitStatement: public Statement {
+class ExitContextStatement: public Statement {
  public:
-  WithExitStatement() { }
-
   virtual bool IsInlineable() const;
 
-  DECLARE_NODE_TYPE(WithExitStatement)
+  DECLARE_NODE_TYPE(ExitContextStatement)
 };
 
 
 class CaseClause: public ZoneObject {
  public:
-  CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
+  CaseClause(Isolate* isolate,
+             Expression* label,
+             ZoneList<Statement*>* statements,
+             int pos);
 
   bool is_default() const { return label_ == NULL; }
   Expression* label() const {
@@ -683,7 +691,7 @@
 
 class SwitchStatement: public BreakableStatement {
  public:
-  explicit inline SwitchStatement(ZoneStringList* labels);
+  inline SwitchStatement(Isolate* isolate, ZoneStringList* labels);
 
   DECLARE_NODE_TYPE(SwitchStatement)
 
@@ -709,14 +717,16 @@
 // given if-statement has a then- or an else-part containing code.
 class IfStatement: public Statement {
  public:
-  IfStatement(Expression* condition,
+  IfStatement(Isolate* isolate,
+              Expression* condition,
               Statement* then_statement,
               Statement* else_statement)
       : condition_(condition),
         then_statement_(then_statement),
         else_statement_(else_statement),
-        then_id_(GetNextId()),
-        else_id_(GetNextId()) {
+        if_id_(GetNextId(isolate)),
+        then_id_(GetNextId(isolate)),
+        else_id_(GetNextId(isolate)) {
   }
 
   DECLARE_NODE_TYPE(IfStatement)
@@ -730,6 +740,7 @@
   Statement* then_statement() const { return then_statement_; }
   Statement* else_statement() const { return else_statement_; }
 
+  int IfId() const { return if_id_; }
   int ThenId() const { return then_id_; }
   int ElseId() const { return else_id_; }
 
@@ -737,6 +748,7 @@
   Expression* condition_;
   Statement* then_statement_;
   Statement* else_statement_;
+  int if_id_;
   int then_id_;
   int else_id_;
 };
@@ -746,9 +758,7 @@
 // stack in the compiler; this should probably be reworked.
 class TargetCollector: public AstNode {
  public:
-  explicit TargetCollector(ZoneList<Label*>* targets)
-      : targets_(targets) {
-  }
+  TargetCollector(): targets_(0) { }
 
   // Adds a jump target to the collector. The collector stores a pointer not
   // a copy of the target to make binding work, so make sure not to pass in
@@ -759,11 +769,11 @@
   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
   virtual TargetCollector* AsTargetCollector() { return this; }
 
-  ZoneList<Label*>* targets() { return targets_; }
+  ZoneList<Label*>* targets() { return &targets_; }
   virtual bool IsInlineable() const;
 
  private:
-  ZoneList<Label*>* targets_;
+  ZoneList<Label*> targets_;
 };
 
 
@@ -789,21 +799,25 @@
 class TryCatchStatement: public TryStatement {
  public:
   TryCatchStatement(Block* try_block,
-                    VariableProxy* catch_var,
+                    Scope* scope,
+                    Variable* variable,
                     Block* catch_block)
       : TryStatement(try_block),
-        catch_var_(catch_var),
+        scope_(scope),
+        variable_(variable),
         catch_block_(catch_block) {
   }
 
   DECLARE_NODE_TYPE(TryCatchStatement)
 
-  VariableProxy* catch_var() const { return catch_var_; }
+  Scope* scope() { return scope_; }
+  Variable* variable() { return variable_; }
   Block* catch_block() const { return catch_block_; }
   virtual bool IsInlineable() const;
 
  private:
-  VariableProxy* catch_var_;
+  Scope* scope_;
+  Variable* variable_;
   Block* catch_block_;
 };
 
@@ -841,7 +855,8 @@
 
 class Literal: public Expression {
  public:
-  explicit Literal(Handle<Object> handle) : handle_(handle) { }
+  Literal(Isolate* isolate, Handle<Object> handle)
+      : Expression(isolate), handle_(handle) { }
 
   DECLARE_NODE_TYPE(Literal)
 
@@ -894,8 +909,14 @@
 // Base class for literals that needs space in the corresponding JSFunction.
 class MaterializedLiteral: public Expression {
  public:
-  explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
-      : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
+  MaterializedLiteral(Isolate* isolate,
+                      int literal_index,
+                      bool is_simple,
+                      int depth)
+      : Expression(isolate),
+        literal_index_(literal_index),
+        is_simple_(is_simple),
+        depth_(depth) {}
 
   virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
 
@@ -951,14 +972,15 @@
     bool emit_store_;
   };
 
-  ObjectLiteral(Handle<FixedArray> constant_properties,
+  ObjectLiteral(Isolate* isolate,
+                Handle<FixedArray> constant_properties,
                 ZoneList<Property*>* properties,
                 int literal_index,
                 bool is_simple,
                 bool fast_elements,
                 int depth,
                 bool has_function)
-      : MaterializedLiteral(literal_index, is_simple, depth),
+      : MaterializedLiteral(isolate, literal_index, is_simple, depth),
         constant_properties_(constant_properties),
         properties_(properties),
         fast_elements_(fast_elements),
@@ -997,10 +1019,11 @@
 // Node for capturing a regexp literal.
 class RegExpLiteral: public MaterializedLiteral {
  public:
-  RegExpLiteral(Handle<String> pattern,
+  RegExpLiteral(Isolate* isolate,
+                Handle<String> pattern,
                 Handle<String> flags,
                 int literal_index)
-      : MaterializedLiteral(literal_index, false, 1),
+      : MaterializedLiteral(isolate, literal_index, false, 1),
         pattern_(pattern),
         flags_(flags) {}
 
@@ -1018,15 +1041,16 @@
 // for minimizing the work when constructing it at runtime.
 class ArrayLiteral: public MaterializedLiteral {
  public:
-  ArrayLiteral(Handle<FixedArray> constant_elements,
+  ArrayLiteral(Isolate* isolate,
+               Handle<FixedArray> constant_elements,
                ZoneList<Expression*>* values,
                int literal_index,
                bool is_simple,
                int depth)
-      : MaterializedLiteral(literal_index, is_simple, depth),
+      : MaterializedLiteral(isolate, literal_index, is_simple, depth),
         constant_elements_(constant_elements),
         values_(values),
-        first_element_id_(ReserveIdRange(values->length())) {}
+        first_element_id_(ReserveIdRange(isolate, values->length())) {}
 
   DECLARE_NODE_TYPE(ArrayLiteral)
 
@@ -1043,44 +1067,14 @@
 };
 
 
-// Node for constructing a context extension object for a catch block.
-// The catch context extension object has one property, the catch
-// variable, which should be DontDelete.
-class CatchExtensionObject: public Expression {
- public:
-  CatchExtensionObject(Literal* key, VariableProxy* value)
-      : key_(key), value_(value) {
-  }
-
-  DECLARE_NODE_TYPE(CatchExtensionObject)
-
-  Literal* key() const { return key_; }
-  VariableProxy* value() const { return value_; }
-  virtual bool IsInlineable() const;
-
- private:
-  Literal* key_;
-  VariableProxy* value_;
-};
-
-
 class VariableProxy: public Expression {
  public:
-  explicit VariableProxy(Variable* var);
+  VariableProxy(Isolate* isolate, Variable* var);
 
   DECLARE_NODE_TYPE(VariableProxy)
 
   // Type testing & conversion
-  virtual Property* AsProperty() {
-    return var_ == NULL ? NULL : var_->AsProperty();
-  }
-
-  Variable* AsVariable() {
-    if (this == NULL || var_ == NULL) return NULL;
-    Expression* rewrite = var_->rewrite();
-    if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
-    return NULL;
-  }
+  Variable* AsVariable() { return (this == NULL) ? NULL : var_; }
 
   virtual bool IsValidLeftHandSide() {
     return var_ == NULL ? true : var_->IsValidLeftHandSide();
@@ -1122,11 +1116,12 @@
   bool is_trivial_;
   int position_;
 
-  VariableProxy(Handle<String> name,
+  VariableProxy(Isolate* isolate,
+                Handle<String> name,
                 bool is_this,
                 bool inside_with,
                 int position = RelocInfo::kNoPosition);
-  explicit VariableProxy(bool is_this);
+  VariableProxy(Isolate* isolate, bool is_this);
 
   friend class Scope;
 };
@@ -1137,7 +1132,8 @@
   virtual bool IsValidLeftHandSide() { return !is_this(); }
 
  private:
-  explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
+  VariableProxySentinel(Isolate* isolate, bool is_this)
+      : VariableProxy(isolate, is_this) { }
 
   friend class AstSentinels;
 };
@@ -1167,8 +1163,8 @@
     LOOKUP
   };
 
-  Slot(Variable* var, Type type, int index)
-      : var_(var), type_(type), index_(index) {
+  Slot(Isolate* isolate, Variable* var, Type type, int index)
+      : Expression(isolate), var_(var), type_(type), index_(index) {
     ASSERT(var != NULL);
   }
 
@@ -1199,8 +1195,13 @@
   // properties should use the global object as receiver, not the base object
   // of the resolved Reference.
   enum Type { NORMAL, SYNTHETIC };
-  Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
-      : obj_(obj),
+  Property(Isolate* isolate,
+           Expression* obj,
+           Expression* key,
+           int pos,
+           Type type = NORMAL)
+      : Expression(isolate),
+        obj_(obj),
         key_(key),
         pos_(pos),
         type_(type),
@@ -1209,8 +1210,7 @@
         is_array_length_(false),
         is_string_length_(false),
         is_string_access_(false),
-        is_function_prototype_(false),
-        is_arguments_access_(false) { }
+        is_function_prototype_(false) { }
 
   DECLARE_NODE_TYPE(Property)
 
@@ -1226,13 +1226,6 @@
   bool IsStringAccess() const { return is_string_access_; }
   bool IsFunctionPrototype() const { return is_function_prototype_; }
 
-  // Marks that this is actually an argument rewritten to a keyed property
-  // accessing the argument through the arguments shadow object.
-  void set_is_arguments_access(bool is_arguments_access) {
-    is_arguments_access_ = is_arguments_access;
-  }
-  bool is_arguments_access() const { return is_arguments_access_; }
-
   // Type feedback information.
   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
   virtual bool IsMonomorphic() { return is_monomorphic_; }
@@ -1254,21 +1247,24 @@
   bool is_string_length_ : 1;
   bool is_string_access_ : 1;
   bool is_function_prototype_ : 1;
-  bool is_arguments_access_ : 1;
   Handle<Map> monomorphic_receiver_type_;
 };
 
 
 class Call: public Expression {
  public:
-  Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
-      : expression_(expression),
+  Call(Isolate* isolate,
+       Expression* expression,
+       ZoneList<Expression*>* arguments,
+       int pos)
+      : Expression(isolate),
+        expression_(expression),
         arguments_(arguments),
         pos_(pos),
         is_monomorphic_(false),
         check_type_(RECEIVER_MAP_CHECK),
         receiver_types_(NULL),
-        return_id_(GetNextId()) {
+        return_id_(GetNextId(isolate)) {
   }
 
   DECLARE_NODE_TYPE(Call)
@@ -1347,8 +1343,14 @@
 
 class CallNew: public Expression {
  public:
-  CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
-      : expression_(expression), arguments_(arguments), pos_(pos) { }
+  CallNew(Isolate* isolate,
+          Expression* expression,
+          ZoneList<Expression*>* arguments,
+          int pos)
+      : Expression(isolate),
+        expression_(expression),
+        arguments_(arguments),
+        pos_(pos) { }
 
   DECLARE_NODE_TYPE(CallNew)
 
@@ -1371,10 +1373,14 @@
 // implemented in JavaScript (see "v8natives.js").
 class CallRuntime: public Expression {
  public:
-  CallRuntime(Handle<String> name,
+  CallRuntime(Isolate* isolate,
+              Handle<String> name,
               const Runtime::Function* function,
               ZoneList<Expression*>* arguments)
-      : name_(name), function_(function), arguments_(arguments) { }
+      : Expression(isolate),
+        name_(name),
+        function_(function),
+        arguments_(arguments) { }
 
   DECLARE_NODE_TYPE(CallRuntime)
 
@@ -1394,8 +1400,11 @@
 
 class UnaryOperation: public Expression {
  public:
-  UnaryOperation(Token::Value op, Expression* expression, int pos)
-      : op_(op), expression_(expression), pos_(pos) {
+  UnaryOperation(Isolate* isolate,
+                 Token::Value op,
+                 Expression* expression,
+                 int pos)
+      : Expression(isolate), op_(op), expression_(expression), pos_(pos) {
     ASSERT(Token::IsUnaryOp(op));
   }
 
@@ -1418,14 +1427,15 @@
 
 class BinaryOperation: public Expression {
  public:
-  BinaryOperation(Token::Value op,
+  BinaryOperation(Isolate* isolate,
+                  Token::Value op,
                   Expression* left,
                   Expression* right,
                   int pos)
-      : op_(op), left_(left), right_(right), pos_(pos) {
+      : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
     ASSERT(Token::IsBinaryOp(op));
     right_id_ = (op == Token::AND || op == Token::OR)
-        ? static_cast<int>(GetNextId())
+        ? static_cast<int>(GetNextId(isolate))
         : AstNode::kNoNumber;
   }
 
@@ -1456,13 +1466,19 @@
 
 class CountOperation: public Expression {
  public:
-  CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
-      : op_(op),
+  CountOperation(Isolate* isolate,
+                 Token::Value op,
+                 bool is_prefix,
+                 Expression* expr,
+                 int pos)
+      : Expression(isolate),
+        op_(op),
         is_prefix_(is_prefix),
         expression_(expr),
         pos_(pos),
-        assignment_id_(GetNextId()),
-        count_id_(GetNextId()) { }
+        assignment_id_(GetNextId(isolate)),
+        count_id_(GetNextId(isolate)),
+        receiver_types_(NULL) { }
 
   DECLARE_NODE_TYPE(CountOperation)
 
@@ -1486,6 +1502,7 @@
   virtual Handle<Map> GetMonomorphicReceiverType() {
     return monomorphic_receiver_type_;
   }
+  virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
 
   // Bailout support.
   int AssignmentId() const { return assignment_id_; }
@@ -1500,16 +1517,23 @@
   int assignment_id_;
   int count_id_;
   Handle<Map> monomorphic_receiver_type_;
+  ZoneMapList* receiver_types_;
 };
 
 
 class CompareOperation: public Expression {
  public:
-  CompareOperation(Token::Value op,
+  CompareOperation(Isolate* isolate,
+                   Token::Value op,
                    Expression* left,
                    Expression* right,
                    int pos)
-      : op_(op), left_(left), right_(right), pos_(pos), compare_type_(NONE) {
+      : Expression(isolate),
+        op_(op),
+        left_(left),
+        right_(right),
+        pos_(pos),
+        compare_type_(NONE) {
     ASSERT(Token::IsCompareOp(op));
   }
 
@@ -1527,6 +1551,10 @@
   bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
   bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
 
+  // Match special cases.
+  bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
+  bool IsLiteralCompareUndefined(Expression** expr);
+
  private:
   Token::Value op_;
   Expression* left_;
@@ -1540,8 +1568,8 @@
 
 class CompareToNull: public Expression {
  public:
-  CompareToNull(bool is_strict, Expression* expression)
-      : is_strict_(is_strict), expression_(expression) { }
+  CompareToNull(Isolate* isolate, bool is_strict, Expression* expression)
+      : Expression(isolate), is_strict_(is_strict), expression_(expression) { }
 
   DECLARE_NODE_TYPE(CompareToNull)
 
@@ -1559,18 +1587,20 @@
 
 class Conditional: public Expression {
  public:
-  Conditional(Expression* condition,
+  Conditional(Isolate* isolate,
+              Expression* condition,
               Expression* then_expression,
               Expression* else_expression,
               int then_expression_position,
               int else_expression_position)
-      : condition_(condition),
+      : Expression(isolate),
+        condition_(condition),
         then_expression_(then_expression),
         else_expression_(else_expression),
         then_expression_position_(then_expression_position),
         else_expression_position_(else_expression_position),
-        then_id_(GetNextId()),
-        else_id_(GetNextId()) {
+        then_id_(GetNextId(isolate)),
+        else_id_(GetNextId(isolate)) {
   }
 
   DECLARE_NODE_TYPE(Conditional)
@@ -1600,7 +1630,11 @@
 
 class Assignment: public Expression {
  public:
-  Assignment(Token::Value op, Expression* target, Expression* value, int pos);
+  Assignment(Isolate* isolate,
+             Token::Value op,
+             Expression* target,
+             Expression* value,
+             int pos);
 
   DECLARE_NODE_TYPE(Assignment)
 
@@ -1660,8 +1694,8 @@
 
 class Throw: public Expression {
  public:
-  Throw(Expression* exception, int pos)
-      : exception_(exception), pos_(pos) {}
+  Throw(Isolate* isolate, Expression* exception, int pos)
+      : Expression(isolate), exception_(exception), pos_(pos) {}
 
   DECLARE_NODE_TYPE(Throw)
 
@@ -1677,7 +1711,14 @@
 
 class FunctionLiteral: public Expression {
  public:
-  FunctionLiteral(Handle<String> name,
+  enum Type {
+    ANONYMOUS_EXPRESSION,
+    NAMED_EXPRESSION,
+    DECLARATION
+  };
+
+  FunctionLiteral(Isolate* isolate,
+                  Handle<String> name,
                   Scope* scope,
                   ZoneList<Statement*>* body,
                   int materialized_literal_count,
@@ -1687,8 +1728,10 @@
                   int num_parameters,
                   int start_position,
                   int end_position,
-                  bool is_expression)
-      : name_(name),
+                  Type type,
+                  bool has_duplicate_parameters)
+      : Expression(isolate),
+        name_(name),
         scope_(scope),
         body_(body),
         materialized_literal_count_(materialized_literal_count),
@@ -1699,10 +1742,13 @@
         num_parameters_(num_parameters),
         start_position_(start_position),
         end_position_(end_position),
-        is_expression_(is_expression),
         function_token_position_(RelocInfo::kNoPosition),
         inferred_name_(HEAP->empty_string()),
-        pretenure_(false) { }
+        is_expression_(type != DECLARATION),
+        is_anonymous_(type == ANONYMOUS_EXPRESSION),
+        pretenure_(false),
+        has_duplicate_parameters_(has_duplicate_parameters) {
+  }
 
   DECLARE_NODE_TYPE(FunctionLiteral)
 
@@ -1714,6 +1760,7 @@
   int start_position() const { return start_position_; }
   int end_position() const { return end_position_; }
   bool is_expression() const { return is_expression_; }
+  bool is_anonymous() const { return is_anonymous_; }
   bool strict_mode() const;
 
   int materialized_literal_count() { return materialized_literal_count_; }
@@ -1742,6 +1789,8 @@
   void set_pretenure(bool value) { pretenure_ = value; }
   virtual bool IsInlineable() const;
 
+  bool has_duplicate_parameters() { return has_duplicate_parameters_; }
+
  private:
   Handle<String> name_;
   Scope* scope_;
@@ -1753,18 +1802,21 @@
   int num_parameters_;
   int start_position_;
   int end_position_;
-  bool is_expression_;
   int function_token_position_;
   Handle<String> inferred_name_;
+  bool is_expression_;
+  bool is_anonymous_;
   bool pretenure_;
+  bool has_duplicate_parameters_;
 };
 
 
 class SharedFunctionInfoLiteral: public Expression {
  public:
-  explicit SharedFunctionInfoLiteral(
+  SharedFunctionInfoLiteral(
+      Isolate* isolate,
       Handle<SharedFunctionInfo> shared_function_info)
-      : shared_function_info_(shared_function_info) { }
+      : Expression(isolate), shared_function_info_(shared_function_info) { }
 
   DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
 
@@ -1780,6 +1832,7 @@
 
 class ThisFunction: public Expression {
  public:
+  explicit ThisFunction(Isolate* isolate) : Expression(isolate) {}
   DECLARE_NODE_TYPE(ThisFunction)
   virtual bool IsInlineable() const;
 };
@@ -1950,6 +2003,7 @@
   uc16 standard_type() { return set_.standard_set_type(); }
   ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
   bool is_negated() { return is_negated_; }
+
  private:
   CharacterSet set_;
   bool is_negated_;
@@ -2034,6 +2088,7 @@
   bool is_non_greedy() { return type_ == NON_GREEDY; }
   bool is_greedy() { return type_ == GREEDY; }
   RegExpTree* body() { return body_; }
+
  private:
   RegExpTree* body_;
   int min_;
@@ -2066,6 +2121,7 @@
   int index() { return index_; }
   static int StartRegister(int index) { return index * 2; }
   static int EndRegister(int index) { return index * 2 + 1; }
+
  private:
   RegExpTree* body_;
   int index_;
@@ -2096,6 +2152,7 @@
   bool is_positive() { return is_positive_; }
   int capture_count() { return capture_count_; }
   int capture_from() { return capture_from_; }
+
  private:
   RegExpTree* body_;
   bool is_positive_;
diff --git a/src/bignum.cc b/src/bignum.cc
index a973974..9436322 100644
--- a/src/bignum.cc
+++ b/src/bignum.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,10 +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.
 
-#include "v8.h"
-
-#include "bignum.h"
+#include "../include/v8stdint.h"
 #include "utils.h"
+#include "bignum.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index d32ac80..5375cde 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -47,8 +47,9 @@
 
 NativesExternalStringResource::NativesExternalStringResource(
     Bootstrapper* bootstrapper,
-    const char* source)
-    : data_(source), length_(StrLength(source)) {
+    const char* source,
+    size_t length)
+    : data_(source), length_(length) {
   if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
     bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
   }
@@ -75,16 +76,18 @@
   if (heap->natives_source_cache()->get(index)->IsUndefined()) {
     if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
       // We can use external strings for the natives.
+      Vector<const char> source = Natives::GetRawScriptSource(index);
       NativesExternalStringResource* resource =
           new NativesExternalStringResource(this,
-              Natives::GetScriptSource(index).start());
+                                            source.start(),
+                                            source.length());
       Handle<String> source_code =
           factory->NewExternalStringFromAscii(resource);
       heap->natives_source_cache()->set(index, *source_code);
     } else {
       // Old snapshot code can't cope with external strings at all.
       Handle<String> source_code =
-        factory->NewStringFromAscii(Natives::GetScriptSource(index));
+        factory->NewStringFromAscii(Natives::GetRawScriptSource(index));
       heap->natives_source_cache()->set(index, *source_code);
     }
   }
@@ -811,7 +814,6 @@
   // --- G l o b a l   C o n t e x t ---
   // Use the empty function as closure (no scope info).
   global_context()->set_closure(*empty_function);
-  global_context()->set_fcontext(*global_context());
   global_context()->set_previous(NULL);
   // Set extension and global object.
   global_context()->set_extension(*inner_global);
@@ -1052,6 +1054,24 @@
 #endif
   }
 
+  {  // --- aliased_arguments_boilerplate_
+    Handle<Map> old_map(global_context()->arguments_boilerplate()->map());
+    Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
+    new_map->set_pre_allocated_property_fields(2);
+    Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
+    new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
+    // Set up a well-formed parameter map to make assertions happy.
+    Handle<FixedArray> elements = factory->NewFixedArray(2);
+    elements->set_map(heap->non_strict_arguments_elements_map());
+    Handle<FixedArray> array;
+    array = factory->NewFixedArray(0);
+    elements->set(0, *array);
+    array = factory->NewFixedArray(0);
+    elements->set(1, *array);
+    result->set_elements(*elements);
+    global_context()->set_aliased_arguments_boilerplate(*result);
+  }
+
   {  // --- strict mode arguments boilerplate
     const PropertyAttributes attributes =
       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
@@ -1182,7 +1202,8 @@
   Vector<const char> name = ExperimentalNatives::GetScriptName(index);
   Factory* factory = isolate->factory();
   Handle<String> source_code =
-      factory->NewStringFromAscii(ExperimentalNatives::GetScriptSource(index));
+      factory->NewStringFromAscii(
+          ExperimentalNatives::GetRawScriptSource(index));
   return CompileNative(name, source_code);
 }
 
@@ -1288,7 +1309,9 @@
 
 void Genesis::InstallExperimentalNativeFunctions() {
   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);
   }
 }
 
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index 2e05452..abf61b9 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -168,8 +168,9 @@
 class NativesExternalStringResource
     : public v8::String::ExternalAsciiStringResource {
  public:
-  explicit NativesExternalStringResource(Bootstrapper* bootstrapper,
-                                         const char* source);
+  NativesExternalStringResource(Bootstrapper* bootstrapper,
+                                const char* source,
+                                size_t length);
 
   const char* data() const {
     return data_;
diff --git a/src/builtins.cc b/src/builtins.cc
index c34b074..d403a95 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1202,10 +1202,10 @@
   ASSERT(!CalledAsConstructor(isolate));
   Heap* heap = isolate->heap();
 
-  Handle<Object> receiver = args.at<Object>(0);
+  Handle<Object> receiver = args.receiver();
 
   // Get the object called.
-  JSObject* obj = JSObject::cast(*args.receiver());
+  JSObject* obj = JSObject::cast(*receiver);
 
   // Get the invocation callback from the function descriptor that was
   // used to create the called object.
@@ -1351,6 +1351,9 @@
   KeyedLoadIC::GenerateIndexedInterceptor(masm);
 }
 
+static void Generate_KeyedLoadIC_NonStrictArguments(MacroAssembler* masm) {
+  KeyedLoadIC::GenerateNonStrictArguments(masm);
+}
 
 static void Generate_StoreIC_Initialize(MacroAssembler* masm) {
   StoreIC::GenerateInitialize(masm);
@@ -1441,6 +1444,9 @@
   KeyedStoreIC::GenerateInitialize(masm);
 }
 
+static void Generate_KeyedStoreIC_NonStrictArguments(MacroAssembler* masm) {
+  KeyedStoreIC::GenerateNonStrictArguments(masm);
+}
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 static void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
diff --git a/src/builtins.h b/src/builtins.h
index eca998c..f9a5a13 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -132,6 +132,8 @@
                                     Code::kNoExtraICState)              \
   V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MEGAMORPHIC,         \
                                     Code::kNoExtraICState)              \
+  V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, MEGAMORPHIC,         \
+                                    Code::kNoExtraICState)              \
                                                                         \
   V(StoreIC_Initialize,             STORE_IC, UNINITIALIZED,            \
                                     Code::kNoExtraICState)              \
@@ -163,6 +165,8 @@
                                     kStrictMode)                        \
   V(KeyedStoreIC_Generic_Strict,    KEYED_STORE_IC, MEGAMORPHIC,        \
                                     kStrictMode)                        \
+  V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, MEGAMORPHIC,       \
+                                     Code::kNoExtraICState)             \
                                                                         \
   /* Uses KeyedLoadIC_Initialize; must be after in list. */             \
   V(FunctionCall,                   BUILTIN, UNINITIALIZED,             \
diff --git a/src/cached-powers.cc b/src/cached-powers.cc
index 43dbc78..30a67a6 100644
--- a/src/cached-powers.cc
+++ b/src/cached-powers.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -26,10 +26,12 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <stdarg.h>
+#include <math.h>
 #include <limits.h>
 
-#include "v8.h"
-
+#include "../include/v8stdint.h"
+#include "globals.h"
+#include "checks.h"
 #include "cached-powers.h"
 
 namespace v8 {
@@ -147,7 +149,9 @@
     DiyFp* power,
     int* decimal_exponent) {
   int kQ = DiyFp::kSignificandSize;
-  double k = ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10);
+  // Some platforms return incorrect sign on 0 result. We can ignore that here,
+  // which means we can avoid depending on platform.h.
+  double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
   int foo = kCachedPowersOffset;
   int index =
       (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index d12def8..1d1128f 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -61,21 +61,29 @@
 }
 
 
+SmartPointer<const char> CodeStub::GetName() {
+  char buffer[100];
+  NoAllocationStringAllocator allocator(buffer,
+                                        static_cast<unsigned>(sizeof(buffer)));
+  StringStream stream(&allocator);
+  PrintName(&stream);
+  return stream.ToCString();
+}
+
+
 void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
   code->set_major_key(MajorKey());
 
   Isolate* isolate = masm->isolate();
-  PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
-  GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
+  SmartPointer<const char> name = GetName();
+  PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name));
+  GDBJIT(AddCode(GDBJITInterface::STUB, *name, code));
   Counters* counters = isolate->counters();
   counters->total_stubs_code_size()->Increment(code->instruction_size());
 
 #ifdef ENABLE_DISASSEMBLER
   if (FLAG_print_code_stubs) {
-#ifdef DEBUG
-    Print();
-#endif
-    code->Disassemble(GetName());
+    code->Disassemble(*name);
     PrintF("\n");
   }
 #endif
@@ -170,7 +178,7 @@
 const char* CodeStub::MajorName(CodeStub::Major major_key,
                                 bool allow_unknown_keys) {
   switch (major_key) {
-#define DEF_CASE(name) case name: return #name;
+#define DEF_CASE(name) case name: return #name "Stub";
     CODE_STUB_LIST(DEF_CASE)
 #undef DEF_CASE
     default:
@@ -213,13 +221,7 @@
 }
 
 
-const char* InstanceofStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
+void InstanceofStub::PrintName(StringStream* stream) {
   const char* args = "";
   if (HasArgsInRegisters()) {
     args = "_REGS";
@@ -235,33 +237,96 @@
     return_true_false_object = "_TRUEFALSE";
   }
 
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "InstanceofStub%s%s%s",
-               args,
-               inline_check,
-               return_true_false_object);
-  return name_;
+  stream->Add("InstanceofStub%s%s%s",
+              args,
+              inline_check,
+              return_true_false_object);
 }
 
 
-void KeyedLoadFastElementStub::Generate(MacroAssembler* masm) {
-  KeyedLoadStubCompiler::GenerateLoadFastElement(masm);
+void KeyedLoadElementStub::Generate(MacroAssembler* masm) {
+  switch (elements_kind_) {
+    case JSObject::FAST_ELEMENTS:
+      KeyedLoadStubCompiler::GenerateLoadFastElement(masm);
+      break;
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+      KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm);
+      break;
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+      KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_);
+      break;
+    case JSObject::DICTIONARY_ELEMENTS:
+      KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
+      break;
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNREACHABLE();
+      break;
+  }
 }
 
 
-void KeyedStoreFastElementStub::Generate(MacroAssembler* masm) {
-  KeyedStoreStubCompiler::GenerateStoreFastElement(masm, is_js_array_);
+void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
+  switch (elements_kind_) {
+    case JSObject::FAST_ELEMENTS:
+      KeyedStoreStubCompiler::GenerateStoreFastElement(masm, is_js_array_);
+      break;
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+      KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
+                                                             is_js_array_);
+      break;
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+      KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_);
+      break;
+    case JSObject::DICTIONARY_ELEMENTS:
+      KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm);
+      break;
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNREACHABLE();
+      break;
+  }
 }
 
 
-void KeyedLoadExternalArrayStub::Generate(MacroAssembler* masm) {
-  KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, array_type_);
+void ArgumentsAccessStub::PrintName(StringStream* stream) {
+  const char* type_name = NULL;  // Make g++ happy.
+  switch (type_) {
+    case READ_ELEMENT: type_name = "ReadElement"; break;
+    case NEW_NON_STRICT_FAST: type_name = "NewNonStrictFast"; break;
+    case NEW_NON_STRICT_SLOW: type_name = "NewNonStrictSlow"; break;
+    case NEW_STRICT: type_name = "NewStrict"; break;
+  }
+  stream->Add("ArgumentsAccessStub_%s", type_name);
 }
 
 
-void KeyedStoreExternalArrayStub::Generate(MacroAssembler* masm) {
-  KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, array_type_);
+void CallFunctionStub::PrintName(StringStream* stream) {
+  const char* in_loop_name = NULL;  // Make g++ happy.
+  switch (in_loop_) {
+    case NOT_IN_LOOP: in_loop_name = ""; break;
+    case IN_LOOP: in_loop_name = "_InLoop"; break;
+  }
+  const char* flags_name = NULL;  // Make g++ happy.
+  switch (flags_) {
+    case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break;
+    case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break;
+  }
+  stream->Add("CallFunctionStub_Args%d%s%s", argc_, in_loop_name, flags_name);
 }
 
-
 } }  // namespace v8::internal
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 7ab0b7c..17c245c 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -34,8 +34,7 @@
 namespace v8 {
 namespace internal {
 
-// List of code stubs used on all platforms. The order in this list is important
-// as only the stubs up to and including Instanceof allows nested stub calls.
+// List of code stubs used on all platforms.
 #define CODE_STUB_LIST_ALL_PLATFORMS(V)  \
   V(CallFunction)                        \
   V(UnaryOp)                             \
@@ -43,12 +42,18 @@
   V(StringAdd)                           \
   V(SubString)                           \
   V(StringCompare)                       \
-  V(SmiOp)                               \
   V(Compare)                             \
   V(CompareIC)                           \
   V(MathPow)                             \
   V(TranscendentalCache)                 \
   V(Instanceof)                          \
+  /* All stubs above this line only exist in a few versions, which are  */  \
+  /* generated ahead of time.  Therefore compiling a call to one of     */  \
+  /* them can't cause a new stub to be compiled, so compiling a call to */  \
+  /* them is GC safe.  The ones below this line exist in many variants  */  \
+  /* so code compiling a call to one can cause a GC.  This means they   */  \
+  /* can't be called from other stubs, since stub generation code is    */  \
+  /* not GC safe.                                                       */  \
   V(ConvertToDouble)                     \
   V(WriteInt32ToHeapNumber)              \
   V(StackCheck)                          \
@@ -65,10 +70,8 @@
   V(NumberToString)                      \
   V(CEntry)                              \
   V(JSEntry)                             \
-  V(KeyedLoadFastElement)                \
-  V(KeyedStoreFastElement)               \
-  V(KeyedLoadExternalArray)              \
-  V(KeyedStoreExternalArray)             \
+  V(KeyedLoadElement)                    \
+  V(KeyedStoreElement)                   \
   V(DebuggerStatement)                   \
   V(StringDictionaryNegativeLookup)
 
@@ -178,16 +181,15 @@
   }
 
   // Returns a name for logging/debugging purposes.
-  virtual const char* GetName() { return MajorName(MajorKey(), false); }
+  SmartPointer<const char> GetName();
+  virtual void PrintName(StringStream* stream) {
+    stream->Add("%s", MajorName(MajorKey(), false));
+  }
 
   // Returns whether the code generated for this stub needs to be allocated as
   // a fixed (non-moveable) code object.
   virtual bool NeedsImmovableCode() { return false; }
 
-  #ifdef DEBUG
-  virtual void Print() { PrintF("%s\n", GetName()); }
-#endif
-
   // Computes the key based on major and minor.
   uint32_t GetKey() {
     ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
@@ -195,6 +197,7 @@
            MajorKeyBits::encode(MajorKey());
   }
 
+  // See comment above, where Instanceof is defined.
   bool AllowsStubCalls() { return MajorKey() <= Instanceof; }
 
   class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {};
@@ -268,9 +271,6 @@
   void Generate(MacroAssembler* masm);
 
  private:
-
-  const char* GetName() { return "StackCheckStub"; }
-
   Major MajorKey() { return StackCheck; }
   int MinorKey() { return 0; }
 };
@@ -285,7 +285,6 @@
  private:
   Major MajorKey() { return ToNumber; }
   int MinorKey() { return 0; }
-  const char* GetName() { return "ToNumberStub"; }
 };
 
 
@@ -297,7 +296,6 @@
   void Generate(MacroAssembler* masm);
 
  private:
-  const char* GetName() { return "FastNewClosureStub"; }
   Major MajorKey() { return FastNewClosure; }
   int MinorKey() { return strict_mode_; }
 
@@ -318,7 +316,6 @@
  private:
   int slots_;
 
-  const char* GetName() { return "FastNewContextStub"; }
   Major MajorKey() { return FastNewContext; }
   int MinorKey() { return slots_; }
 };
@@ -347,7 +344,6 @@
   Mode mode_;
   int length_;
 
-  const char* GetName() { return "FastCloneShallowArrayStub"; }
   Major MajorKey() { return FastCloneShallowArray; }
   int MinorKey() {
     ASSERT(mode_ == 0 || mode_ == 1);
@@ -365,7 +361,7 @@
     kReturnTrueFalseObject = 1 << 2
   };
 
-  explicit InstanceofStub(Flags flags) : flags_(flags), name_(NULL) { }
+  explicit InstanceofStub(Flags flags) : flags_(flags) { }
 
   static Register left();
   static Register right();
@@ -388,10 +384,9 @@
     return (flags_ & kReturnTrueFalseObject) != 0;
   }
 
-  const char* GetName();
+  virtual void PrintName(StringStream* stream);
 
   Flags flags_;
-  char* name_;
 };
 
 
@@ -403,8 +398,6 @@
  private:
   virtual CodeStub::Major MajorKey() { return MathPow; }
   virtual int MinorKey() { return 0; }
-
-  const char* GetName() { return "MathPowStub"; }
 };
 
 
@@ -471,8 +464,7 @@
       include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
       include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
       lhs_(lhs),
-      rhs_(rhs),
-      name_(NULL) { }
+      rhs_(rhs) { }
 
   CompareStub(Condition cc,
               bool strict,
@@ -483,8 +475,7 @@
       include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
       include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
       lhs_(no_reg),
-      rhs_(no_reg),
-      name_(NULL) { }
+      rhs_(no_reg) { }
 
   void Generate(MacroAssembler* masm);
 
@@ -538,26 +529,7 @@
 
   // Unfortunately you have to run without snapshots to see most of these
   // names in the profile since most compare stubs end up in the snapshot.
-  char* name_;
-  const char* GetName();
-#ifdef DEBUG
-  void Print() {
-    PrintF("CompareStub (minor %d) (cc %d), (strict %s), "
-           "(never_nan_nan %s), (smi_compare %s) (number_compare %s) ",
-           MinorKey(),
-           static_cast<int>(cc_),
-           strict_ ? "true" : "false",
-           never_nan_nan_ ? "true" : "false",
-           include_smi_compare_ ? "inluded" : "not included",
-           include_number_compare_ ? "included" : "not included");
-
-    if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) {
-      PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code());
-    } else {
-      PrintF("\n");
-    }
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 };
 
 
@@ -588,8 +560,6 @@
   int MinorKey();
 
   bool NeedsImmovableCode();
-
-  const char* GetName() { return "CEntryStub"; }
 };
 
 
@@ -605,8 +575,6 @@
  private:
   Major MajorKey() { return JSEntry; }
   int MinorKey() { return 0; }
-
-  const char* GetName() { return "JSEntryStub"; }
 };
 
 
@@ -619,7 +587,9 @@
  private:
   int MinorKey() { return 1; }
 
-  const char* GetName() { return "JSConstructEntryStub"; }
+  virtual void PrintName(StringStream* stream) {
+    stream->Add("JSConstructEntryStub");
+  }
 };
 
 
@@ -627,7 +597,8 @@
  public:
   enum Type {
     READ_ELEMENT,
-    NEW_NON_STRICT,
+    NEW_NON_STRICT_FAST,
+    NEW_NON_STRICT_SLOW,
     NEW_STRICT
   };
 
@@ -641,28 +612,11 @@
 
   void Generate(MacroAssembler* masm);
   void GenerateReadElement(MacroAssembler* masm);
-  void GenerateNewObject(MacroAssembler* masm);
+  void GenerateNewStrict(MacroAssembler* masm);
+  void GenerateNewNonStrictFast(MacroAssembler* masm);
+  void GenerateNewNonStrictSlow(MacroAssembler* masm);
 
-  int GetArgumentsBoilerplateIndex() const {
-  return (type_ == NEW_STRICT)
-      ? Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX
-      : Context::ARGUMENTS_BOILERPLATE_INDEX;
-  }
-
-  int GetArgumentsObjectSize() const {
-    if (type_ == NEW_STRICT)
-      return Heap::kArgumentsObjectSizeStrict;
-    else
-      return Heap::kArgumentsObjectSize;
-  }
-
-  const char* GetName() { return "ArgumentsAccessStub"; }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("ArgumentsAccessStub (type %d)\n", type_);
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 };
 
 
@@ -675,14 +629,6 @@
   int MinorKey() { return 0; }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "RegExpExecStub"; }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("RegExpExecStub\n");
-  }
-#endif
 };
 
 
@@ -695,14 +641,6 @@
   int MinorKey() { return 0; }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "RegExpConstructResultStub"; }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("RegExpConstructResultStub\n");
-  }
-#endif
 };
 
 
@@ -722,14 +660,7 @@
   InLoopFlag in_loop_;
   CallFunctionFlags flags_;
 
-#ifdef DEBUG
-  void Print() {
-    PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n",
-           argc_,
-           static_cast<int>(in_loop_),
-           static_cast<int>(flags_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
   class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
@@ -926,86 +857,59 @@
   DISALLOW_COPY_AND_ASSIGN(AllowStubCallsScope);
 };
 
-#ifdef DEBUG
-#define DECLARE_ARRAY_STUB_PRINT(name) void Print() { PrintF(#name); }
-#else
-#define DECLARE_ARRAY_STUB_PRINT(name)
-#endif
 
-
-class KeyedLoadFastElementStub : public CodeStub {
+class KeyedLoadElementStub : public CodeStub {
  public:
-  explicit KeyedLoadFastElementStub() {
-  }
+  explicit KeyedLoadElementStub(JSObject::ElementsKind elements_kind)
+      : elements_kind_(elements_kind)
+  { }
 
-  Major MajorKey() { return KeyedLoadFastElement; }
-  int MinorKey() { return 0; }
+  Major MajorKey() { return KeyedLoadElement; }
+  int MinorKey() { return elements_kind_; }
 
   void Generate(MacroAssembler* masm);
 
-  const char* GetName() { return "KeyedLoadFastElementStub"; }
+ private:
+  JSObject::ElementsKind elements_kind_;
 
-  DECLARE_ARRAY_STUB_PRINT(KeyedLoadFastElementStub)
+  DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub);
 };
 
 
-class KeyedStoreFastElementStub : public CodeStub {
+class KeyedStoreElementStub : public CodeStub {
  public:
-  explicit KeyedStoreFastElementStub(bool is_js_array)
-      : is_js_array_(is_js_array) { }
+  KeyedStoreElementStub(bool is_js_array,
+                        JSObject::ElementsKind elements_kind)
+    : is_js_array_(is_js_array),
+    elements_kind_(elements_kind) { }
 
-  Major MajorKey() { return KeyedStoreFastElement; }
-  int MinorKey() { return is_js_array_ ? 1 : 0; }
+  Major MajorKey() { return KeyedStoreElement; }
+  int MinorKey() {
+    return (is_js_array_ ? 0 : JSObject::kElementsKindCount) + elements_kind_;
+  }
 
   void Generate(MacroAssembler* masm);
 
-  const char* GetName() { return "KeyedStoreFastElementStub"; }
-
-  DECLARE_ARRAY_STUB_PRINT(KeyedStoreFastElementStub)
-
  private:
   bool is_js_array_;
+  JSObject::ElementsKind elements_kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub);
 };
 
 
-class KeyedLoadExternalArrayStub : public CodeStub {
+class ToBooleanStub: public CodeStub {
  public:
-  explicit KeyedLoadExternalArrayStub(ExternalArrayType array_type)
-      : array_type_(array_type) { }
-
-  Major MajorKey() { return KeyedLoadExternalArray; }
-  int MinorKey() { return array_type_; }
+  explicit ToBooleanStub(Register tos) : tos_(tos) { }
 
   void Generate(MacroAssembler* masm);
 
-  const char* GetName() { return "KeyedLoadExternalArrayStub"; }
-
-  DECLARE_ARRAY_STUB_PRINT(KeyedLoadExternalArrayStub)
-
- protected:
-  ExternalArrayType array_type_;
+ private:
+  Register tos_;
+  Major MajorKey() { return ToBoolean; }
+  int MinorKey() { return tos_.code(); }
 };
 
-
-class KeyedStoreExternalArrayStub : public CodeStub {
- public:
-  explicit KeyedStoreExternalArrayStub(ExternalArrayType array_type)
-      : array_type_(array_type) { }
-
-  Major MajorKey() { return KeyedStoreExternalArray; }
-  int MinorKey() { return array_type_; }
-
-  void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "KeyedStoreExternalArrayStub"; }
-
-  DECLARE_ARRAY_STUB_PRINT(KeyedStoreExternalArrayStub)
-
- protected:
-  ExternalArrayType array_type_;
-};
-
-
 } }  // namespace v8::internal
 
 #endif  // V8_CODE_STUBS_H_
diff --git a/src/codegen.cc b/src/codegen.cc
index ad3cf1b..fb723a3 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -169,8 +169,6 @@
 #endif  // ENABLE_DISASSEMBLER
 }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 static Vector<const char> kRegexp = CStrVector("regexp");
 
 bool CodeGenerator::ShouldGenerateLog(Expression* type) {
@@ -187,8 +185,6 @@
   return false;
 }
 
-#endif
-
 
 bool CodeGenerator::RecordPositions(MacroAssembler* masm,
                                     int pos,
@@ -209,9 +205,14 @@
     case READ_ELEMENT:
       GenerateReadElement(masm);
       break;
-    case NEW_NON_STRICT:
+    case NEW_NON_STRICT_FAST:
+      GenerateNewNonStrictFast(masm);
+      break;
+    case NEW_NON_STRICT_SLOW:
+      GenerateNewNonStrictSlow(masm);
+      break;
     case NEW_STRICT:
-      GenerateNewObject(masm);
+      GenerateNewStrict(masm);
       break;
   }
 }
diff --git a/src/compilation-cache.cc b/src/compilation-cache.cc
index 5bd8bf3..28e833a 100644
--- a/src/compilation-cache.cc
+++ b/src/compilation-cache.cc
@@ -52,8 +52,7 @@
       eval_global_(isolate, kEvalGlobalGenerations),
       eval_contextual_(isolate, kEvalContextualGenerations),
       reg_exp_(isolate, kRegExpGenerations),
-      enabled_(true),
-      eager_optimizing_set_(NULL) {
+      enabled_(true) {
   CompilationSubCache* subcaches[kSubCacheCount] =
     {&script_, &eval_global_, &eval_contextual_, &reg_exp_};
   for (int i = 0; i < kSubCacheCount; ++i) {
@@ -62,10 +61,7 @@
 }
 
 
-CompilationCache::~CompilationCache() {
-  delete eager_optimizing_set_;
-  eager_optimizing_set_ = NULL;
-}
+CompilationCache::~CompilationCache() {}
 
 
 static Handle<CompilationCacheTable> AllocateTable(Isolate* isolate, int size) {
@@ -457,47 +453,6 @@
 }
 
 
-static bool SourceHashCompare(void* key1, void* key2) {
-  return key1 == key2;
-}
-
-
-HashMap* CompilationCache::EagerOptimizingSet() {
-  if (eager_optimizing_set_ == NULL) {
-    eager_optimizing_set_ = new HashMap(&SourceHashCompare);
-  }
-  return eager_optimizing_set_;
-}
-
-
-bool CompilationCache::ShouldOptimizeEagerly(Handle<JSFunction> function) {
-  if (FLAG_opt_eagerly) return true;
-  uint32_t hash = function->SourceHash();
-  void* key = reinterpret_cast<void*>(hash);
-  return EagerOptimizingSet()->Lookup(key, hash, false) != NULL;
-}
-
-
-void CompilationCache::MarkForEagerOptimizing(Handle<JSFunction> function) {
-  uint32_t hash = function->SourceHash();
-  void* key = reinterpret_cast<void*>(hash);
-  EagerOptimizingSet()->Lookup(key, hash, true);
-}
-
-
-void CompilationCache::MarkForLazyOptimizing(Handle<JSFunction> function) {
-  uint32_t hash = function->SourceHash();
-  void* key = reinterpret_cast<void*>(hash);
-  EagerOptimizingSet()->Remove(key, hash);
-}
-
-
-void CompilationCache::ResetEagerOptimizingData() {
-  HashMap* set = EagerOptimizingSet();
-  if (set->occupancy() > 0) set->Clear();
-}
-
-
 void CompilationCache::Clear() {
   for (int i = 0; i < kSubCacheCount; i++) {
     subcaches_[i]->Clear();
diff --git a/src/compilation-cache.h b/src/compilation-cache.h
index 887d4e8..1fcf753 100644
--- a/src/compilation-cache.h
+++ b/src/compilation-cache.h
@@ -223,14 +223,6 @@
                  JSRegExp::Flags flags,
                  Handle<FixedArray> data);
 
-  // Support for eager optimization tracking.
-  bool ShouldOptimizeEagerly(Handle<JSFunction> function);
-  void MarkForEagerOptimizing(Handle<JSFunction> function);
-  void MarkForLazyOptimizing(Handle<JSFunction> function);
-
-  // Reset the eager optimization tracking data.
-  void ResetEagerOptimizingData();
-
   // Clear the cache - also used to initialize the cache at startup.
   void Clear();
 
@@ -274,8 +266,6 @@
   // Current enable state of the compilation cache.
   bool enabled_;
 
-  HashMap* eager_optimizing_set_;
-
   friend class Isolate;
 
   DISALLOW_COPY_AND_ASSIGN(CompilationCache);
diff --git a/src/compiler.cc b/src/compiler.cc
index d82bcd0..abff8b6 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -109,8 +109,6 @@
 void CompilationInfo::AbortOptimization() {
   Handle<Code> code(shared_info()->code());
   SetCode(code);
-  Isolate* isolate = code->GetIsolate();
-  isolate->compilation_cache()->MarkForLazyOptimizing(closure());
 }
 
 
@@ -340,7 +338,7 @@
 
 static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
   Isolate* isolate = info->isolate();
-  CompilationZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+  ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
   PostponeInterruptsScope postpone(isolate);
 
   ASSERT(!isolate->global_context().is_null());
@@ -413,7 +411,8 @@
         String::cast(script->name())));
     GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
                    script,
-                   info->code()));
+                   info->code(),
+                   info));
   } else {
     PROFILE(isolate, CodeCreateEvent(
         info->is_eval()
@@ -422,7 +421,7 @@
         *info->code(),
         *result,
         isolate->heap()->empty_string()));
-    GDBJIT(AddCode(Handle<String>(), script, info->code()));
+    GDBJIT(AddCode(Handle<String>(), script, info->code(), info));
   }
 
   // Hint to the runtime system used when allocating space for initial
@@ -573,7 +572,7 @@
 bool Compiler::CompileLazy(CompilationInfo* info) {
   Isolate* isolate = info->isolate();
 
-  CompilationZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+  ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
 
   // The VM is in the COMPILER state until exiting this function.
   VMState state(isolate, COMPILER);
@@ -614,6 +613,7 @@
       RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
 
       if (info->IsOptimizing()) {
+        ASSERT(shared->scope_info() != SerializedScopeInfo::Empty());
         function->ReplaceCode(*code);
       } else {
         // Update the shared function info with the compiled code and the
@@ -655,9 +655,6 @@
             CompilationInfo optimized(function);
             optimized.SetOptimizing(AstNode::kNoNumber);
             return CompileLazy(&optimized);
-          } else if (isolate->compilation_cache()->ShouldOptimizeEagerly(
-              function)) {
-            isolate->runtime_profiler()->OptimizeSoon(*function);
           }
         }
       }
@@ -736,6 +733,7 @@
   function_info->set_start_position(lit->start_position());
   function_info->set_end_position(lit->end_position());
   function_info->set_is_expression(lit->is_expression());
+  function_info->set_is_anonymous(lit->is_anonymous());
   function_info->set_is_toplevel(is_toplevel);
   function_info->set_inferred_name(*lit->inferred_name());
   function_info->SetThisPropertyAssignmentsInfo(
@@ -743,6 +741,8 @@
       *lit->this_property_assignments());
   function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   function_info->set_strict_mode(lit->strict_mode());
+  function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
+  function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
 }
 
 
@@ -781,7 +781,8 @@
 
   GDBJIT(AddCode(Handle<String>(shared->DebugName()),
                  Handle<Script>(info->script()),
-                 Handle<Code>(info->code())));
+                 Handle<Code>(info->code()),
+                 info));
 }
 
 } }  // namespace v8::internal
diff --git a/src/compiler.h b/src/compiler.h
index ea74d60..181446b 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -167,6 +167,7 @@
 
   void Initialize(Mode mode) {
     mode_ = V8::UseCrankshaft() ? mode : NONOPT;
+    ASSERT(!script_.is_null());
     if (script_->type()->value() == Script::TYPE_NATIVE) {
       MarkAsNative();
     }
@@ -195,6 +196,7 @@
   // Is this a function from our natives.
   class IsNative: public BitField<bool, 6, 1> {};
 
+
   unsigned flags_;
 
   // Fields filled in by the compilation pipeline.
@@ -292,24 +294,6 @@
 };
 
 
-// During compilation we need a global list of handles to constants
-// for frame elements.  When the zone gets deleted, we make sure to
-// clear this list of handles as well.
-class CompilationZoneScope : public ZoneScope {
- public:
-  CompilationZoneScope(Isolate* isolate, ZoneScopeMode mode)
-      : ZoneScope(isolate, mode) {}
-
-  virtual ~CompilationZoneScope() {
-    if (ShouldDeleteOnExit()) {
-      Isolate* isolate = Isolate::Current();
-      isolate->frame_element_constant_list()->Clear();
-      isolate->result_constant_list()->Clear();
-    }
-  }
-};
-
-
 } }  // namespace v8::internal
 
 #endif  // V8_COMPILER_H_
diff --git a/src/contexts.cc b/src/contexts.cc
index f6031f1..d066d34 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -34,6 +34,16 @@
 namespace v8 {
 namespace internal {
 
+Context* Context::declaration_context() {
+  Context* current = this;
+  while (!current->IsFunctionContext() && !current->IsGlobalContext()) {
+    current = current->previous();
+    ASSERT(current->closure() == closure());
+  }
+  return current;
+}
+
+
 JSBuiltinsObject* Context::builtins() {
   GlobalObject* object = global();
   if (object->IsJSGlobalObject()) {
@@ -74,8 +84,10 @@
 }
 
 
-Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
-                               int* index_, PropertyAttributes* attributes) {
+Handle<Object> Context::Lookup(Handle<String> name,
+                               ContextLookupFlags flags,
+                               int* index_,
+                               PropertyAttributes* attributes) {
   Isolate* isolate = GetIsolate();
   Handle<Context> context(this, isolate);
 
@@ -96,40 +108,52 @@
       PrintF("\n");
     }
 
-    // check extension/with object
+    // Check extension/with/global object.
     if (context->has_extension()) {
-      Handle<JSObject> extension = Handle<JSObject>(context->extension(),
-                                                    isolate);
-      // 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.
-      if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
-          extension->IsJSContextExtensionObject()) {
-        *attributes = extension->GetLocalPropertyAttribute(*name);
-      } else {
-        *attributes = extension->GetPropertyAttribute(*name);
-      }
-      if (*attributes != ABSENT) {
-        // property found
-        if (FLAG_trace_contexts) {
-          PrintF("=> found property in context object %p\n",
-                 reinterpret_cast<void*>(*extension));
+      if (context->IsCatchContext()) {
+        // Catch contexts have the variable name in the extension slot.
+        if (name->Equals(String::cast(context->extension()))) {
+          if (FLAG_trace_contexts) {
+            PrintF("=> found in catch context\n");
+          }
+          *index_ = Context::THROWN_OBJECT_INDEX;
+          *attributes = NONE;
+          return context;
         }
-        return extension;
+      } else {
+        // Global, function, and with contexts may have an object in the
+        // extension slot.
+        Handle<JSObject> extension(JSObject::cast(context->extension()),
+                                   isolate);
+        // 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.
+        if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
+            extension->IsJSContextExtensionObject()) {
+          *attributes = extension->GetLocalPropertyAttribute(*name);
+        } else {
+          *attributes = extension->GetPropertyAttribute(*name);
+        }
+        if (*attributes != ABSENT) {
+          // property found
+          if (FLAG_trace_contexts) {
+            PrintF("=> found property in context object %p\n",
+                   reinterpret_cast<void*>(*extension));
+          }
+          return extension;
+        }
       }
     }
 
-    if (context->is_function_context()) {
-      // we have context-local slots
-
-      // check non-parameter locals in context
+    // Only functions can have locals, parameters, and a function name.
+    if (context->IsFunctionContext()) {
+      // We may have context-local slots.  Check locals in the context.
       Handle<SerializedScopeInfo> scope_info(
           context->closure()->shared()->scope_info(), isolate);
       Variable::Mode mode;
       int index = scope_info->ContextSlotIndex(*name, &mode);
       ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS);
       if (index >= 0) {
-        // slot found
         if (FLAG_trace_contexts) {
           PrintF("=> found local in context slot %d (mode = %d)\n",
                  index, mode);
@@ -142,39 +166,28 @@
         // declared variables that were introduced through declaration nodes)
         // must not appear here.
         switch (mode) {
-          case Variable::INTERNAL:  // fall through
-          case Variable::VAR: *attributes = NONE; break;
-          case Variable::CONST: *attributes = READ_ONLY; break;
-          case Variable::DYNAMIC: UNREACHABLE(); break;
-          case Variable::DYNAMIC_GLOBAL: UNREACHABLE(); break;
-          case Variable::DYNAMIC_LOCAL: UNREACHABLE(); break;
-          case Variable::TEMPORARY: UNREACHABLE(); break;
+          case Variable::INTERNAL:  // Fall through.
+          case Variable::VAR:
+            *attributes = NONE;
+            break;
+          case Variable::CONST:
+            *attributes = READ_ONLY;
+            break;
+          case Variable::DYNAMIC:
+          case Variable::DYNAMIC_GLOBAL:
+          case Variable::DYNAMIC_LOCAL:
+          case Variable::TEMPORARY:
+            UNREACHABLE();
+            break;
         }
         return context;
       }
 
-      // check parameter locals in context
-      int param_index = scope_info->ParameterIndex(*name);
-      if (param_index >= 0) {
-        // slot found.
-        int index = scope_info->ContextSlotIndex(
-            isolate->heap()->arguments_shadow_symbol(), NULL);
-        ASSERT(index >= 0);  // arguments must exist and be in the heap context
-        Handle<JSObject> arguments(JSObject::cast(context->get(index)),
-                                   isolate);
-        if (FLAG_trace_contexts) {
-          PrintF("=> found parameter %d in arguments object\n", param_index);
-        }
-        *index_ = param_index;
-        *attributes = NONE;
-        return arguments;
-      }
-
-      // check intermediate context (holding only the function name variable)
+      // Check the slot corresponding to the intermediate context holding
+      // only the function name variable.
       if (follow_context_chain) {
         int index = scope_info->FunctionContextSlotIndex(*name);
         if (index >= 0) {
-          // slot found
           if (FLAG_trace_contexts) {
             PrintF("=> found intermediate function in context slot %d\n",
                    index);
@@ -186,18 +199,14 @@
       }
     }
 
-    // proceed with enclosing context
+    // Proceed with the previous context.
     if (context->IsGlobalContext()) {
       follow_context_chain = false;
-    } else if (context->is_function_context()) {
-      context = Handle<Context>(Context::cast(context->closure()->context()),
-                                isolate);
     } else {
       context = Handle<Context>(context->previous(), isolate);
     }
   } while (follow_context_chain);
 
-  // slot not found
   if (FLAG_trace_contexts) {
     PrintF("=> no property/slot found\n");
   }
@@ -212,11 +221,12 @@
   // before the global context and check that there are no context
   // extension objects (conservative check for with statements).
   while (!context->IsGlobalContext()) {
-    // Check if the context is a potentially a with context.
+    // Check if the context is a catch or with context, or has introduced
+    // bindings by calling non-strict eval.
     if (context->has_extension()) return false;
 
     // Not a with context so it must be a function context.
-    ASSERT(context->is_function_context());
+    ASSERT(context->IsFunctionContext());
 
     // Check non-parameter locals.
     Handle<SerializedScopeInfo> scope_info(
@@ -233,7 +243,7 @@
     // Check context only holding the function name variable.
     index = scope_info->FunctionContextSlotIndex(*name);
     if (index >= 0) return false;
-    context = Context::cast(context->closure()->context());
+    context = context->previous();
   }
 
   // No local or potential with statement found so the variable is
@@ -244,21 +254,24 @@
 
 void Context::ComputeEvalScopeInfo(bool* outer_scope_calls_eval,
                                    bool* outer_scope_calls_non_strict_eval) {
+  // Skip up the context chain checking all the function contexts to see
+  // whether they call eval.
   Context* context = this;
-  while (true) {
-    Handle<SerializedScopeInfo> scope_info(
-        context->closure()->shared()->scope_info());
-    if (scope_info->CallsEval()) {
-      *outer_scope_calls_eval = true;
-      if (!scope_info->IsStrictMode()) {
-        // No need to go further since the answers will not change
-        // from here.
-        *outer_scope_calls_non_strict_eval = true;
-        return;
+  while (!context->IsGlobalContext()) {
+    if (context->IsFunctionContext()) {
+      Handle<SerializedScopeInfo> scope_info(
+          context->closure()->shared()->scope_info());
+      if (scope_info->CallsEval()) {
+        *outer_scope_calls_eval = true;
+        if (!scope_info->IsStrictMode()) {
+          // No need to go further since the answers will not change from
+          // here.
+          *outer_scope_calls_non_strict_eval = true;
+          return;
+        }
       }
     }
-    if (context->IsGlobalContext()) break;
-    context = Context::cast(context->closure()->context());
+    context = context->previous();
   }
 }
 
diff --git a/src/contexts.h b/src/contexts.h
index b0d3ae4..53b40f1 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -88,6 +88,8 @@
   V(JS_ARRAY_MAP_INDEX, Map, js_array_map)\
   V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)\
   V(ARGUMENTS_BOILERPLATE_INDEX, JSObject, arguments_boilerplate) \
+  V(ALIASED_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
+    aliased_arguments_boilerplate) \
   V(STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
     strict_mode_arguments_boilerplate) \
   V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
@@ -108,7 +110,9 @@
   V(MAP_CACHE_INDEX, Object, map_cache) \
   V(CONTEXT_DATA_INDEX, Object, data) \
   V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
-  V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap)
+  V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
+  V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
+  V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap)
 
 // JSFunctions are pairs (context, function code), sometimes also called
 // closures. A Context object is used to represent function contexts and
@@ -127,13 +131,6 @@
 //                statically allocated context slots. The names are needed
 //                for dynamic lookups in the presence of 'with' or 'eval'.
 //
-// [ fcontext  ]  A pointer to the innermost enclosing function context.
-//                It is the same for all contexts *allocated* inside a
-//                function, and the function context's fcontext points
-//                to itself. It is only needed for fast access of the
-//                function context (used for declarations, and static
-//                context slot access).
-//
 // [ previous  ]  A pointer to the previous context. It is NULL for
 //                function contexts, and non-NULL for 'with' contexts.
 //                Used to implement the 'with' statement.
@@ -155,19 +152,6 @@
 // (via static context addresses) or through 'eval' (dynamic context lookups).
 // Finally, the global context contains additional slots for fast access to
 // global properties.
-//
-// We may be able to simplify the implementation:
-//
-// - We may be able to get rid of 'fcontext': We can always use the fact that
-//   previous == NULL for function contexts and so we can search for them. They
-//   are only needed when doing dynamic declarations, and the context chains
-//   tend to be very very short (depth of nesting of 'with' statements). At
-//   the moment we also use it in generated code for context slot accesses -
-//   and there we don't want a loop because of code bloat - but we may not
-//   need it there after all (see comment in codegen_*.cc).
-//
-// - If we cannot get rid of fcontext, consider making 'previous' never NULL
-//   except for the global context. This could simplify Context::Lookup.
 
 class Context: public FixedArray {
  public:
@@ -181,16 +165,22 @@
   enum {
     // These slots are in all contexts.
     CLOSURE_INDEX,
-    FCONTEXT_INDEX,
     PREVIOUS_INDEX,
+    // The extension slot is used for either the global object (in global
+    // contexts), eval extension object (function contexts), subject of with
+    // (with contexts), or the variable name (catch contexts).
     EXTENSION_INDEX,
     GLOBAL_INDEX,
     MIN_CONTEXT_SLOTS,
 
+    // This slot holds the thrown value in catch contexts.
+    THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS,
+
     // These slots are only in global contexts.
     GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
     SECURITY_TOKEN_INDEX,
     ARGUMENTS_BOILERPLATE_INDEX,
+    ALIASED_ARGUMENTS_BOILERPLATE_INDEX,
     STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX,
     JS_ARRAY_MAP_INDEX,
     REGEXP_RESULT_MAP_INDEX,
@@ -236,14 +226,16 @@
     OPAQUE_REFERENCE_FUNCTION_INDEX,
     CONTEXT_EXTENSION_FUNCTION_INDEX,
     OUT_OF_MEMORY_INDEX,
-    MAP_CACHE_INDEX,
     CONTEXT_DATA_INDEX,
     ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
+    DERIVED_HAS_TRAP_INDEX,
     DERIVED_GET_TRAP_INDEX,
+    DERIVED_SET_TRAP_INDEX,
 
     // Properties from here are treated as weak references by the full GC.
     // Scavenge treats them as strong references.
     OPTIMIZED_FUNCTIONS_LIST,  // Weak.
+    MAP_CACHE_INDEX,  // Weak.
     NEXT_CONTEXT_LINK,  // Weak.
 
     // Total number of slots.
@@ -256,9 +248,6 @@
   JSFunction* closure() { return JSFunction::cast(get(CLOSURE_INDEX)); }
   void set_closure(JSFunction* closure) { set(CLOSURE_INDEX, closure); }
 
-  Context* fcontext() { return Context::cast(get(FCONTEXT_INDEX)); }
-  void set_fcontext(Context* context) { set(FCONTEXT_INDEX, context); }
-
   Context* previous() {
     Object* result = unchecked_previous();
     ASSERT(IsBootstrappingOrContext(result));
@@ -266,9 +255,13 @@
   }
   void set_previous(Context* context) { set(PREVIOUS_INDEX, context); }
 
-  bool has_extension() { return unchecked_extension() != NULL; }
-  JSObject* extension() { return JSObject::cast(unchecked_extension()); }
-  void set_extension(JSObject* object) { set(EXTENSION_INDEX, object); }
+  bool has_extension() { return extension() != NULL; }
+  Object* extension() { return get(EXTENSION_INDEX); }
+  void set_extension(Object* object) { set(EXTENSION_INDEX, object); }
+
+  // Get the context where var declarations will be hoisted to, which
+  // may be the context itself.
+  Context* declaration_context();
 
   GlobalObject* global() {
     Object* result = get(GLOBAL_INDEX);
@@ -287,8 +280,21 @@
   // Compute the global context by traversing the context chain.
   Context* global_context();
 
-  // Tells if this is a function context (as opposed to a 'with' context).
-  bool is_function_context() { return unchecked_previous() == NULL; }
+  // Predicates for context types.  IsGlobalContext is defined on Object
+  // because we frequently have to know if arbitrary objects are global
+  // contexts.
+  bool IsFunctionContext() {
+    Map* map = this->map();
+    return map == map->GetHeap()->function_context_map();
+  }
+  bool IsCatchContext() {
+    Map* map = this->map();
+    return map == map->GetHeap()->catch_context_map();
+  }
+  bool IsWithContext() {
+    Map* map = this->map();
+    return map == map->GetHeap()->with_context_map();
+  }
 
   // Tells whether the global context is marked with out of memory.
   inline bool has_out_of_memory();
@@ -377,7 +383,6 @@
  private:
   // Unchecked access to the slots.
   Object* unchecked_previous() { return get(PREVIOUS_INDEX); }
-  Object* unchecked_extension() { return get(EXTENSION_INDEX); }
 
 #ifdef DEBUG
   // Bootstrapping-aware type checks.
diff --git a/src/conversions-inl.h b/src/conversions-inl.h
index cb7dbf8..1a20645 100644
--- a/src/conversions-inl.h
+++ b/src/conversions-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -28,19 +28,26 @@
 #ifndef V8_CONVERSIONS_INL_H_
 #define V8_CONVERSIONS_INL_H_
 
+#include <limits.h>        // Required for INT_MAX etc.
 #include <math.h>
-#include <float.h>         // required for DBL_MAX and on Win32 for finite()
+#include <float.h>         // Required for DBL_MAX and on Win32 for finite()
 #include <stdarg.h>
 
 // ----------------------------------------------------------------------------
 // Extra POSIX/ANSI functions for Win32/MSVC.
 
 #include "conversions.h"
+#include "strtod.h"
 #include "platform.h"
 
 namespace v8 {
 namespace internal {
 
+static inline double JunkStringValue() {
+  return BitCast<double, uint64_t>(kQuietNaNMask);
+}
+
+
 // The fast double-to-unsigned-int conversion routine does not guarantee
 // rounding towards zero, or any reasonable value if the argument is larger
 // than what fits in an unsigned 32-bit integer.
@@ -77,18 +84,6 @@
 }
 
 
-int32_t NumberToInt32(Object* number) {
-  if (number->IsSmi()) return Smi::cast(number)->value();
-  return DoubleToInt32(number->Number());
-}
-
-
-uint32_t NumberToUint32(Object* number) {
-  if (number->IsSmi()) return Smi::cast(number)->value();
-  return DoubleToUint32(number->Number());
-}
-
-
 int32_t DoubleToInt32(double x) {
   int32_t i = FastD2I(x);
   if (FastI2D(i) == x) return i;
@@ -101,6 +96,569 @@
 }
 
 
+template <class Iterator, class EndMark>
+static bool SubStringEquals(Iterator* current,
+                            EndMark end,
+                            const char* substring) {
+  ASSERT(**current == *substring);
+  for (substring++; *substring != '\0'; substring++) {
+    ++*current;
+    if (*current == end || **current != *substring) return false;
+  }
+  ++*current;
+  return true;
+}
+
+
+// Returns true if a nonspace character has been found and false if the
+// end was been reached before finding a nonspace character.
+template <class Iterator, class EndMark>
+static inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
+                                     Iterator* current,
+                                     EndMark end) {
+  while (*current != end) {
+    if (!unicode_cache->IsWhiteSpace(**current)) return true;
+    ++*current;
+  }
+  return false;
+}
+
+
+// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
+template <int radix_log_2, class Iterator, class EndMark>
+static double InternalStringToIntDouble(UnicodeCache* unicode_cache,
+                                        Iterator current,
+                                        EndMark end,
+                                        bool negative,
+                                        bool allow_trailing_junk) {
+  ASSERT(current != end);
+
+  // Skip leading 0s.
+  while (*current == '0') {
+    ++current;
+    if (current == end) return SignedZero(negative);
+  }
+
+  int64_t number = 0;
+  int exponent = 0;
+  const int radix = (1 << radix_log_2);
+
+  do {
+    int digit;
+    if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
+      digit = static_cast<char>(*current) - '0';
+    } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
+      digit = static_cast<char>(*current) - 'a' + 10;
+    } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
+      digit = static_cast<char>(*current) - 'A' + 10;
+    } else {
+      if (allow_trailing_junk ||
+          !AdvanceToNonspace(unicode_cache, &current, end)) {
+        break;
+      } else {
+        return JunkStringValue();
+      }
+    }
+
+    number = number * radix + digit;
+    int overflow = static_cast<int>(number >> 53);
+    if (overflow != 0) {
+      // Overflow occurred. Need to determine which direction to round the
+      // result.
+      int overflow_bits_count = 1;
+      while (overflow > 1) {
+        overflow_bits_count++;
+        overflow >>= 1;
+      }
+
+      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
+      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
+      number >>= overflow_bits_count;
+      exponent = overflow_bits_count;
+
+      bool zero_tail = true;
+      while (true) {
+        ++current;
+        if (current == end || !isDigit(*current, radix)) break;
+        zero_tail = zero_tail && *current == '0';
+        exponent += radix_log_2;
+      }
+
+      if (!allow_trailing_junk &&
+          AdvanceToNonspace(unicode_cache, &current, end)) {
+        return JunkStringValue();
+      }
+
+      int middle_value = (1 << (overflow_bits_count - 1));
+      if (dropped_bits > middle_value) {
+        number++;  // Rounding up.
+      } else if (dropped_bits == middle_value) {
+        // Rounding to even to consistency with decimals: half-way case rounds
+        // up if significant part is odd and down otherwise.
+        if ((number & 1) != 0 || !zero_tail) {
+          number++;  // Rounding up.
+        }
+      }
+
+      // Rounding up may cause overflow.
+      if ((number & ((int64_t)1 << 53)) != 0) {
+        exponent++;
+        number >>= 1;
+      }
+      break;
+    }
+    ++current;
+  } while (current != end);
+
+  ASSERT(number < ((int64_t)1 << 53));
+  ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
+
+  if (exponent == 0) {
+    if (negative) {
+      if (number == 0) return -0.0;
+      number = -number;
+    }
+    return static_cast<double>(number);
+  }
+
+  ASSERT(number != 0);
+  // The double could be constructed faster from number (mantissa), exponent
+  // and sign. Assuming it's a rare case more simple code is used.
+  return static_cast<double>(negative ? -number : number) * pow(2.0, exponent);
+}
+
+
+template <class Iterator, class EndMark>
+static double InternalStringToInt(UnicodeCache* unicode_cache,
+                                  Iterator current,
+                                  EndMark end,
+                                  int radix) {
+  const bool allow_trailing_junk = true;
+  const double empty_string_val = JunkStringValue();
+
+  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
+    return empty_string_val;
+  }
+
+  bool negative = false;
+  bool leading_zero = false;
+
+  if (*current == '+') {
+    // Ignore leading sign; skip following spaces.
+    ++current;
+    if (current == end) {
+      return JunkStringValue();
+    }
+  } else if (*current == '-') {
+    ++current;
+    if (current == end) {
+      return JunkStringValue();
+    }
+    negative = true;
+  }
+
+  if (radix == 0) {
+    // Radix detection.
+    if (*current == '0') {
+      ++current;
+      if (current == end) return SignedZero(negative);
+      if (*current == 'x' || *current == 'X') {
+        radix = 16;
+        ++current;
+        if (current == end) return JunkStringValue();
+      } else {
+        radix = 8;
+        leading_zero = true;
+      }
+    } else {
+      radix = 10;
+    }
+  } else if (radix == 16) {
+    if (*current == '0') {
+      // Allow "0x" prefix.
+      ++current;
+      if (current == end) return SignedZero(negative);
+      if (*current == 'x' || *current == 'X') {
+        ++current;
+        if (current == end) return JunkStringValue();
+      } else {
+        leading_zero = true;
+      }
+    }
+  }
+
+  if (radix < 2 || radix > 36) return JunkStringValue();
+
+  // Skip leading zeros.
+  while (*current == '0') {
+    leading_zero = true;
+    ++current;
+    if (current == end) return SignedZero(negative);
+  }
+
+  if (!leading_zero && !isDigit(*current, radix)) {
+    return JunkStringValue();
+  }
+
+  if (IsPowerOf2(radix)) {
+    switch (radix) {
+      case 2:
+        return InternalStringToIntDouble<1>(
+            unicode_cache, current, end, negative, allow_trailing_junk);
+      case 4:
+        return InternalStringToIntDouble<2>(
+            unicode_cache, current, end, negative, allow_trailing_junk);
+      case 8:
+        return InternalStringToIntDouble<3>(
+            unicode_cache, current, end, negative, allow_trailing_junk);
+
+      case 16:
+        return InternalStringToIntDouble<4>(
+            unicode_cache, current, end, negative, allow_trailing_junk);
+
+      case 32:
+        return InternalStringToIntDouble<5>(
+            unicode_cache, current, end, negative, allow_trailing_junk);
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  if (radix == 10) {
+    // Parsing with strtod.
+    const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308.
+    // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
+    // end.
+    const int kBufferSize = kMaxSignificantDigits + 2;
+    char buffer[kBufferSize];
+    int buffer_pos = 0;
+    while (*current >= '0' && *current <= '9') {
+      if (buffer_pos <= kMaxSignificantDigits) {
+        // If the number has more than kMaxSignificantDigits it will be parsed
+        // as infinity.
+        ASSERT(buffer_pos < kBufferSize);
+        buffer[buffer_pos++] = static_cast<char>(*current);
+      }
+      ++current;
+      if (current == end) break;
+    }
+
+    if (!allow_trailing_junk &&
+        AdvanceToNonspace(unicode_cache, &current, end)) {
+      return JunkStringValue();
+    }
+
+    ASSERT(buffer_pos < kBufferSize);
+    buffer[buffer_pos] = '\0';
+    Vector<const char> buffer_vector(buffer, buffer_pos);
+    return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
+  }
+
+  // The following code causes accumulating rounding error for numbers greater
+  // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
+  // 16, or 32, then mathInt may be an implementation-dependent approximation to
+  // the mathematical integer value" (15.1.2.2).
+
+  int lim_0 = '0' + (radix < 10 ? radix : 10);
+  int lim_a = 'a' + (radix - 10);
+  int lim_A = 'A' + (radix - 10);
+
+  // NOTE: The code for computing the value may seem a bit complex at
+  // first glance. It is structured to use 32-bit multiply-and-add
+  // loops as long as possible to avoid loosing precision.
+
+  double v = 0.0;
+  bool done = false;
+  do {
+    // Parse the longest part of the string starting at index j
+    // possible while keeping the multiplier, and thus the part
+    // itself, within 32 bits.
+    unsigned int part = 0, multiplier = 1;
+    while (true) {
+      int d;
+      if (*current >= '0' && *current < lim_0) {
+        d = *current - '0';
+      } else if (*current >= 'a' && *current < lim_a) {
+        d = *current - 'a' + 10;
+      } else if (*current >= 'A' && *current < lim_A) {
+        d = *current - 'A' + 10;
+      } else {
+        done = true;
+        break;
+      }
+
+      // Update the value of the part as long as the multiplier fits
+      // in 32 bits. When we can't guarantee that the next iteration
+      // will not overflow the multiplier, we stop parsing the part
+      // by leaving the loop.
+      const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
+      uint32_t m = multiplier * radix;
+      if (m > kMaximumMultiplier) break;
+      part = part * radix + d;
+      multiplier = m;
+      ASSERT(multiplier > part);
+
+      ++current;
+      if (current == end) {
+        done = true;
+        break;
+      }
+    }
+
+    // Update the value and skip the part in the string.
+    v = v * multiplier + part;
+  } while (!done);
+
+  if (!allow_trailing_junk &&
+      AdvanceToNonspace(unicode_cache, &current, end)) {
+    return JunkStringValue();
+  }
+
+  return negative ? -v : v;
+}
+
+
+// Converts a string to a double value. Assumes the Iterator supports
+// the following operations:
+// 1. current == end (other ops are not allowed), current != end.
+// 2. *current - gets the current character in the sequence.
+// 3. ++current (advances the position).
+template <class Iterator, class EndMark>
+static double InternalStringToDouble(UnicodeCache* unicode_cache,
+                                     Iterator current,
+                                     EndMark end,
+                                     int flags,
+                                     double empty_string_val) {
+  // To make sure that iterator dereferencing is valid the following
+  // convention is used:
+  // 1. Each '++current' statement is followed by check for equality to 'end'.
+  // 2. If AdvanceToNonspace returned false then current == end.
+  // 3. If 'current' becomes be equal to 'end' the function returns or goes to
+  // 'parsing_done'.
+  // 4. 'current' is not dereferenced after the 'parsing_done' label.
+  // 5. Code before 'parsing_done' may rely on 'current != end'.
+  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
+    return empty_string_val;
+  }
+
+  const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
+
+  // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
+  const int kBufferSize = kMaxSignificantDigits + 10;
+  char buffer[kBufferSize];  // NOLINT: size is known at compile time.
+  int buffer_pos = 0;
+
+  // Exponent will be adjusted if insignificant digits of the integer part
+  // or insignificant leading zeros of the fractional part are dropped.
+  int exponent = 0;
+  int significant_digits = 0;
+  int insignificant_digits = 0;
+  bool nonzero_digit_dropped = false;
+
+  bool negative = false;
+
+  if (*current == '+') {
+    // Ignore leading sign.
+    ++current;
+    if (current == end) return JunkStringValue();
+  } else if (*current == '-') {
+    ++current;
+    if (current == end) return JunkStringValue();
+    negative = true;
+  }
+
+  static const char kInfinitySymbol[] = "Infinity";
+  if (*current == kInfinitySymbol[0]) {
+    if (!SubStringEquals(&current, end, kInfinitySymbol)) {
+      return JunkStringValue();
+    }
+
+    if (!allow_trailing_junk &&
+        AdvanceToNonspace(unicode_cache, &current, end)) {
+      return JunkStringValue();
+    }
+
+    ASSERT(buffer_pos == 0);
+    return negative ? -V8_INFINITY : V8_INFINITY;
+  }
+
+  bool leading_zero = false;
+  if (*current == '0') {
+    ++current;
+    if (current == end) return SignedZero(negative);
+
+    leading_zero = true;
+
+    // It could be hexadecimal value.
+    if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
+      ++current;
+      if (current == end || !isDigit(*current, 16)) {
+        return JunkStringValue();  // "0x".
+      }
+
+      return InternalStringToIntDouble<4>(unicode_cache,
+                                          current,
+                                          end,
+                                          negative,
+                                          allow_trailing_junk);
+    }
+
+    // Ignore leading zeros in the integer part.
+    while (*current == '0') {
+      ++current;
+      if (current == end) return SignedZero(negative);
+    }
+  }
+
+  bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0;
+
+  // Copy significant digits of the integer part (if any) to the buffer.
+  while (*current >= '0' && *current <= '9') {
+    if (significant_digits < kMaxSignificantDigits) {
+      ASSERT(buffer_pos < kBufferSize);
+      buffer[buffer_pos++] = static_cast<char>(*current);
+      significant_digits++;
+      // Will later check if it's an octal in the buffer.
+    } else {
+      insignificant_digits++;  // Move the digit into the exponential part.
+      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
+    }
+    octal = octal && *current < '8';
+    ++current;
+    if (current == end) goto parsing_done;
+  }
+
+  if (significant_digits == 0) {
+    octal = false;
+  }
+
+  if (*current == '.') {
+    if (octal && !allow_trailing_junk) return JunkStringValue();
+    if (octal) goto parsing_done;
+
+    ++current;
+    if (current == end) {
+      if (significant_digits == 0 && !leading_zero) {
+        return JunkStringValue();
+      } else {
+        goto parsing_done;
+      }
+    }
+
+    if (significant_digits == 0) {
+      // octal = false;
+      // Integer part consists of 0 or is absent. Significant digits start after
+      // leading zeros (if any).
+      while (*current == '0') {
+        ++current;
+        if (current == end) return SignedZero(negative);
+        exponent--;  // Move this 0 into the exponent.
+      }
+    }
+
+    // There is a fractional part.  We don't emit a '.', but adjust the exponent
+    // instead.
+    while (*current >= '0' && *current <= '9') {
+      if (significant_digits < kMaxSignificantDigits) {
+        ASSERT(buffer_pos < kBufferSize);
+        buffer[buffer_pos++] = static_cast<char>(*current);
+        significant_digits++;
+        exponent--;
+      } else {
+        // Ignore insignificant digits in the fractional part.
+        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
+      }
+      ++current;
+      if (current == end) goto parsing_done;
+    }
+  }
+
+  if (!leading_zero && exponent == 0 && significant_digits == 0) {
+    // If leading_zeros is true then the string contains zeros.
+    // If exponent < 0 then string was [+-]\.0*...
+    // If significant_digits != 0 the string is not equal to 0.
+    // Otherwise there are no digits in the string.
+    return JunkStringValue();
+  }
+
+  // Parse exponential part.
+  if (*current == 'e' || *current == 'E') {
+    if (octal) return JunkStringValue();
+    ++current;
+    if (current == end) {
+      if (allow_trailing_junk) {
+        goto parsing_done;
+      } else {
+        return JunkStringValue();
+      }
+    }
+    char sign = '+';
+    if (*current == '+' || *current == '-') {
+      sign = static_cast<char>(*current);
+      ++current;
+      if (current == end) {
+        if (allow_trailing_junk) {
+          goto parsing_done;
+        } else {
+          return JunkStringValue();
+        }
+      }
+    }
+
+    if (current == end || *current < '0' || *current > '9') {
+      if (allow_trailing_junk) {
+        goto parsing_done;
+      } else {
+        return JunkStringValue();
+      }
+    }
+
+    const int max_exponent = INT_MAX / 2;
+    ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
+    int num = 0;
+    do {
+      // Check overflow.
+      int digit = *current - '0';
+      if (num >= max_exponent / 10
+          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
+        num = max_exponent;
+      } else {
+        num = num * 10 + digit;
+      }
+      ++current;
+    } while (current != end && *current >= '0' && *current <= '9');
+
+    exponent += (sign == '-' ? -num : num);
+  }
+
+  if (!allow_trailing_junk &&
+      AdvanceToNonspace(unicode_cache, &current, end)) {
+    return JunkStringValue();
+  }
+
+  parsing_done:
+  exponent += insignificant_digits;
+
+  if (octal) {
+    return InternalStringToIntDouble<3>(unicode_cache,
+                                        buffer,
+                                        buffer + buffer_pos,
+                                        negative,
+                                        allow_trailing_junk);
+  }
+
+  if (nonzero_digit_dropped) {
+    buffer[buffer_pos++] = '1';
+    exponent--;
+  }
+
+  ASSERT(buffer_pos < kBufferSize);
+  buffer[buffer_pos] = '\0';
+
+  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
+  return negative ? -converted : converted;
+}
+
 } }  // namespace v8::internal
 
 #endif  // V8_CONVERSIONS_INL_H_
diff --git a/src/conversions.cc b/src/conversions.cc
index 353b681..c34fe51 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -28,693 +28,15 @@
 #include <stdarg.h>
 #include <limits.h>
 
-#include "v8.h"
-
 #include "conversions-inl.h"
 #include "dtoa.h"
-#include "factory.h"
 #include "scanner-base.h"
 #include "strtod.h"
+#include "utils.h"
 
 namespace v8 {
 namespace internal {
 
-namespace {
-
-// C++-style iterator adaptor for StringInputBuffer
-// (unlike C++ iterators the end-marker has different type).
-class StringInputBufferIterator {
- public:
-  class EndMarker {};
-
-  explicit StringInputBufferIterator(StringInputBuffer* buffer);
-
-  int operator*() const;
-  void operator++();
-  bool operator==(EndMarker const&) const { return end_; }
-  bool operator!=(EndMarker const& m) const { return !end_; }
-
- private:
-  StringInputBuffer* const buffer_;
-  int current_;
-  bool end_;
-};
-
-
-StringInputBufferIterator::StringInputBufferIterator(
-    StringInputBuffer* buffer) : buffer_(buffer) {
-  ++(*this);
-}
-
-int StringInputBufferIterator::operator*() const {
-  return current_;
-}
-
-
-void StringInputBufferIterator::operator++() {
-  end_ = !buffer_->has_more();
-  if (!end_) {
-    current_ = buffer_->GetNext();
-  }
-}
-}
-
-
-template <class Iterator, class EndMark>
-static bool SubStringEquals(Iterator* current,
-                            EndMark end,
-                            const char* substring) {
-  ASSERT(**current == *substring);
-  for (substring++; *substring != '\0'; substring++) {
-    ++*current;
-    if (*current == end || **current != *substring) return false;
-  }
-  ++*current;
-  return true;
-}
-
-
-// Maximum number of significant digits in decimal representation.
-// The longest possible double in decimal representation is
-// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
-// (768 digits). If we parse a number whose first digits are equal to a
-// mean of 2 adjacent doubles (that could have up to 769 digits) the result
-// must be rounded to the bigger one unless the tail consists of zeros, so
-// we don't need to preserve all the digits.
-const int kMaxSignificantDigits = 772;
-
-
-static const double JUNK_STRING_VALUE = OS::nan_value();
-
-
-// Returns true if a nonspace found and false if the end has reached.
-template <class Iterator, class EndMark>
-static inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
-                                     Iterator* current,
-                                     EndMark end) {
-  while (*current != end) {
-    if (!unicode_cache->IsWhiteSpace(**current)) return true;
-    ++*current;
-  }
-  return false;
-}
-
-
-static bool isDigit(int x, int radix) {
-  return (x >= '0' && x <= '9' && x < '0' + radix)
-      || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
-      || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
-}
-
-
-static double SignedZero(bool negative) {
-  return negative ? -0.0 : 0.0;
-}
-
-
-// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
-template <int radix_log_2, class Iterator, class EndMark>
-static double InternalStringToIntDouble(UnicodeCache* unicode_cache,
-                                        Iterator current,
-                                        EndMark end,
-                                        bool negative,
-                                        bool allow_trailing_junk) {
-  ASSERT(current != end);
-
-  // Skip leading 0s.
-  while (*current == '0') {
-    ++current;
-    if (current == end) return SignedZero(negative);
-  }
-
-  int64_t number = 0;
-  int exponent = 0;
-  const int radix = (1 << radix_log_2);
-
-  do {
-    int digit;
-    if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
-      digit = static_cast<char>(*current) - '0';
-    } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
-      digit = static_cast<char>(*current) - 'a' + 10;
-    } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
-      digit = static_cast<char>(*current) - 'A' + 10;
-    } else {
-      if (allow_trailing_junk ||
-          !AdvanceToNonspace(unicode_cache, &current, end)) {
-        break;
-      } else {
-        return JUNK_STRING_VALUE;
-      }
-    }
-
-    number = number * radix + digit;
-    int overflow = static_cast<int>(number >> 53);
-    if (overflow != 0) {
-      // Overflow occurred. Need to determine which direction to round the
-      // result.
-      int overflow_bits_count = 1;
-      while (overflow > 1) {
-        overflow_bits_count++;
-        overflow >>= 1;
-      }
-
-      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
-      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
-      number >>= overflow_bits_count;
-      exponent = overflow_bits_count;
-
-      bool zero_tail = true;
-      while (true) {
-        ++current;
-        if (current == end || !isDigit(*current, radix)) break;
-        zero_tail = zero_tail && *current == '0';
-        exponent += radix_log_2;
-      }
-
-      if (!allow_trailing_junk &&
-          AdvanceToNonspace(unicode_cache, &current, end)) {
-        return JUNK_STRING_VALUE;
-      }
-
-      int middle_value = (1 << (overflow_bits_count - 1));
-      if (dropped_bits > middle_value) {
-        number++;  // Rounding up.
-      } else if (dropped_bits == middle_value) {
-        // Rounding to even to consistency with decimals: half-way case rounds
-        // up if significant part is odd and down otherwise.
-        if ((number & 1) != 0 || !zero_tail) {
-          number++;  // Rounding up.
-        }
-      }
-
-      // Rounding up may cause overflow.
-      if ((number & ((int64_t)1 << 53)) != 0) {
-        exponent++;
-        number >>= 1;
-      }
-      break;
-    }
-    ++current;
-  } while (current != end);
-
-  ASSERT(number < ((int64_t)1 << 53));
-  ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
-
-  if (exponent == 0) {
-    if (negative) {
-      if (number == 0) return -0.0;
-      number = -number;
-    }
-    return static_cast<double>(number);
-  }
-
-  ASSERT(number != 0);
-  // The double could be constructed faster from number (mantissa), exponent
-  // and sign. Assuming it's a rare case more simple code is used.
-  return static_cast<double>(negative ? -number : number) * pow(2.0, exponent);
-}
-
-
-template <class Iterator, class EndMark>
-static double InternalStringToInt(UnicodeCache* unicode_cache,
-                                  Iterator current,
-                                  EndMark end,
-                                  int radix) {
-  const bool allow_trailing_junk = true;
-  const double empty_string_val = JUNK_STRING_VALUE;
-
-  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
-    return empty_string_val;
-  }
-
-  bool negative = false;
-  bool leading_zero = false;
-
-  if (*current == '+') {
-    // Ignore leading sign; skip following spaces.
-    ++current;
-    if (current == end) {
-      return JUNK_STRING_VALUE;
-    }
-  } else if (*current == '-') {
-    ++current;
-    if (current == end) {
-      return JUNK_STRING_VALUE;
-    }
-    negative = true;
-  }
-
-  if (radix == 0) {
-    // Radix detection.
-    if (*current == '0') {
-      ++current;
-      if (current == end) return SignedZero(negative);
-      if (*current == 'x' || *current == 'X') {
-        radix = 16;
-        ++current;
-        if (current == end) return JUNK_STRING_VALUE;
-      } else {
-        radix = 8;
-        leading_zero = true;
-      }
-    } else {
-      radix = 10;
-    }
-  } else if (radix == 16) {
-    if (*current == '0') {
-      // Allow "0x" prefix.
-      ++current;
-      if (current == end) return SignedZero(negative);
-      if (*current == 'x' || *current == 'X') {
-        ++current;
-        if (current == end) return JUNK_STRING_VALUE;
-      } else {
-        leading_zero = true;
-      }
-    }
-  }
-
-  if (radix < 2 || radix > 36) return JUNK_STRING_VALUE;
-
-  // Skip leading zeros.
-  while (*current == '0') {
-    leading_zero = true;
-    ++current;
-    if (current == end) return SignedZero(negative);
-  }
-
-  if (!leading_zero && !isDigit(*current, radix)) {
-    return JUNK_STRING_VALUE;
-  }
-
-  if (IsPowerOf2(radix)) {
-    switch (radix) {
-      case 2:
-        return InternalStringToIntDouble<1>(
-            unicode_cache, current, end, negative, allow_trailing_junk);
-      case 4:
-        return InternalStringToIntDouble<2>(
-            unicode_cache, current, end, negative, allow_trailing_junk);
-      case 8:
-        return InternalStringToIntDouble<3>(
-            unicode_cache, current, end, negative, allow_trailing_junk);
-
-      case 16:
-        return InternalStringToIntDouble<4>(
-            unicode_cache, current, end, negative, allow_trailing_junk);
-
-      case 32:
-        return InternalStringToIntDouble<5>(
-            unicode_cache, current, end, negative, allow_trailing_junk);
-      default:
-        UNREACHABLE();
-    }
-  }
-
-  if (radix == 10) {
-    // Parsing with strtod.
-    const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308.
-    // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
-    // end.
-    const int kBufferSize = kMaxSignificantDigits + 2;
-    char buffer[kBufferSize];
-    int buffer_pos = 0;
-    while (*current >= '0' && *current <= '9') {
-      if (buffer_pos <= kMaxSignificantDigits) {
-        // If the number has more than kMaxSignificantDigits it will be parsed
-        // as infinity.
-        ASSERT(buffer_pos < kBufferSize);
-        buffer[buffer_pos++] = static_cast<char>(*current);
-      }
-      ++current;
-      if (current == end) break;
-    }
-
-    if (!allow_trailing_junk &&
-        AdvanceToNonspace(unicode_cache, &current, end)) {
-      return JUNK_STRING_VALUE;
-    }
-
-    ASSERT(buffer_pos < kBufferSize);
-    buffer[buffer_pos] = '\0';
-    Vector<const char> buffer_vector(buffer, buffer_pos);
-    return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
-  }
-
-  // The following code causes accumulating rounding error for numbers greater
-  // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
-  // 16, or 32, then mathInt may be an implementation-dependent approximation to
-  // the mathematical integer value" (15.1.2.2).
-
-  int lim_0 = '0' + (radix < 10 ? radix : 10);
-  int lim_a = 'a' + (radix - 10);
-  int lim_A = 'A' + (radix - 10);
-
-  // NOTE: The code for computing the value may seem a bit complex at
-  // first glance. It is structured to use 32-bit multiply-and-add
-  // loops as long as possible to avoid loosing precision.
-
-  double v = 0.0;
-  bool done = false;
-  do {
-    // Parse the longest part of the string starting at index j
-    // possible while keeping the multiplier, and thus the part
-    // itself, within 32 bits.
-    unsigned int part = 0, multiplier = 1;
-    while (true) {
-      int d;
-      if (*current >= '0' && *current < lim_0) {
-        d = *current - '0';
-      } else if (*current >= 'a' && *current < lim_a) {
-        d = *current - 'a' + 10;
-      } else if (*current >= 'A' && *current < lim_A) {
-        d = *current - 'A' + 10;
-      } else {
-        done = true;
-        break;
-      }
-
-      // Update the value of the part as long as the multiplier fits
-      // in 32 bits. When we can't guarantee that the next iteration
-      // will not overflow the multiplier, we stop parsing the part
-      // by leaving the loop.
-      const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
-      uint32_t m = multiplier * radix;
-      if (m > kMaximumMultiplier) break;
-      part = part * radix + d;
-      multiplier = m;
-      ASSERT(multiplier > part);
-
-      ++current;
-      if (current == end) {
-        done = true;
-        break;
-      }
-    }
-
-    // Update the value and skip the part in the string.
-    v = v * multiplier + part;
-  } while (!done);
-
-  if (!allow_trailing_junk &&
-      AdvanceToNonspace(unicode_cache, &current, end)) {
-    return JUNK_STRING_VALUE;
-  }
-
-  return negative ? -v : v;
-}
-
-
-// Converts a string to a double value. Assumes the Iterator supports
-// the following operations:
-// 1. current == end (other ops are not allowed), current != end.
-// 2. *current - gets the current character in the sequence.
-// 3. ++current (advances the position).
-template <class Iterator, class EndMark>
-static double InternalStringToDouble(UnicodeCache* unicode_cache,
-                                     Iterator current,
-                                     EndMark end,
-                                     int flags,
-                                     double empty_string_val) {
-  // To make sure that iterator dereferencing is valid the following
-  // convention is used:
-  // 1. Each '++current' statement is followed by check for equality to 'end'.
-  // 2. If AdvanceToNonspace returned false then current == end.
-  // 3. If 'current' becomes be equal to 'end' the function returns or goes to
-  // 'parsing_done'.
-  // 4. 'current' is not dereferenced after the 'parsing_done' label.
-  // 5. Code before 'parsing_done' may rely on 'current != end'.
-  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
-    return empty_string_val;
-  }
-
-  const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
-
-  // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
-  const int kBufferSize = kMaxSignificantDigits + 10;
-  char buffer[kBufferSize];  // NOLINT: size is known at compile time.
-  int buffer_pos = 0;
-
-  // Exponent will be adjusted if insignificant digits of the integer part
-  // or insignificant leading zeros of the fractional part are dropped.
-  int exponent = 0;
-  int significant_digits = 0;
-  int insignificant_digits = 0;
-  bool nonzero_digit_dropped = false;
-  bool fractional_part = false;
-
-  bool negative = false;
-
-  if (*current == '+') {
-    // Ignore leading sign.
-    ++current;
-    if (current == end) return JUNK_STRING_VALUE;
-  } else if (*current == '-') {
-    ++current;
-    if (current == end) return JUNK_STRING_VALUE;
-    negative = true;
-  }
-
-  static const char kInfinitySymbol[] = "Infinity";
-  if (*current == kInfinitySymbol[0]) {
-    if (!SubStringEquals(&current, end, kInfinitySymbol)) {
-      return JUNK_STRING_VALUE;
-    }
-
-    if (!allow_trailing_junk &&
-        AdvanceToNonspace(unicode_cache, &current, end)) {
-      return JUNK_STRING_VALUE;
-    }
-
-    ASSERT(buffer_pos == 0);
-    return negative ? -V8_INFINITY : V8_INFINITY;
-  }
-
-  bool leading_zero = false;
-  if (*current == '0') {
-    ++current;
-    if (current == end) return SignedZero(negative);
-
-    leading_zero = true;
-
-    // It could be hexadecimal value.
-    if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
-      ++current;
-      if (current == end || !isDigit(*current, 16)) {
-        return JUNK_STRING_VALUE;  // "0x".
-      }
-
-      return InternalStringToIntDouble<4>(unicode_cache,
-                                          current,
-                                          end,
-                                          negative,
-                                          allow_trailing_junk);
-    }
-
-    // Ignore leading zeros in the integer part.
-    while (*current == '0') {
-      ++current;
-      if (current == end) return SignedZero(negative);
-    }
-  }
-
-  bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0;
-
-  // Copy significant digits of the integer part (if any) to the buffer.
-  while (*current >= '0' && *current <= '9') {
-    if (significant_digits < kMaxSignificantDigits) {
-      ASSERT(buffer_pos < kBufferSize);
-      buffer[buffer_pos++] = static_cast<char>(*current);
-      significant_digits++;
-      // Will later check if it's an octal in the buffer.
-    } else {
-      insignificant_digits++;  // Move the digit into the exponential part.
-      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
-    }
-    octal = octal && *current < '8';
-    ++current;
-    if (current == end) goto parsing_done;
-  }
-
-  if (significant_digits == 0) {
-    octal = false;
-  }
-
-  if (*current == '.') {
-    if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE;
-    if (octal) goto parsing_done;
-
-    ++current;
-    if (current == end) {
-      if (significant_digits == 0 && !leading_zero) {
-        return JUNK_STRING_VALUE;
-      } else {
-        goto parsing_done;
-      }
-    }
-
-    if (significant_digits == 0) {
-      // octal = false;
-      // Integer part consists of 0 or is absent. Significant digits start after
-      // leading zeros (if any).
-      while (*current == '0') {
-        ++current;
-        if (current == end) return SignedZero(negative);
-        exponent--;  // Move this 0 into the exponent.
-      }
-    }
-
-    // We don't emit a '.', but adjust the exponent instead.
-    fractional_part = true;
-
-    // There is a fractional part.
-    while (*current >= '0' && *current <= '9') {
-      if (significant_digits < kMaxSignificantDigits) {
-        ASSERT(buffer_pos < kBufferSize);
-        buffer[buffer_pos++] = static_cast<char>(*current);
-        significant_digits++;
-        exponent--;
-      } else {
-        // Ignore insignificant digits in the fractional part.
-        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
-      }
-      ++current;
-      if (current == end) goto parsing_done;
-    }
-  }
-
-  if (!leading_zero && exponent == 0 && significant_digits == 0) {
-    // If leading_zeros is true then the string contains zeros.
-    // If exponent < 0 then string was [+-]\.0*...
-    // If significant_digits != 0 the string is not equal to 0.
-    // Otherwise there are no digits in the string.
-    return JUNK_STRING_VALUE;
-  }
-
-  // Parse exponential part.
-  if (*current == 'e' || *current == 'E') {
-    if (octal) return JUNK_STRING_VALUE;
-    ++current;
-    if (current == end) {
-      if (allow_trailing_junk) {
-        goto parsing_done;
-      } else {
-        return JUNK_STRING_VALUE;
-      }
-    }
-    char sign = '+';
-    if (*current == '+' || *current == '-') {
-      sign = static_cast<char>(*current);
-      ++current;
-      if (current == end) {
-        if (allow_trailing_junk) {
-          goto parsing_done;
-        } else {
-          return JUNK_STRING_VALUE;
-        }
-      }
-    }
-
-    if (current == end || *current < '0' || *current > '9') {
-      if (allow_trailing_junk) {
-        goto parsing_done;
-      } else {
-        return JUNK_STRING_VALUE;
-      }
-    }
-
-    const int max_exponent = INT_MAX / 2;
-    ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
-    int num = 0;
-    do {
-      // Check overflow.
-      int digit = *current - '0';
-      if (num >= max_exponent / 10
-          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
-        num = max_exponent;
-      } else {
-        num = num * 10 + digit;
-      }
-      ++current;
-    } while (current != end && *current >= '0' && *current <= '9');
-
-    exponent += (sign == '-' ? -num : num);
-  }
-
-  if (!allow_trailing_junk &&
-      AdvanceToNonspace(unicode_cache, &current, end)) {
-    return JUNK_STRING_VALUE;
-  }
-
-  parsing_done:
-  exponent += insignificant_digits;
-
-  if (octal) {
-    return InternalStringToIntDouble<3>(unicode_cache,
-                                        buffer,
-                                        buffer + buffer_pos,
-                                        negative,
-                                        allow_trailing_junk);
-  }
-
-  if (nonzero_digit_dropped) {
-    buffer[buffer_pos++] = '1';
-    exponent--;
-  }
-
-  ASSERT(buffer_pos < kBufferSize);
-  buffer[buffer_pos] = '\0';
-
-  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
-  return negative ? -converted : converted;
-}
-
-
-double StringToDouble(UnicodeCache* unicode_cache,
-                      String* str, int flags, double empty_string_val) {
-  StringShape shape(str);
-  if (shape.IsSequentialAscii()) {
-    const char* begin = SeqAsciiString::cast(str)->GetChars();
-    const char* end = begin + str->length();
-    return InternalStringToDouble(unicode_cache, begin, end, flags,
-                                  empty_string_val);
-  } else if (shape.IsSequentialTwoByte()) {
-    const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
-    const uc16* end = begin + str->length();
-    return InternalStringToDouble(unicode_cache, begin, end, flags,
-                                  empty_string_val);
-  } else {
-    StringInputBuffer buffer(str);
-    return InternalStringToDouble(unicode_cache,
-                                  StringInputBufferIterator(&buffer),
-                                  StringInputBufferIterator::EndMarker(),
-                                  flags,
-                                  empty_string_val);
-  }
-}
-
-
-double StringToInt(UnicodeCache* unicode_cache,
-                   String* str,
-                   int radix) {
-  StringShape shape(str);
-  if (shape.IsSequentialAscii()) {
-    const char* begin = SeqAsciiString::cast(str)->GetChars();
-    const char* end = begin + str->length();
-    return InternalStringToInt(unicode_cache, begin, end, radix);
-  } else if (shape.IsSequentialTwoByte()) {
-    const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
-    const uc16* end = begin + str->length();
-    return InternalStringToInt(unicode_cache, begin, end, radix);
-  } else {
-    StringInputBuffer buffer(str);
-    return InternalStringToInt(unicode_cache,
-                               StringInputBufferIterator(&buffer),
-                               StringInputBufferIterator::EndMarker(),
-                               radix);
-  }
-}
 
 
 double StringToDouble(UnicodeCache* unicode_cache,
@@ -750,7 +72,7 @@
     case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity");
     case FP_ZERO: return "0";
     default: {
-      StringBuilder builder(buffer.start(), buffer.length());
+      SimpleStringBuilder builder(buffer.start(), buffer.length());
       int decimal_point;
       int sign;
       const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
@@ -791,7 +113,7 @@
         builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
         int exponent = decimal_point - 1;
         if (exponent < 0) exponent = -exponent;
-        builder.AddFormatted("%d", exponent);
+        builder.AddDecimalInteger(exponent);
       }
     return builder.Finalize();
     }
@@ -869,7 +191,7 @@
 
   unsigned rep_length =
       zero_prefix_length + decimal_rep_length + zero_postfix_length;
-  StringBuilder rep_builder(rep_length + 1);
+  SimpleStringBuilder rep_builder(rep_length + 1);
   rep_builder.AddPadding('0', zero_prefix_length);
   rep_builder.AddString(decimal_rep);
   rep_builder.AddPadding('0', zero_postfix_length);
@@ -878,7 +200,7 @@
   // Create the result string by appending a minus and putting in a
   // decimal point if needed.
   unsigned result_size = decimal_point + f + 2;
-  StringBuilder builder(result_size + 1);
+  SimpleStringBuilder builder(result_size + 1);
   if (negative) builder.AddCharacter('-');
   builder.AddSubstring(rep, decimal_point);
   if (f > 0) {
@@ -904,7 +226,7 @@
   // letter 'e', a minus or a plus depending on the exponent, and a
   // three digit exponent.
   unsigned result_size = significant_digits + 7;
-  StringBuilder builder(result_size + 1);
+  SimpleStringBuilder builder(result_size + 1);
 
   if (negative) builder.AddCharacter('-');
   builder.AddCharacter(decimal_rep[0]);
@@ -917,7 +239,7 @@
 
   builder.AddCharacter('e');
   builder.AddCharacter(negative_exponent ? '-' : '+');
-  builder.AddFormatted("%d", exponent);
+  builder.AddDecimalInteger(exponent);
   return builder.Finalize();
 }
 
@@ -1009,7 +331,7 @@
     unsigned result_size = (decimal_point <= 0)
         ? -decimal_point + p + 3
         : p + 2;
-    StringBuilder builder(result_size + 1);
+    SimpleStringBuilder builder(result_size + 1);
     if (negative) builder.AddCharacter('-');
     if (decimal_point <= 0) {
       builder.AddString("0.");
@@ -1101,31 +423,11 @@
   // If the number has a decimal part, leave room for the period.
   if (decimal_pos > 0) result_size++;
   // Allocate result and fill in the parts.
-  StringBuilder builder(result_size + 1);
+  SimpleStringBuilder builder(result_size + 1);
   builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size);
   if (decimal_pos > 0) builder.AddCharacter('.');
   builder.AddSubstring(decimal_buffer, decimal_pos);
   return builder.Finalize();
 }
 
-
-static Mutex* dtoa_lock_one = OS::CreateMutex();
-static Mutex* dtoa_lock_zero = OS::CreateMutex();
-
-
 } }  // namespace v8::internal
-
-
-extern "C" {
-void ACQUIRE_DTOA_LOCK(int n) {
-  ASSERT(n == 0 || n == 1);
-  (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock();
-}
-
-
-void FREE_DTOA_LOCK(int n) {
-  ASSERT(n == 0 || n == 1);
-  (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->
-      Unlock();
-}
-}
diff --git a/src/conversions.h b/src/conversions.h
index 4cbeeca..9c0b8f3 100644
--- a/src/conversions.h
+++ b/src/conversions.h
@@ -29,10 +29,32 @@
 #define V8_CONVERSIONS_H_
 
 #include "scanner-base.h"
+#include "utils.h"
 
 namespace v8 {
 namespace internal {
 
+// Maximum number of significant digits in decimal representation.
+// The longest possible double in decimal representation is
+// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
+// (768 digits). If we parse a number whose first digits are equal to a
+// mean of 2 adjacent doubles (that could have up to 769 digits) the result
+// must be rounded to the bigger one unless the tail consists of zeros, so
+// we don't need to preserve all the digits.
+const int kMaxSignificantDigits = 772;
+
+
+static bool isDigit(int x, int radix) {
+  return (x >= '0' && x <= '9' && x < '0' + radix)
+      || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
+      || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
+}
+
+
+static double SignedZero(bool negative) {
+  return negative ? -0.0 : 0.0;
+}
+
 
 // The fast double-to-(unsigned-)int conversion routine does not guarantee
 // rounding towards zero.
@@ -87,17 +109,8 @@
 };
 
 
-// Convert from Number object to C integer.
-static inline int32_t NumberToInt32(Object* number);
-static inline uint32_t NumberToUint32(Object* number);
-
-
 // Converts a string into a double value according to ECMA-262 9.3.1
 double StringToDouble(UnicodeCache* unicode_cache,
-                      String* str,
-                      int flags,
-                      double empty_string_val = 0);
-double StringToDouble(UnicodeCache* unicode_cache,
                       Vector<const char> str,
                       int flags,
                       double empty_string_val = 0);
@@ -111,9 +124,6 @@
                       int flags,
                       double empty_string_val = 0);
 
-// Converts a string into an integer.
-double StringToInt(UnicodeCache* unicode_cache, String* str, int radix);
-
 // Converts a double to a string value according to ECMA-262 9.8.1.
 // The buffer should be large enough for any floating point number.
 // 100 characters is enough.
diff --git a/src/cpu-profiler-inl.h b/src/cpu-profiler-inl.h
index b704417..938b632 100644
--- a/src/cpu-profiler-inl.h
+++ b/src/cpu-profiler-inl.h
@@ -30,8 +30,7 @@
 
 #include "cpu-profiler.h"
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
+#include <new>
 #include "circular-queue-inl.h"
 #include "profile-generator-inl.h"
 #include "unbound-queue-inl.h"
@@ -62,24 +61,10 @@
 }
 
 
-TickSampleEventRecord* TickSampleEventRecord::init(void* value) {
-  TickSampleEventRecord* result =
-      reinterpret_cast<TickSampleEventRecord*>(value);
-  result->filler = 1;
-  ASSERT(result->filler != SamplingCircularQueue::kClear);
-  // Init the required fields only.
-  result->sample.pc = NULL;
-  result->sample.frames_count = 0;
-  result->sample.has_external_callback = false;
-  return result;
-}
-
-
 TickSample* ProfilerEventsProcessor::TickSampleEvent() {
   generator_->Tick();
   TickSampleEventRecord* evt =
-      TickSampleEventRecord::init(ticks_buffer_.Enqueue());
-  evt->order = enqueue_order_;  // No increment!
+      new(ticks_buffer_.Enqueue()) TickSampleEventRecord(enqueue_order_);
   return &evt->sample;
 }
 
@@ -96,6 +81,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 #endif  // V8_CPU_PROFILER_INL_H_
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index f54e3e8..bb480fc 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -29,8 +29,6 @@
 
 #include "cpu-profiler-inl.h"
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "frames-inl.h"
 #include "hashmap.h"
 #include "log-inl.h"
@@ -46,9 +44,8 @@
 static const int kTickSamplesBufferChunksCount = 16;
 
 
-ProfilerEventsProcessor::ProfilerEventsProcessor(Isolate* isolate,
-                                                 ProfileGenerator* generator)
-    : Thread(isolate, "v8:ProfEvntProc"),
+ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
+    : Thread("v8:ProfEvntProc"),
       generator_(generator),
       running_(true),
       ticks_buffer_(sizeof(TickSampleEventRecord),
@@ -182,20 +179,16 @@
 
 
 void ProfilerEventsProcessor::AddCurrentStack() {
-  TickSampleEventRecord record;
+  TickSampleEventRecord record(enqueue_order_);
   TickSample* sample = &record.sample;
   Isolate* isolate = Isolate::Current();
   sample->state = isolate->current_vm_state();
   sample->pc = reinterpret_cast<Address>(sample);  // Not NULL.
-  sample->tos = NULL;
-  sample->has_external_callback = false;
-  sample->frames_count = 0;
   for (StackTraceFrameIterator it(isolate);
        !it.done() && sample->frames_count < TickSample::kMaxFramesCount;
        it.Advance()) {
     sample->stack[sample->frames_count++] = it.frame()->pc();
   }
-  record.order = enqueue_order_;
   ticks_from_vm_buffer_.Enqueue(record);
 }
 
@@ -507,7 +500,7 @@
     saved_logging_nesting_ = isolate->logger()->logging_nesting_;
     isolate->logger()->logging_nesting_ = 0;
     generator_ = new ProfileGenerator(profiles_);
-    processor_ = new ProfilerEventsProcessor(isolate, generator_);
+    processor_ = new ProfilerEventsProcessor(generator_);
     NoBarrier_Store(&is_profiling_, true);
     processor_->Start();
     // Enumerate stuff we already have in the heap.
@@ -579,31 +572,21 @@
   logger->logging_nesting_ = saved_logging_nesting_;
 }
 
-} }  // namespace v8::internal
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
-namespace v8 {
-namespace internal {
 
 void CpuProfiler::Setup() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   if (isolate->cpu_profiler() == NULL) {
     isolate->set_cpu_profiler(new CpuProfiler());
   }
-#endif
 }
 
 
 void CpuProfiler::TearDown() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   if (isolate->cpu_profiler() != NULL) {
     delete isolate->cpu_profiler();
   }
   isolate->set_cpu_profiler(NULL);
-#endif
 }
 
 } }  // namespace v8::internal
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index f9f6167..4175e8f 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -28,8 +28,6 @@
 #ifndef V8_CPU_PROFILER_H_
 #define V8_CPU_PROFILER_H_
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "allocation.h"
 #include "atomicops.h"
 #include "circular-queue.h"
@@ -106,10 +104,14 @@
 };
 
 
-class TickSampleEventRecord BASE_EMBEDDED {
+class TickSampleEventRecord {
  public:
-  TickSampleEventRecord()
-      : filler(1) {
+  // The parameterless constructor is used when we dequeue data from
+  // the ticks buffer.
+  TickSampleEventRecord() { }
+  explicit TickSampleEventRecord(unsigned order)
+      : filler(1),
+        order(order) {
     ASSERT(filler != SamplingCircularQueue::kClear);
   }
 
@@ -125,8 +127,6 @@
   static TickSampleEventRecord* cast(void* value) {
     return reinterpret_cast<TickSampleEventRecord*>(value);
   }
-
-  INLINE(static TickSampleEventRecord* init(void* value));
 };
 
 
@@ -134,8 +134,7 @@
 // methods called by event producers: VM and stack sampler threads.
 class ProfilerEventsProcessor : public Thread {
  public:
-  ProfilerEventsProcessor(Isolate* isolate,
-                          ProfileGenerator* generator);
+  explicit ProfilerEventsProcessor(ProfileGenerator* generator);
   virtual ~ProfilerEventsProcessor() {}
 
   // Thread control.
@@ -205,9 +204,6 @@
       v8::internal::CpuProfiler::Call;                        \
     }                                                         \
   } while (false)
-#else
-#define PROFILE(isolate, Call) LOG(isolate, Call)
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 
 namespace v8 {
@@ -220,7 +216,6 @@
   static void Setup();
   static void TearDown();
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static void StartProfiling(const char* title);
   static void StartProfiling(String* title);
   static CpuProfile* StopProfiling(const char* title);
@@ -288,10 +283,6 @@
   bool need_to_stop_sampler_;
   Atomic32 is_profiling_;
 
-#else
-  static INLINE(bool is_profiling(Isolate* isolate)) { return false; }
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
  private:
   DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
 };
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index 3df8693..0662205 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -159,7 +159,7 @@
 
 
 void RunRemoteDebugger(int port) {
-  RemoteDebugger debugger(i::Isolate::Current(), port);
+  RemoteDebugger debugger(port);
   debugger.Run();
 }
 
@@ -186,11 +186,11 @@
   }
 
   // Start the receiver thread.
-  ReceiverThread receiver(isolate_, this);
+  ReceiverThread receiver(this);
   receiver.Start();
 
   // Start the keyboard thread.
-  KeyboardThread keyboard(isolate_, this);
+  KeyboardThread keyboard(this);
   keyboard.Start();
   PrintPrompt();
 
@@ -272,6 +272,7 @@
 
 
 void RemoteDebugger::HandleMessageReceived(char* message) {
+  Locker lock;
   HandleScope scope;
 
   // Print the event details.
@@ -300,6 +301,7 @@
 
 
 void RemoteDebugger::HandleKeyboardCommand(char* command) {
+  Locker lock;
   HandleScope scope;
 
   // Convert the debugger command to a JSON debugger request.
diff --git a/src/d8-debug.h b/src/d8-debug.h
index ceb9e36..4e33e6f 100644
--- a/src/d8-debug.h
+++ b/src/d8-debug.h
@@ -53,11 +53,11 @@
 // Remote debugging class.
 class RemoteDebugger {
  public:
-  RemoteDebugger(i::Isolate* isolate, int port)
+  explicit RemoteDebugger(int port)
       : port_(port),
         event_access_(i::OS::CreateMutex()),
         event_available_(i::OS::CreateSemaphore(0)),
-        head_(NULL), tail_(NULL), isolate_(isolate) {}
+        head_(NULL), tail_(NULL) {}
   void Run();
 
   // Handle events from the subordinate threads.
@@ -89,7 +89,6 @@
   i::Semaphore* event_available_;
   RemoteDebuggerEvent* head_;
   RemoteDebuggerEvent* tail_;
-  i::Isolate* isolate_;
 
   friend class ReceiverThread;
 };
@@ -98,8 +97,8 @@
 // Thread reading from debugged V8 instance.
 class ReceiverThread: public i::Thread {
  public:
-  ReceiverThread(i::Isolate* isolate, RemoteDebugger* remote_debugger)
-      : Thread(isolate, "d8:ReceiverThrd"),
+  explicit ReceiverThread(RemoteDebugger* remote_debugger)
+      : Thread("d8:ReceiverThrd"),
         remote_debugger_(remote_debugger) {}
   ~ReceiverThread() {}
 
@@ -113,8 +112,8 @@
 // Thread reading keyboard input.
 class KeyboardThread: public i::Thread {
  public:
-  explicit KeyboardThread(i::Isolate* isolate, RemoteDebugger* remote_debugger)
-      : Thread(isolate, "d8:KeyboardThrd"),
+  explicit KeyboardThread(RemoteDebugger* remote_debugger)
+      : Thread("d8:KeyboardThrd"),
         remote_debugger_(remote_debugger) {}
   ~KeyboardThread() {}
 
diff --git a/src/d8-posix.cc b/src/d8-posix.cc
index a7a4049..658fd4f 100644
--- a/src/d8-posix.cc
+++ b/src/d8-posix.cc
@@ -311,10 +311,6 @@
                                int read_timeout,
                                int total_timeout) {
   Handle<String> accumulator = String::Empty();
-  const char* source = "(function(a, b) { return a + b; })";
-  Handle<Value> cons_as_obj(Script::Compile(String::New(source))->Run());
-  Handle<Function> cons_function(Function::Cast(*cons_as_obj));
-  Handle<Value> cons_args[2];
 
   int fullness = 0;
   static const int kStdoutReadBufferSize = 4096;
@@ -350,12 +346,7 @@
                    bytes_read + fullness :
                    LengthWithoutIncompleteUtf8(buffer, bytes_read + fullness);
       Handle<String> addition = String::New(buffer, length);
-      cons_args[0] = accumulator;
-      cons_args[1] = addition;
-      accumulator = Handle<String>::Cast(cons_function->Call(
-          Shell::utility_context()->Global(),
-          2,
-          cons_args));
+      accumulator = String::Concat(accumulator, addition);
       fullness = bytes_read + fullness - length;
       memcpy(buffer, buffer + length, fullness);
     }
diff --git a/src/d8.cc b/src/d8.cc
index f1068cb..5fd9d27 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -26,27 +26,49 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-#include <stdlib.h>
-#include <errno.h>
+#ifdef V8_SHARED
+#define USING_V8_SHARED
+#endif
 
-#include "v8.h"
+#ifdef COMPRESS_STARTUP_DATA_BZ2
+#include <bzlib.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef USING_V8_SHARED
+#include <assert.h>
+#include "../include/v8-testing.h"
+#endif  // USING_V8_SHARED
 
 #include "d8.h"
+
+#ifndef USING_V8_SHARED
+#include "api.h"
+#include "checks.h"
 #include "d8-debug.h"
 #include "debug.h"
-#include "api.h"
 #include "natives.h"
 #include "platform.h"
+#include "v8.h"
+#endif  // USING_V8_SHARED
 
+#if !defined(_WIN32) && !defined(_WIN64)
+#include <unistd.h>  // NOLINT
+#endif
+
+#ifdef USING_V8_SHARED
+#define ASSERT(condition) assert(condition)
+#endif  // USING_V8_SHARED
 
 namespace v8 {
 
 
-const char* Shell::kHistoryFileName = ".d8_history";
-const char* Shell::kPrompt = "d8> ";
-
-
+#ifndef USING_V8_SHARED
 LineEditor *LineEditor::first_ = NULL;
+const char* Shell::kHistoryFileName = ".d8_history";
 
 
 LineEditor::LineEditor(Type type, const char* name)
@@ -92,15 +114,22 @@
 i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
 CounterCollection Shell::local_counters_;
 CounterCollection* Shell::counters_ = &local_counters_;
+i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
 Persistent<Context> Shell::utility_context_;
+#endif  // USING_V8_SHARED
+
 Persistent<Context> Shell::evaluation_context_;
+ShellOptions Shell::options;
+const char* Shell::kPrompt = "d8> ";
 
 
+#ifndef USING_V8_SHARED
 bool CounterMap::Match(void* key1, void* key2) {
   const char* name1 = reinterpret_cast<const char*>(key1);
   const char* name2 = reinterpret_cast<const char*>(key2);
   return strcmp(name1, name2) == 0;
 }
+#endif  // USING_V8_SHARED
 
 
 // Converts a V8 value to a C string.
@@ -114,16 +143,22 @@
                           Handle<Value> name,
                           bool print_result,
                           bool report_exceptions) {
+#ifndef USING_V8_SHARED
+  bool FLAG_debugger = i::FLAG_debugger;
+#else
+  bool FLAG_debugger = false;
+#endif  // USING_V8_SHARED
   HandleScope handle_scope;
   TryCatch try_catch;
-  if (i::FLAG_debugger) {
+  options.script_executed = true;
+  if (FLAG_debugger) {
     // When debugging make exceptions appear to be uncaught.
     try_catch.SetVerbose(true);
   }
   Handle<Script> script = Script::Compile(source, name);
   if (script.IsEmpty()) {
     // Print errors that happened during compilation.
-    if (report_exceptions && !i::FLAG_debugger)
+    if (report_exceptions && !FLAG_debugger)
       ReportException(&try_catch);
     return false;
   } else {
@@ -131,7 +166,7 @@
     if (result.IsEmpty()) {
       ASSERT(try_catch.HasCaught());
       // Print errors that happened during execution.
-      if (report_exceptions && !i::FLAG_debugger)
+      if (report_exceptions && !FLAG_debugger)
         ReportException(&try_catch);
       return false;
     } else {
@@ -152,6 +187,7 @@
 Handle<Value> Shell::Print(const Arguments& args) {
   Handle<Value> val = Write(args);
   printf("\n");
+  fflush(stdout);
   return val;
 }
 
@@ -187,15 +223,20 @@
 
 
 Handle<Value> Shell::ReadLine(const Arguments& args) {
-  i::SmartPointer<char> line(i::ReadLine(""));
-  if (*line == NULL) {
-    return Null();
-  }
-  size_t len = strlen(*line);
-  if (len > 0 && line[len - 1] == '\n') {
-    --len;
-  }
-  return String::New(*line, len);
+  static const int kBufferSize = 256;
+  char buffer[kBufferSize];
+  Handle<String> accumulator = String::New("");
+  bool linebreak;
+  int length;
+  do {  // Repeat if the line ends with an escape '\'.
+    // fgets got an error. Just give up.
+    if (fgets(buffer, kBufferSize, stdin) == NULL) return Null();
+    length = strlen(buffer);
+    linebreak = (length > 1 && buffer[length-2] == '\\');
+    if (linebreak) buffer[length-2] = '\n';
+    accumulator = String::Concat(accumulator, String::New(buffer, length-1));
+  } while (linebreak);
+  return accumulator;
 }
 
 
@@ -218,6 +259,107 @@
 }
 
 
+Handle<Value> Shell::CreateExternalArray(const Arguments& args,
+                                         ExternalArrayType type,
+                                         size_t element_size) {
+  ASSERT(element_size == 1 || element_size == 2 || element_size == 4 ||
+         element_size == 8);
+  if (args.Length() != 1) {
+    return ThrowException(
+        String::New("Array constructor needs one parameter."));
+  }
+  static const int kMaxLength = 0x3fffffff;
+#ifndef USING_V8_SHARED
+  ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
+#endif  // USING_V8_SHARED
+  size_t length = 0;
+  if (args[0]->IsUint32()) {
+    length = args[0]->Uint32Value();
+  } else if (args[0]->IsNumber()) {
+    double raw_length = args[0]->NumberValue();
+    if (raw_length < 0) {
+      return ThrowException(String::New("Array length must not be negative."));
+    }
+    if (raw_length > kMaxLength) {
+      return ThrowException(
+          String::New("Array length exceeds maximum length."));
+    }
+    length = static_cast<size_t>(raw_length);
+  } else {
+    return ThrowException(String::New("Array length must be a number."));
+  }
+  if (length > static_cast<size_t>(kMaxLength)) {
+    return ThrowException(String::New("Array length exceeds maximum length."));
+  }
+  void* data = calloc(length, element_size);
+  if (data == NULL) {
+    return ThrowException(String::New("Memory allocation failed."));
+  }
+  Handle<Object> array = Object::New();
+  Persistent<Object> persistent_array = Persistent<Object>::New(array);
+  persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
+  persistent_array.MarkIndependent();
+  array->SetIndexedPropertiesToExternalArrayData(data, type, length);
+  array->Set(String::New("length"), Int32::New(length), ReadOnly);
+  array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
+  return array;
+}
+
+
+void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
+  free(data);
+  object.Dispose();
+}
+
+
+Handle<Value> Shell::Int8Array(const Arguments& args) {
+  return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
+}
+
+
+Handle<Value> Shell::Uint8Array(const Arguments& args) {
+  return CreateExternalArray(args, kExternalUnsignedByteArray, sizeof(uint8_t));
+}
+
+
+Handle<Value> Shell::Int16Array(const Arguments& args) {
+  return CreateExternalArray(args, kExternalShortArray, sizeof(int16_t));
+}
+
+
+Handle<Value> Shell::Uint16Array(const Arguments& args) {
+  return CreateExternalArray(args, kExternalUnsignedShortArray,
+                             sizeof(uint16_t));
+}
+
+
+Handle<Value> Shell::Int32Array(const Arguments& args) {
+  return CreateExternalArray(args, kExternalIntArray, sizeof(int32_t));
+}
+
+
+Handle<Value> Shell::Uint32Array(const Arguments& args) {
+  return CreateExternalArray(args, kExternalUnsignedIntArray, sizeof(uint32_t));
+}
+
+
+Handle<Value> Shell::Float32Array(const Arguments& args) {
+  return CreateExternalArray(args, kExternalFloatArray,
+                             sizeof(float));  // NOLINT
+}
+
+
+Handle<Value> Shell::Float64Array(const Arguments& args) {
+  return CreateExternalArray(args, kExternalDoubleArray,
+                             sizeof(double));  // NOLINT
+}
+
+
+Handle<Value> Shell::PixelArray(const Arguments& args) {
+  return CreateExternalArray(args, kExternalPixelArray, sizeof(uint8_t));
+}
+
+
 Handle<Value> Shell::Yield(const Arguments& args) {
   v8::Unlocker unlocker;
   return Undefined();
@@ -226,7 +368,9 @@
 
 Handle<Value> Shell::Quit(const Arguments& args) {
   int exit_code = args[0]->Int32Value();
+#ifndef USING_V8_SHARED
   OnExit();
+#endif  // USING_V8_SHARED
   exit(exit_code);
   return Undefined();
 }
@@ -275,6 +419,7 @@
 }
 
 
+#ifndef USING_V8_SHARED
 Handle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) {
   HandleScope handle_scope;
   Context::Scope context_scope(utility_context_);
@@ -308,9 +453,11 @@
   Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
   return val;
 }
-#endif
+#endif  // ENABLE_DEBUGGER_SUPPORT
+#endif  // USING_V8_SHARED
 
 
+#ifndef USING_V8_SHARED
 int32_t* Counter::Bind(const char* name, bool is_histogram) {
   int i;
   for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
@@ -342,8 +489,8 @@
 
 
 void Shell::MapCounters(const char* name) {
-  counters_file_ = i::OS::MemoryMappedFile::create(name,
-    sizeof(CounterCollection), &local_counters_);
+  counters_file_ = i::OS::MemoryMappedFile::create(
+      name, sizeof(CounterCollection), &local_counters_);
   void* memory = (counters_file_ == NULL) ?
       NULL : counters_file_->memory();
   if (memory == NULL) {
@@ -409,56 +556,15 @@
 }
 
 
-void Shell::Initialize() {
-  Shell::counter_map_ = new CounterMap();
-  // Set up counters
-  if (i::StrLength(i::FLAG_map_counters) != 0)
-    MapCounters(i::FLAG_map_counters);
-  if (i::FLAG_dump_counters) {
-    V8::SetCounterFunction(LookupCounter);
-    V8::SetCreateHistogramFunction(CreateHistogram);
-    V8::SetAddHistogramSampleFunction(AddHistogramSample);
-  }
-
-  // Initialize the global objects
+void Shell::InstallUtilityScript() {
+  Locker lock;
   HandleScope scope;
-  Handle<ObjectTemplate> global_template = ObjectTemplate::New();
-  global_template->Set(String::New("print"), FunctionTemplate::New(Print));
-  global_template->Set(String::New("write"), FunctionTemplate::New(Write));
-  global_template->Set(String::New("read"), FunctionTemplate::New(Read));
-  global_template->Set(String::New("readline"),
-                       FunctionTemplate::New(ReadLine));
-  global_template->Set(String::New("load"), FunctionTemplate::New(Load));
-  global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
-  global_template->Set(String::New("version"), FunctionTemplate::New(Version));
-
-#ifdef LIVE_OBJECT_LIST
-  global_template->Set(String::New("lol_is_enabled"), Boolean::New(true));
-#else
-  global_template->Set(String::New("lol_is_enabled"), Boolean::New(false));
-#endif
-
-  Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
-  AddOSMethods(os_templ);
-  global_template->Set(String::New("os"), os_templ);
-
-  utility_context_ = Context::New(NULL, global_template);
+  // If we use the utility context, we have to set the security tokens so that
+  // utility, evaluation and debug context can all access each other.
   utility_context_->SetSecurityToken(Undefined());
+  evaluation_context_->SetSecurityToken(Undefined());
   Context::Scope utility_scope(utility_context_);
 
-  i::JSArguments js_args = i::FLAG_js_arguments;
-  i::Handle<i::FixedArray> arguments_array =
-      FACTORY->NewFixedArray(js_args.argc());
-  for (int j = 0; j < js_args.argc(); j++) {
-    i::Handle<i::String> arg =
-        FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j]));
-    arguments_array->set(j, *arg);
-  }
-  i::Handle<i::JSArray> arguments_jsarray =
-      FACTORY->NewJSArrayWithElements(arguments_array);
-  global_template->Set(String::New("arguments"),
-                       Utils::ToLocal(arguments_jsarray));
-
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Install the debugger object in the utility scope
   i::Debug* debug = i::Isolate::Current()->debug();
@@ -467,21 +573,21 @@
       = i::Handle<i::JSObject>(debug->debug_context()->global());
   utility_context_->Global()->Set(String::New("$debug"),
                                   Utils::ToLocal(js_debug));
-#endif
+  debug->debug_context()->set_security_token(HEAP->undefined_value());
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
   // 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>::GetScriptSource(source_index);
-  i::Vector<const char> shell_source_name
-      = i::NativesCollection<i::D8>::GetScriptName(source_index);
+  i::Vector<const char> shell_source =
+      i::NativesCollection<i::D8>::GetRawScriptSource(source_index);
+  i::Vector<const char> shell_source_name =
+      i::NativesCollection<i::D8>::GetScriptName(source_index);
   Handle<String> source = String::New(shell_source.start(),
-                                      shell_source.length());
+      shell_source.length());
   Handle<String> name = String::New(shell_source_name.start(),
-                                    shell_source_name.length());
+      shell_source_name.length());
   Handle<Script> script = Script::Compile(source, name);
   script->Run();
-
   // Mark the d8 shell script as native to avoid it showing up as normal source
   // in the debugger.
   i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
@@ -492,53 +598,189 @@
           i::SharedFunctionInfo::cast(*compiled_script)->script()));
   script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
 
-  // Create the evaluation context
-  evaluation_context_ = Context::New(NULL, global_template);
-  evaluation_context_->SetSecurityToken(Undefined());
-
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  // Set the security token of the debug context to allow access.
-  debug->debug_context()->set_security_token(HEAP->undefined_value());
-
-  // Start the debugger agent if requested.
-  if (i::FLAG_debugger_agent) {
-    v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
-  }
-
   // Start the in-process debugger if requested.
   if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
     v8::Debug::SetDebugEventListener(HandleDebugEvent);
   }
+#endif  // ENABLE_DEBUGGER_SUPPORT
+}
+#endif  // USING_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) {
+    ASSERT_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() {
+  Handle<ObjectTemplate> global_template = ObjectTemplate::New();
+  global_template->Set(String::New("print"), FunctionTemplate::New(Print));
+  global_template->Set(String::New("write"), FunctionTemplate::New(Write));
+  global_template->Set(String::New("read"), FunctionTemplate::New(Read));
+  global_template->Set(String::New("readline"),
+                       FunctionTemplate::New(ReadLine));
+  global_template->Set(String::New("load"), FunctionTemplate::New(Load));
+  global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
+  global_template->Set(String::New("version"), FunctionTemplate::New(Version));
+
+  // Bind the handlers for external arrays.
+  global_template->Set(String::New("Int8Array"),
+                       FunctionTemplate::New(Int8Array));
+  global_template->Set(String::New("Uint8Array"),
+                       FunctionTemplate::New(Uint8Array));
+  global_template->Set(String::New("Int16Array"),
+                       FunctionTemplate::New(Int16Array));
+  global_template->Set(String::New("Uint16Array"),
+                       FunctionTemplate::New(Uint16Array));
+  global_template->Set(String::New("Int32Array"),
+                       FunctionTemplate::New(Int32Array));
+  global_template->Set(String::New("Uint32Array"),
+                       FunctionTemplate::New(Uint32Array));
+  global_template->Set(String::New("Float32Array"),
+                       FunctionTemplate::New(Float32Array));
+  global_template->Set(String::New("Float64Array"),
+                       FunctionTemplate::New(Float64Array));
+  global_template->Set(String::New("PixelArray"),
+                       FunctionTemplate::New(PixelArray));
+
+#ifdef LIVE_OBJECT_LIST
+  global_template->Set(String::New("lol_is_enabled"), Boolean::New(true));
+#else
+  global_template->Set(String::New("lol_is_enabled"), Boolean::New(false));
+#endif
+
+#ifndef USING_V8_SHARED
+  Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
+  AddOSMethods(os_templ);
+  global_template->Set(String::New("os"), os_templ);
+#endif  // USING_V8_SHARED
+
+  return global_template;
 }
 
 
+void Shell::Initialize() {
+#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 USING_V8_SHARED
+  Shell::counter_map_ = new CounterMap();
+  // Set up counters
+  if (i::StrLength(i::FLAG_map_counters) != 0)
+    MapCounters(i::FLAG_map_counters);
+  if (i::FLAG_dump_counters) {
+    V8::SetCounterFunction(LookupCounter);
+    V8::SetCreateHistogramFunction(CreateHistogram);
+    V8::SetAddHistogramSampleFunction(AddHistogramSample);
+  }
+#endif  // USING_V8_SHARED
+  if (options.test_shell) return;
+
+#ifndef USING_V8_SHARED
+  Locker lock;
+  HandleScope scope;
+  Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
+  utility_context_ = Context::New(NULL, global_template);
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  // Start the debugger agent if requested.
+  if (i::FLAG_debugger_agent) {
+    v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
+  }
+#endif  // ENABLE_DEBUGGER_SUPPORT
+#endif  // USING_V8_SHARED
+}
+
+
+Persistent<Context> Shell::CreateEvaluationContext() {
+#ifndef USING_V8_SHARED
+  // This needs to be a critical section since this is not thread-safe
+  i::ScopedLock lock(context_mutex_);
+#endif  // USING_V8_SHARED
+  // Initialize the global objects
+  Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
+  Persistent<Context> context = Context::New(NULL, global_template);
+  Context::Scope scope(context);
+
+#ifndef USING_V8_SHARED
+  i::JSArguments js_args = i::FLAG_js_arguments;
+  i::Handle<i::FixedArray> arguments_array =
+      FACTORY->NewFixedArray(js_args.argc());
+  for (int j = 0; j < js_args.argc(); j++) {
+    i::Handle<i::String> arg =
+        FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j]));
+    arguments_array->set(j, *arg);
+  }
+  i::Handle<i::JSArray> arguments_jsarray =
+      FACTORY->NewJSArrayWithElements(arguments_array);
+  context->Global()->Set(String::New("arguments"),
+                         Utils::ToLocal(arguments_jsarray));
+#endif  // USING_V8_SHARED
+  return context;
+}
+
+
+#ifndef USING_V8_SHARED
 void Shell::OnExit() {
   if (i::FLAG_dump_counters) {
-    ::printf("+----------------------------------------+-------------+\n");
-    ::printf("| Name                                   | Value       |\n");
-    ::printf("+----------------------------------------+-------------+\n");
+    printf("+----------------------------------------+-------------+\n");
+    printf("| Name                                   | Value       |\n");
+    printf("+----------------------------------------+-------------+\n");
     for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
       Counter* counter = i.CurrentValue();
       if (counter->is_histogram()) {
-        ::printf("| c:%-36s | %11i |\n", i.CurrentKey(), counter->count());
-        ::printf("| t:%-36s | %11i |\n",
-                 i.CurrentKey(),
-                 counter->sample_total());
+        printf("| c:%-36s | %11i |\n", i.CurrentKey(), counter->count());
+        printf("| t:%-36s | %11i |\n", i.CurrentKey(), counter->sample_total());
       } else {
-        ::printf("| %-38s | %11i |\n", i.CurrentKey(), counter->count());
+        printf("| %-38s | %11i |\n", i.CurrentKey(), counter->count());
       }
     }
-    ::printf("+----------------------------------------+-------------+\n");
+    printf("+----------------------------------------+-------------+\n");
   }
   if (counters_file_ != NULL)
     delete counters_file_;
 }
+#endif  // USING_V8_SHARED
 
 
 static char* ReadChars(const char* name, int* size_out) {
-  v8::Unlocker unlocker;  // Release the V8 lock while reading files.
+  // Release the V8 lock while reading files.
+  v8::Unlocker unlocker(Isolate::GetCurrent());
+#ifndef USING_V8_SHARED
   FILE* file = i::OS::FOpen(name, "rb");
+#else
+  // TODO(yangguo@chromium.org): reading from a directory hangs!
+  FILE* file = fopen(name, "rb");
+#endif  // USING_V8_SHARED
   if (file == NULL) return NULL;
 
   fseek(file, 0, SEEK_END);
@@ -557,6 +799,7 @@
 }
 
 
+#ifndef USING_V8_SHARED
 static char* ReadToken(char* data, char token) {
   char* next = i::OS::StrChr(data, token);
   if (next != NULL) {
@@ -576,6 +819,7 @@
 static char* ReadWord(char* data) {
   return ReadToken(data, ' ');
 }
+#endif  // USING_V8_SHARED
 
 
 // Reads a file into a v8 string.
@@ -590,6 +834,11 @@
 
 
 void Shell::RunShell() {
+  Locker locker;
+  Context::Scope context_scope(evaluation_context_);
+  HandleScope handle_scope;
+  Handle<String> name = String::New("(d8)");
+#ifndef USING_V8_SHARED
   LineEditor* editor = LineEditor::Get();
   printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name());
   if (i::FLAG_debugger) {
@@ -597,26 +846,32 @@
   }
   editor->Open();
   while (true) {
-    Locker locker;
-    HandleScope handle_scope;
-    Context::Scope context_scope(evaluation_context_);
     i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt);
-    if (input.is_empty())
-      break;
+    if (input.is_empty()) break;
     editor->AddHistory(*input);
-    Handle<String> name = String::New("(d8)");
     ExecuteString(String::New(*input), name, true, true);
   }
   editor->Close();
+#else
+  printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion());
+  static const int kBufferSize = 256;
+  while (true) {
+    char buffer[kBufferSize];
+    printf("%s", Shell::kPrompt);
+    if (fgets(buffer, kBufferSize, stdin) == NULL) break;
+    ExecuteString(String::New(buffer), name, true, true);
+  }
+#endif  // USING_V8_SHARED
   printf("\n");
 }
 
 
+#ifndef USING_V8_SHARED
 class ShellThread : public i::Thread {
  public:
-  ShellThread(i::Isolate* isolate, int no, i::Vector<const char> files)
-    : Thread(isolate, "d8:ShellThread"),
-      no_(no), files_(files) { }
+  ShellThread(int no, i::Vector<const char> files)
+      : Thread("d8:ShellThread"),
+        no_(no), files_(files) { }
   virtual void Run();
  private:
   int no_;
@@ -625,25 +880,6 @@
 
 
 void ShellThread::Run() {
-  // Prepare the context for this thread.
-  Locker locker;
-  HandleScope scope;
-  Handle<ObjectTemplate> global_template = ObjectTemplate::New();
-  global_template->Set(String::New("print"),
-                       FunctionTemplate::New(Shell::Print));
-  global_template->Set(String::New("write"),
-                       FunctionTemplate::New(Shell::Write));
-  global_template->Set(String::New("read"),
-                       FunctionTemplate::New(Shell::Read));
-  global_template->Set(String::New("readline"),
-                       FunctionTemplate::New(Shell::ReadLine));
-  global_template->Set(String::New("load"),
-                       FunctionTemplate::New(Shell::Load));
-  global_template->Set(String::New("yield"),
-                       FunctionTemplate::New(Shell::Yield));
-  global_template->Set(String::New("version"),
-                       FunctionTemplate::New(Shell::Version));
-
   char* ptr = const_cast<char*>(files_.start());
   while ((ptr != NULL) && (*ptr != '\0')) {
     // For each newline-separated line.
@@ -655,8 +891,10 @@
       continue;
     }
 
-    Persistent<Context> thread_context = Context::New(NULL, global_template);
-    thread_context->SetSecurityToken(Undefined());
+    // Prepare the context for this thread.
+    Locker locker;
+    HandleScope scope;
+    Persistent<Context> thread_context = Shell::CreateEvaluationContext();
     Context::Scope context_scope(thread_context);
 
     while ((ptr != NULL) && (*ptr != '\0')) {
@@ -681,118 +919,377 @@
     ptr = next_line;
   }
 }
+#endif  // USING_V8_SHARED
 
 
-int Shell::Main(int argc, char* argv[]) {
-  i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
-  if (i::FLAG_help) {
-    return 1;
-  }
-  Initialize();
-  bool run_shell = (argc == 1);
+void SourceGroup::ExitShell(int exit_code) {
+  // Use _exit instead of exit to avoid races between isolate
+  // threads and static destructors.
+  fflush(stdout);
+  fflush(stderr);
+  _exit(exit_code);
+}
 
-  // Default use preemption if threads are created.
-  bool use_preemption = true;
 
-  // Default to use lowest possible thread preemption interval to test as many
-  // edgecases as possible.
-  int preemption_interval = 1;
-
-  i::List<i::Thread*> threads(1);
-
-  {
-    // Acquire the V8 lock once initialization has finished. Since the thread
-    // below may spawn new threads accessing V8 holding the V8 lock here is
-    // mandatory.
-    Locker locker;
-    Context::Scope context_scope(evaluation_context_);
-    for (int i = 1; i < argc; i++) {
-      char* str = argv[i];
-      if (strcmp(str, "--shell") == 0) {
-        run_shell = true;
-      } else if (strcmp(str, "--preemption") == 0) {
-        use_preemption = true;
-      } else if (strcmp(str, "--no-preemption") == 0) {
-        use_preemption = false;
-      } else if (strcmp(str, "--preemption-interval") == 0) {
-        if (i + 1 < argc) {
-          char* end = NULL;
-          preemption_interval = strtol(argv[++i], &end, 10);  // NOLINT
-          if (preemption_interval <= 0 || *end != '\0' || errno == ERANGE) {
-            printf("Invalid value for --preemption-interval '%s'\n", argv[i]);
-            return 1;
-          }
-        } else {
-          printf("Missing value for --preemption-interval\n");
-          return 1;
-       }
-      } else if (strcmp(str, "-f") == 0) {
-        // Ignore any -f flags for compatibility with other stand-alone
-        // JavaScript engines.
-        continue;
-      } else if (strncmp(str, "--", 2) == 0) {
-        printf("Warning: unknown flag %s.\nTry --help for options\n", str);
-      } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
-        // Execute argument given to -e option directly.
-        v8::HandleScope handle_scope;
-        v8::Handle<v8::String> file_name = v8::String::New("unnamed");
-        v8::Handle<v8::String> source = v8::String::New(argv[i + 1]);
-        if (!ExecuteString(source, file_name, false, true)) {
-          OnExit();
-          return 1;
-        }
-        i++;
-      } else if (strcmp(str, "-p") == 0 && i + 1 < argc) {
-        int size = 0;
-        const char* files = ReadChars(argv[++i], &size);
-        if (files == NULL) return 1;
-        ShellThread* thread =
-            new ShellThread(i::Isolate::Current(),
-                            threads.length(),
-                            i::Vector<const char>(files, size));
-        thread->Start();
-        threads.Add(thread);
-      } else {
-        // Use all other arguments as names of files to load and run.
-        HandleScope handle_scope;
-        Handle<String> file_name = v8::String::New(str);
-        Handle<String> source = ReadFile(str);
-        if (source.IsEmpty()) {
-          printf("Error reading '%s'\n", str);
-          return 1;
-        }
-        if (!ExecuteString(source, file_name, false, true)) {
-          OnExit();
-          return 1;
-        }
+void SourceGroup::Execute() {
+  for (int i = begin_offset_; i < end_offset_; ++i) {
+    const char* arg = argv_[i];
+    if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
+      // Execute argument given to -e option directly.
+      HandleScope handle_scope;
+      Handle<String> file_name = String::New("unnamed");
+      Handle<String> source = String::New(argv_[i + 1]);
+      if (!Shell::ExecuteString(source, file_name, false, true)) {
+        ExitShell(1);
+        return;
+      }
+      ++i;
+    } else if (arg[0] == '-') {
+      // Ignore other options. They have been parsed already.
+    } else {
+      // Use all other arguments as names of files to load and run.
+      HandleScope handle_scope;
+      Handle<String> file_name = String::New(arg);
+      Handle<String> source = ReadFile(arg);
+      if (source.IsEmpty()) {
+        printf("Error reading '%s'\n", arg);
+        ExitShell(1);
+        return;
+      }
+      if (!Shell::ExecuteString(source, file_name, false, true)) {
+        ExitShell(1);
+        return;
       }
     }
+  }
+}
 
+
+Handle<String> SourceGroup::ReadFile(const char* name) {
+#ifndef USING_V8_SHARED
+  FILE* file = i::OS::FOpen(name, "rb");
+#else
+  // TODO(yangguo@chromium.org): reading from a directory hangs!
+  FILE* file = fopen(name, "rb");
+#endif  // USING_V8_SHARED
+  if (file == NULL) return Handle<String>();
+
+  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 = fread(&chars[i], 1, size - i, file);
+    i += read;
+  }
+  fclose(file);
+  Handle<String> result = String::New(chars, size);
+  delete[] chars;
+  return result;
+}
+
+
+#ifndef USING_V8_SHARED
+i::Thread::Options SourceGroup::GetThreadOptions() {
+  i::Thread::Options options;
+  options.name = "IsolateThread";
+  // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
+  // which is not enough to parse the big literal expressions used in tests.
+  // The stack size should be at least StackGuard::kLimitSize + some
+  // OS-specific padding for thread startup code.
+  options.stack_size = 2 << 20;  // 2 Mb seems to be enough
+  return options;
+}
+
+
+void SourceGroup::ExecuteInThread() {
+  Isolate* isolate = Isolate::New();
+  do {
+    if (next_semaphore_ != NULL) next_semaphore_->Wait();
+    {
+      Isolate::Scope iscope(isolate);
+      Locker lock(isolate);
+      HandleScope scope;
+      Persistent<Context> context = Shell::CreateEvaluationContext();
+      {
+        Context::Scope cscope(context);
+        Execute();
+      }
+      context.Dispose();
+    }
+    if (done_semaphore_ != NULL) done_semaphore_->Signal();
+  } while (!Shell::options.last_run);
+  isolate->Dispose();
+}
+
+
+void SourceGroup::StartExecuteInThread() {
+  if (thread_ == NULL) {
+    thread_ = new IsolateThread(this);
+    thread_->Start();
+  }
+  next_semaphore_->Signal();
+}
+
+
+void SourceGroup::WaitForThread() {
+  if (thread_ == NULL) return;
+  if (Shell::options.last_run) {
+    thread_->Join();
+    thread_ = NULL;
+  } else {
+    done_semaphore_->Wait();
+  }
+}
+#endif  // USING_V8_SHARED
+
+
+bool Shell::SetOptions(int argc, char* argv[]) {
+  for (int i = 0; i < argc; i++) {
+    if (strcmp(argv[i], "--stress-opt") == 0) {
+      options.stress_opt = true;
+      argv[i] = NULL;
+    } else if (strcmp(argv[i], "--stress-deopt") == 0) {
+      options.stress_deopt = true;
+      argv[i] = NULL;
+    } else if (strcmp(argv[i], "--noalways-opt") == 0) {
+      // No support for stressing if we can't use --always-opt.
+      options.stress_opt = false;
+      options.stress_deopt = false;
+    } else if (strcmp(argv[i], "--shell") == 0) {
+      options.interactive_shell = true;
+      argv[i] = NULL;
+    } else if (strcmp(argv[i], "--test") == 0) {
+      options.test_shell = true;
+      argv[i] = NULL;
+    } else if (strcmp(argv[i], "--preemption") == 0) {
+#ifdef USING_V8_SHARED
+      printf("D8 with shared library does not support multi-threading\n");
+      return false;
+#else
+      options.use_preemption = true;
+      argv[i] = NULL;
+#endif  // USING_V8_SHARED
+    } else if (strcmp(argv[i], "--no-preemption") == 0) {
+#ifdef USING_V8_SHARED
+      printf("D8 with shared library does not support multi-threading\n");
+      return false;
+#else
+      options.use_preemption = false;
+      argv[i] = NULL;
+#endif  // USING_V8_SHARED
+    } else if (strcmp(argv[i], "--preemption-interval") == 0) {
+#ifdef USING_V8_SHARED
+      printf("D8 with shared library does not support multi-threading\n");
+      return false;
+#else
+      if (++i < argc) {
+        argv[i-1] = NULL;
+        char* end = NULL;
+        options.preemption_interval = strtol(argv[i], &end, 10);  // NOLINT
+        if (options.preemption_interval <= 0
+            || *end != '\0'
+            || errno == ERANGE) {
+          printf("Invalid value for --preemption-interval '%s'\n", argv[i]);
+          return false;
+        }
+        argv[i] = NULL;
+      } else {
+        printf("Missing value for --preemption-interval\n");
+        return false;
+      }
+#endif  // USING_V8_SHARED
+    } else if (strcmp(argv[i], "-f") == 0) {
+      // Ignore any -f flags for compatibility with other stand-alone
+      // JavaScript engines.
+      continue;
+    } else if (strcmp(argv[i], "--isolate") == 0) {
+#ifdef USING_V8_SHARED
+      printf("D8 with shared library does not support multi-threading\n");
+      return false;
+#endif  // USING_V8_SHARED
+      options.num_isolates++;
+    }
+#ifdef USING_V8_SHARED
+    else if (strcmp(argv[i], "--dump-counters") == 0) {
+      printf("D8 with shared library does not include counters\n");
+      return false;
+    } else if (strcmp(argv[i], "-p") == 0) {
+      printf("D8 with shared library does not support multi-threading\n");
+      return false;
+    } else if (strcmp(argv[i], "--debugger") == 0) {
+      printf("Javascript debugger not included\n");
+      return false;
+    }
+#endif  // USING_V8_SHARED
+  }
+
+#ifndef USING_V8_SHARED
+  // Run parallel threads if we are not using --isolate
+  for (int i = 1; i < argc; i++) {
+    if (argv[i] == NULL) continue;
+    if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
+      if (options.num_isolates > 1) {
+        printf("-p is not compatible with --isolate\n");
+        return false;
+      }
+      argv[i] = NULL;
+      if (options.parallel_files == NULL) {
+        options.parallel_files = new i::List<i::Vector<const char> >();
+      }
+      int size = 0;
+      const char* files = ReadChars(argv[++i], &size);
+      if (files == NULL) {
+        printf("-p option incomplete\n");
+        return false;
+      }
+      argv[i] = NULL;
+      options.parallel_files->Add(i::Vector<const char>(files, size));
+    }
+  }
+#endif  // USING_V8_SHARED
+
+  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
+
+  // set up isolated source groups
+  options.isolate_sources = new SourceGroup[options.num_isolates];
+  SourceGroup* current = options.isolate_sources;
+  current->Begin(argv, 1);
+  for (int i = 1; i < argc; i++) {
+    const char* str = argv[i];
+    if (strcmp(str, "--isolate") == 0) {
+      current->End(i);
+      current++;
+      current->Begin(argv, i + 1);
+    } else if (strncmp(argv[i], "--", 2) == 0) {
+      printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
+    }
+  }
+  current->End(argc);
+
+  return true;
+}
+
+
+int Shell::RunMain(int argc, char* argv[]) {
+#ifndef USING_V8_SHARED
+  i::List<i::Thread*> threads(1);
+  if (options.parallel_files != NULL)
+    for (int i = 0; i < options.parallel_files->length(); i++) {
+      i::Vector<const char> files = options.parallel_files->at(i);
+      ShellThread* thread = new ShellThread(threads.length(), files);
+      thread->Start();
+      threads.Add(thread);
+    }
+
+  for (int i = 1; i < options.num_isolates; ++i) {
+    options.isolate_sources[i].StartExecuteInThread();
+  }
+#endif  // USING_V8_SHARED
+  {  // NOLINT
+    Locker lock;
+    HandleScope scope;
+    Persistent<Context> context = CreateEvaluationContext();
+    if (options.last_run) {
+      // Keep using the same context in the interactive shell.
+      evaluation_context_ = context;
+#ifndef V8_SHARED
+      // If the interactive debugger is enabled make sure to activate
+      // it before running the files passed on the command line.
+      if (i::FLAG_debugger) {
+        InstallUtilityScript();
+      }
+#endif  // V8_SHARED
+    }
+    {
+      Context::Scope cscope(context);
+      options.isolate_sources[0].Execute();
+    }
+    if (!options.last_run) {
+      context.Dispose();
+    }
+
+#ifndef USING_V8_SHARED
     // Start preemption if threads have been created and preemption is enabled.
-    if (threads.length() > 0 && use_preemption) {
-      Locker::StartPreemption(preemption_interval);
+    if (options.parallel_files != NULL
+        && threads.length() > 0
+        && options.use_preemption) {
+      Locker::StartPreemption(options.preemption_interval);
+    }
+#endif  // USING_V8_SHARED
+  }
+
+#ifndef USING_V8_SHARED
+  for (int i = 1; i < options.num_isolates; ++i) {
+    options.isolate_sources[i].WaitForThread();
+  }
+
+  if (options.parallel_files != NULL)
+    for (int i = 0; i < threads.length(); i++) {
+      i::Thread* thread = threads[i];
+      thread->Join();
+      delete thread;
     }
 
-#ifdef ENABLE_DEBUGGER_SUPPORT
-    // Run the remote debugger if requested.
-    if (i::FLAG_remote_debugger) {
-      RunRemoteDebugger(i::FLAG_debugger_port);
-      return 0;
-    }
-#endif
-  }
-  if (run_shell)
-    RunShell();
-  for (int i = 0; i < threads.length(); i++) {
-    i::Thread* thread = threads[i];
-    thread->Join();
-    delete thread;
-  }
   OnExit();
+#endif  // USING_V8_SHARED
   return 0;
 }
 
 
+int Shell::Main(int argc, char* argv[]) {
+  if (!SetOptions(argc, argv)) return 1;
+  Initialize();
+
+  int result = 0;
+  if (options.stress_opt || options.stress_deopt) {
+    Testing::SetStressRunType(
+        options.stress_opt ? Testing::kStressTypeOpt
+                           : Testing::kStressTypeDeopt);
+    int stress_runs = Testing::GetStressRuns();
+    for (int i = 0; i < stress_runs && result == 0; i++) {
+      printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
+      Testing::PrepareStressRun(i);
+      options.last_run = (i == stress_runs - 1);
+      result = RunMain(argc, argv);
+    }
+    printf("======== Full Deoptimization =======\n");
+    Testing::DeoptimizeAll();
+  } else {
+    result = RunMain(argc, argv);
+  }
+
+
+#if !defined(USING_V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+  // Run remote debugger if requested, but never on --test
+  if (i::FLAG_remote_debugger && !options.test_shell) {
+    InstallUtilityScript();
+    RunRemoteDebugger(i::FLAG_debugger_port);
+    return 0;
+  }
+#endif  // !USING_V8_SHARED && ENABLE_DEBUGGER_SUPPORT
+
+  // Run interactive shell if explicitly requested or if no script has been
+  // executed, but never on --test
+
+  if (( options.interactive_shell
+      || !options.script_executed )
+      && !options.test_shell ) {
+#ifndef USING_V8_SHARED
+    if (!i::FLAG_debugger) {
+      InstallUtilityScript();
+    }
+#endif  // USING_V8_SHARED
+    RunShell();
+  }
+
+  V8::Dispose();
+
+  return result;
+}
+
 }  // namespace v8
 
 
diff --git a/src/d8.gyp b/src/d8.gyp
index 8b52ed9..48442b1 100644
--- a/src/d8.gyp
+++ b/src/d8.gyp
@@ -1,4 +1,4 @@
-# Copyright 2010 the V8 project authors. All rights reserved.
+# Copyright 2011 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
@@ -26,34 +26,42 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 {
+  'variables': {
+    'console%': '',
+  },
   'targets': [
     {
       'target_name': 'd8',
       'type': 'executable',
       'dependencies': [
-        'd8_js2c#host',
         '../tools/gyp/v8.gyp:v8',
       ],
       'include_dirs+': [
         '../src',
       ],
       'defines': [
-        'ENABLE_LOGGING_AND_PROFILING',
         'ENABLE_DEBUGGER_SUPPORT',
-        'ENABLE_VMSTATE_TRACKING',
-        'V8_FAST_TLS',
       ],
       'sources': [
         'd8.cc',
-        'd8-debug.cc',
-        '<(SHARED_INTERMEDIATE_DIR)/d8-js.cc',
       ],
       'conditions': [
-        [ 'OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
-          'sources': [ 'd8-posix.cc', ]
-        }],
-        [ 'OS=="win"', {
-          'sources': [ 'd8-windows.cc', ]
+        [ 'component!="shared_library"', {
+          'dependencies': [ 'd8_js2c#host', ], 
+          'sources': [ 'd8-debug.cc', '<(SHARED_INTERMEDIATE_DIR)/d8-js.cc', ],
+          'conditions': [
+            [ 'console=="readline"', {
+              'libraries': [ '-lreadline', ],
+              'sources': [ 'd8-readline.cc' ],
+            }],
+            [ '(OS=="linux" or OS=="mac" or OS=="freebsd" \
+              or OS=="openbsd" or OS=="solaris")', {
+              'sources': [ 'd8-posix.cc', ]
+            }],
+            [ 'OS=="win"', {
+              'sources': [ 'd8-windows.cc', ]
+            }],
+          ],
         }],
       ],
     },
@@ -82,6 +90,7 @@
             '../tools/js2c.py',
             '<@(_outputs)',
             'D8',
+            'off',  # compress startup data
             '<@(js_files)'
           ],
         },
diff --git a/src/d8.h b/src/d8.h
index dc02322..840ca1e 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -28,20 +28,23 @@
 #ifndef V8_D8_H_
 #define V8_D8_H_
 
-#include "allocation.h"
-#include "v8.h"
-#include "hashmap.h"
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-#error Using compressed startup data is not supported for D8
-#endif
+#ifndef USING_V8_SHARED
+#include "v8.h"
+#include "allocation.h"
+#include "hashmap.h"
+#else
+#include "../include/v8.h"
+#endif  // USING_V8_SHARED
 
 namespace v8 {
 
-
+#ifndef USING_V8_SHARED
 namespace i = v8::internal;
+#endif  // USING_V8_SHARED
 
 
+#ifndef USING_V8_SHARED
 // A single counter in a counter collection.
 class Counter {
  public:
@@ -108,14 +111,108 @@
     i::HashMap* map_;
     i::HashMap::Entry* entry_;
   };
+
  private:
   static int Hash(const char* name);
   static bool Match(void* key1, void* key2);
   i::HashMap hash_map_;
 };
+#endif  // USING_V8_SHARED
 
 
-class Shell: public i::AllStatic {
+class SourceGroup {
+ public:
+  SourceGroup() :
+#ifndef USING_V8_SHARED
+      next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
+      done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
+      thread_(NULL),
+#endif  // USING_V8_SHARED
+      argv_(NULL),
+      begin_offset_(0),
+      end_offset_(0) { }
+
+  void Begin(char** argv, int offset) {
+    argv_ = const_cast<const char**>(argv);
+    begin_offset_ = offset;
+  }
+
+  void End(int offset) { end_offset_ = offset; }
+
+  void Execute();
+
+#ifndef USING_V8_SHARED
+  void StartExecuteInThread();
+  void WaitForThread();
+
+ private:
+  class IsolateThread : public i::Thread {
+   public:
+    explicit IsolateThread(SourceGroup* group)
+        : i::Thread(GetThreadOptions()), group_(group) {}
+
+    virtual void Run() {
+      group_->ExecuteInThread();
+    }
+
+   private:
+    SourceGroup* group_;
+  };
+
+  static i::Thread::Options GetThreadOptions();
+  void ExecuteInThread();
+
+  i::Semaphore* next_semaphore_;
+  i::Semaphore* done_semaphore_;
+  i::Thread* thread_;
+#endif  // USING_V8_SHARED
+
+  void ExitShell(int exit_code);
+  Handle<String> ReadFile(const char* name);
+
+  const char** argv_;
+  int begin_offset_;
+  int end_offset_;
+};
+
+
+class ShellOptions {
+ public:
+  ShellOptions() :
+#ifndef USING_V8_SHARED
+     use_preemption(true),
+     preemption_interval(10),
+     parallel_files(NULL),
+#endif  // USING_V8_SHARED
+     script_executed(false),
+     last_run(true),
+     stress_opt(false),
+     stress_deopt(false),
+     interactive_shell(false),
+     test_shell(false),
+     num_isolates(1),
+     isolate_sources(NULL) { }
+
+#ifndef USING_V8_SHARED
+  bool use_preemption;
+  int preemption_interval;
+  i::List< i::Vector<const char> >* parallel_files;
+#endif  // USING_V8_SHARED
+  bool script_executed;
+  bool last_run;
+  bool stress_opt;
+  bool stress_deopt;
+  bool interactive_shell;
+  bool test_shell;
+  int num_isolates;
+  SourceGroup* isolate_sources;
+};
+
+#ifdef USING_V8_SHARED
+class Shell {
+#else
+class Shell : public i::AllStatic {
+#endif  // USING_V8_SHARED
  public:
   static bool ExecuteString(Handle<String> source,
                             Handle<Value> name,
@@ -123,7 +220,14 @@
                             bool report_exceptions);
   static const char* ToCString(const v8::String::Utf8Value& value);
   static void ReportException(TryCatch* try_catch);
-  static void Initialize();
+  static Handle<String> ReadFile(const char* name);
+  static Persistent<Context> CreateEvaluationContext();
+  static int RunMain(int argc, char* argv[]);
+  static int Main(int argc, char* argv[]);
+
+#ifndef USING_V8_SHARED
+  static Handle<Array> GetCompletions(Handle<String> text,
+                                      Handle<String> full);
   static void OnExit();
   static int* LookupCounter(const char* name);
   static void* CreateHistogram(const char* name,
@@ -132,11 +236,8 @@
                                size_t buckets);
   static void AddHistogramSample(void* histogram, int sample);
   static void MapCounters(const char* name);
-  static Handle<String> ReadFile(const char* name);
-  static void RunShell();
-  static int Main(int argc, char* argv[]);
-  static Handle<Array> GetCompletions(Handle<String> text,
-                                      Handle<String> full);
+#endif  // USING_V8_SHARED
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
   static Handle<Object> DebugMessageDetails(Handle<String> message);
   static Handle<Value> DebugCommandToJSONRequest(Handle<String> command);
@@ -154,6 +255,15 @@
   static Handle<Value> Read(const Arguments& args);
   static Handle<Value> ReadLine(const Arguments& args);
   static Handle<Value> Load(const Arguments& args);
+  static Handle<Value> Int8Array(const Arguments& args);
+  static Handle<Value> Uint8Array(const Arguments& args);
+  static Handle<Value> Int16Array(const Arguments& args);
+  static Handle<Value> Uint16Array(const Arguments& args);
+  static Handle<Value> Int32Array(const Arguments& args);
+  static Handle<Value> Uint32Array(const Arguments& args);
+  static Handle<Value> Float32Array(const Arguments& args);
+  static Handle<Value> Float64Array(const Arguments& args);
+  static Handle<Value> PixelArray(const Arguments& args);
   // The OS object on the global object contains methods for performing
   // operating system calls:
   //
@@ -190,24 +300,39 @@
   static Handle<Value> RemoveDirectory(const Arguments& args);
 
   static void AddOSMethods(Handle<ObjectTemplate> os_template);
-
-  static Handle<Context> utility_context() { return utility_context_; }
-
+#ifndef USING_V8_SHARED
   static const char* kHistoryFileName;
+#endif  // USING_V8_SHARED
   static const char* kPrompt;
+  static ShellOptions options;
+
  private:
-  static Persistent<Context> utility_context_;
   static Persistent<Context> evaluation_context_;
+#ifndef USING_V8_SHARED
+  static Persistent<Context> utility_context_;
   static CounterMap* counter_map_;
   // We statically allocate a set of local counters to be used if we
   // don't want to store the stats in a memory-mapped file
   static CounterCollection local_counters_;
   static CounterCollection* counters_;
   static i::OS::MemoryMappedFile* counters_file_;
+  static i::Mutex* context_mutex_;
+
   static Counter* GetCounter(const char* name, bool is_histogram);
+  static void InstallUtilityScript();
+#endif  // USING_V8_SHARED
+  static void Initialize();
+  static void RunShell();
+  static bool SetOptions(int argc, char* argv[]);
+  static Handle<ObjectTemplate> CreateGlobalTemplate();
+  static Handle<Value> CreateExternalArray(const Arguments& args,
+                                           ExternalArrayType type,
+                                           size_t element_size);
+  static void ExternalArrayWeakCallback(Persistent<Value> object, void* data);
 };
 
 
+#ifndef USING_V8_SHARED
 class LineEditor {
  public:
   enum Type { DUMB = 0, READLINE = 1 };
@@ -227,6 +352,7 @@
   LineEditor* next_;
   static LineEditor* first_;
 };
+#endif  // USING_V8_SHARED
 
 
 }  // namespace v8
diff --git a/src/d8.js b/src/d8.js
index 9798078..033455e 100644
--- a/src/d8.js
+++ b/src/d8.js
@@ -977,9 +977,14 @@
     // specification it is considered a function break point.
     pos = target.indexOf(':');
     if (pos > 0) {
-      type = 'script';
       var tmp = target.substring(pos + 1, target.length);
       target = target.substring(0, pos);
+      if (target[0] == '/' && target[target.length - 1] == '/') {
+        type = 'scriptRegExp';
+        target = target.substring(1, target.length - 1);
+      } else {
+        type = 'script';
+      }
 
       // Check for both line and column.
       pos = tmp.indexOf(':');
@@ -1984,6 +1989,9 @@
           if (breakpoint.script_name) {
               result += ' script_name=' + breakpoint.script_name;
           }
+          if (breakpoint.script_regexp) {
+              result += ' script_regexp=' + breakpoint.script_regexp;
+          }
           result += ' line=' + (breakpoint.line + 1);
           if (breakpoint.column != null) {
             result += ' column=' + (breakpoint.column + 1);
diff --git a/src/date.js b/src/date.js
index 5a2e9a2..79b846d 100644
--- a/src/date.js
+++ b/src/date.js
@@ -981,11 +981,22 @@
 function DateToISOString() {
   var t = DATE_VALUE(this);
   if (NUMBER_IS_NAN(t)) return kInvalidDate;
-  return this.getUTCFullYear() + 
+  var year = this.getUTCFullYear();
+  var year_string;
+  if (year >= 0 && year <= 9999) {
+    year_string = PadInt(year, 4);
+  } else {
+    if (year < 0) {
+      year_string = "-" + PadInt(-year, 6);
+    } else {
+      year_string = "+" + PadInt(year, 6);
+    }
+  }
+  return year_string +
       '-' + PadInt(this.getUTCMonth() + 1, 2) +
-      '-' + PadInt(this.getUTCDate(), 2) + 
+      '-' + PadInt(this.getUTCDate(), 2) +
       'T' + PadInt(this.getUTCHours(), 2) +
-      ':' + PadInt(this.getUTCMinutes(), 2) + 
+      ':' + PadInt(this.getUTCMinutes(), 2) +
       ':' + PadInt(this.getUTCSeconds(), 2) +
       '.' + PadInt(this.getUTCMilliseconds(), 3) +
       'Z';
@@ -995,8 +1006,8 @@
 function DateToJSON(key) {
   var o = ToObject(this);
   var tv = DefaultNumber(o);
-  if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) { 
-    return null; 
+  if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
+    return null;
   }
   return o.toISOString();
 }
diff --git a/src/dateparser-inl.h b/src/dateparser-inl.h
index 7f8fac8..32f0f9e 100644
--- a/src/dateparser-inl.h
+++ b/src/dateparser-inl.h
@@ -39,16 +39,71 @@
                        UnicodeCache* unicode_cache) {
   ASSERT(out->length() >= OUTPUT_SIZE);
   InputReader<Char> in(unicode_cache, str);
+  DateStringTokenizer<Char> scanner(&in);
   TimeZoneComposer tz;
   TimeComposer time;
   DayComposer day;
 
-  while (!in.IsEnd()) {
-    if (in.IsAsciiDigit()) {
-      // Parse a number (possibly with 1 or 2 trailing colons).
-      int n = in.ReadUnsignedNumber();
-      if (in.Skip(':')) {
-        if (in.Skip(':')) {
+  // Specification:
+  // Accept ES5 ISO 8601 date-time-strings or legacy dates compatible
+  // with Safari.
+  // ES5 ISO 8601 dates:
+  //   [('-'|'+')yy]yyyy[-MM[-DD]][THH:mm[:ss[.sss]][Z|(+|-)hh:mm]]
+  //   where yyyy is in the range 0000..9999 and
+  //         +/-yyyyyy is in the range -999999..+999999 -
+  //           but -000000 is invalid (year zero must be positive),
+  //         MM is in the range 01..12,
+  //         DD is in the range 01..31,
+  //         MM and DD defaults to 01 if missing,,
+  //         HH is generally in the range 00..23, but can be 24 if mm, ss
+  //           and sss are zero (or missing), representing midnight at the
+  //           end of a day,
+  //         mm and ss are in the range 00..59,
+  //         sss is in the range 000..999,
+  //         hh is in the range 00..23,
+  //         mm, ss, and sss default to 00 if missing, and
+  //         timezone defaults to Z if missing.
+  //  Extensions:
+  //   We also allow sss to have more or less than three digits (but at
+  //   least one).
+  //   We allow hh:mm to be specified as hhmm.
+  // Legacy dates:
+  //  Any unrecognized word before the first number is ignored.
+  //  Parenthesized text is ignored.
+  //  An unsigned number followed by ':' is a time value, and is
+  //  added to the TimeComposer. A number followed by '::' adds a second
+  //  zero as well. A number followed by '.' is also a time and must be
+  //  followed by milliseconds.
+  //  Any other number is a date component and is added to DayComposer.
+  //  A month name (or really: any word having the same first three letters
+  //  as a month name) is recorded as a named month in the Day composer.
+  //  A word recognizable as a time-zone is recorded as such, as is
+  //  '(+|-)(hhmm|hh:)'.
+  //  Legacy dates don't allow extra signs ('+' or '-') or umatched ')'
+  //  after a number has been read (before the first number, any garbage
+  //  is allowed).
+  // Intersection of the two:
+  //  A string that matches both formats (e.g. 1970-01-01) will be
+  //  parsed as an ES5 date-time string - which means it will default
+  //  to UTC time-zone. That's unavoidable if following the ES5
+  //  specification.
+  //  After a valid "T" has been read while scanning an ES5 datetime string,
+  //  the input can no longer be a valid legacy date, since the "T" is a
+  //  garbage string after a number has been read.
+
+  // First try getting as far as possible with as ES5 Date Time String.
+  DateToken next_unhandled_token = ParseES5DateTime(&scanner, &day, &time, &tz);
+  if (next_unhandled_token.IsInvalid()) return false;
+  bool has_read_number = !day.IsEmpty();
+  // If there's anything left, continue with the legacy parser.
+  for (DateToken token = next_unhandled_token;
+       !token.IsEndOfInput();
+       token = scanner.Next()) {
+    if (token.IsNumber()) {
+      has_read_number = true;
+      int n = token.number();
+      if (scanner.SkipSymbol(':')) {
+        if (scanner.SkipSymbol(':')) {
           // n + "::"
           if (!time.IsEmpty()) return false;
           time.Add(n);
@@ -56,12 +111,13 @@
         } else {
           // n + ":"
           if (!time.Add(n)) return false;
-          in.Skip('.');
+          if (scanner.Peek().IsSymbol('.')) scanner.Next();
         }
-      } else if (in.Skip('.') && time.IsExpecting(n)) {
+      } else if (scanner.SkipSymbol('.') && time.IsExpecting(n)) {
         time.Add(n);
-        if (!in.IsAsciiDigit()) return false;
-        int n = in.ReadMilliseconds();
+        if (!scanner.Peek().IsNumber()) return false;
+        int n = ReadMilliseconds(scanner.Next());
+        if (n < 0) return false;
         time.AddFinal(n);
       } else if (tz.IsExpecting(n)) {
         tz.SetAbsoluteMinute(n);
@@ -69,59 +125,206 @@
         time.AddFinal(n);
         // Require end, white space, "Z", "+" or "-" immediately after
         // finalizing time.
-        if (!in.IsEnd() && !in.SkipWhiteSpace() && !in.Is('Z') &&
-            !in.IsAsciiSign()) return false;
+        DateToken peek = scanner.Peek();
+        if (!peek.IsEndOfInput() &&
+            !peek.IsWhiteSpace() &&
+            !peek.IsKeywordZ() &&
+            !peek.IsAsciiSign()) return false;
       } else {
         if (!day.Add(n)) return false;
-        in.Skip('-');  // Ignore suffix '-' for year, month, or day.
-        // Skip trailing 'T' for ECMAScript 5 date string format but make
-        // sure that it is followed by a digit (for the time).
-        if (in.Skip('T') && !in.IsAsciiDigit()) return false;
+        scanner.SkipSymbol('-');
       }
-    } else if (in.IsAsciiAlphaOrAbove()) {
+    } else if (token.IsKeyword()) {
       // Parse a "word" (sequence of chars. >= 'A').
-      uint32_t pre[KeywordTable::kPrefixLength];
-      int len = in.ReadWord(pre, KeywordTable::kPrefixLength);
-      int index = KeywordTable::Lookup(pre, len);
-      KeywordType type = KeywordTable::GetType(index);
-
+      KeywordType type = token.keyword_type();
+      int value = token.keyword_value();
       if (type == AM_PM && !time.IsEmpty()) {
-        time.SetHourOffset(KeywordTable::GetValue(index));
+        time.SetHourOffset(value);
       } else if (type == MONTH_NAME) {
-        day.SetNamedMonth(KeywordTable::GetValue(index));
-        in.Skip('-');  // Ignore suffix '-' for month names
-      } else if (type == TIME_ZONE_NAME && in.HasReadNumber()) {
-        tz.Set(KeywordTable::GetValue(index));
+        day.SetNamedMonth(value);
+        scanner.SkipSymbol('-');
+      } else if (type == TIME_ZONE_NAME && has_read_number) {
+        tz.Set(value);
       } else {
         // Garbage words are illegal if a number has been read.
-        if (in.HasReadNumber()) return false;
+        if (has_read_number) return false;
       }
-    } else if (in.IsAsciiSign() && (tz.IsUTC() || !time.IsEmpty())) {
+    } else if (token.IsAsciiSign() && (tz.IsUTC() || !time.IsEmpty())) {
       // Parse UTC offset (only after UTC or time).
-      tz.SetSign(in.GetAsciiSignValue());
-      in.Next();
-      int n = in.ReadUnsignedNumber();
-      if (in.Skip(':')) {
+      tz.SetSign(token.ascii_sign());
+      // The following number may be empty.
+      int n = 0;
+      if (scanner.Peek().IsNumber()) {
+        n = scanner.Next().number();
+      }
+      has_read_number = true;
+
+      if (scanner.Peek().IsSymbol(':')) {
         tz.SetAbsoluteHour(n);
         tz.SetAbsoluteMinute(kNone);
       } else {
         tz.SetAbsoluteHour(n / 100);
         tz.SetAbsoluteMinute(n % 100);
       }
-    } else if (in.Is('(')) {
-      // Ignore anything from '(' to a matching ')' or end of string.
-      in.SkipParentheses();
-    } else if ((in.IsAsciiSign() || in.Is(')')) && in.HasReadNumber()) {
+    } else if ((token.IsAsciiSign() || token.IsSymbol(')')) &&
+               has_read_number) {
       // Extra sign or ')' is illegal if a number has been read.
       return false;
     } else {
-      // Ignore other characters.
-      in.Next();
+      // Ignore other characters and whitespace.
     }
   }
+
   return day.Write(out) && time.Write(out) && tz.Write(out);
 }
 
+
+template<typename CharType>
+DateParser::DateToken DateParser::DateStringTokenizer<CharType>::Scan() {
+  int pre_pos = in_->position();
+  if (in_->IsEnd()) return DateToken::EndOfInput();
+  if (in_->IsAsciiDigit()) {
+    int n = in_->ReadUnsignedNumeral();
+    int length = in_->position() - pre_pos;
+    return DateToken::Number(n, length);
+  }
+  if (in_->Skip(':')) return DateToken::Symbol(':');
+  if (in_->Skip('-')) return DateToken::Symbol('-');
+  if (in_->Skip('+')) return DateToken::Symbol('+');
+  if (in_->Skip('.')) return DateToken::Symbol('.');
+  if (in_->Skip(')')) return DateToken::Symbol(')');
+  if (in_->IsAsciiAlphaOrAbove()) {
+    ASSERT(KeywordTable::kPrefixLength == 3);
+    uint32_t buffer[3] = {0, 0, 0};
+    int length = in_->ReadWord(buffer, 3);
+    int index = KeywordTable::Lookup(buffer, length);
+    return DateToken::Keyword(KeywordTable::GetType(index),
+                              KeywordTable::GetValue(index),
+                              length);
+  }
+  if (in_->SkipWhiteSpace()) {
+    return DateToken::WhiteSpace(in_->position() - pre_pos);
+  }
+  if (in_->SkipParentheses()) {
+    return DateToken::Unknown();
+  }
+  in_->Next();
+  return DateToken::Unknown();
+}
+
+
+template <typename Char>
+DateParser::DateToken DateParser::ParseES5DateTime(
+    DateStringTokenizer<Char>* scanner,
+    DayComposer* day,
+    TimeComposer* time,
+    TimeZoneComposer* tz) {
+  ASSERT(day->IsEmpty());
+  ASSERT(time->IsEmpty());
+  ASSERT(tz->IsEmpty());
+
+  // Parse mandatory date string: [('-'|'+')yy]yyyy[':'MM[':'DD]]
+  if (scanner->Peek().IsAsciiSign()) {
+    // Keep the sign token, so we can pass it back to the legacy
+    // parser if we don't use it.
+    DateToken sign_token = scanner->Next();
+    if (!scanner->Peek().IsFixedLengthNumber(6)) return sign_token;
+    int sign = sign_token.ascii_sign();
+    int year = scanner->Next().number();
+    if (sign < 0 && year == 0) return sign_token;
+    day->Add(sign * year);
+  } else if (scanner->Peek().IsFixedLengthNumber(4)) {
+    day->Add(scanner->Next().number());
+  } else {
+    return scanner->Next();
+  }
+  if (scanner->SkipSymbol('-')) {
+    if (!scanner->Peek().IsFixedLengthNumber(2) ||
+        !DayComposer::IsMonth(scanner->Peek().number())) return scanner->Next();
+    day->Add(scanner->Next().number());
+    if (scanner->SkipSymbol('-')) {
+      if (!scanner->Peek().IsFixedLengthNumber(2) ||
+          !DayComposer::IsDay(scanner->Peek().number())) return scanner->Next();
+      day->Add(scanner->Next().number());
+    }
+  }
+  // Check for optional time string: 'T'HH':'mm[':'ss['.'sss]]Z
+  if (!scanner->Peek().IsKeywordType(TIME_SEPARATOR)) {
+    if (!scanner->Peek().IsEndOfInput()) return scanner->Next();
+  } else {
+    // ES5 Date Time String time part is present.
+    scanner->Next();
+    if (!scanner->Peek().IsFixedLengthNumber(2) ||
+        !Between(scanner->Peek().number(), 0, 24)) {
+      return DateToken::Invalid();
+    }
+    // Allow 24:00[:00[.000]], but no other time starting with 24.
+    bool hour_is_24 = (scanner->Peek().number() == 24);
+    time->Add(scanner->Next().number());
+    if (!scanner->SkipSymbol(':')) return DateToken::Invalid();
+    if (!scanner->Peek().IsFixedLengthNumber(2) ||
+        !TimeComposer::IsMinute(scanner->Peek().number()) ||
+        (hour_is_24 && scanner->Peek().number() > 0)) {
+      return DateToken::Invalid();
+    }
+    time->Add(scanner->Next().number());
+    if (scanner->SkipSymbol(':')) {
+      if (!scanner->Peek().IsFixedLengthNumber(2) ||
+          !TimeComposer::IsSecond(scanner->Peek().number()) ||
+          (hour_is_24 && scanner->Peek().number() > 0)) {
+        return DateToken::Invalid();
+      }
+      time->Add(scanner->Next().number());
+      if (scanner->SkipSymbol('.')) {
+        if (!scanner->Peek().IsNumber() ||
+            (hour_is_24 && scanner->Peek().number() > 0)) {
+          return DateToken::Invalid();
+        }
+        // Allow more or less than the mandated three digits.
+        time->Add(ReadMilliseconds(scanner->Next()));
+      }
+    }
+    // Check for optional timezone designation: 'Z' | ('+'|'-')hh':'mm
+    if (scanner->Peek().IsKeywordZ()) {
+      scanner->Next();
+      tz->Set(0);
+    } else if (scanner->Peek().IsSymbol('+') ||
+               scanner->Peek().IsSymbol('-')) {
+      tz->SetSign(scanner->Next().symbol() == '+' ? 1 : -1);
+      if (scanner->Peek().IsFixedLengthNumber(4)) {
+        // hhmm extension syntax.
+        int hourmin = scanner->Next().number();
+        int hour = hourmin / 100;
+        int min = hourmin % 100;
+        if (!TimeComposer::IsHour(hour) || !TimeComposer::IsMinute(min)) {
+          return DateToken::Invalid();
+        }
+        tz->SetAbsoluteHour(hour);
+        tz->SetAbsoluteMinute(min);
+      } else {
+        // hh:mm standard syntax.
+        if (!scanner->Peek().IsFixedLengthNumber(2) ||
+            !TimeComposer::IsHour(scanner->Peek().number())) {
+          return DateToken::Invalid();
+        }
+        tz->SetAbsoluteHour(scanner->Next().number());
+        if (!scanner->SkipSymbol(':')) return DateToken::Invalid();
+        if (!scanner->Peek().IsFixedLengthNumber(2) ||
+            !TimeComposer::IsMinute(scanner->Peek().number())) {
+          return DateToken::Invalid();
+        }
+        tz->SetAbsoluteMinute(scanner->Next().number());
+      }
+    }
+    if (!scanner->Peek().IsEndOfInput()) return DateToken::Invalid();
+  }
+  // Successfully parsed ES5 Date Time String. Default to UTC if no TZ given.
+  if (tz->IsEmpty()) tz->Set(0);
+  day->set_iso_date();
+  return DateToken::EndOfInput();
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_DATEPARSER_INL_H_
diff --git a/src/dateparser.cc b/src/dateparser.cc
index 6d80488..4a0721f 100644
--- a/src/dateparser.cc
+++ b/src/dateparser.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -44,7 +44,7 @@
   int day = kNone;
 
   if (named_month_ == kNone) {
-    if (index_ == 3 && !IsDay(comp_[0])) {
+    if (is_iso_date_ || (index_ == 3 && !IsDay(comp_[0]))) {
       // YMD
       year = comp_[0];
       month = comp_[1];
@@ -71,8 +71,10 @@
     }
   }
 
-  if (Between(year, 0, 49)) year += 2000;
-  else if (Between(year, 50, 99)) year += 1900;
+  if (!is_iso_date_) {
+    if (Between(year, 0, 49)) year += 2000;
+    else if (Between(year, 50, 99)) year += 1900;
+  }
 
   if (!Smi::IsValid(year) || !IsMonth(month) || !IsDay(day)) return false;
 
@@ -151,6 +153,7 @@
   {'m', 's', 't', DateParser::TIME_ZONE_NAME, -7},
   {'p', 'd', 't', DateParser::TIME_ZONE_NAME, -7},
   {'p', 's', 't', DateParser::TIME_ZONE_NAME, -8},
+  {'t', '\0', '\0', DateParser::TIME_SEPARATOR, 0},
   {'\0', '\0', '\0', DateParser::INVALID, 0},
 };
 
@@ -175,4 +178,35 @@
 }
 
 
+int DateParser::ReadMilliseconds(DateToken token) {
+  // Read first three significant digits of the original numeral,
+  // as inferred from the value and the number of digits.
+  // I.e., use the number of digits to see if there were
+  // leading zeros.
+  int number = token.number();
+  int length = token.length();
+  if (length < 3) {
+    // Less than three digits. Multiply to put most significant digit
+    // in hundreds position.
+    if (length == 1) {
+      number *= 100;
+    } else if (length == 2) {
+      number *= 10;
+    }
+  } else if (length > 3) {
+    if (length > kMaxSignificantDigits) length = kMaxSignificantDigits;
+    // More than three digits. Divide by 10^(length - 3) to get three
+    // most significant digits.
+    int factor = 1;
+    do {
+      ASSERT(factor <= 100000000);  // factor won't overflow.
+      factor *= 10;
+      length--;
+    } while (length > 3);
+    number /= factor;
+  }
+  return number;
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/dateparser.h b/src/dateparser.h
index 6e87c34..4bd320e 100644
--- a/src/dateparser.h
+++ b/src/dateparser.h
@@ -61,9 +61,14 @@
   static inline bool Between(int x, int lo, int hi) {
     return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo);
   }
+
   // Indicates a missing value.
   static const int kNone = kMaxInt;
 
+  // Maximal number of digits used to build the value of a numeral.
+  // Remaining digits are ignored.
+  static const int kMaxSignificantDigits = 9;
+
   // InputReader provides basic string parsing and character classification.
   template <typename Char>
   class InputReader BASE_EMBEDDED {
@@ -71,32 +76,28 @@
     InputReader(UnicodeCache* unicode_cache, Vector<Char> s)
         : index_(0),
           buffer_(s),
-          has_read_number_(false),
           unicode_cache_(unicode_cache) {
       Next();
     }
 
-    // Advance to the next character of the string.
-    void Next() { ch_ = (index_ < buffer_.length()) ? buffer_[index_++] : 0; }
+    int position() { return index_; }
 
-    // Read a string of digits as an unsigned number (cap just below kMaxInt).
-    int ReadUnsignedNumber() {
-      has_read_number_ = true;
-      int n;
-      for (n = 0; IsAsciiDigit() && n < kMaxInt / 10 - 1; Next()) {
-        n = n * 10 + ch_ - '0';
-      }
-      return n;
+    // Advance to the next character of the string.
+    void Next() {
+      ch_ = (index_ < buffer_.length()) ? buffer_[index_] : 0;
+      index_++;
     }
 
-    // Read a string of digits, take the first three or fewer as an unsigned
-    // number of milliseconds, and ignore any digits after the first three.
-    int ReadMilliseconds() {
-      has_read_number_ = true;
+    // Read a string of digits as an unsigned number. Cap value at
+    // kMaxSignificantDigits, but skip remaining digits if the numeral
+    // is longer.
+    int ReadUnsignedNumeral() {
       int n = 0;
-      int power;
-      for (power = 100; IsAsciiDigit(); Next(), power = power / 10) {
-        n = n + power * (ch_ - '0');
+      int i = 0;
+      while (IsAsciiDigit()) {
+        if (i < kMaxSignificantDigits) n = n * 10 + ch_ - '0';
+        i++;
+        Next();
       }
       return n;
     }
@@ -151,18 +152,138 @@
     // Return 1 for '+' and -1 for '-'.
     int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); }
 
-    // Indicates whether any (possibly empty!) numbers have been read.
-    bool HasReadNumber() const { return has_read_number_; }
-
    private:
     int index_;
     Vector<Char> buffer_;
-    bool has_read_number_;
     uint32_t ch_;
     UnicodeCache* unicode_cache_;
   };
 
-  enum KeywordType { INVALID, MONTH_NAME, TIME_ZONE_NAME, AM_PM };
+  enum KeywordType {
+      INVALID, MONTH_NAME, TIME_ZONE_NAME, TIME_SEPARATOR, AM_PM
+  };
+
+  struct DateToken {
+   public:
+    bool IsInvalid() { return tag_ == kInvalidTokenTag; }
+    bool IsUnknown() { return tag_ == kUnknownTokenTag; }
+    bool IsNumber() { return tag_ == kNumberTag; }
+    bool IsSymbol() { return tag_ == kSymbolTag; }
+    bool IsWhiteSpace() { return tag_ == kWhiteSpaceTag; }
+    bool IsEndOfInput() { return tag_ == kEndOfInputTag; }
+    bool IsKeyword() { return tag_ >= kKeywordTagStart; }
+
+    int length() { return length_; }
+
+    int number() {
+      ASSERT(IsNumber());
+      return value_;
+    }
+    KeywordType keyword_type() {
+      ASSERT(IsKeyword());
+      return static_cast<KeywordType>(tag_);
+    }
+    int keyword_value() {
+      ASSERT(IsKeyword());
+      return value_;
+    }
+    char symbol() {
+      ASSERT(IsSymbol());
+      return static_cast<char>(value_);
+    }
+    bool IsSymbol(char symbol) {
+      return IsSymbol() && this->symbol() == symbol;
+    }
+    bool IsKeywordType(KeywordType tag) {
+      return tag_ == tag;
+    }
+    bool IsFixedLengthNumber(int length) {
+      return IsNumber() && length_ == length;
+    }
+    bool IsAsciiSign() {
+      return tag_ == kSymbolTag && (value_ == '-' || value_ == '+');
+    }
+    int ascii_sign() {
+      ASSERT(IsAsciiSign());
+      return 44 - value_;
+    }
+    bool IsKeywordZ() {
+      return IsKeywordType(TIME_ZONE_NAME) && length_ == 1 && value_ == 0;
+    }
+    bool IsUnknown(int character) {
+      return IsUnknown() && value_ == character;
+    }
+    // Factory functions.
+    static DateToken Keyword(KeywordType tag, int value, int length) {
+      return DateToken(tag, length, value);
+    }
+    static DateToken Number(int value, int length) {
+      return DateToken(kNumberTag, length, value);
+    }
+    static DateToken Symbol(char symbol) {
+      return DateToken(kSymbolTag, 1, symbol);
+    }
+    static DateToken EndOfInput() {
+      return DateToken(kEndOfInputTag, 0, -1);
+    }
+    static DateToken WhiteSpace(int length) {
+      return DateToken(kWhiteSpaceTag, length, -1);
+    }
+    static DateToken Unknown() {
+      return DateToken(kUnknownTokenTag, 1, -1);
+    }
+    static DateToken Invalid() {
+      return DateToken(kInvalidTokenTag, 0, -1);
+    }
+   private:
+    enum TagType {
+      kInvalidTokenTag = -6,
+      kUnknownTokenTag = -5,
+      kWhiteSpaceTag = -4,
+      kNumberTag = -3,
+      kSymbolTag = -2,
+      kEndOfInputTag = -1,
+      kKeywordTagStart = 0
+    };
+    DateToken(int tag, int length, int value)
+        : tag_(tag),
+          length_(length),
+          value_(value) { }
+
+    int tag_;
+    int length_;  // Number of characters.
+    int value_;
+  };
+
+  template <typename Char>
+  class DateStringTokenizer {
+   public:
+    explicit DateStringTokenizer(InputReader<Char>* in)
+        : in_(in), next_(Scan()) { }
+    DateToken Next() {
+      DateToken result = next_;
+      next_ = Scan();
+      return result;
+    }
+
+    DateToken Peek() {
+      return next_;
+    }
+    bool SkipSymbol(char symbol) {
+      if (next_.IsSymbol(symbol)) {
+        next_ = Scan();
+        return true;
+      }
+      return false;
+    }
+   private:
+    DateToken Scan();
+
+    InputReader<Char>* in_;
+    DateToken next_;
+  };
+
+  static int ReadMilliseconds(DateToken number);
 
   // KeywordTable maps names of months, time zones, am/pm to numbers.
   class KeywordTable : public AllStatic {
@@ -201,6 +322,7 @@
     }
     bool IsUTC() const { return hour_ == 0 && minute_ == 0; }
     bool Write(FixedArray* output);
+    bool IsEmpty() { return hour_ == kNone; }
    private:
     int sign_;
     int hour_;
@@ -228,10 +350,10 @@
     bool Write(FixedArray* output);
 
     static bool IsMinute(int x) { return Between(x, 0, 59); }
-   private:
     static bool IsHour(int x) { return Between(x, 0, 23); }
-    static bool IsHour12(int x) { return Between(x, 0, 12); }
     static bool IsSecond(int x) { return Between(x, 0, 59); }
+   private:
+    static bool IsHour12(int x) { return Between(x, 0, 12); }
     static bool IsMillisecond(int x) { return Between(x, 0, 999); }
 
     static const int kSize = 4;
@@ -242,22 +364,42 @@
 
   class DayComposer BASE_EMBEDDED {
    public:
-    DayComposer() : index_(0), named_month_(kNone) {}
+    DayComposer() : index_(0), named_month_(kNone), is_iso_date_(false) {}
     bool IsEmpty() const { return index_ == 0; }
     bool Add(int n) {
-      return index_ < kSize ? (comp_[index_++] = n, true) : false;
+      if (index_ < kSize) {
+        comp_[index_] = n;
+        index_++;
+        return true;
+      }
+      return false;
     }
     void SetNamedMonth(int n) { named_month_ = n; }
     bool Write(FixedArray* output);
-   private:
+    void set_iso_date() { is_iso_date_ = true; }
     static bool IsMonth(int x) { return Between(x, 1, 12); }
     static bool IsDay(int x) { return Between(x, 1, 31); }
 
+   private:
     static const int kSize = 3;
     int comp_[kSize];
     int index_;
     int named_month_;
+    // If set, ensures that data is always parsed in year-month-date order.
+    bool is_iso_date_;
   };
+
+  // Tries to parse an ES5 Date Time String. Returns the next token
+  // to continue with in the legacy date string parser. If parsing is
+  // complete, returns DateToken::EndOfInput(). If terminally unsuccessful,
+  // returns DateToken::Invalid(). Otherwise parsing continues in the
+  // legacy parser.
+  template <typename Char>
+  static DateParser::DateToken ParseES5DateTime(
+      DateStringTokenizer<Char>* scanner,
+      DayComposer* day,
+      TimeComposer* time,
+      TimeZoneComposer* tz);
 };
 
 
diff --git a/src/debug-agent.cc b/src/debug-agent.cc
index 498b88a..520bc62 100644
--- a/src/debug-agent.cc
+++ b/src/debug-agent.cc
@@ -116,8 +116,8 @@
   }
 
   // Create a new session and hook up the debug message handler.
-  session_ = new DebuggerAgentSession(isolate(), this, client);
-  v8::Debug::SetMessageHandler2(DebuggerAgentMessageHandler);
+  session_ = new DebuggerAgentSession(this, client);
+  isolate_->debugger()->SetMessageHandler(DebuggerAgentMessageHandler);
   session_->Start();
 }
 
@@ -203,7 +203,9 @@
 
     // Send the request received to the debugger.
     v8::Debug::SendCommand(reinterpret_cast<const uint16_t *>(temp.start()),
-                           len);
+                           len,
+                           NULL,
+                           reinterpret_cast<v8::Isolate*>(agent_->isolate()));
 
     if (is_closing_session) {
       // Session is closed.
diff --git a/src/debug-agent.h b/src/debug-agent.h
index a25002e..e167871 100644
--- a/src/debug-agent.h
+++ b/src/debug-agent.h
@@ -43,24 +43,27 @@
 // handles connection from a remote debugger.
 class DebuggerAgent: public Thread {
  public:
-  DebuggerAgent(Isolate* isolate, const char* name, int port)
-      : Thread(isolate, name),
+  DebuggerAgent(const char* name, int port)
+      : Thread(name),
+        isolate_(Isolate::Current()),
         name_(StrDup(name)), port_(port),
         server_(OS::CreateSocket()), terminate_(false),
         session_access_(OS::CreateMutex()), session_(NULL),
         terminate_now_(OS::CreateSemaphore(0)),
         listening_(OS::CreateSemaphore(0)) {
-    ASSERT(Isolate::Current()->debugger_agent_instance() == NULL);
-    Isolate::Current()->set_debugger_agent_instance(this);
+    ASSERT(isolate_->debugger_agent_instance() == NULL);
+    isolate_->set_debugger_agent_instance(this);
   }
   ~DebuggerAgent() {
-     Isolate::Current()->set_debugger_agent_instance(NULL);
+     isolate_->set_debugger_agent_instance(NULL);
      delete server_;
   }
 
   void Shutdown();
   void WaitUntilListening();
 
+  Isolate* isolate() { return isolate_; }
+
  private:
   void Run();
   void CreateSession(Socket* socket);
@@ -68,6 +71,7 @@
   void CloseSession();
   void OnSessionClosed(DebuggerAgentSession* session);
 
+  Isolate* isolate_;
   SmartPointer<const char> name_;  // Name of the embedding application.
   int port_;  // Port to use for the agent.
   Socket* server_;  // Server socket for listen/accept.
@@ -88,8 +92,8 @@
 // debugger and sends debugger events/responses to the remote debugger.
 class DebuggerAgentSession: public Thread {
  public:
-  DebuggerAgentSession(Isolate* isolate, DebuggerAgent* agent, Socket* client)
-      : Thread(isolate, "v8:DbgAgntSessn"),
+  DebuggerAgentSession(DebuggerAgent* agent, Socket* client)
+      : Thread("v8:DbgAgntSessn"),
         agent_(agent), client_(client) {}
 
   void DebuggerMessage(Vector<uint16_t> message);
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index 908fcd2..36b624e 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -68,7 +68,8 @@
 
 // The different script break point types.
 Debug.ScriptBreakPointType = { ScriptId: 0,
-                               ScriptName: 1 };
+                               ScriptName: 1,
+                               ScriptRegExp: 2 };
 
 function ScriptTypeFlag(type) {
   return (1 << type);
@@ -255,8 +256,12 @@
   this.type_ = type;
   if (type == Debug.ScriptBreakPointType.ScriptId) {
     this.script_id_ = script_id_or_name;
-  } else {  // type == Debug.ScriptBreakPointType.ScriptName
+  } else if (type == Debug.ScriptBreakPointType.ScriptName) {
     this.script_name_ = script_id_or_name;
+  } else if (type == Debug.ScriptBreakPointType.ScriptRegExp) {
+    this.script_regexp_object_ = new RegExp(script_id_or_name);
+  } else {
+    throw new Error("Unexpected breakpoint type " + type);
   }
   this.line_ = opt_line || 0;
   this.column_ = opt_column;
@@ -309,6 +314,11 @@
 };
 
 
+ScriptBreakPoint.prototype.script_regexp_object = function() {
+  return this.script_regexp_object_;
+};
+
+
 ScriptBreakPoint.prototype.line = function() {
   return this.line_;
 };
@@ -384,10 +394,19 @@
 ScriptBreakPoint.prototype.matchesScript = function(script) {
   if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
     return this.script_id_ == script.id;
-  } else {  // this.type_ == Debug.ScriptBreakPointType.ScriptName
-    return this.script_name_ == script.nameOrSourceURL() &&
-           script.line_offset <= this.line_  &&
-           this.line_ < script.line_offset + script.lineCount();
+  } else {
+    // We might want to account columns here as well.
+    if (!(script.line_offset <= this.line_  &&
+          this.line_ < script.line_offset + script.lineCount())) {
+      return false;
+    }
+    if (this.type_ == Debug.ScriptBreakPointType.ScriptName) {
+      return this.script_name_ == script.nameOrSourceURL();
+    } else if (this.type_ == Debug.ScriptBreakPointType.ScriptRegExp) {
+      return this.script_regexp_object_.test(script.nameOrSourceURL());
+    } else { 
+      throw new Error("Unexpected breakpoint type " + this.type_);
+    }
   }
 };
 
@@ -431,7 +450,8 @@
   }
   var actual_location = script.locationFromPosition(actual_position, true);
   break_point.actual_location = { line: actual_location.line,
-                                  column: actual_location.column };
+                                  column: actual_location.column,
+                                  script_id: script.id };
   this.break_points_.push(break_point);
   return break_point;
 };
@@ -644,7 +664,8 @@
     actual_position += this.sourcePosition(func);
     var actual_location = script.locationFromPosition(actual_position, true);
     break_point.actual_location = { line: actual_location.line,
-                                    column: actual_location.column };
+                                    column: actual_location.column,
+                                    script_id: script.id };
     break_point.setCondition(opt_condition);
     return break_point.number();
   }
@@ -799,6 +820,15 @@
 }
 
 
+Debug.setScriptBreakPointByRegExp = function(script_regexp,
+                                             opt_line, opt_column,
+                                             opt_condition, opt_groupId) {
+  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptRegExp,
+                                  script_regexp, opt_line, opt_column,
+                                  opt_condition, opt_groupId);
+}
+
+
 Debug.enableScriptBreakPoint = function(break_point_number) {
   var script_break_point = this.findScriptBreakPoint(break_point_number, false);
   script_break_point.enable();
@@ -1549,12 +1579,7 @@
     response.failed('Missing argument "type" or "target"');
     return;
   }
-  if (type != 'function' && type != 'handle' &&
-      type != 'script' && type != 'scriptId') {
-    response.failed('Illegal type "' + type + '"');
-    return;
-  }
-
+  
   // Either function or script break point.
   var break_point_number;
   if (type == 'function') {
@@ -1598,9 +1623,16 @@
     break_point_number =
         Debug.setScriptBreakPointByName(target, line, column, condition,
                                         groupId);
-  } else {  // type == 'scriptId.
+  } else if (type == 'scriptId') { 
     break_point_number =
         Debug.setScriptBreakPointById(target, line, column, condition, groupId);
+  } else if (type == 'scriptRegExp') { 
+    break_point_number =
+        Debug.setScriptBreakPointByRegExp(target, line, column, condition,
+                                          groupId);
+  } else {
+    response.failed('Illegal type "' + type + '"');
+    return;
   }
 
   // Set additional break point properties.
@@ -1621,9 +1653,14 @@
     if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
       response.body.type = 'scriptId';
       response.body.script_id = break_point.script_id();
-    } else {
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptName) {
       response.body.type = 'scriptName';
       response.body.script_name = break_point.script_name();
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) {
+      response.body.type = 'scriptRegExp';
+      response.body.script_regexp = break_point.script_regexp_object().source;
+    } else {
+      throw new Error("Internal error: Unexpected breakpoint type: " + break_point.type());
     }
     response.body.line = break_point.line();
     response.body.column = break_point.column();
@@ -1753,9 +1790,14 @@
     if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
       description.type = 'scriptId';
       description.script_id = break_point.script_id();
-    } else {
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptName) {
       description.type = 'scriptName';
       description.script_name = break_point.script_name();
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) {
+      description.type = 'scriptRegExp';
+      description.script_regexp = break_point.script_regexp_object().source;
+    } else {
+      throw new Error("Internal error: Unexpected breakpoint type: " + break_point.type()); 
     }
     array.push(description);
   }
@@ -2269,21 +2311,10 @@
 
 
 DebugCommandProcessor.prototype.profileRequest_ = function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-  var modules = parseInt(request.arguments.modules);
-  if (isNaN(modules)) {
-    return response.failed('Modules is not an integer');
-  }
-  var tag = parseInt(request.arguments.tag);
-  if (isNaN(tag)) {
-    tag = 0;
-  }
   if (request.arguments.command == 'resume') {
-    %ProfilerResume(modules, tag);
+    %ProfilerResume();
   } else if (request.arguments.command == 'pause') {
-    %ProfilerPause(modules, tag);
+    %ProfilerPause();
   } else {
     return response.failed('Unknown command');
   }
diff --git a/src/debug.cc b/src/debug.cc
index 85c4b5e..aecbb46 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -772,9 +772,9 @@
   bool caught_exception = false;
   Handle<JSFunction> function =
       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
-  Handle<Object> result =
-      Execution::TryCall(function, Handle<Object>(context->global()),
-                         0, NULL, &caught_exception);
+
+  Execution::TryCall(function, Handle<Object>(context->global()),
+                     0, NULL, &caught_exception);
 
   // Check for caught exceptions.
   if (caught_exception) {
@@ -796,7 +796,6 @@
   // Return if debugger is already loaded.
   if (IsLoaded()) return true;
 
-  ASSERT(Isolate::Current() == isolate_);
   Debugger* debugger = isolate_->debugger();
 
   // Bail out if we're already in the process of compiling the native
@@ -1048,7 +1047,6 @@
 
 // Check whether a single break point object is triggered.
 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
-  ASSERT(Isolate::Current() == isolate_);
   Factory* factory = isolate_->factory();
   HandleScope scope(isolate_);
 
@@ -1234,7 +1232,6 @@
 
 
 void Debug::PrepareStep(StepAction step_action, int step_count) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
   ASSERT(Debug::InDebugger());
 
@@ -1739,7 +1736,6 @@
 
 
 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
 
   // Get the executing function in which the debug break occurred.
@@ -1825,6 +1821,13 @@
 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
   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
+  // return.
+  if (!has_break_points_) {
+    return false;
+  }
+
   // Get the executing function in which the debug break occurred.
   Handle<SharedFunctionInfo> shared =
       Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
@@ -1872,7 +1875,6 @@
 
 
 void Debug::ClearMirrorCache() {
-  ASSERT(Isolate::Current() == isolate_);
   PostponeInterruptsScope postpone(isolate_);
   HandleScope scope(isolate_);
   ASSERT(isolate_->context() == *Debug::debug_context());
@@ -1884,15 +1886,13 @@
       *function_name));
   ASSERT(fun->IsJSFunction());
   bool caught_exception;
-  Handle<Object> js_object = Execution::TryCall(
-      Handle<JSFunction>::cast(fun),
+  Execution::TryCall(Handle<JSFunction>::cast(fun),
       Handle<JSObject>(Debug::debug_context()->global()),
       0, NULL, &caught_exception);
 }
 
 
 void Debug::CreateScriptCache() {
-  ASSERT(Isolate::Current() == isolate_);
   Heap* heap = isolate_->heap();
   HandleScope scope(isolate_);
 
@@ -1934,7 +1934,6 @@
 
 
 Handle<FixedArray> Debug::GetLoadedScripts() {
-  ASSERT(Isolate::Current() == isolate_);
   // Create and fill the script cache when the loaded scripts is requested for
   // the first time.
   if (script_cache_ == NULL) {
@@ -1964,7 +1963,7 @@
 }
 
 
-Debugger::Debugger()
+Debugger::Debugger(Isolate* isolate)
     : debugger_access_(OS::CreateMutex()),
       event_listener_(Handle<Object>()),
       event_listener_data_(Handle<Object>()),
@@ -1979,9 +1978,10 @@
       message_dispatch_helper_thread_(NULL),
       host_dispatch_micros_(100 * 1000),
       agent_(NULL),
-      command_queue_(kQueueInitialSize),
+      command_queue_(isolate->logger(), kQueueInitialSize),
       command_received_(OS::CreateSemaphore(0)),
-      event_command_queue_(kQueueInitialSize) {
+      event_command_queue_(isolate->logger(), kQueueInitialSize),
+      isolate_(isolate) {
 }
 
 
@@ -1998,7 +1998,6 @@
 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
                                       int argc, Object*** argv,
                                       bool* caught_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
 
   // Create the execution state object.
@@ -2020,7 +2019,6 @@
 
 
 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   // Create the execution state object.
   Handle<Object> break_id = isolate_->factory()->NewNumberFromInt(
       isolate_->debug()->break_id());
@@ -2034,7 +2032,6 @@
 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state,
                                         Handle<Object> break_points_hit,
                                         bool* caught_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   // Create the new break event object.
   const int argc = 2;
   Object** argv[argc] = { exec_state.location(),
@@ -2050,7 +2047,6 @@
                                             Handle<Object> exception,
                                             bool uncaught,
                                             bool* caught_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   Factory* factory = isolate_->factory();
   // Create the new exception event object.
   const int argc = 3;
@@ -2065,7 +2061,6 @@
 
 Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function,
                                               bool* caught_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   // Create the new function event object.
   const int argc = 1;
   Object** argv[argc] = { function.location() };
@@ -2077,7 +2072,6 @@
 Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
                                           bool before,
                                           bool* caught_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   Factory* factory = isolate_->factory();
   // Create the compile event object.
   Handle<Object> exec_state = MakeExecutionState(caught_exception);
@@ -2097,7 +2091,6 @@
 
 Handle<Object> Debugger::MakeScriptCollectedEvent(int id,
                                                   bool* caught_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   // Create the script collected event object.
   Handle<Object> exec_state = MakeExecutionState(caught_exception);
   Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id));
@@ -2112,7 +2105,6 @@
 
 
 void Debugger::OnException(Handle<Object> exception, bool uncaught) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
   Debug* debug = isolate_->debug();
 
@@ -2157,7 +2149,6 @@
 
 void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
                             bool auto_continue) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
 
   // Debugger has already been entered by caller.
@@ -2167,7 +2158,7 @@
   if (!Debugger::EventActive(v8::Break)) return;
 
   // Debugger must be entered in advance.
-  ASSERT(Isolate::Current()->context() == *isolate_->debug()->debug_context());
+  ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
 
   // Create the event data object.
   bool caught_exception = false;
@@ -2190,7 +2181,6 @@
 
 
 void Debugger::OnBeforeCompile(Handle<Script> script) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
 
   // Bail out based on state or if there is no listener for this event
@@ -2220,7 +2210,6 @@
 // Handle debugger actions when a new script is compiled.
 void Debugger::OnAfterCompile(Handle<Script> script,
                               AfterCompileFlags after_compile_flags) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
   Debug* debug = isolate_->debug();
 
@@ -2262,8 +2251,7 @@
   bool caught_exception = false;
   const int argc = 1;
   Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) };
-  Handle<Object> result = Execution::TryCall(
-      Handle<JSFunction>::cast(update_script_break_points),
+  Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
       Isolate::Current()->js_builtins_object(), argc, argv,
       &caught_exception);
   if (caught_exception) {
@@ -2289,7 +2277,6 @@
 
 
 void Debugger::OnScriptCollected(int id) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
 
   // No more to do if not debugging.
@@ -2319,7 +2306,6 @@
 void Debugger::ProcessDebugEvent(v8::DebugEvent event,
                                  Handle<JSObject> event_data,
                                  bool auto_continue) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
 
   // Clear any pending debug break if this is a real break.
@@ -2395,7 +2381,6 @@
                                    Handle<Object> exec_state,
                                    Handle<Object> event_data) {
   ASSERT(event_listener_->IsJSFunction());
-  ASSERT(Isolate::Current() == isolate_);
   Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
 
   // Invoke the JavaScript debug event listener.
@@ -2411,7 +2396,6 @@
 
 
 Handle<Context> Debugger::GetDebugContext() {
-  ASSERT(Isolate::Current() == isolate_);
   never_unload_debugger_ = true;
   EnterDebugger debugger;
   return isolate_->debug()->debug_context();
@@ -2419,7 +2403,6 @@
 
 
 void Debugger::UnloadDebugger() {
-  ASSERT(Isolate::Current() == isolate_);
   Debug* debug = isolate_->debug();
 
   // Make sure that there are no breakpoints left.
@@ -2439,7 +2422,6 @@
                                     Handle<JSObject> exec_state,
                                     Handle<JSObject> event_data,
                                     bool auto_continue) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
 
   if (!isolate_->debug()->Load()) return;
@@ -2535,7 +2517,8 @@
 
     // Get the command from the queue.
     CommandMessage command = command_queue_.Get();
-    LOGGER->DebugTag("Got request from command queue, in interactive loop.");
+    isolate_->logger()->DebugTag(
+        "Got request from command queue, in interactive loop.");
     if (!Debugger::IsDebuggerActive()) {
       // Delete command text and user data.
       command.Dispose();
@@ -2609,7 +2592,6 @@
 
 void Debugger::SetEventListener(Handle<Object> callback,
                                 Handle<Object> data) {
-  ASSERT(Isolate::Current() == isolate_);
   HandleScope scope(isolate_);
   GlobalHandles* global_handles = isolate_->global_handles();
 
@@ -2643,7 +2625,6 @@
 
 
 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
-  ASSERT(Isolate::Current() == isolate_);
   ScopedLock with(debugger_access_);
 
   message_handler_ = handler;
@@ -2659,7 +2640,6 @@
 
 
 void Debugger::ListenersChanged() {
-  ASSERT(Isolate::Current() == isolate_);
   if (IsDebuggerActive()) {
     // Disable the compilation cache when the debugger is active.
     isolate_->compilation_cache()->Disable();
@@ -2675,7 +2655,6 @@
 
 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
                                       int period) {
-  ASSERT(Isolate::Current() == isolate_);
   host_dispatch_handler_ = handler;
   host_dispatch_micros_ = period * 1000;
 }
@@ -2683,7 +2662,6 @@
 
 void Debugger::SetDebugMessageDispatchHandler(
     v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) {
-  ASSERT(Isolate::Current() == isolate_);
   ScopedLock with(dispatch_handler_access_);
   debug_message_dispatch_handler_ = handler;
 
@@ -2697,7 +2675,6 @@
 // Calls the registered debug message handler. This callback is part of the
 // public API.
 void Debugger::InvokeMessageHandler(MessageImpl message) {
-  ASSERT(Isolate::Current() == isolate_);
   ScopedLock with(debugger_access_);
 
   if (message_handler_ != NULL) {
@@ -2712,13 +2689,12 @@
 // by the API client thread.
 void Debugger::ProcessCommand(Vector<const uint16_t> command,
                               v8::Debug::ClientData* client_data) {
-  ASSERT(Isolate::Current() == isolate_);
   // Need to cast away const.
   CommandMessage message = CommandMessage::New(
       Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
                        command.length()),
       client_data);
-  LOGGER->DebugTag("Put command on command_queue.");
+  isolate_->logger()->DebugTag("Put command on command_queue.");
   command_queue_.Put(message);
   command_received_->Signal();
 
@@ -2742,13 +2718,11 @@
 
 
 bool Debugger::HasCommands() {
-  ASSERT(Isolate::Current() == isolate_);
   return !command_queue_.IsEmpty();
 }
 
 
 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
-  ASSERT(Isolate::Current() == isolate_);
   CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
   event_command_queue_.Put(message);
 
@@ -2760,7 +2734,6 @@
 
 
 bool Debugger::IsDebuggerActive() {
-  ASSERT(Isolate::Current() == isolate_);
   ScopedLock with(debugger_access_);
 
   return message_handler_ != NULL || !event_listener_.is_null();
@@ -2770,7 +2743,6 @@
 Handle<Object> Debugger::Call(Handle<JSFunction> fun,
                               Handle<Object> data,
                               bool* pending_exception) {
-  ASSERT(Isolate::Current() == isolate_);
   // When calling functions in the debugger prevent it from beeing unloaded.
   Debugger::never_unload_debugger_ = true;
 
@@ -2820,7 +2792,7 @@
 
   if (Socket::Setup()) {
     if (agent_ == NULL) {
-      agent_ = new DebuggerAgent(isolate_, name, port);
+      agent_ = new DebuggerAgent(name, port);
       agent_->Start();
     }
     return true;
@@ -2849,7 +2821,6 @@
 
 
 void Debugger::CallMessageDispatchHandler() {
-  ASSERT(Isolate::Current() == isolate_);
   v8::Debug::DebugMessageDispatchHandler handler;
   {
     ScopedLock with(dispatch_handler_access_);
@@ -2957,7 +2928,7 @@
   v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
   // Isolate::context() may be NULL when "script collected" event occures.
   ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected);
-  return GetDebugEventContext(isolate);
+  return context;
 }
 
 
@@ -3083,8 +3054,8 @@
 }
 
 
-LockingCommandMessageQueue::LockingCommandMessageQueue(int size)
-    : queue_(size) {
+LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
+    : logger_(logger), queue_(size) {
   lock_ = OS::CreateMutex();
 }
 
@@ -3103,7 +3074,7 @@
 CommandMessage LockingCommandMessageQueue::Get() {
   ScopedLock sl(lock_);
   CommandMessage result = queue_.Get();
-  LOGGER->DebugEvent("Get", result.text());
+  logger_->DebugEvent("Get", result.text());
   return result;
 }
 
@@ -3111,7 +3082,7 @@
 void LockingCommandMessageQueue::Put(const CommandMessage& message) {
   ScopedLock sl(lock_);
   queue_.Put(message);
-  LOGGER->DebugEvent("Put", message.text());
+  logger_->DebugEvent("Put", message.text());
 }
 
 
@@ -3122,7 +3093,7 @@
 
 
 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate)
-    : Thread(isolate, "v8:MsgDispHelpr"),
+    : Thread("v8:MsgDispHelpr"),
       sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
       already_signalled_(false) {
 }
diff --git a/src/debug.h b/src/debug.h
index 95dca72..c614844 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -35,6 +35,7 @@
 #include "execution.h"
 #include "factory.h"
 #include "flags.h"
+#include "frames-inl.h"
 #include "hashmap.h"
 #include "platform.h"
 #include "string-stream.h"
@@ -678,13 +679,14 @@
 // Mutex to CommandMessageQueue.  Includes logging of all puts and gets.
 class LockingCommandMessageQueue BASE_EMBEDDED {
  public:
-  explicit LockingCommandMessageQueue(int size);
+  LockingCommandMessageQueue(Logger* logger, int size);
   ~LockingCommandMessageQueue();
   bool IsEmpty() const;
   CommandMessage Get();
   void Put(const CommandMessage& message);
   void Clear();
  private:
+  Logger* logger_;
   CommandMessageQueue queue_;
   Mutex* lock_;
   DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
@@ -811,7 +813,7 @@
   bool IsDebuggerActive();
 
  private:
-  Debugger();
+  explicit Debugger(Isolate* isolate);
 
   void CallEventCallback(v8::DebugEvent event,
                          Handle<Object> exec_state,
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 2fc0e47..c90df45 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -44,6 +44,9 @@
   lazy_deoptimization_entry_code_ = NULL;
   current_ = NULL;
   deoptimizing_code_list_ = NULL;
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  deoptimized_frame_info_ = NULL;
+#endif
 }
 
 
@@ -58,6 +61,16 @@
   }
 }
 
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void DeoptimizerData::Iterate(ObjectVisitor* v) {
+  if (deoptimized_frame_info_ != NULL) {
+    deoptimized_frame_info_->Iterate(v);
+  }
+}
+#endif
+
+
 Deoptimizer* Deoptimizer::New(JSFunction* function,
                               BailoutType type,
                               unsigned bailout_id,
@@ -70,7 +83,8 @@
                                              type,
                                              bailout_id,
                                              from,
-                                             fp_to_sp_delta);
+                                             fp_to_sp_delta,
+                                             NULL);
   ASSERT(isolate->deoptimizer_data()->current_ == NULL);
   isolate->deoptimizer_data()->current_ = deoptimizer;
   return deoptimizer;
@@ -86,6 +100,91 @@
   return result;
 }
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
+    JavaScriptFrame* frame,
+    int frame_index,
+    Isolate* isolate) {
+  ASSERT(isolate == Isolate::Current());
+  ASSERT(frame->is_optimized());
+  ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
+
+  // Get the function and code from the frame.
+  JSFunction* function = JSFunction::cast(frame->function());
+  Code* code = frame->LookupCode();
+  Address code_start_address = code->instruction_start();
+
+  // Locate the deoptimization point in the code. As we are at a call the
+  // return address must be at a place in the code with deoptimization support.
+  int deoptimization_index = Safepoint::kNoDeoptimizationIndex;
+  // Scope this as the safe point constructor will disallow allocation.
+  {
+    SafepointTable table(code);
+    for (unsigned i = 0; i < table.length(); ++i) {
+      Address address = code_start_address + table.GetPcOffset(i);
+      if (address == frame->pc()) {
+        SafepointEntry safepoint_entry = table.GetEntry(i);
+        ASSERT(safepoint_entry.deoptimization_index() !=
+               Safepoint::kNoDeoptimizationIndex);
+        deoptimization_index = safepoint_entry.deoptimization_index();
+        break;
+      }
+    }
+  }
+  ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex);
+
+  // Always use the actual stack slots when calculating the fp to sp
+  // delta adding two for the function and context.
+  unsigned stack_slots = code->stack_slots();
+  unsigned fp_to_sp_delta = ((stack_slots + 2) * kPointerSize);
+
+  Deoptimizer* deoptimizer = new Deoptimizer(isolate,
+                                             function,
+                                             Deoptimizer::DEBUGGER,
+                                             deoptimization_index,
+                                             frame->pc(),
+                                             fp_to_sp_delta,
+                                             code);
+  Address tos = frame->fp() - fp_to_sp_delta;
+  deoptimizer->FillInputFrame(tos, frame);
+
+  // Calculate the output frames.
+  Deoptimizer::ComputeOutputFrames(deoptimizer);
+
+  // Create the GC safe output frame information and register it for GC
+  // handling.
+  ASSERT_LT(frame_index, deoptimizer->output_count());
+  DeoptimizedFrameInfo* info =
+      new DeoptimizedFrameInfo(deoptimizer, frame_index);
+  isolate->deoptimizer_data()->deoptimized_frame_info_ = info;
+
+  // Get the "simulated" top and size for the requested frame.
+  Address top =
+      reinterpret_cast<Address>(deoptimizer->output_[frame_index]->GetTop());
+  uint32_t size = deoptimizer->output_[frame_index]->GetFrameSize();
+
+  // Done with the GC-unsafe frame descriptions. This re-enables allocation.
+  deoptimizer->DeleteFrameDescriptions();
+
+  // Allocate a heap number for the doubles belonging to this frame.
+  deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
+      top, size, info);
+
+  // Finished using the deoptimizer instance.
+  delete deoptimizer;
+
+  return info;
+}
+
+
+void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
+                                                 Isolate* isolate) {
+  ASSERT(isolate == Isolate::Current());
+  ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info);
+  delete info;
+  isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL;
+}
+#endif
 
 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
                                                 int count,
@@ -209,18 +308,24 @@
                          BailoutType type,
                          unsigned bailout_id,
                          Address from,
-                         int fp_to_sp_delta)
+                         int fp_to_sp_delta,
+                         Code* optimized_code)
     : isolate_(isolate),
       function_(function),
       bailout_id_(bailout_id),
       bailout_type_(type),
       from_(from),
       fp_to_sp_delta_(fp_to_sp_delta),
+      input_(NULL),
       output_count_(0),
       output_(NULL),
       deferred_heap_numbers_(0) {
   if (FLAG_trace_deopt && type != OSR) {
-    PrintF("**** DEOPT: ");
+    if (type == DEBUGGER) {
+      PrintF("**** DEOPT FOR DEBUGGER: ");
+    } else {
+      PrintF("**** DEOPT: ");
+    }
     function->PrintName();
     PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
            bailout_id,
@@ -248,10 +353,16 @@
     optimized_code_ = function_->code();
     ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION);
     ASSERT(!optimized_code_->contains(from));
+  } else if (type == DEBUGGER) {
+    optimized_code_ = optimized_code;
+    ASSERT(optimized_code_->contains(from));
   }
   ASSERT(HEAP->allow_allocation(false));
   unsigned size = ComputeInputFrameSize();
   input_ = new(size) FrameDescription(size, function);
+#ifdef DEBUG
+  input_->SetKind(Code::OPTIMIZED_FUNCTION);
+#endif
 }
 
 
@@ -417,6 +528,7 @@
 
 
 void Deoptimizer::MaterializeHeapNumbers() {
+  ASSERT_NE(DEBUGGER, bailout_type_);
   for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
     HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
     Handle<Object> num = isolate_->factory()->NewNumber(d.value());
@@ -432,6 +544,47 @@
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
+    Address top, uint32_t size, DeoptimizedFrameInfo* info) {
+  ASSERT_EQ(DEBUGGER, bailout_type_);
+  for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
+    HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
+
+    // Check of the heap number to materialize actually belong to the frame
+    // being extracted.
+    Address slot = d.slot_address();
+    if (top <= slot && slot < top + size) {
+      Handle<Object> num = isolate_->factory()->NewNumber(d.value());
+      // Calculate the index with the botton of the expression stack
+      // at index 0, and the fixed part (including incoming arguments)
+      // at negative indexes.
+      int index = static_cast<int>(
+          info->expression_count_ - (slot - top) / kPointerSize - 1);
+      if (FLAG_trace_deopt) {
+        PrintF("Materializing a new heap number %p [%e] in slot %p"
+               "for stack index %d\n",
+               reinterpret_cast<void*>(*num),
+               d.value(),
+               d.slot_address(),
+               index);
+      }
+      if (index >=0) {
+        info->SetExpression(index, *num);
+      } else {
+        // Calculate parameter index subtracting one for the receiver.
+        int parameter_index =
+            index +
+            static_cast<int>(size) / kPointerSize -
+            info->expression_count_ - 1;
+        info->SetParameter(parameter_index, *num);
+      }
+    }
+  }
+}
+#endif
+
+
 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
                                      int frame_index,
                                      unsigned output_offset) {
@@ -460,11 +613,13 @@
       intptr_t input_value = input_->GetRegister(input_reg);
       if (FLAG_trace_deopt) {
         PrintF(
-            "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s\n",
+            "    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ",
             output_[frame_index]->GetTop() + output_offset,
             output_offset,
             input_value,
             converter.NameOfCPURegister(input_reg));
+        reinterpret_cast<Object*>(input_value)->ShortPrint();
+        PrintF("\n");
       }
       output_[frame_index]->SetFrameSlot(output_offset, input_value);
       return;
@@ -522,10 +677,12 @@
       if (FLAG_trace_deopt) {
         PrintF("    0x%08" V8PRIxPTR ": ",
                output_[frame_index]->GetTop() + output_offset);
-        PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d]\n",
+        PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d] ",
                output_offset,
                input_value,
                input_offset);
+        reinterpret_cast<Object*>(input_value)->ShortPrint();
+        PrintF("\n");
       }
       output_[frame_index]->SetFrameSlot(output_offset, input_value);
       return;
@@ -901,6 +1058,9 @@
   ASSERT(desc.reloc_size == 0);
 
   LargeObjectChunk* chunk = LargeObjectChunk::New(desc.instr_size, EXECUTABLE);
+  if (chunk == NULL) {
+    V8::FatalProcessOutOfMemory("Not enough memory for deoptimization table");
+  }
   memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size);
   CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size);
   return chunk;
@@ -969,18 +1129,48 @@
   if (slot_index >= 0) {
     // Local or spill slots. Skip the fixed part of the frame
     // including all arguments.
-    unsigned base = static_cast<unsigned>(
-        GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction()));
+    unsigned base =
+        GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction());
     return base - ((slot_index + 1) * kPointerSize);
   } else {
     // Incoming parameter.
-    unsigned base = static_cast<unsigned>(GetFrameSize() -
-        deoptimizer->ComputeIncomingArgumentSize(GetFunction()));
+    unsigned base = GetFrameSize() -
+        deoptimizer->ComputeIncomingArgumentSize(GetFunction());
     return base - ((slot_index + 1) * kPointerSize);
   }
 }
 
 
+int FrameDescription::ComputeParametersCount() {
+  return function_->shared()->formal_parameter_count();
+}
+
+
+Object* FrameDescription::GetParameter(Deoptimizer* deoptimizer, int index) {
+  ASSERT_EQ(Code::FUNCTION, kind_);
+  ASSERT(index >= 0);
+  ASSERT(index < ComputeParametersCount());
+  // The slot indexes for incoming arguments are negative.
+  unsigned offset = GetOffsetFromSlotIndex(deoptimizer,
+                                           index - ComputeParametersCount());
+  return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
+}
+
+
+unsigned FrameDescription::GetExpressionCount(Deoptimizer* deoptimizer) {
+  ASSERT_EQ(Code::FUNCTION, kind_);
+  unsigned size = GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction());
+  return size / kPointerSize;
+}
+
+
+Object* FrameDescription::GetExpression(Deoptimizer* deoptimizer, int index) {
+  ASSERT_EQ(Code::FUNCTION, kind_);
+  unsigned offset = GetOffsetFromSlotIndex(deoptimizer, index);
+  return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
+}
+
+
 void TranslationBuffer::Add(int32_t value) {
   // Encode the sign bit in the least significant bit.
   bool is_negative = (value < 0);
@@ -1104,7 +1294,7 @@
 }
 
 
-#ifdef OBJECT_PRINT
+#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
 
 const char* Translation::StringFor(Opcode opcode) {
   switch (opcode) {
@@ -1253,4 +1443,33 @@
 }
 
 
+DeoptimizedFrameInfo::DeoptimizedFrameInfo(
+    Deoptimizer* deoptimizer, int frame_index) {
+  FrameDescription* output_frame = deoptimizer->output_[frame_index];
+  SetFunction(output_frame->GetFunction());
+  expression_count_ = output_frame->GetExpressionCount(deoptimizer);
+  parameters_count_ = output_frame->ComputeParametersCount();
+  parameters_ = new Object*[parameters_count_];
+  for (int i = 0; i < parameters_count_; i++) {
+    SetParameter(i, output_frame->GetParameter(deoptimizer, i));
+  }
+  expression_stack_ = new Object*[expression_count_];
+  for (int i = 0; i < expression_count_; i++) {
+    SetExpression(i, output_frame->GetExpression(deoptimizer, i));
+  }
+}
+
+
+DeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
+  delete[] expression_stack_;
+  delete[] parameters_;
+}
+
+void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
+  v->VisitPointer(BitCast<Object**>(&function_));
+  v->VisitPointers(parameters_, parameters_ + parameters_count_);
+  v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index 7c5dfb8..9265905 100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -41,7 +41,7 @@
 class FrameDescription;
 class TranslationIterator;
 class DeoptimizingCodeListNode;
-
+class DeoptimizedFrameInfo;
 
 class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
  public:
@@ -81,11 +81,19 @@
   DeoptimizerData();
   ~DeoptimizerData();
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  void Iterate(ObjectVisitor* v);
+#endif
+
  private:
   LargeObjectChunk* eager_deoptimization_entry_code_;
   LargeObjectChunk* lazy_deoptimization_entry_code_;
   Deoptimizer* current_;
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  DeoptimizedFrameInfo* deoptimized_frame_info_;
+#endif
+
   // List of deoptimized code which still have references from active stack
   // frames. These code objects are needed by the deoptimizer when deoptimizing
   // a frame for which the code object for the function function has been
@@ -103,7 +111,10 @@
   enum BailoutType {
     EAGER,
     LAZY,
-    OSR
+    OSR,
+    // This last bailout type is not really a bailout, but used by the
+    // debugger to deoptimize stack frames to allow inspection.
+    DEBUGGER
   };
 
   int output_count() const { return output_count_; }
@@ -116,6 +127,16 @@
                           Isolate* isolate);
   static Deoptimizer* Grab(Isolate* isolate);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  // The returned object with information on the optimized frame needs to be
+  // freed before another one can be generated.
+  static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
+                                                        int frame_index,
+                                                        Isolate* isolate);
+  static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
+                                             Isolate* isolate);
+#endif
+
   // Makes sure that there is enough room in the relocation
   // information of a code object to perform lazy deoptimization
   // patching. If there is not enough room a new relocation
@@ -171,6 +192,10 @@
   ~Deoptimizer();
 
   void MaterializeHeapNumbers();
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  void MaterializeHeapNumbersForDebuggerInspectableFrame(
+      Address top, uint32_t size, DeoptimizedFrameInfo* info);
+#endif
 
   static void ComputeOutputFrames(Deoptimizer* deoptimizer);
 
@@ -233,7 +258,8 @@
               BailoutType type,
               unsigned bailout_id,
               Address from,
-              int fp_to_sp_delta);
+              int fp_to_sp_delta,
+              Code* optimized_code);
   void DeleteFrameDescriptions();
 
   void DoComputeOutputFrames();
@@ -269,6 +295,11 @@
   static Code* FindDeoptimizingCodeFromAddress(Address addr);
   static void RemoveDeoptimizingCode(Code* code);
 
+  // Fill the input from from a JavaScript frame. This is used when
+  // the debugger needs to inspect an optimized frame. For normal
+  // deoptimizations the input frame is filled in generated code.
+  void FillInputFrame(Address tos, JavaScriptFrame* frame);
+
   Isolate* isolate_;
   JSFunction* function_;
   Code* optimized_code_;
@@ -290,6 +321,7 @@
 
   friend class FrameDescription;
   friend class DeoptimizingCodeListNode;
+  friend class DeoptimizedFrameInfo;
 };
 
 
@@ -308,7 +340,10 @@
     free(description);
   }
 
-  intptr_t GetFrameSize() const { return frame_size_; }
+  uint32_t GetFrameSize() const {
+    ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_);
+    return static_cast<uint32_t>(frame_size_);
+  }
 
   JSFunction* GetFunction() const { return function_; }
 
@@ -360,6 +395,23 @@
 
   void SetContinuation(intptr_t pc) { continuation_ = pc; }
 
+#ifdef DEBUG
+  Code::Kind GetKind() const { return kind_; }
+  void SetKind(Code::Kind kind) { kind_ = kind; }
+#endif
+
+  // Get the incoming arguments count.
+  int ComputeParametersCount();
+
+  // Get a parameter value for an unoptimized frame.
+  Object* GetParameter(Deoptimizer* deoptimizer, int index);
+
+  // Get the expression stack height for a unoptimized frame.
+  unsigned GetExpressionCount(Deoptimizer* deoptimizer);
+
+  // Get the expression stack value for an unoptimized frame.
+  Object* GetExpression(Deoptimizer* deoptimizer, int index);
+
   static int registers_offset() {
     return OFFSET_OF(FrameDescription, registers_);
   }
@@ -391,6 +443,9 @@
  private:
   static const uint32_t kZapUint32 = 0xbeeddead;
 
+  // Frame_size_ must hold a uint32_t value.  It is only a uintptr_t to
+  // keep the variable-size array frame_content_ of type intptr_t at
+  // the end of the structure aligned.
   uintptr_t frame_size_;  // Number of bytes.
   JSFunction* function_;
   intptr_t registers_[Register::kNumRegisters];
@@ -399,6 +454,9 @@
   intptr_t pc_;
   intptr_t fp_;
   Smi* state_;
+#ifdef DEBUG
+  Code::Kind kind_;
+#endif
 
   // Continuation is the PC where the execution continues after
   // deoptimizing.
@@ -495,7 +553,7 @@
 
   static int NumberOfOperandsFor(Opcode opcode);
 
-#ifdef OBJECT_PRINT
+#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   static const char* StringFor(Opcode opcode);
 #endif
 
@@ -597,6 +655,70 @@
 };
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+// Class used to represent an unoptimized frame when the debugger
+// needs to inspect a frame that is part of an optimized frame. The
+// internally used FrameDescription objects are not GC safe so for use
+// by the debugger frame information is copied to an object of this type.
+class DeoptimizedFrameInfo : public Malloced {
+ public:
+  DeoptimizedFrameInfo(Deoptimizer* deoptimizer, int frame_index);
+  virtual ~DeoptimizedFrameInfo();
+
+  // GC support.
+  void Iterate(ObjectVisitor* v);
+
+  // Return the number of incoming arguments.
+  int parameters_count() { return parameters_count_; }
+
+  // Return the height of the expression stack.
+  int expression_count() { return expression_count_; }
+
+  // Get the frame function.
+  JSFunction* GetFunction() {
+    return function_;
+  }
+
+  // Get an incoming argument.
+  Object* GetParameter(int index) {
+    ASSERT(0 <= index && index < parameters_count());
+    return parameters_[index];
+  }
+
+  // Get an expression from the expression stack.
+  Object* GetExpression(int index) {
+    ASSERT(0 <= index && index < expression_count());
+    return expression_stack_[index];
+  }
+
+ private:
+  // Set the frame function.
+  void SetFunction(JSFunction* function) {
+    function_ = function;
+  }
+
+  // Set an incoming argument.
+  void SetParameter(int index, Object* obj) {
+    ASSERT(0 <= index && index < parameters_count());
+    parameters_[index] = obj;
+  }
+
+  // Set an expression on the expression stack.
+  void SetExpression(int index, Object* obj) {
+    ASSERT(0 <= index && index < expression_count());
+    expression_stack_[index] = obj;
+  }
+
+  JSFunction* function_;
+  int parameters_count_;
+  int expression_count_;
+  Object** parameters_;
+  Object** expression_stack_;
+
+  friend class Deoptimizer;
+};
+#endif
+
 } }  // namespace v8::internal
 
 #endif  // V8_DEOPTIMIZER_H_
diff --git a/src/diy-fp.cc b/src/diy-fp.cc
index c54bd1d..4913877 100644
--- a/src/diy-fp.cc
+++ b/src/diy-fp.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,8 +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.
 
-#include "v8.h"
-
+#include "../include/v8stdint.h"
+#include "globals.h"
+#include "checks.h"
 #include "diy-fp.h"
 
 namespace v8 {
diff --git a/src/diy-fp.h b/src/diy-fp.h
index cfe05ef..26ff1a2 100644
--- a/src/diy-fp.h
+++ b/src/diy-fp.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -80,7 +80,7 @@
 
     // This method is mainly called for normalizing boundaries. In general
     // boundaries need to be shifted by 10 bits. We thus optimize for this case.
-    const uint64_t k10MSBits = V8_2PART_UINT64_C(0xFFC00000, 00000000);
+    const uint64_t k10MSBits = static_cast<uint64_t>(0x3FF) << 54;
     while ((f & k10MSBits) == 0) {
       f <<= 10;
       e -= 10;
@@ -106,7 +106,7 @@
   void set_e(int new_value) { e_ = new_value; }
 
  private:
-  static const uint64_t kUint64MSB = V8_2PART_UINT64_C(0x80000000, 00000000);
+  static const uint64_t kUint64MSB = static_cast<uint64_t>(1) << 63;
 
   uint64_t f_;
   int e_;
diff --git a/src/execution.cc b/src/execution.cc
index e84ab9e..6ab73e7 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -210,23 +210,6 @@
   // If you return a function from here, it will be called when an
   // attempt is made to call the given object as a function.
 
-  // Regular expressions can be called as functions in both Firefox
-  // and Safari so we allow it too.
-  if (object->IsJSRegExp()) {
-    Handle<String> exec = factory->exec_symbol();
-    // TODO(lrn): Bug 617.  We should use the default function here, not the
-    // one on the RegExp object.
-    Object* exec_function;
-    { MaybeObject* maybe_exec_function = object->GetProperty(*exec);
-      // This can lose an exception, but the alternative is to put a failure
-      // object in a handle, which is not GC safe.
-      if (!maybe_exec_function->ToObject(&exec_function)) {
-        return factory->undefined_value();
-      }
-    }
-    return Handle<Object>(exec_function);
-  }
-
   // Objects created through the API can have an instance-call handler
   // that should be used when calling the object as a function.
   if (object->IsHeapObject() &&
@@ -469,8 +452,9 @@
 
 
 void StackGuard::FreeThreadResources() {
-  Isolate::CurrentPerIsolateThreadData()->set_stack_limit(
-      thread_local_.real_climit_);
+  Isolate::PerIsolateThreadData* per_thread =
+      isolate_->FindOrAllocatePerThreadDataForThisThread();
+  per_thread->set_stack_limit(thread_local_.real_climit_);
 }
 
 
@@ -519,7 +503,7 @@
   uintptr_t stored_limit = per_thread->stack_limit();
   // You should hold the ExecutionAccess lock when you call this.
   if (stored_limit != 0) {
-    StackGuard::SetStackLimit(stored_limit);
+    SetStackLimit(stored_limit);
   }
 }
 
diff --git a/src/extensions/experimental/break-iterator.cc b/src/extensions/experimental/break-iterator.cc
index e8baea7..e695a3e 100644
--- a/src/extensions/experimental/break-iterator.cc
+++ b/src/extensions/experimental/break-iterator.cc
@@ -25,7 +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.
 
-#include "break-iterator.h"
+#include "src/extensions/experimental/break-iterator.h"
+
+#include <string.h>
 
 #include "unicode/brkiter.h"
 #include "unicode/locid.h"
diff --git a/src/extensions/experimental/break-iterator.h b/src/extensions/experimental/break-iterator.h
index fac1ed8..73b9bbd 100644
--- a/src/extensions/experimental/break-iterator.h
+++ b/src/extensions/experimental/break-iterator.h
@@ -28,7 +28,7 @@
 #ifndef V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
 #define V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
 
-#include <v8.h>
+#include "include/v8.h"
 
 #include "unicode/uversion.h"
 
diff --git a/src/extensions/experimental/collator.cc b/src/extensions/experimental/collator.cc
index 7d1a21d..5cf2192 100644
--- a/src/extensions/experimental/collator.cc
+++ b/src/extensions/experimental/collator.cc
@@ -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.
 
-#include "collator.h"
+#include "src/extensions/experimental/collator.h"
 
 #include "unicode/coll.h"
 #include "unicode/locid.h"
@@ -153,6 +153,11 @@
   bool ignore_case, ignore_accents, numeric;
 
   if (ExtractBooleanOption(options, "ignoreCase", &ignore_case)) {
+    // We need to explicitly set the level to secondary to get case ignored.
+    // The default L3 ignores UCOL_CASE_LEVEL == UCOL_OFF !
+    if (ignore_case) {
+      collator->setStrength(icu::Collator::SECONDARY);
+    }
     collator->setAttribute(UCOL_CASE_LEVEL, ignore_case ? UCOL_OFF : UCOL_ON,
                            status);
     if (U_FAILURE(status)) {
@@ -215,4 +220,3 @@
 }
 
 } }  // namespace v8::internal
-
diff --git a/src/extensions/experimental/collator.h b/src/extensions/experimental/collator.h
index 10d6ffb..ca7e4dc 100644
--- a/src/extensions/experimental/collator.h
+++ b/src/extensions/experimental/collator.h
@@ -28,7 +28,7 @@
 #ifndef V8_EXTENSIONS_EXPERIMENTAL_COLLATOR_H
 #define V8_EXTENSIONS_EXPERIMENTAL_COLLATOR_H_
 
-#include <v8.h>
+#include "include/v8.h"
 
 #include "unicode/uversion.h"
 
@@ -66,4 +66,3 @@
 } }  // namespace v8::internal
 
 #endif  // V8_EXTENSIONS_EXPERIMENTAL_COLLATOR
-
diff --git a/src/extensions/experimental/datetime-format.cc b/src/extensions/experimental/datetime-format.cc
new file mode 100644
index 0000000..7f46302
--- /dev/null
+++ b/src/extensions/experimental/datetime-format.cc
@@ -0,0 +1,384 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/extensions/experimental/datetime-format.h"
+
+#include <string.h>
+
+#include "src/extensions/experimental/i18n-utils.h"
+#include "unicode/dtfmtsym.h"
+#include "unicode/dtptngen.h"
+#include "unicode/locid.h"
+#include "unicode/smpdtfmt.h"
+
+namespace v8 {
+namespace internal {
+
+v8::Persistent<v8::FunctionTemplate> DateTimeFormat::datetime_format_template_;
+
+static icu::DateFormat* CreateDateTimeFormat(v8::Handle<v8::String>,
+                                             v8::Handle<v8::Object>);
+static v8::Handle<v8::Value> GetSymbols(
+    const v8::Arguments&,
+    const icu::UnicodeString*, int32_t,
+    const icu::UnicodeString*, int32_t,
+    const icu::UnicodeString*, int32_t);
+static v8::Handle<v8::Value> ThrowUnexpectedObjectError();
+static icu::DateFormat::EStyle GetDateTimeStyle(const icu::UnicodeString&);
+
+icu::SimpleDateFormat* DateTimeFormat::UnpackDateTimeFormat(
+    v8::Handle<v8::Object> obj) {
+  if (datetime_format_template_->HasInstance(obj)) {
+    return static_cast<icu::SimpleDateFormat*>(
+        obj->GetPointerFromInternalField(0));
+  }
+
+  return NULL;
+}
+
+void DateTimeFormat::DeleteDateTimeFormat(v8::Persistent<v8::Value> object,
+                                          void* param) {
+  v8::Persistent<v8::Object> persistent_object =
+      v8::Persistent<v8::Object>::Cast(object);
+
+  // First delete the hidden C++ object.
+  // Unpacking should never return NULL here. That would only happen if
+  // this method is used as the weak callback for persistent handles not
+  // pointing to a date time formatter.
+  delete UnpackDateTimeFormat(persistent_object);
+
+  // Then dispose of the persistent handle to JS object.
+  persistent_object.Dispose();
+}
+
+v8::Handle<v8::Value> DateTimeFormat::Format(const v8::Arguments& args) {
+  v8::HandleScope handle_scope;
+
+  double millis = 0.0;
+  if (args.Length() != 1 || !args[0]->IsDate()) {
+    // Create a new date.
+    v8::TryCatch try_catch;
+    v8::Local<v8::Script> date_script =
+        v8::Script::Compile(v8::String::New("eval('new Date()')"));
+    millis = date_script->Run()->NumberValue();
+    if (try_catch.HasCaught()) {
+      return try_catch.ReThrow();
+    }
+  } else {
+    millis = v8::Date::Cast(*args[0])->NumberValue();
+  }
+
+  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
+  if (!date_format) {
+    return ThrowUnexpectedObjectError();
+  }
+
+  icu::UnicodeString result;
+  date_format->format(millis, result);
+
+  return v8::String::New(
+      reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length());
+}
+
+v8::Handle<v8::Value> DateTimeFormat::GetMonths(const v8::Arguments& args) {
+  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
+  if (!date_format) {
+    return ThrowUnexpectedObjectError();
+  }
+
+  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
+
+  int32_t narrow_count;
+  const icu::UnicodeString* narrow = symbols->getMonths(
+      narrow_count,
+      icu::DateFormatSymbols::STANDALONE,
+      icu::DateFormatSymbols::NARROW);
+  int32_t abbrev_count;
+  const icu::UnicodeString* abbrev = symbols->getMonths(
+      abbrev_count,
+      icu::DateFormatSymbols::STANDALONE,
+      icu::DateFormatSymbols::ABBREVIATED);
+  int32_t wide_count;
+  const icu::UnicodeString* wide = symbols->getMonths(
+      wide_count,
+      icu::DateFormatSymbols::STANDALONE,
+      icu::DateFormatSymbols::WIDE);
+
+  return GetSymbols(
+      args, narrow, narrow_count, abbrev, abbrev_count, wide, wide_count);
+}
+
+v8::Handle<v8::Value> DateTimeFormat::GetWeekdays(const v8::Arguments& args) {
+  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
+  if (!date_format) {
+    ThrowUnexpectedObjectError();
+  }
+
+  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
+
+  int32_t narrow_count;
+  const icu::UnicodeString* narrow = symbols->getWeekdays(
+      narrow_count,
+      icu::DateFormatSymbols::STANDALONE,
+      icu::DateFormatSymbols::NARROW);
+  int32_t abbrev_count;
+  const icu::UnicodeString* abbrev = symbols->getWeekdays(
+      abbrev_count,
+      icu::DateFormatSymbols::STANDALONE,
+      icu::DateFormatSymbols::ABBREVIATED);
+  int32_t wide_count;
+  const icu::UnicodeString* wide = symbols->getWeekdays(
+      wide_count,
+      icu::DateFormatSymbols::STANDALONE,
+      icu::DateFormatSymbols::WIDE);
+
+  // getXXXWeekdays always returns 8 elements - ICU stable API.
+  // We can't use ASSERT_EQ(8, narrow_count) because ASSERT is internal to v8.
+  if (narrow_count != 8 || abbrev_count != 8 || wide_count != 8) {
+    return v8::ThrowException(v8::Exception::Error(
+        v8::String::New("Failed to get weekday information.")));
+  }
+
+  // ICU documentation says we should ignore element 0 of the returned array.
+  return GetSymbols(args, narrow + 1, narrow_count - 1, abbrev + 1,
+                    abbrev_count -1 , wide + 1, wide_count - 1);
+}
+
+v8::Handle<v8::Value> DateTimeFormat::GetEras(const v8::Arguments& args) {
+  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
+  if (!date_format) {
+    return ThrowUnexpectedObjectError();
+  }
+
+  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
+
+  int32_t narrow_count;
+  const icu::UnicodeString* narrow = symbols->getNarrowEras(narrow_count);
+  int32_t abbrev_count;
+  const icu::UnicodeString* abbrev = symbols->getEras(abbrev_count);
+  int32_t wide_count;
+  const icu::UnicodeString* wide = symbols->getEraNames(wide_count);
+
+  return GetSymbols(
+      args, narrow, narrow_count, abbrev, abbrev_count, wide, wide_count);
+}
+
+v8::Handle<v8::Value> DateTimeFormat::GetAmPm(const v8::Arguments& args) {
+  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
+  if (!date_format) {
+    return ThrowUnexpectedObjectError();
+  }
+
+  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
+
+  // In this case narrow == abbreviated == wide
+  int32_t count;
+  const icu::UnicodeString* wide = symbols->getAmPmStrings(count);
+
+  return GetSymbols(args, wide, count, wide, count, wide, count);
+}
+
+v8::Handle<v8::Value> DateTimeFormat::JSDateTimeFormat(
+    const v8::Arguments& args) {
+  v8::HandleScope handle_scope;
+
+  if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsObject()) {
+    return v8::ThrowException(v8::Exception::SyntaxError(
+        v8::String::New("Locale and date/time options are required.")));
+  }
+
+  icu::SimpleDateFormat* date_format = static_cast<icu::SimpleDateFormat*>(
+      CreateDateTimeFormat(args[0]->ToString(), args[1]->ToObject()));
+
+  if (datetime_format_template_.IsEmpty()) {
+    v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
+
+    raw_template->SetClassName(v8::String::New("v8Locale.DateTimeFormat"));
+
+    // Define internal field count on instance template.
+    v8::Local<v8::ObjectTemplate> object_template =
+        raw_template->InstanceTemplate();
+
+    // Set aside internal field for icu date time formatter.
+    object_template->SetInternalFieldCount(1);
+
+    // Define all of the prototype methods on prototype template.
+    v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
+    proto->Set(v8::String::New("format"),
+               v8::FunctionTemplate::New(Format));
+    proto->Set(v8::String::New("getMonths"),
+               v8::FunctionTemplate::New(GetMonths));
+    proto->Set(v8::String::New("getWeekdays"),
+               v8::FunctionTemplate::New(GetWeekdays));
+    proto->Set(v8::String::New("getEras"),
+               v8::FunctionTemplate::New(GetEras));
+    proto->Set(v8::String::New("getAmPm"),
+               v8::FunctionTemplate::New(GetAmPm));
+
+    datetime_format_template_ =
+        v8::Persistent<v8::FunctionTemplate>::New(raw_template);
+  }
+
+  // Create an empty object wrapper.
+  v8::Local<v8::Object> local_object =
+      datetime_format_template_->GetFunction()->NewInstance();
+  v8::Persistent<v8::Object> wrapper =
+      v8::Persistent<v8::Object>::New(local_object);
+
+  // Set date time formatter as internal field of the resulting JS object.
+  wrapper->SetPointerInInternalField(0, date_format);
+
+  // Set resolved pattern in options.pattern.
+  icu::UnicodeString pattern;
+  date_format->toPattern(pattern);
+  v8::Local<v8::Object> options = v8::Object::New();
+  options->Set(v8::String::New("pattern"),
+               v8::String::New(reinterpret_cast<const uint16_t*>(
+                   pattern.getBuffer()), pattern.length()));
+  wrapper->Set(v8::String::New("options"), options);
+
+  // Make object handle weak so we can delete iterator once GC kicks in.
+  wrapper.MakeWeak(NULL, DeleteDateTimeFormat);
+
+  return wrapper;
+}
+
+// Returns SimpleDateFormat.
+static icu::DateFormat* CreateDateTimeFormat(
+    v8::Handle<v8::String> locale, v8::Handle<v8::Object> settings) {
+  v8::HandleScope handle_scope;
+
+  v8::String::AsciiValue ascii_locale(locale);
+  icu::Locale icu_locale(*ascii_locale);
+
+  // Make formatter from skeleton.
+  icu::SimpleDateFormat* date_format = NULL;
+  UErrorCode status = U_ZERO_ERROR;
+  icu::UnicodeString skeleton;
+  if (I18NUtils::ExtractStringSetting(settings, "skeleton", &skeleton)) {
+    v8::Local<icu::DateTimePatternGenerator> generator(
+        icu::DateTimePatternGenerator::createInstance(icu_locale, status));
+    icu::UnicodeString pattern =
+        generator->getBestPattern(skeleton, status);
+
+    date_format = new icu::SimpleDateFormat(pattern, icu_locale, status);
+    if (U_SUCCESS(status)) {
+      return date_format;
+    } else {
+      delete date_format;
+    }
+  }
+
+  // Extract date style and time style from settings.
+  icu::UnicodeString date_style;
+  icu::DateFormat::EStyle icu_date_style = icu::DateFormat::kNone;
+  if (I18NUtils::ExtractStringSetting(settings, "dateStyle", &date_style)) {
+    icu_date_style = GetDateTimeStyle(date_style);
+  }
+
+  icu::UnicodeString time_style;
+  icu::DateFormat::EStyle icu_time_style = icu::DateFormat::kNone;
+  if (I18NUtils::ExtractStringSetting(settings, "timeStyle", &time_style)) {
+    icu_time_style = GetDateTimeStyle(time_style);
+  }
+
+  // Try all combinations of date/time styles.
+  if (icu_date_style == icu::DateFormat::kNone &&
+      icu_time_style == icu::DateFormat::kNone) {
+    // Return default short date, short
+    return icu::DateFormat::createDateTimeInstance(
+        icu::DateFormat::kShort, icu::DateFormat::kShort, icu_locale);
+  } else if (icu_date_style != icu::DateFormat::kNone &&
+             icu_time_style != icu::DateFormat::kNone) {
+    return icu::DateFormat::createDateTimeInstance(
+        icu_date_style, icu_time_style, icu_locale);
+  } else if (icu_date_style != icu::DateFormat::kNone) {
+    return icu::DateFormat::createDateInstance(icu_date_style, icu_locale);
+  } else {
+    // icu_time_style != icu::DateFormat::kNone
+    return icu::DateFormat::createTimeInstance(icu_time_style, icu_locale);
+  }
+}
+
+// Creates a v8::Array of narrow, abbrev or wide symbols.
+static v8::Handle<v8::Value> GetSymbols(const v8::Arguments& args,
+                                        const icu::UnicodeString* narrow,
+                                        int32_t narrow_count,
+                                        const icu::UnicodeString* abbrev,
+                                        int32_t abbrev_count,
+                                        const icu::UnicodeString* wide,
+                                        int32_t wide_count) {
+  v8::HandleScope handle_scope;
+
+  // Make wide width default.
+  const icu::UnicodeString* result = wide;
+  int32_t count = wide_count;
+
+  if (args.Length() == 1 && args[0]->IsString()) {
+    v8::String::AsciiValue ascii_value(args[0]);
+    if (strcmp(*ascii_value, "abbreviated") == 0) {
+      result = abbrev;
+      count = abbrev_count;
+    } else if (strcmp(*ascii_value, "narrow") == 0) {
+      result = narrow;
+      count = narrow_count;
+    }
+  }
+
+  v8::Handle<v8::Array> symbols = v8::Array::New();
+  for (int32_t i = 0; i < count; ++i) {
+    symbols->Set(i, v8::String::New(
+        reinterpret_cast<const uint16_t*>(result[i].getBuffer()),
+        result[i].length()));
+  }
+
+  return handle_scope.Close(symbols);
+}
+
+// Throws a JavaScript exception.
+static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
+  // Returns undefined, and schedules an exception to be thrown.
+  return v8::ThrowException(v8::Exception::Error(
+      v8::String::New("DateTimeFormat method called on an object "
+                      "that is not a DateTimeFormat.")));
+}
+
+// Returns icu date/time style.
+static icu::DateFormat::EStyle GetDateTimeStyle(
+    const icu::UnicodeString& type) {
+  if (type == UNICODE_STRING_SIMPLE("medium")) {
+    return icu::DateFormat::kMedium;
+  } else if (type == UNICODE_STRING_SIMPLE("long")) {
+    return icu::DateFormat::kLong;
+  } else if (type == UNICODE_STRING_SIMPLE("full")) {
+    return icu::DateFormat::kFull;
+  }
+
+  return icu::DateFormat::kShort;
+}
+
+} }  // namespace v8::internal
diff --git a/src/extensions/experimental/datetime-format.h b/src/extensions/experimental/datetime-format.h
new file mode 100644
index 0000000..a6a228c
--- /dev/null
+++ b/src/extensions/experimental/datetime-format.h
@@ -0,0 +1,83 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
+#define V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
+
+#include "include/v8.h"
+
+#include "unicode/uversion.h"
+
+namespace U_ICU_NAMESPACE {
+class SimpleDateFormat;
+}
+
+namespace v8 {
+namespace internal {
+
+class DateTimeFormat {
+ public:
+  static v8::Handle<v8::Value> JSDateTimeFormat(const v8::Arguments& args);
+
+  // Helper methods for various bindings.
+
+  // Unpacks date format object from corresponding JavaScript object.
+  static icu::SimpleDateFormat* UnpackDateTimeFormat(
+      v8::Handle<v8::Object> obj);
+
+  // Release memory we allocated for the DateFormat once the JS object that
+  // holds the pointer gets garbage collected.
+  static void DeleteDateTimeFormat(v8::Persistent<v8::Value> object,
+                                   void* param);
+
+  // Formats date and returns corresponding string.
+  static v8::Handle<v8::Value> Format(const v8::Arguments& args);
+
+  // All date time symbol methods below return stand-alone names in
+  // either narrow, abbreviated or wide width.
+
+  // Get list of months.
+  static v8::Handle<v8::Value> GetMonths(const v8::Arguments& args);
+
+  // Get list of weekdays.
+  static v8::Handle<v8::Value> GetWeekdays(const v8::Arguments& args);
+
+  // Get list of eras.
+  static v8::Handle<v8::Value> GetEras(const v8::Arguments& args);
+
+  // Get list of day periods.
+  static v8::Handle<v8::Value> GetAmPm(const v8::Arguments& args);
+
+ private:
+  DateTimeFormat();
+
+  static v8::Persistent<v8::FunctionTemplate> datetime_format_template_;
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
diff --git a/src/extensions/experimental/experimental.gyp b/src/extensions/experimental/experimental.gyp
index 2a7775e..24fb683 100644
--- a/src/extensions/experimental/experimental.gyp
+++ b/src/extensions/experimental/experimental.gyp
@@ -41,32 +41,44 @@
         'break-iterator.h',
         'collator.cc',
         'collator.h',
+        'datetime-format.cc',
+        'datetime-format.h',
         'i18n-extension.cc',
         'i18n-extension.h',
         'i18n-locale.cc',
         'i18n-locale.h',
+        'i18n-natives.h',
         'i18n-utils.cc',
         'i18n-utils.h',
         'language-matcher.cc',
         'language-matcher.h',
+        'number-format.cc',
+        'number-format.h',
         '<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
       ],
       'include_dirs': [
         '<(icu_src_dir)/public/common',
-        '../..',
+        # v8/ is root for all includes.
+        '../../..'
       ],
       'dependencies': [
         '<(icu_src_dir)/icu.gyp:*',
         'js2c_i18n#host',
         '../../../tools/gyp/v8.gyp:v8',
       ],
+      'direct_dependent_settings': {
+        # Adds -Iv8 for embedders.
+        'include_dirs': [
+          '../../..'
+        ],
+      },
     },
     {
       'target_name': 'js2c_i18n',
       'type': 'none',
       'toolsets': ['host'],
       'variables': {
-        'library_files': [
+        'js_files': [
           'i18n.js'
         ],
       },
@@ -74,18 +86,17 @@
         {
           'action_name': 'js2c_i18n',
           'inputs': [
-            '../../../tools/js2c.py',
-            '<@(library_files)',
+            'i18n-js2c.py',
+            '<@(js_files)',
           ],
           'outputs': [
             '<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
           ],
           'action': [
             'python',
-            '../../../tools/js2c.py',
+            'i18n-js2c.py',
             '<@(_outputs)',
-            'I18N',
-            '<@(library_files)'
+            '<@(js_files)'
           ],
         },
       ],
diff --git a/src/extensions/experimental/i18n-extension.cc b/src/extensions/experimental/i18n-extension.cc
index 88c609e..c5afcf0 100644
--- a/src/extensions/experimental/i18n-extension.cc
+++ b/src/extensions/experimental/i18n-extension.cc
@@ -25,30 +25,22 @@
 // (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 "i18n-extension.h"
+#include "src/extensions/experimental/i18n-extension.h"
 
-#include "break-iterator.h"
-#include "collator.h"
-#include "i18n-locale.h"
-#include "natives.h"
+#include "src/extensions/experimental/break-iterator.h"
+#include "src/extensions/experimental/collator.h"
+#include "src/extensions/experimental/datetime-format.h"
+#include "src/extensions/experimental/i18n-locale.h"
+#include "src/extensions/experimental/i18n-natives.h"
+#include "src/extensions/experimental/number-format.h"
 
 namespace v8 {
 namespace internal {
 
 I18NExtension* I18NExtension::extension_ = NULL;
 
-// Returns a pointer to static string containing the actual
-// JavaScript code generated from i18n.js file.
-static const char* GetScriptSource() {
-  int index = NativesCollection<I18N>::GetIndex("i18n");
-  Vector<const char> script_data =
-      NativesCollection<I18N>::GetScriptSource(index);
-
-  return script_data.start();
-}
-
 I18NExtension::I18NExtension()
-    : v8::Extension("v8/i18n", GetScriptSource()) {
+    : v8::Extension("v8/i18n", I18Natives::GetScriptSource()) {
 }
 
 v8::Handle<v8::FunctionTemplate> I18NExtension::GetNativeFunction(
@@ -59,6 +51,10 @@
     return v8::FunctionTemplate::New(BreakIterator::JSBreakIterator);
   } else if (name->Equals(v8::String::New("NativeJSCollator"))) {
     return v8::FunctionTemplate::New(Collator::JSCollator);
+  } else if (name->Equals(v8::String::New("NativeJSDateTimeFormat"))) {
+    return v8::FunctionTemplate::New(DateTimeFormat::JSDateTimeFormat);
+  } else if (name->Equals(v8::String::New("NativeJSNumberFormat"))) {
+    return v8::FunctionTemplate::New(NumberFormat::JSNumberFormat);
   }
 
   return v8::Handle<v8::FunctionTemplate>();
diff --git a/src/extensions/experimental/i18n-extension.h b/src/extensions/experimental/i18n-extension.h
index b4dc7c3..5401f25 100644
--- a/src/extensions/experimental/i18n-extension.h
+++ b/src/extensions/experimental/i18n-extension.h
@@ -28,7 +28,7 @@
 #ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
 #define V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
 
-#include <v8.h>
+#include "include/v8.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/extensions/experimental/i18n-js2c.py b/src/extensions/experimental/i18n-js2c.py
new file mode 100644
index 0000000..9c3128b
--- /dev/null
+++ b/src/extensions/experimental/i18n-js2c.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This is a utility for converting I18N JavaScript source code into C-style
+# char arrays. It is used for embedded JavaScript code in the V8
+# library.
+# This is a pared down copy of v8/tools/js2c.py that avoids use of
+# v8/src/natives.h and produces different cc template.
+
+import os, re, sys, string
+
+
+def ToCArray(lines):
+  result = []
+  for chr in lines:
+    value = ord(chr)
+    assert value < 128
+    result.append(str(value))
+  result.append("0")
+  return ", ".join(result)
+
+
+def RemoveCommentsAndTrailingWhitespace(lines):
+  lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments
+  lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments.
+  lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace
+  return lines
+
+
+def ReadFile(filename):
+  file = open(filename, "rt")
+  try:
+    lines = file.read()
+  finally:
+    file.close()
+  return lines
+
+
+EVAL_PATTERN = re.compile(r'\beval\s*\(');
+WITH_PATTERN = re.compile(r'\bwith\s*\(');
+
+
+def Validate(lines, file):
+  lines = RemoveCommentsAndTrailingWhitespace(lines)
+  # Because of simplified context setup, eval and with is not
+  # allowed in the natives files.
+  eval_match = EVAL_PATTERN.search(lines)
+  if eval_match:
+    raise ("Eval disallowed in natives: %s" % file)
+  with_match = WITH_PATTERN.search(lines)
+  if with_match:
+    raise ("With statements disallowed in natives: %s" % file)
+
+
+HEADER_TEMPLATE = """\
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+// This file was generated from .js source files by gyp.  If you
+// want to make changes to this file you should either change the
+// javascript source files or the i18n-js2c.py script.
+
+#include "src/extensions/experimental/i18n-natives.h"
+
+namespace v8 {
+namespace internal {
+
+// static
+const char* I18Natives::GetScriptSource() {
+  // JavaScript source gets injected here.
+  static const char i18n_source[] = {%s};
+
+  return i18n_source;
+}
+
+}  // internal
+}  // v8
+"""
+
+
+def JS2C(source, target):
+  filename = str(source)
+
+  lines = ReadFile(filename)
+  Validate(lines, filename)
+  data = ToCArray(lines)
+
+  # Emit result
+  output = open(target, "w")
+  output.write(HEADER_TEMPLATE % data)
+  output.close()
+
+
+def main():
+  target = sys.argv[1]
+  source = sys.argv[2]
+  JS2C(source, target)
+
+
+if __name__ == "__main__":
+  main()
diff --git a/src/extensions/experimental/i18n-locale.cc b/src/extensions/experimental/i18n-locale.cc
index cf17812..46a5f87 100644
--- a/src/extensions/experimental/i18n-locale.cc
+++ b/src/extensions/experimental/i18n-locale.cc
@@ -25,13 +25,12 @@
 // (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 "i18n-locale.h"
+#include "src/extensions/experimental/i18n-locale.h"
 
-#include "i18n-utils.h"
-#include "language-matcher.h"
+#include "src/extensions/experimental/i18n-utils.h"
+#include "src/extensions/experimental/language-matcher.h"
 #include "unicode/locid.h"
 #include "unicode/uloc.h"
-#include "utils.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/extensions/experimental/i18n-locale.h b/src/extensions/experimental/i18n-locale.h
index 053886b..607818c 100644
--- a/src/extensions/experimental/i18n-locale.h
+++ b/src/extensions/experimental/i18n-locale.h
@@ -28,7 +28,7 @@
 #ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
 #define V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
 
-#include <v8.h>
+#include "include/v8.h"
 
 namespace v8 {
 namespace internal {
diff --git a/test/mjsunit/override-eval-with-non-function.js b/src/extensions/experimental/i18n-natives.h
similarity index 79%
copy from test/mjsunit/override-eval-with-non-function.js
copy to src/extensions/experimental/i18n-natives.h
index edbcb19..37362d0 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/src/extensions/experimental/i18n-natives.h
@@ -25,12 +25,19 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
+#define V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+namespace v8 {
+namespace internal {
 
-test();
+class I18Natives {
+ public:
+  // Gets script source from generated file.
+  // Source is statically allocated string.
+  static const char* GetScriptSource();
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
diff --git a/src/extensions/experimental/i18n-utils.cc b/src/extensions/experimental/i18n-utils.cc
index a82c8eb..dc2be1a 100644
--- a/src/extensions/experimental/i18n-utils.cc
+++ b/src/extensions/experimental/i18n-utils.cc
@@ -25,10 +25,12 @@
 // (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 "i18n-utils.h"
+#include "src/extensions/experimental/i18n-utils.h"
 
 #include <string.h>
 
+#include "unicode/unistr.h"
+
 namespace v8 {
 namespace internal {
 
@@ -40,4 +42,46 @@
   dest[length - 1] = '\0';
 }
 
+// static
+bool I18NUtils::ExtractStringSetting(const v8::Handle<v8::Object>& settings,
+                                     const char* setting,
+                                     icu::UnicodeString* result) {
+  if (!setting || !result) return false;
+
+  v8::HandleScope handle_scope;
+  v8::TryCatch try_catch;
+  v8::Handle<v8::Value> value = settings->Get(v8::String::New(setting));
+  if (try_catch.HasCaught()) {
+    return false;
+  }
+  // No need to check if |value| is empty because it's taken care of
+  // by TryCatch above.
+  if (!value->IsUndefined() && !value->IsNull() && value->IsString()) {
+    v8::String::Utf8Value utf8_value(value);
+    if (*utf8_value == NULL) return false;
+    result->setTo(icu::UnicodeString::fromUTF8(*utf8_value));
+    return true;
+  }
+  return false;
+}
+
+// static
+void I18NUtils::AsciiToUChar(const char* source,
+                             int32_t source_length,
+                             UChar* target,
+                             int32_t target_length) {
+  int32_t length =
+      source_length < target_length ? source_length : target_length;
+
+  if (length <= 0) {
+    return;
+  }
+
+  for (int32_t i = 0; i < length - 1; ++i) {
+    target[i] = static_cast<UChar>(source[i]);
+  }
+
+  target[length - 1] = 0x0u;
+}
+
 } }  // namespace v8::internal
diff --git a/src/extensions/experimental/i18n-utils.h b/src/extensions/experimental/i18n-utils.h
index 7702708..7c31528 100644
--- a/src/extensions/experimental/i18n-utils.h
+++ b/src/extensions/experimental/i18n-utils.h
@@ -28,6 +28,14 @@
 #ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
 #define V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
 
+#include "include/v8.h"
+
+#include "unicode/uversion.h"
+
+namespace U_ICU_NAMESPACE {
+class UnicodeString;
+}
+
 namespace v8 {
 namespace internal {
 
@@ -37,9 +45,21 @@
   // (length - 1) bytes.
   // We can't use snprintf since it's not supported on all relevant platforms.
   // We can't use OS::SNPrintF, it's only for internal code.
-  // TODO(cira): Find a way to use OS::SNPrintF instead.
   static void StrNCopy(char* dest, int length, const char* src);
 
+  // Extract a string setting named in |settings| and set it to |result|.
+  // Return true if it's specified. Otherwise, return false.
+  static bool ExtractStringSetting(const v8::Handle<v8::Object>& settings,
+                                   const char* setting,
+                                   icu::UnicodeString* result);
+
+  // Converts ASCII array into UChar array.
+  // Target is always \0 terminated.
+  static void AsciiToUChar(const char* source,
+                           int32_t source_length,
+                           UChar* target,
+                           int32_t target_length);
+
  private:
   I18NUtils() {}
 };
diff --git a/src/extensions/experimental/i18n.js b/src/extensions/experimental/i18n.js
index 0fa7ae7..56bcf9e 100644
--- a/src/extensions/experimental/i18n.js
+++ b/src/extensions/experimental/i18n.js
@@ -45,11 +45,11 @@
   }
 
   var properties = NativeJSLocale(
-      v8Locale.createSettingsOrDefault_(settings, {'localeID': 'root'}));
+      v8Locale.__createSettingsOrDefault(settings, {'localeID': 'root'}));
 
   // Keep the resolved ICU locale ID around to avoid resolving localeID to
   // ICU locale ID every time BreakIterator, Collator and so forth are called.
-  this.__icuLocaleID__ = properties.icuLocaleID;
+  this.__icuLocaleID = properties.icuLocaleID;
   this.options = {'localeID': properties.localeID,
                   'regionID': properties.regionID};
 };
@@ -61,7 +61,7 @@
  */
 v8Locale.prototype.derive = function(settings) {
   return new v8Locale(
-      v8Locale.createSettingsOrDefault_(settings, this.options));
+      v8Locale.__createSettingsOrDefault(settings, this.options));
 };
 
 /**
@@ -74,14 +74,15 @@
  *   - word
  *   - sentence
  *   - line
+ * @private
  * @constructor
  */
 v8Locale.v8BreakIterator = function(locale, type) {
   native function NativeJSBreakIterator();
 
-  locale = v8Locale.createLocaleOrDefault_(locale);
+  locale = v8Locale.__createLocaleOrDefault(locale);
   // BCP47 ID would work in this case, but we use ICU locale for consistency.
-  var iterator = NativeJSBreakIterator(locale.__icuLocaleID__, type);
+  var iterator = NativeJSBreakIterator(locale.__icuLocaleID, type);
   iterator.type = type;
   return iterator;
 };
@@ -117,27 +118,218 @@
  *   - ignoreCase
  *   - ignoreAccents
  *   - numeric
+ * @private
  * @constructor
  */
 v8Locale.Collator = function(locale, settings) {
   native function NativeJSCollator();
 
-  locale = v8Locale.createLocaleOrDefault_(locale);
+  locale = v8Locale.__createLocaleOrDefault(locale);
   var collator = NativeJSCollator(
-      locale.__icuLocaleID__, v8Locale.createSettingsOrDefault_(settings, {}));
+      locale.__icuLocaleID, v8Locale.__createSettingsOrDefault(settings, {}));
   return collator;
 };
 
 /**
  * Creates new Collator based on current locale.
  * @param {Object} - collation flags. See constructor.
- * @returns {Object} - new v8BreakIterator object.
+ * @returns {Object} - new Collator object.
  */
 v8Locale.prototype.createCollator = function(settings) {
   return new v8Locale.Collator(this, settings);
 };
 
 /**
+ * DateTimeFormat class implements locale-aware date and time formatting.
+ * Constructor is not part of public API.
+ * @param {Object} locale - locale object to pass to formatter.
+ * @param {Object} settings - formatting flags:
+ *   - skeleton
+ *   - dateStyle
+ *   - timeStyle
+ * @private
+ * @constructor
+ */
+v8Locale.__DateTimeFormat = function(locale, settings) {
+  native function NativeJSDateTimeFormat();
+
+  settings = v8Locale.__createSettingsOrDefault(settings, {});
+
+  var cleanSettings = {};
+  if (settings.hasOwnProperty('skeleton')) {
+    cleanSettings['skeleton'] = settings['skeleton'];
+  } else {
+    cleanSettings = {};
+    if (settings.hasOwnProperty('dateStyle')) {
+      var ds = settings['dateStyle'];
+      if (!/^(short|medium|long|full)$/.test(ds)) ds = 'short';
+      cleanSettings['dateStyle'] = ds;
+    } else if (settings.hasOwnProperty('dateType')) {
+      // Obsolete. New spec requires dateStyle, but we'll keep this around
+      // for current users.
+      // TODO(cira): Remove when all internal users switch to dateStyle.
+      var dt = settings['dateType'];
+      if (!/^(short|medium|long|full)$/.test(dt)) dt = 'short';
+      cleanSettings['dateStyle'] = dt;
+    }
+
+    if (settings.hasOwnProperty('timeStyle')) {
+      var ts = settings['timeStyle'];
+      if (!/^(short|medium|long|full)$/.test(ts)) ts = 'short';
+      cleanSettings['timeStyle'] = ts;
+    } else if (settings.hasOwnProperty('timeType')) {
+      // TODO(cira): Remove when all internal users switch to timeStyle.
+      var tt = settings['timeType'];
+      if (!/^(short|medium|long|full)$/.test(tt)) tt = 'short';
+      cleanSettings['timeStyle'] = tt;
+    }
+  }
+
+  // Default is to show short date and time.
+  if (!cleanSettings.hasOwnProperty('skeleton') &&
+      !cleanSettings.hasOwnProperty('dateStyle') &&
+      !cleanSettings.hasOwnProperty('timeStyle')) {
+    cleanSettings = {'dateStyle': 'short',
+                     'timeStyle': 'short'};
+  }
+
+  locale = v8Locale.__createLocaleOrDefault(locale);
+  var formatter = NativeJSDateTimeFormat(locale.__icuLocaleID, cleanSettings);
+
+  // NativeJSDateTimeFormat creates formatter.options for us, we just need
+  // to append actual settings to it.
+  for (key in cleanSettings) {
+    formatter.options[key] = cleanSettings[key];
+  }
+
+  /**
+   * Clones existing date time format with possible overrides for some
+   * of the options.
+   * @param {!Object} overrideSettings - overrides for current format settings.
+   * @returns {Object} - new DateTimeFormat object.
+   * @public
+   */
+  formatter.derive = function(overrideSettings) {
+    // To remove a setting user can specify undefined as its value. We'll remove
+    // it from the map in that case.
+    for (var prop in overrideSettings) {
+      if (settings.hasOwnProperty(prop) && !overrideSettings[prop]) {
+        delete settings[prop];
+      }
+    }
+    return new v8Locale.__DateTimeFormat(
+        locale, v8Locale.__createSettingsOrDefault(overrideSettings, settings));
+  };
+
+  return formatter;
+};
+
+/**
+ * Creates new DateTimeFormat based on current locale.
+ * @param {Object} - formatting flags. See constructor.
+ * @returns {Object} - new DateTimeFormat object.
+ */
+v8Locale.prototype.createDateTimeFormat = function(settings) {
+  return new v8Locale.__DateTimeFormat(this, settings);
+};
+
+/**
+ * NumberFormat class implements locale-aware number formatting.
+ * Constructor is not part of public API.
+ * @param {Object} locale - locale object to pass to formatter.
+ * @param {Object} settings - formatting flags:
+ *   - skeleton
+ *   - pattern
+ *   - style - decimal, currency, percent or scientific
+ *   - currencyCode - ISO 4217 3-letter currency code
+ * @private
+ * @constructor
+ */
+v8Locale.__NumberFormat = function(locale, settings) {
+  native function NativeJSNumberFormat();
+
+  settings = v8Locale.__createSettingsOrDefault(settings, {});
+
+  var cleanSettings = {};
+  if (settings.hasOwnProperty('skeleton')) {
+    // Assign skeleton to cleanSettings and fix invalid currency pattern
+    // if present - 'ooxo' becomes 'o'.
+    cleanSettings['skeleton'] =
+        settings['skeleton'].replace(/\u00a4+[^\u00a4]+\u00a4+/g, '\u00a4');
+  } else if (settings.hasOwnProperty('pattern')) {
+    cleanSettings['pattern'] = settings['pattern'];
+  } else if (settings.hasOwnProperty('style')) {
+    var style = settings['style'];
+    if (!/^(decimal|currency|percent|scientific)$/.test(style)) {
+      style = 'decimal';
+    }
+    cleanSettings['style'] = style;
+  }
+
+  // Default is to show decimal style.
+  if (!cleanSettings.hasOwnProperty('skeleton') &&
+      !cleanSettings.hasOwnProperty('pattern') &&
+      !cleanSettings.hasOwnProperty('style')) {
+    cleanSettings = {'style': 'decimal'};
+  }
+
+  // Add currency code if available and valid (3-letter ASCII code).
+  if (settings.hasOwnProperty('currencyCode') &&
+      /^[a-zA-Z]{3}$/.test(settings['currencyCode'])) {
+    cleanSettings['currencyCode'] = settings['currencyCode'].toUpperCase();
+  }
+
+  locale = v8Locale.__createLocaleOrDefault(locale);
+  // Pass in region ID for proper currency detection. Use ZZ if region is empty.
+  var region = locale.options.regionID !== '' ? locale.options.regionID : 'ZZ';
+  var formatter = NativeJSNumberFormat(
+      locale.__icuLocaleID, 'und_' + region, cleanSettings);
+
+  // ICU doesn't always uppercase the currency code.
+  if (formatter.options.hasOwnProperty('currencyCode')) {
+    formatter.options['currencyCode'] =
+        formatter.options['currencyCode'].toUpperCase();
+  }
+
+  for (key in cleanSettings) {
+    // Don't overwrite keys that are alredy in.
+    if (formatter.options.hasOwnProperty(key)) continue;
+
+    formatter.options[key] = cleanSettings[key];
+  }
+
+  /**
+   * Clones existing number format with possible overrides for some
+   * of the options.
+   * @param {!Object} overrideSettings - overrides for current format settings.
+   * @returns {Object} - new or cached NumberFormat object.
+   * @public
+   */
+  formatter.derive = function(overrideSettings) {
+    // To remove a setting user can specify undefined as its value. We'll remove
+    // it from the map in that case.
+    for (var prop in overrideSettings) {
+      if (settings.hasOwnProperty(prop) && !overrideSettings[prop]) {
+        delete settings[prop];
+      }
+    }
+    return new v8Locale.__NumberFormat(
+        locale, v8Locale.__createSettingsOrDefault(overrideSettings, settings));
+  };
+
+  return formatter;
+};
+
+/**
+ * Creates new NumberFormat based on current locale.
+ * @param {Object} - formatting flags. See constructor.
+ * @returns {Object} - new or cached NumberFormat object.
+ */
+v8Locale.prototype.createNumberFormat = function(settings) {
+  return new v8Locale.__NumberFormat(this, settings);
+};
+
+/**
  * Merges user settings and defaults.
  * Settings that are not of object type are rejected.
  * Actual property values are not validated, but whitespace is trimmed if they
@@ -145,8 +337,9 @@
  * @param {!Object} settings - user provided settings.
  * @param {!Object} defaults - default values for this type of settings.
  * @returns {Object} - valid settings object.
+ * @private
  */
-v8Locale.createSettingsOrDefault_ = function(settings, defaults) {
+v8Locale.__createSettingsOrDefault = function(settings, defaults) {
   if (!settings || typeof(settings) !== 'object' ) {
     return defaults;
   }
@@ -155,11 +348,17 @@
       settings[key] = defaults[key];
     }
   }
-  // Clean up values, like trimming whitespace.
+  // Clean up settings.
   for (var key in settings) {
+    // Trim whitespace.
     if (typeof(settings[key]) === "string") {
       settings[key] = settings[key].trim();
     }
+    // Remove all properties that are set to undefined/null. This allows
+    // derive method to remove a setting we don't need anymore.
+    if (!settings[key]) {
+      delete settings[key];
+    }
   }
 
   return settings;
@@ -170,8 +369,9 @@
  * we create default locale and return it.
  * @param {!Object} locale - user provided locale.
  * @returns {Object} - v8Locale object.
+ * @private
  */
-v8Locale.createLocaleOrDefault_ = function(locale) {
+v8Locale.__createLocaleOrDefault = function(locale) {
   if (!locale || !(locale instanceof v8Locale)) {
     return new v8Locale();
   } else {
diff --git a/src/extensions/experimental/language-matcher.cc b/src/extensions/experimental/language-matcher.cc
index 385ebff..127e571 100644
--- a/src/extensions/experimental/language-matcher.cc
+++ b/src/extensions/experimental/language-matcher.cc
@@ -28,13 +28,14 @@
 // TODO(cira): Remove LanguageMatcher from v8 when ICU implements
 // language matching API.
 
-#include "language-matcher.h"
+#include "src/extensions/experimental/language-matcher.h"
 
-#include "i18n-utils.h"
+#include <string.h>
+
+#include "src/extensions/experimental/i18n-utils.h"
 #include "unicode/datefmt.h"  // For getAvailableLocales
 #include "unicode/locid.h"
 #include "unicode/uloc.h"
-#include "utils.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/extensions/experimental/language-matcher.h b/src/extensions/experimental/language-matcher.h
index b5336a2..dd29304 100644
--- a/src/extensions/experimental/language-matcher.h
+++ b/src/extensions/experimental/language-matcher.h
@@ -28,7 +28,7 @@
 #ifndef V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
 #define V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
 
-#include <v8.h>
+#include "include/v8.h"
 
 #include "unicode/uloc.h"
 
diff --git a/src/extensions/experimental/number-format.cc b/src/extensions/experimental/number-format.cc
new file mode 100644
index 0000000..51e0b95
--- /dev/null
+++ b/src/extensions/experimental/number-format.cc
@@ -0,0 +1,356 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/extensions/experimental/number-format.h"
+
+#include <string.h>
+
+#include "src/extensions/experimental/i18n-utils.h"
+#include "unicode/dcfmtsym.h"
+#include "unicode/decimfmt.h"
+#include "unicode/locid.h"
+#include "unicode/numfmt.h"
+#include "unicode/uchar.h"
+#include "unicode/ucurr.h"
+
+namespace v8 {
+namespace internal {
+
+const int NumberFormat::kCurrencyCodeLength = 4;
+
+v8::Persistent<v8::FunctionTemplate> NumberFormat::number_format_template_;
+
+static icu::DecimalFormat* CreateNumberFormat(v8::Handle<v8::String>,
+                                              v8::Handle<v8::String>,
+                                              v8::Handle<v8::Object>);
+static icu::DecimalFormat* CreateFormatterFromSkeleton(
+    const icu::Locale&, const icu::UnicodeString&, UErrorCode*);
+static icu::DecimalFormatSymbols* GetFormatSymbols(const icu::Locale&);
+static bool GetCurrencyCode(const icu::Locale&,
+                            const char* const,
+                            v8::Handle<v8::Object>,
+                            UChar*);
+static v8::Handle<v8::Value> ThrowUnexpectedObjectError();
+
+icu::DecimalFormat* NumberFormat::UnpackNumberFormat(
+    v8::Handle<v8::Object> obj) {
+  if (number_format_template_->HasInstance(obj)) {
+    return static_cast<icu::DecimalFormat*>(
+        obj->GetPointerFromInternalField(0));
+  }
+
+  return NULL;
+}
+
+void NumberFormat::DeleteNumberFormat(v8::Persistent<v8::Value> object,
+                                      void* param) {
+  v8::Persistent<v8::Object> persistent_object =
+      v8::Persistent<v8::Object>::Cast(object);
+
+  // First delete the hidden C++ object.
+  // Unpacking should never return NULL here. That would only happen if
+  // this method is used as the weak callback for persistent handles not
+  // pointing to a number formatter.
+  delete UnpackNumberFormat(persistent_object);
+
+  // Then dispose of the persistent handle to JS object.
+  persistent_object.Dispose();
+}
+
+v8::Handle<v8::Value> NumberFormat::Format(const v8::Arguments& args) {
+  v8::HandleScope handle_scope;
+
+  if (args.Length() != 1 || !args[0]->IsNumber()) {
+    // Just return NaN on invalid input.
+    return v8::String::New("NaN");
+  }
+
+  icu::DecimalFormat* number_format = UnpackNumberFormat(args.Holder());
+  if (!number_format) {
+    return ThrowUnexpectedObjectError();
+  }
+
+  // ICU will handle actual NaN value properly and return NaN string.
+  icu::UnicodeString result;
+  number_format->format(args[0]->NumberValue(), result);
+
+  return v8::String::New(
+      reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length());
+}
+
+v8::Handle<v8::Value> NumberFormat::JSNumberFormat(const v8::Arguments& args) {
+  v8::HandleScope handle_scope;
+
+  // Expect locale id, region id and settings.
+  if (args.Length() != 3 ||
+      !args[0]->IsString() || !args[1]->IsString() || !args[2]->IsObject()) {
+    return v8::ThrowException(v8::Exception::SyntaxError(
+        v8::String::New("Locale, region and number settings are required.")));
+  }
+
+  icu::DecimalFormat* number_format = CreateNumberFormat(
+      args[0]->ToString(), args[1]->ToString(), args[2]->ToObject());
+
+  if (number_format_template_.IsEmpty()) {
+    v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
+
+    raw_template->SetClassName(v8::String::New("v8Locale.NumberFormat"));
+
+    // Define internal field count on instance template.
+    v8::Local<v8::ObjectTemplate> object_template =
+        raw_template->InstanceTemplate();
+
+    // Set aside internal field for icu number formatter.
+    object_template->SetInternalFieldCount(1);
+
+    // Define all of the prototype methods on prototype template.
+    v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
+    proto->Set(v8::String::New("format"),
+               v8::FunctionTemplate::New(Format));
+
+    number_format_template_ =
+        v8::Persistent<v8::FunctionTemplate>::New(raw_template);
+  }
+
+  // Create an empty object wrapper.
+  v8::Local<v8::Object> local_object =
+      number_format_template_->GetFunction()->NewInstance();
+  v8::Persistent<v8::Object> wrapper =
+      v8::Persistent<v8::Object>::New(local_object);
+
+  // Set number formatter as internal field of the resulting JS object.
+  wrapper->SetPointerInInternalField(0, number_format);
+
+  // Create options key.
+  v8::Local<v8::Object> options = v8::Object::New();
+
+  // Show what ICU decided to use for easier problem tracking.
+  // Keep it as v8 specific extension.
+  icu::UnicodeString pattern;
+  number_format->toPattern(pattern);
+  options->Set(v8::String::New("v8ResolvedPattern"),
+               v8::String::New(reinterpret_cast<const uint16_t*>(
+                   pattern.getBuffer()), pattern.length()));
+
+  // Set resolved currency code in options.currency if not empty.
+  icu::UnicodeString currency(number_format->getCurrency());
+  if (!currency.isEmpty()) {
+    options->Set(v8::String::New("currencyCode"),
+                 v8::String::New(reinterpret_cast<const uint16_t*>(
+                     currency.getBuffer()), currency.length()));
+  }
+
+  wrapper->Set(v8::String::New("options"), options);
+
+  // Make object handle weak so we can delete iterator once GC kicks in.
+  wrapper.MakeWeak(NULL, DeleteNumberFormat);
+
+  return wrapper;
+}
+
+// Returns DecimalFormat.
+static icu::DecimalFormat* CreateNumberFormat(v8::Handle<v8::String> locale,
+                                              v8::Handle<v8::String> region,
+                                              v8::Handle<v8::Object> settings) {
+  v8::HandleScope handle_scope;
+
+  v8::String::AsciiValue ascii_locale(locale);
+  icu::Locale icu_locale(*ascii_locale);
+
+  // Make formatter from skeleton.
+  icu::DecimalFormat* number_format = NULL;
+  UErrorCode status = U_ZERO_ERROR;
+  icu::UnicodeString setting;
+
+  if (I18NUtils::ExtractStringSetting(settings, "skeleton", &setting)) {
+    // TODO(cira): Use ICU skeleton once
+    // http://bugs.icu-project.org/trac/ticket/8610 is resolved.
+    number_format = CreateFormatterFromSkeleton(icu_locale, setting, &status);
+  } else if (I18NUtils::ExtractStringSetting(settings, "pattern", &setting)) {
+    number_format =
+        new icu::DecimalFormat(setting, GetFormatSymbols(icu_locale), status);
+  } else if (I18NUtils::ExtractStringSetting(settings, "style", &setting)) {
+    if (setting == UNICODE_STRING_SIMPLE("currency")) {
+      number_format = static_cast<icu::DecimalFormat*>(
+          icu::NumberFormat::createCurrencyInstance(icu_locale, status));
+    } else if (setting == UNICODE_STRING_SIMPLE("percent")) {
+      number_format = static_cast<icu::DecimalFormat*>(
+          icu::NumberFormat::createPercentInstance(icu_locale, status));
+    } else if (setting == UNICODE_STRING_SIMPLE("scientific")) {
+      number_format = static_cast<icu::DecimalFormat*>(
+          icu::NumberFormat::createScientificInstance(icu_locale, status));
+    } else {
+      // Make it decimal in any other case.
+      number_format = static_cast<icu::DecimalFormat*>(
+          icu::NumberFormat::createInstance(icu_locale, status));
+    }
+  }
+
+  if (U_FAILURE(status)) {
+    delete number_format;
+    status = U_ZERO_ERROR;
+    number_format = static_cast<icu::DecimalFormat*>(
+        icu::NumberFormat::createInstance(icu_locale, status));
+  }
+
+  // Attach appropriate currency code to the formatter.
+  // It affects currency formatters only.
+  // Region is full language identifier in form 'und_' + region id.
+  v8::String::AsciiValue ascii_region(region);
+
+  UChar currency_code[NumberFormat::kCurrencyCodeLength];
+  if (GetCurrencyCode(icu_locale, *ascii_region, settings, currency_code)) {
+    number_format->setCurrency(currency_code, status);
+  }
+
+  return number_format;
+}
+
+// Generates ICU number format pattern from given skeleton.
+static icu::DecimalFormat* CreateFormatterFromSkeleton(
+    const icu::Locale& icu_locale,
+    const icu::UnicodeString& skeleton,
+    UErrorCode* status) {
+  icu::DecimalFormat skeleton_format(
+      skeleton, GetFormatSymbols(icu_locale), *status);
+
+  // Find out if skeleton contains currency or percent symbol and create
+  // proper instance to tweak.
+  icu::DecimalFormat* base_format = NULL;
+
+  // UChar representation of U+00A4 currency symbol.
+  const UChar currency_symbol = 0xA4u;
+
+  int32_t index = skeleton.indexOf(currency_symbol);
+  if (index != -1) {
+    // Find how many U+00A4 are there. There is at least one.
+    // Case of non-consecutive U+00A4 is taken care of in i18n.js.
+    int32_t end_index = skeleton.lastIndexOf(currency_symbol, index);
+
+    icu::NumberFormat::EStyles style;
+    switch (end_index - index) {
+      case 0:
+        style = icu::NumberFormat::kCurrencyStyle;
+        break;
+      case 1:
+        style = icu::NumberFormat::kIsoCurrencyStyle;
+        break;
+      default:
+        style = icu::NumberFormat::kPluralCurrencyStyle;
+    }
+
+    base_format = static_cast<icu::DecimalFormat*>(
+        icu::NumberFormat::createInstance(icu_locale, style, *status));
+  } else if (skeleton.indexOf('%') != -1) {
+    base_format = static_cast<icu::DecimalFormat*>(
+        icu::NumberFormat::createPercentInstance(icu_locale, *status));
+  } else {
+    // TODO(cira): Handle scientific skeleton.
+    base_format = static_cast<icu::DecimalFormat*>(
+        icu::NumberFormat::createInstance(icu_locale, *status));
+  }
+
+  if (U_FAILURE(*status)) {
+    delete base_format;
+    return NULL;
+  }
+
+  // Copy important information from skeleton to the new formatter.
+  // TODO(cira): copy rounding information from skeleton?
+  base_format->setGroupingUsed(skeleton_format.isGroupingUsed());
+
+  base_format->setMinimumIntegerDigits(
+      skeleton_format.getMinimumIntegerDigits());
+
+  base_format->setMinimumFractionDigits(
+      skeleton_format.getMinimumFractionDigits());
+
+  base_format->setMaximumFractionDigits(
+      skeleton_format.getMaximumFractionDigits());
+
+  return base_format;
+}
+
+// Gets decimal symbols for a locale.
+static icu::DecimalFormatSymbols* GetFormatSymbols(
+    const icu::Locale& icu_locale) {
+  UErrorCode status = U_ZERO_ERROR;
+  icu::DecimalFormatSymbols* symbols =
+      new icu::DecimalFormatSymbols(icu_locale, status);
+
+  if (U_FAILURE(status)) {
+    delete symbols;
+    // Use symbols from default locale.
+    symbols = new icu::DecimalFormatSymbols(status);
+  }
+
+  return symbols;
+}
+
+// Gets currency ISO 4217 3-letter code.
+// Check currencyCode setting first, then @currency=code and in the end
+// try to infer currency code from locale in the form 'und_' + region id.
+// Returns false in case of error.
+static bool GetCurrencyCode(const icu::Locale& icu_locale,
+                            const char* const und_region_locale,
+                            v8::Handle<v8::Object> settings,
+                            UChar* code) {
+  UErrorCode status = U_ZERO_ERROR;
+
+  // If there is user specified currency code, use it.
+  icu::UnicodeString currency;
+  if (I18NUtils::ExtractStringSetting(settings, "currencyCode", &currency)) {
+    currency.extract(code, NumberFormat::kCurrencyCodeLength, status);
+    return true;
+  }
+
+  // If ICU locale has -cu- currency code use it.
+  char currency_code[NumberFormat::kCurrencyCodeLength];
+  int32_t length = icu_locale.getKeywordValue(
+      "currency", currency_code, NumberFormat::kCurrencyCodeLength, status);
+  if (length != 0) {
+    I18NUtils::AsciiToUChar(currency_code, length + 1,
+                            code, NumberFormat::kCurrencyCodeLength);
+    return true;
+  }
+
+  // Otherwise infer currency code from the region id.
+  ucurr_forLocale(
+      und_region_locale, code, NumberFormat::kCurrencyCodeLength, &status);
+
+  return !!U_SUCCESS(status);
+}
+
+// Throws a JavaScript exception.
+static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
+  // Returns undefined, and schedules an exception to be thrown.
+  return v8::ThrowException(v8::Exception::Error(
+      v8::String::New("NumberFormat method called on an object "
+                      "that is not a NumberFormat.")));
+}
+
+} }  // namespace v8::internal
diff --git a/src/extensions/experimental/number-format.h b/src/extensions/experimental/number-format.h
new file mode 100644
index 0000000..bcfaed6
--- /dev/null
+++ b/src/extensions/experimental/number-format.h
@@ -0,0 +1,71 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
+#define V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
+
+#include "include/v8.h"
+
+#include "unicode/uversion.h"
+
+namespace U_ICU_NAMESPACE {
+class DecimalFormat;
+}
+
+namespace v8 {
+namespace internal {
+
+class NumberFormat {
+ public:
+  // 3-letter ISO 4217 currency code plus \0.
+  static const int kCurrencyCodeLength;
+
+  static v8::Handle<v8::Value> JSNumberFormat(const v8::Arguments& args);
+
+  // Helper methods for various bindings.
+
+  // Unpacks date format object from corresponding JavaScript object.
+  static icu::DecimalFormat* UnpackNumberFormat(
+      v8::Handle<v8::Object> obj);
+
+  // Release memory we allocated for the NumberFormat once the JS object that
+  // holds the pointer gets garbage collected.
+  static void DeleteNumberFormat(v8::Persistent<v8::Value> object,
+                                 void* param);
+
+  // Formats number and returns corresponding string.
+  static v8::Handle<v8::Value> Format(const v8::Arguments& args);
+
+ private:
+  NumberFormat();
+
+  static v8::Persistent<v8::FunctionTemplate> number_format_template_;
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
diff --git a/src/factory.cc b/src/factory.cc
index 06d1655..ac96668 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -58,6 +58,16 @@
 }
 
 
+Handle<FixedArray> Factory::NewFixedDoubleArray(int size,
+                                                PretenureFlag pretenure) {
+  ASSERT(0 <= size);
+  CALL_HEAP_FUNCTION(
+      isolate(),
+      isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure),
+      FixedArray);
+}
+
+
 Handle<StringDictionary> Factory::NewStringDictionary(int at_least_space_for) {
   ASSERT(0 <= at_least_space_for);
   CALL_HEAP_FUNCTION(isolate(),
@@ -169,21 +179,21 @@
 }
 
 
-Handle<String> Factory::NewRawAsciiString(int length,
-                                          PretenureFlag pretenure) {
+Handle<SeqAsciiString> Factory::NewRawAsciiString(int length,
+                                                  PretenureFlag pretenure) {
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateRawAsciiString(length, pretenure),
-      String);
+      SeqAsciiString);
 }
 
 
-Handle<String> Factory::NewRawTwoByteString(int length,
-                                            PretenureFlag pretenure) {
+Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length,
+                                                      PretenureFlag pretenure) {
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateRawTwoByteString(length, pretenure),
-      String);
+      SeqTwoByteString);
 }
 
 
@@ -204,6 +214,16 @@
 }
 
 
+Handle<String> Factory::NewProperSubString(Handle<String> str,
+                                           int begin,
+                                           int end) {
+  ASSERT(begin > 0 || end < str->length());
+  CALL_HEAP_FUNCTION(isolate(),
+                     isolate()->heap()->AllocateSubString(*str, begin, end),
+                     String);
+}
+
+
 Handle<String> Factory::NewExternalStringFromAscii(
     ExternalAsciiString::Resource* resource) {
   CALL_HEAP_FUNCTION(
@@ -231,22 +251,34 @@
 
 
 Handle<Context> Factory::NewFunctionContext(int length,
-                                            Handle<JSFunction> closure) {
+                                            Handle<JSFunction> function) {
   CALL_HEAP_FUNCTION(
       isolate(),
-      isolate()->heap()->AllocateFunctionContext(length, *closure),
+      isolate()->heap()->AllocateFunctionContext(length, *function),
       Context);
 }
 
 
-Handle<Context> Factory::NewWithContext(Handle<Context> previous,
-                                        Handle<JSObject> extension,
-                                        bool is_catch_context) {
+Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function,
+                                         Handle<Context> previous,
+                                         Handle<String> name,
+                                         Handle<Object> thrown_object) {
   CALL_HEAP_FUNCTION(
       isolate(),
-      isolate()->heap()->AllocateWithContext(*previous,
-                                             *extension,
-                                             is_catch_context),
+      isolate()->heap()->AllocateCatchContext(*function,
+                                              *previous,
+                                              *name,
+                                              *thrown_object),
+      Context);
+}
+
+
+Handle<Context> Factory::NewWithContext(Handle<JSFunction> function,
+                                        Handle<Context> previous,
+                                        Handle<JSObject> extension) {
+  CALL_HEAP_FUNCTION(
+      isolate(),
+      isolate()->heap()->AllocateWithContext(*function, *previous, *extension),
       Context);
 }
 
@@ -860,6 +892,13 @@
 }
 
 
+void Factory::BecomeJSObject(Handle<JSProxy> object) {
+  CALL_HEAP_FUNCTION_VOID(
+      isolate(),
+      isolate()->heap()->ReinitializeJSProxyAsJSObject(*object));
+}
+
+
 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
     Handle<String> name,
     int number_of_literals,
diff --git a/src/factory.h b/src/factory.h
index 55d1e9a..19f3827 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -39,7 +39,7 @@
 
 class Factory {
  public:
-  // Allocate a new fixed array with undefined entries.
+  // Allocate a new uninitialized fixed array.
   Handle<FixedArray> NewFixedArray(
       int size,
       PretenureFlag pretenure = NOT_TENURED);
@@ -49,6 +49,11 @@
       int size,
       PretenureFlag pretenure = NOT_TENURED);
 
+  // Allocate a new uninitialized fixed double array.
+  Handle<FixedArray> NewFixedDoubleArray(
+      int size,
+      PretenureFlag pretenure = NOT_TENURED);
+
   Handle<NumberDictionary> NewNumberDictionary(int at_least_space_for);
 
   Handle<StringDictionary> NewStringDictionary(int at_least_space_for);
@@ -112,10 +117,10 @@
   // Allocates and partially initializes an ASCII or TwoByte String. The
   // characters of the string are uninitialized. Currently used in regexp code
   // only, where they are pretenured.
-  Handle<String> NewRawAsciiString(
+  Handle<SeqAsciiString> NewRawAsciiString(
       int length,
       PretenureFlag pretenure = NOT_TENURED);
-  Handle<String> NewRawTwoByteString(
+  Handle<SeqTwoByteString> NewRawTwoByteString(
       int length,
       PretenureFlag pretenure = NOT_TENURED);
 
@@ -128,6 +133,11 @@
                               int begin,
                               int end);
 
+  // Create a new string object which holds a proper substring of a string.
+  Handle<String> NewProperSubString(Handle<String> str,
+                                    int begin,
+                                    int end);
+
   // Creates a new external String object.  There are two String encodings
   // in the system: ASCII and two byte.  Unlike other String types, it does
   // not make sense to have a UTF-8 factory function for external strings,
@@ -142,12 +152,18 @@
 
   // Create a function context.
   Handle<Context> NewFunctionContext(int length,
-                                     Handle<JSFunction> closure);
+                                     Handle<JSFunction> function);
+
+  // Create a catch context.
+  Handle<Context> NewCatchContext(Handle<JSFunction> function,
+                                  Handle<Context> previous,
+                                  Handle<String> name,
+                                  Handle<Object> thrown_object);
 
   // Create a 'with' context.
-  Handle<Context> NewWithContext(Handle<Context> previous,
-                                 Handle<JSObject> extension,
-                                 bool is_catch_context);
+  Handle<Context> NewWithContext(Handle<JSFunction> function,
+                                 Handle<Context> previous,
+                                 Handle<JSObject> extension);
 
   // Return the Symbol matching the passed in string.
   Handle<String> SymbolFromString(Handle<String> value);
@@ -237,6 +253,9 @@
 
   Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
 
+  // Change the type of the argument into a regular JS object and reinitialize.
+  void BecomeJSObject(Handle<JSProxy> object);
+
   Handle<JSFunction> NewFunction(Handle<String> name,
                                  Handle<Object> prototype);
 
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index a85f5fe..2db44c3 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -99,6 +99,9 @@
 // Flags for experimental language features.
 DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
 
+// Flags for experimental implementation features.
+DEFINE_bool(unbox_double_arrays, false, "automatically unbox arrays of doubles")
+
 // Flags for Crankshaft.
 #ifdef V8_TARGET_ARCH_MIPS
   DEFINE_bool(crankshaft, false, "use crankshaft")
@@ -131,12 +134,9 @@
 DEFINE_int(deopt_every_n_times,
            0,
            "deoptimize every n times a deopt point is passed")
-DEFINE_bool(process_arguments_object, true, "try to deal with arguments object")
 DEFINE_bool(trap_on_deopt, false, "put a break point before deoptimizing")
 DEFINE_bool(deoptimize_uncommon_cases, true, "deoptimize uncommon cases")
 DEFINE_bool(polymorphic_inlining, true, "polymorphic inlining")
-DEFINE_bool(aggressive_loop_invariant_motion, true,
-            "aggressive motion of instructions out of loops")
 DEFINE_bool(use_osr, true, "use on-stack replacement")
 
 DEFINE_bool(trace_osr, false, "trace on-stack replacement")
@@ -149,8 +149,6 @@
 DEFINE_bool(code_comments, false, "emit comments in code disassembly")
 DEFINE_bool(peephole_optimization, true,
             "perform peephole optimizations in assembly code")
-DEFINE_bool(print_peephole_optimization, false,
-            "print peephole optimizations in assembly code")
 DEFINE_bool(enable_sse2, true,
             "enable use of SSE2 instructions if available")
 DEFINE_bool(enable_sse3, true,
@@ -189,7 +187,6 @@
 
 // codegen-ia32.cc / codegen-arm.cc
 DEFINE_bool(trace, false, "trace function calls")
-DEFINE_bool(defer_negation, true, "defer negation operation")
 DEFINE_bool(mask_constants_with_cookie,
             true,
             "use random jit cookie to mask large constants")
@@ -202,33 +199,23 @@
 DEFINE_bool(opt_eagerly, false, "be more eager when adaptively optimizing")
 DEFINE_bool(always_opt, false, "always try to optimize functions")
 DEFINE_bool(prepare_always_opt, false, "prepare for turning on always opt")
-DEFINE_bool(debug_info, true, "add debug information to compiled functions")
 DEFINE_bool(deopt, true, "support deoptimization")
 DEFINE_bool(trace_deopt, false, "trace deoptimization")
 
 // compiler.cc
-DEFINE_bool(strict, false, "strict error checking")
 DEFINE_int(min_preparse_length, 1024,
            "minimum length for automatic enable preparsing")
-DEFINE_bool(full_compiler, true, "enable dedicated backend for run-once code")
 DEFINE_bool(always_full_compiler, false,
             "try to use the dedicated run-once backend for all code")
 DEFINE_bool(trace_bailout, false,
             "print reasons for falling back to using the classic V8 backend")
-DEFINE_bool(safe_int32_compiler, true,
-            "enable optimized side-effect-free int32 expressions.")
-DEFINE_bool(use_flow_graph, false, "perform flow-graph based optimizations")
 
 // compilation-cache.cc
 DEFINE_bool(compilation_cache, true, "enable compilation cache")
 
 DEFINE_bool(cache_prototype_transitions, true, "cache prototype transitions")
 
-// data-flow.cc
-DEFINE_bool(loop_peeling, false, "Peel off the first iteration of loops.")
-
 // debug.cc
-DEFINE_bool(remote_debugging, false, "enable remote debugging")
 DEFINE_bool(trace_debug_json, false, "trace debugging JSON request/response")
 DEFINE_bool(debugger_auto_break, true,
             "automatically set the debug break flag when debugger commands are "
@@ -316,9 +303,6 @@
 DEFINE_bool(allow_natives_syntax, false, "allow natives syntax")
 DEFINE_bool(strict_mode, true, "allow strict mode directives")
 
-// rewriter.cc
-DEFINE_bool(optimize_ast, true, "optimize the ast")
-
 // simulator-arm.cc and simulator-mips.cc
 DEFINE_bool(trace_sim, false, "Trace simulator execution")
 DEFINE_bool(check_icache, false, "Check icache flushes in ARM simulator")
@@ -337,7 +321,6 @@
             "activate a 100ms timer that switches between V8 threads")
 
 // Regexp
-DEFINE_bool(trace_regexps, false, "trace regexp execution")
 DEFINE_bool(regexp_optimization, true, "generate optimized regexp code")
 DEFINE_bool(regexp_entry_native, true, "use native code to enter regexp")
 
@@ -388,6 +371,8 @@
 DEFINE_bool(gdbjit, false, "enable GDBJIT interface (disables compacting GC)")
 DEFINE_bool(gdbjit_full, false, "enable GDBJIT interface for all code objects")
 DEFINE_bool(gdbjit_dump, false, "dump elf objects with debug info to disk")
+DEFINE_string(gdbjit_dump_filter, "",
+              "dump only objects containing this substring")
 
 //
 // Debug only flags
@@ -414,16 +399,11 @@
 DEFINE_bool(print_json_ast, false, "print source AST as JSON")
 DEFINE_bool(print_builtin_json_ast, false,
             "print source AST for builtins as JSON")
-DEFINE_bool(trace_calls, false, "trace calls")
-DEFINE_bool(trace_builtin_calls, false, "trace builtins calls")
 DEFINE_string(stop_at, "", "function name where to insert a breakpoint")
 
 // compiler.cc
 DEFINE_bool(print_builtin_scopes, false, "print scopes for builtins")
 DEFINE_bool(print_scopes, false, "print scopes")
-DEFINE_bool(print_ir, false, "print the AST as seen by the backend")
-DEFINE_bool(print_graph_text, false,
-            "print a text representation of the flow graph")
 
 // contexts.cc
 DEFINE_bool(trace_contexts, false, "trace contexts operations")
@@ -472,14 +452,10 @@
             "trace regexp macro assembler calls.")
 
 //
-// Logging and profiling only flags
+// Logging and profiling flags
 //
 #undef FLAG
-#ifdef ENABLE_LOGGING_AND_PROFILING
 #define FLAG FLAG_FULL
-#else
-#define FLAG FLAG_READONLY
-#endif
 
 // log.cc
 DEFINE_bool(log, false,
@@ -495,7 +471,6 @@
 DEFINE_bool(log_snapshot_positions, false,
             "log positions of (de)serialized objects in the snapshot.")
 DEFINE_bool(log_suspect, false, "Log suspect operations.")
-DEFINE_bool(log_producers, false, "Log stack traces of JS objects allocations.")
 DEFINE_bool(prof, false,
             "Log statistical profiling information (implies --log-code).")
 DEFINE_bool(prof_auto, true,
@@ -512,19 +487,6 @@
 DEFINE_bool(ll_prof, false, "Enable low-level linux profiler.")
 
 //
-// Heap protection flags
-// Using heap protection requires ENABLE_LOGGING_AND_PROFILING as well.
-//
-#ifdef ENABLE_HEAP_PROTECTION
-#undef FLAG
-#define FLAG FLAG_FULL
-
-DEFINE_bool(protect_heap, false,
-            "Protect/unprotect V8's heap when leaving/entring the VM.")
-
-#endif
-
-//
 // Disassembler only flags
 //
 #undef FLAG
diff --git a/src/frames.cc b/src/frames.cc
index d81d5af..bebd10a 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -36,6 +36,8 @@
 #include "scopeinfo.h"
 #include "string-stream.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
@@ -346,7 +348,6 @@
 // -------------------------------------------------------------------------
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
     Isolate* isolate,
     Address fp, Address sp, Address low_bound, Address high_bound) :
@@ -362,7 +363,6 @@
     if (frame()->is_java_script()) return;
   }
 }
-#endif
 
 
 Code* StackFrame::GetSafepointData(Isolate* isolate,
@@ -371,7 +371,6 @@
                                    unsigned* stack_slots) {
   PcToCodeCache::PcToCodeCacheEntry* entry =
       isolate->pc_to_code_cache()->GetCacheEntry(pc);
-  SafepointEntry cached_safepoint_entry = entry->safepoint_entry;
   if (!entry->safepoint_entry.is_valid()) {
     entry->safepoint_entry = entry->code->GetSafepointEntry(pc);
     ASSERT(entry->safepoint_entry.is_valid());
@@ -528,6 +527,17 @@
 }
 
 
+Object* StandardFrame::GetExpression(Address fp, int index) {
+  return Memory::Object_at(GetExpressionAddress(fp, index));
+}
+
+
+Address StandardFrame::GetExpressionAddress(Address fp, int n) {
+  const int offset = StandardFrameConstants::kExpressionsOffset;
+  return fp + offset - n * kPointerSize;
+}
+
+
 int StandardFrame::ComputeExpressionsCount() const {
   const int offset =
       StandardFrameConstants::kExpressionsOffset + kPointerSize;
@@ -646,6 +656,16 @@
 }
 
 
+int JavaScriptFrame::GetArgumentsLength() const {
+  // If there is an arguments adaptor frame get the arguments length from it.
+  if (has_adapted_arguments()) {
+    return Smi::cast(GetExpression(caller_fp(), 0))->value();
+  } else {
+    return GetNumberOfIncomingArguments();
+  }
+}
+
+
 Code* JavaScriptFrame::unchecked_code() const {
   JSFunction* function = JSFunction::cast(this->function());
   return function->unchecked_code();
@@ -812,6 +832,22 @@
 }
 
 
+int OptimizedFrame::GetInlineCount() {
+  ASSERT(is_optimized());
+
+  int deopt_index = Safepoint::kNoDeoptimizationIndex;
+  DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
+
+  TranslationIterator it(data->TranslationByteArray(),
+                         data->TranslationIndex(deopt_index)->value());
+  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
+  ASSERT(opcode == Translation::BEGIN);
+  USE(opcode);
+  int frame_count = it.Next();
+  return frame_count;
+}
+
+
 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
   ASSERT(functions->length() == 0);
   ASSERT(is_optimized());
diff --git a/src/frames.h b/src/frames.h
index aa91026..f542a92 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -383,6 +383,7 @@
   inline Object* GetExpression(int index) const;
   inline void SetExpression(int index, Object* value);
   int ComputeExpressionsCount() const;
+  static Object* GetExpression(Address fp, int index);
 
   virtual void SetCallerFp(Address caller_fp);
 
@@ -411,6 +412,7 @@
 
   // Returns the address of the n'th expression stack element.
   Address GetExpressionAddress(int n) const;
+  static Address GetExpressionAddress(Address fp, int n);
 
   // Determines if the n'th expression stack element is in a stack
   // handler or not. Requires traversing all handlers in this frame.
@@ -483,6 +485,7 @@
   // actual passed arguments are available in an arguments adaptor
   // frame below it on the stack.
   inline bool has_adapted_arguments() const;
+  int GetArgumentsLength() const;
 
   // Garbage collection support.
   virtual void Iterate(ObjectVisitor* v) const;
@@ -495,6 +498,9 @@
   // Determine the code for the frame.
   virtual Code* unchecked_code() const;
 
+  // Returns the levels of inlining for this frame.
+  virtual int GetInlineCount() { return 1; }
+
   // Return a list with JSFunctions of this frame.
   virtual void GetFunctions(List<JSFunction*>* functions);
 
@@ -533,6 +539,8 @@
   // GC support.
   virtual void Iterate(ObjectVisitor* v) const;
 
+  virtual int GetInlineCount();
+
   // Return a list with JSFunctions of this frame.
   // The functions are ordered bottom-to-top (i.e. functions.last()
   // is the top-most activation)
@@ -835,7 +843,6 @@
 };
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
     SafeJavaScriptFrameIterator;
 
@@ -847,7 +854,6 @@
                                        Address low_bound, Address high_bound);
   void Advance();
 };
-#endif
 
 
 class StackFrameLocator BASE_EMBEDDED {
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 2b43e89..8c2f0d1 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -90,14 +90,14 @@
 }
 
 
-void BreakableStatementChecker::VisitWithEnterStatement(
-    WithEnterStatement* stmt) {
+void BreakableStatementChecker::VisitEnterWithContextStatement(
+    EnterWithContextStatement* stmt) {
   Visit(stmt->expression());
 }
 
 
-void BreakableStatementChecker::VisitWithExitStatement(
-    WithExitStatement* stmt) {
+void BreakableStatementChecker::VisitExitContextStatement(
+    ExitContextStatement* stmt) {
 }
 
 
@@ -187,11 +187,6 @@
 }
 
 
-void BreakableStatementChecker::VisitCatchExtensionObject(
-    CatchExtensionObject* expr) {
-}
-
-
 void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
   // If assigning to a property (including a global property) the assignment is
   // breakable.
@@ -351,7 +346,7 @@
 }
 
 
-void FullCodeGenerator::PrepareForBailout(AstNode* node, State state) {
+void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
   PrepareForBailoutForId(node->id(), state);
 }
 
@@ -409,7 +404,7 @@
   // Adjust by a (parameter or local) base offset.
   switch (slot->type()) {
     case Slot::PARAMETER:
-      offset += (scope()->num_parameters() + 1) * kPointerSize;
+      offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
       break;
     case Slot::LOCAL:
       offset += JavaScriptFrameConstants::kLocal0Offset;
@@ -449,7 +444,7 @@
   // For simplicity we always test the accumulator register.
   __ Move(result_register(), reg);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -471,7 +466,7 @@
   // For simplicity we always test the accumulator register.
   __ pop(result_register());
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -521,6 +516,14 @@
 }
 
 
+void FullCodeGenerator::DoTest(const TestContext* context) {
+  DoTest(context->condition(),
+         context->true_label(),
+         context->false_label(),
+         context->fall_through());
+}
+
+
 void FullCodeGenerator::VisitDeclarations(
     ZoneList<Declaration*>* declarations) {
   int length = declarations->length();
@@ -580,88 +583,78 @@
 
 
 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
-  if (FLAG_debug_info) {
-    CodeGenerator::RecordPositions(masm_, fun->start_position());
-  }
+  CodeGenerator::RecordPositions(masm_, fun->start_position());
 }
 
 
 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
-  if (FLAG_debug_info) {
-    CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
-  }
+  CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
 }
 
 
 void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
-  if (FLAG_debug_info) {
 #ifdef ENABLE_DEBUGGER_SUPPORT
-    if (!isolate()->debugger()->IsDebuggerActive()) {
-      CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
-    } else {
-      // Check if the statement will be breakable without adding a debug break
-      // slot.
-      BreakableStatementChecker checker;
-      checker.Check(stmt);
-      // Record the statement position right here if the statement is not
-      // breakable. For breakable statements the actual recording of the
-      // position will be postponed to the breakable code (typically an IC).
-      bool position_recorded = CodeGenerator::RecordPositions(
-          masm_, stmt->statement_pos(), !checker.is_breakable());
-      // If the position recording did record a new position generate a debug
-      // break slot to make the statement breakable.
-      if (position_recorded) {
-        Debug::GenerateSlot(masm_);
-      }
-    }
-#else
+  if (!isolate()->debugger()->IsDebuggerActive()) {
     CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
-#endif
+  } else {
+    // Check if the statement will be breakable without adding a debug break
+    // slot.
+    BreakableStatementChecker checker;
+    checker.Check(stmt);
+    // Record the statement position right here if the statement is not
+    // breakable. For breakable statements the actual recording of the
+    // position will be postponed to the breakable code (typically an IC).
+    bool position_recorded = CodeGenerator::RecordPositions(
+        masm_, stmt->statement_pos(), !checker.is_breakable());
+    // If the position recording did record a new position generate a debug
+    // break slot to make the statement breakable.
+    if (position_recorded) {
+      Debug::GenerateSlot(masm_);
+    }
   }
+#else
+  CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
+#endif
 }
 
 
 void FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) {
-  if (FLAG_debug_info) {
 #ifdef ENABLE_DEBUGGER_SUPPORT
-    if (!isolate()->debugger()->IsDebuggerActive()) {
-      CodeGenerator::RecordPositions(masm_, pos);
-    } else {
-      // Check if the expression will be breakable without adding a debug break
-      // slot.
-      BreakableStatementChecker checker;
-      checker.Check(expr);
-      // Record a statement position right here if the expression is not
-      // breakable. For breakable expressions the actual recording of the
-      // position will be postponed to the breakable code (typically an IC).
-      // NOTE this will record a statement position for something which might
-      // not be a statement. As stepping in the debugger will only stop at
-      // statement positions this is used for e.g. the condition expression of
-      // a do while loop.
-      bool position_recorded = CodeGenerator::RecordPositions(
-          masm_, pos, !checker.is_breakable());
-      // If the position recording did record a new position generate a debug
-      // break slot to make the statement breakable.
-      if (position_recorded) {
-        Debug::GenerateSlot(masm_);
-      }
-    }
-#else
+  if (!isolate()->debugger()->IsDebuggerActive()) {
     CodeGenerator::RecordPositions(masm_, pos);
-#endif
+  } else {
+    // Check if the expression will be breakable without adding a debug break
+    // slot.
+    BreakableStatementChecker checker;
+    checker.Check(expr);
+    // Record a statement position right here if the expression is not
+    // breakable. For breakable expressions the actual recording of the
+    // position will be postponed to the breakable code (typically an IC).
+    // NOTE this will record a statement position for something which might
+    // not be a statement. As stepping in the debugger will only stop at
+    // statement positions this is used for e.g. the condition expression of
+    // a do while loop.
+    bool position_recorded = CodeGenerator::RecordPositions(
+        masm_, pos, !checker.is_breakable());
+    // If the position recording did record a new position generate a debug
+    // break slot to make the statement breakable.
+    if (position_recorded) {
+      Debug::GenerateSlot(masm_);
+    }
   }
+#else
+  CodeGenerator::RecordPositions(masm_, pos);
+#endif
 }
 
 
 void FullCodeGenerator::SetStatementPosition(int pos) {
-  if (FLAG_debug_info) {
-    CodeGenerator::RecordPositions(masm_, pos);
-  }
+  CodeGenerator::RecordPositions(masm_, pos);
 }
 
 
 void FullCodeGenerator::SetSourcePosition(int pos) {
-  if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
+  if (pos != RelocInfo::kNoPosition) {
     masm_->positions_recorder()->RecordPosition(pos);
   }
 }
@@ -693,7 +686,6 @@
 
 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) {
   ZoneList<Expression*>* args = node->arguments();
-  Handle<String> name = node->name();
   const Runtime::Function* function = node->function();
   ASSERT(function != NULL);
   ASSERT(function->intrinsic_type == Runtime::INLINE);
@@ -704,143 +696,116 @@
 
 
 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
-  Comment cmnt(masm_, "[ BinaryOperation");
-  Token::Value op = expr->op();
-  Expression* left = expr->left();
-  Expression* right = expr->right();
-
-  OverwriteMode mode = NO_OVERWRITE;
-  if (left->ResultOverwriteAllowed()) {
-    mode = OVERWRITE_LEFT;
-  } else if (right->ResultOverwriteAllowed()) {
-    mode = OVERWRITE_RIGHT;
-  }
-
-  switch (op) {
+  switch (expr->op()) {
     case Token::COMMA:
-      VisitForEffect(left);
-      if (context()->IsTest()) ForwardBailoutToChild(expr);
-      context()->HandleExpression(right);
-      break;
-
+      return VisitComma(expr);
     case Token::OR:
     case Token::AND:
-      EmitLogicalOperation(expr);
-      break;
-
-    case Token::ADD:
-    case Token::SUB:
-    case Token::DIV:
-    case Token::MOD:
-    case Token::MUL:
-    case Token::BIT_OR:
-    case Token::BIT_AND:
-    case Token::BIT_XOR:
-    case Token::SHL:
-    case Token::SHR:
-    case Token::SAR: {
-      // Load both operands.
-      VisitForStackValue(left);
-      VisitForAccumulatorValue(right);
-
-      SetSourcePosition(expr->position());
-      if (ShouldInlineSmiCase(op)) {
-        EmitInlineSmiBinaryOp(expr, op, mode, left, right);
-      } else {
-        EmitBinaryOp(expr, op, mode);
-      }
-      break;
-    }
-
+      return VisitLogicalExpression(expr);
     default:
-      UNREACHABLE();
+      return VisitArithmeticExpression(expr);
   }
 }
 
 
-void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
-  Label eval_right, done;
-
-  context()->EmitLogicalLeft(expr, &eval_right, &done);
-
-  PrepareForBailoutForId(expr->RightId(), NO_REGISTERS);
-  __ bind(&eval_right);
+void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
+  Comment cmnt(masm_, "[ Comma");
+  VisitForEffect(expr->left());
   if (context()->IsTest()) ForwardBailoutToChild(expr);
-  context()->HandleExpression(expr->right());
+  VisitInCurrentContext(expr->right());
+}
 
+
+void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
+  bool is_logical_and = expr->op() == Token::AND;
+  Comment cmnt(masm_, is_logical_and ? "[ Logical AND" :  "[ Logical OR");
+  Expression* left = expr->left();
+  Expression* right = expr->right();
+  int right_id = expr->RightId();
+  Label done;
+
+  if (context()->IsTest()) {
+    Label eval_right;
+    const TestContext* test = TestContext::cast(context());
+    if (is_logical_and) {
+      VisitForControl(left, &eval_right, test->false_label(), &eval_right);
+    } else {
+      VisitForControl(left, test->true_label(), &eval_right, &eval_right);
+    }
+    PrepareForBailoutForId(right_id, NO_REGISTERS);
+    __ bind(&eval_right);
+    ForwardBailoutToChild(expr);
+
+  } else if (context()->IsAccumulatorValue()) {
+    VisitForAccumulatorValue(left);
+    // We want the value in the accumulator for the test, and on the stack in
+    // case we need it.
+    __ push(result_register());
+    Label discard, restore;
+    PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
+    if (is_logical_and) {
+      DoTest(left, &discard, &restore, &restore);
+    } else {
+      DoTest(left, &restore, &discard, &restore);
+    }
+    __ bind(&restore);
+    __ pop(result_register());
+    __ jmp(&done);
+    __ bind(&discard);
+    __ Drop(1);
+    PrepareForBailoutForId(right_id, NO_REGISTERS);
+
+  } else if (context()->IsStackValue()) {
+    VisitForAccumulatorValue(left);
+    // We want the value in the accumulator for the test, and on the stack in
+    // case we need it.
+    __ push(result_register());
+    Label discard;
+    PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
+    if (is_logical_and) {
+      DoTest(left, &discard, &done, &discard);
+    } else {
+      DoTest(left, &done, &discard, &discard);
+    }
+    __ bind(&discard);
+    __ Drop(1);
+    PrepareForBailoutForId(right_id, NO_REGISTERS);
+
+  } else {
+    ASSERT(context()->IsEffect());
+    Label eval_right;
+    if (is_logical_and) {
+      VisitForControl(left, &eval_right, &done, &eval_right);
+    } else {
+      VisitForControl(left, &done, &eval_right, &eval_right);
+    }
+    PrepareForBailoutForId(right_id, NO_REGISTERS);
+    __ bind(&eval_right);
+  }
+
+  VisitInCurrentContext(right);
   __ bind(&done);
 }
 
 
-void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr,
-                                                       Label* eval_right,
-                                                       Label* done) const {
-  if (expr->op() == Token::OR) {
-    codegen()->VisitForControl(expr->left(), done, eval_right, eval_right);
+void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
+  Token::Value op = expr->op();
+  Comment cmnt(masm_, "[ ArithmeticExpression");
+  Expression* left = expr->left();
+  Expression* right = expr->right();
+  OverwriteMode mode =
+      left->ResultOverwriteAllowed()
+      ? OVERWRITE_LEFT
+      : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE);
+
+  VisitForStackValue(left);
+  VisitForAccumulatorValue(right);
+
+  SetSourcePosition(expr->position());
+  if (ShouldInlineSmiCase(op)) {
+    EmitInlineSmiBinaryOp(expr, op, mode, left, right);
   } else {
-    ASSERT(expr->op() == Token::AND);
-    codegen()->VisitForControl(expr->left(), eval_right, done, eval_right);
-  }
-}
-
-
-void FullCodeGenerator::AccumulatorValueContext::EmitLogicalLeft(
-    BinaryOperation* expr,
-    Label* eval_right,
-    Label* done) const {
-  HandleExpression(expr->left());
-  // We want the value in the accumulator for the test, and on the stack in case
-  // we need it.
-  __ push(result_register());
-  Label discard, restore;
-  if (expr->op() == Token::OR) {
-    codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-    codegen()->DoTest(&restore, &discard, &restore);
-  } else {
-    ASSERT(expr->op() == Token::AND);
-    codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-    codegen()->DoTest(&discard, &restore, &restore);
-  }
-  __ bind(&restore);
-  __ pop(result_register());
-  __ jmp(done);
-  __ bind(&discard);
-  __ Drop(1);
-}
-
-
-void FullCodeGenerator::StackValueContext::EmitLogicalLeft(
-    BinaryOperation* expr,
-    Label* eval_right,
-    Label* done) const {
-  codegen()->VisitForAccumulatorValue(expr->left());
-  // We want the value in the accumulator for the test, and on the stack in case
-  // we need it.
-  __ push(result_register());
-  Label discard;
-  if (expr->op() == Token::OR) {
-    codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-    codegen()->DoTest(done, &discard, &discard);
-  } else {
-    ASSERT(expr->op() == Token::AND);
-    codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-    codegen()->DoTest(&discard, done, &discard);
-  }
-  __ bind(&discard);
-  __ Drop(1);
-}
-
-
-void FullCodeGenerator::TestContext::EmitLogicalLeft(BinaryOperation* expr,
-                                                     Label* eval_right,
-                                                     Label* done) const {
-  if (expr->op() == Token::OR) {
-    codegen()->VisitForControl(expr->left(),
-                               true_label_, eval_right, eval_right);
-  } else {
-    ASSERT(expr->op() == Token::AND);
-    codegen()->VisitForControl(expr->left(),
-                               eval_right, false_label_, eval_right);
+    EmitBinaryOp(expr, op, mode);
   }
 }
 
@@ -853,46 +818,23 @@
 }
 
 
-void FullCodeGenerator::EffectContext::HandleExpression(
-    Expression* expr) const {
-  codegen()->HandleInNonTestContext(expr, NO_REGISTERS);
-}
-
-
-void FullCodeGenerator::AccumulatorValueContext::HandleExpression(
-    Expression* expr) const {
-  codegen()->HandleInNonTestContext(expr, TOS_REG);
-}
-
-
-void FullCodeGenerator::StackValueContext::HandleExpression(
-    Expression* expr) const {
-  codegen()->HandleInNonTestContext(expr, NO_REGISTERS);
-}
-
-
-void FullCodeGenerator::TestContext::HandleExpression(Expression* expr) const {
-  codegen()->VisitInTestContext(expr);
-}
-
-
-void FullCodeGenerator::HandleInNonTestContext(Expression* expr, State state) {
-  ASSERT(forward_bailout_pending_ == NULL);
-  AstVisitor::Visit(expr);
-  PrepareForBailout(expr, state);
-  // Forwarding bailouts to children is a one shot operation. It
-  // should have been processed at this point.
-  ASSERT(forward_bailout_pending_ == NULL);
-}
-
-
-void FullCodeGenerator::VisitInTestContext(Expression* expr) {
-  ForwardBailoutStack stack(expr, forward_bailout_pending_);
-  ForwardBailoutStack* saved = forward_bailout_stack_;
-  forward_bailout_pending_ = NULL;
-  forward_bailout_stack_ = &stack;
-  AstVisitor::Visit(expr);
-  forward_bailout_stack_ = saved;
+void FullCodeGenerator::VisitInCurrentContext(Expression* expr) {
+  if (context()->IsTest()) {
+    ForwardBailoutStack stack(expr, forward_bailout_pending_);
+    ForwardBailoutStack* saved = forward_bailout_stack_;
+    forward_bailout_pending_ = NULL;
+    forward_bailout_stack_ = &stack;
+    Visit(expr);
+    forward_bailout_stack_ = saved;
+  } else {
+    ASSERT(forward_bailout_pending_ == NULL);
+    Visit(expr);
+    State state = context()->IsAccumulatorValue() ? TOS_REG : NO_REGISTERS;
+    PrepareForBailout(expr, state);
+    // Forwarding bailouts to children is a one shot operation. It should have
+    // been processed at this point.
+    ASSERT(forward_bailout_pending_ == NULL);
+  }
 }
 
 
@@ -945,7 +887,7 @@
     PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
   }
   __ bind(&done);
-  PrepareForBailoutForId(stmt->id(), NO_REGISTERS);
+  PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS);
 }
 
 
@@ -1010,26 +952,20 @@
 }
 
 
-void FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
-  Comment cmnt(masm_, "[ WithEnterStatement");
+void FullCodeGenerator::VisitEnterWithContextStatement(
+    EnterWithContextStatement* stmt) {
+  Comment cmnt(masm_, "[ EnterWithContextStatement");
   SetStatementPosition(stmt);
 
   VisitForStackValue(stmt->expression());
-  if (stmt->is_catch_block()) {
-    __ CallRuntime(Runtime::kPushCatchContext, 1);
-  } else {
-    __ CallRuntime(Runtime::kPushContext, 1);
-  }
-  // Both runtime calls return the new context in both the context and the
-  // result registers.
-
-  // Update local stack frame context field.
+  PushFunctionArgumentForContextAllocation();
+  __ CallRuntime(Runtime::kPushWithContext, 2);
   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
 }
 
 
-void FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
-  Comment cmnt(masm_, "[ WithExitStatement");
+void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) {
+  Comment cmnt(masm_, "[ ExitContextStatement");
   SetStatementPosition(stmt);
 
   // Pop context.
@@ -1170,18 +1106,21 @@
   __ Call(&try_handler_setup);
   // Try handler code, exception in result register.
 
-  // Store exception in local .catch variable before executing catch block.
-  {
-    // The catch variable is *always* a variable proxy for a local variable.
-    Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable();
-    ASSERT_NOT_NULL(catch_var);
-    Slot* variable_slot = catch_var->AsSlot();
-    ASSERT_NOT_NULL(variable_slot);
-    ASSERT_EQ(Slot::LOCAL, variable_slot->type());
-    StoreToFrameField(SlotOffset(variable_slot), result_register());
+  // Extend the context before executing the catch block.
+  { Comment cmnt(masm_, "[ Extend catch context");
+    __ Push(stmt->variable()->name());
+    __ push(result_register());
+    PushFunctionArgumentForContextAllocation();
+    __ CallRuntime(Runtime::kPushCatchContext, 3);
+    StoreToFrameField(StandardFrameConstants::kContextOffset,
+                      context_register());
   }
 
+  Scope* saved_scope = scope();
+  scope_ = stmt->scope();
+  ASSERT(scope_->declarations()->is_empty());
   Visit(stmt->catch_block());
+  scope_ = saved_scope;
   __ jmp(&done);
 
   // Try block code. Sets up the exception handler chain.
@@ -1290,7 +1229,7 @@
                     for_test->false_label(),
                     NULL);
   } else {
-    context()->HandleExpression(expr->then_expression());
+    VisitInCurrentContext(expr->then_expression());
     __ jmp(&done);
   }
 
@@ -1299,7 +1238,7 @@
   if (context()->IsTest()) ForwardBailoutToChild(expr);
   SetExpressionPosition(expr->else_expression(),
                         expr->else_expression_position());
-  context()->HandleExpression(expr->else_expression());
+  VisitInCurrentContext(expr->else_expression());
   // If control flow falls through Visit, merge it with true case here.
   if (!context()->IsTest()) {
     __ bind(&done);
@@ -1334,18 +1273,6 @@
 }
 
 
-void FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
-  // Call runtime routine to allocate the catch extension object and
-  // assign the exception value to the catch variable.
-  Comment cmnt(masm_, "[ CatchExtensionObject");
-  VisitForStackValue(expr->key());
-  VisitForStackValue(expr->value());
-  // Create catch extension object.
-  __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
-  context()->Plug(result_register());
-}
-
-
 void FullCodeGenerator::VisitThrow(Throw* expr) {
   Comment cmnt(masm_, "[ Throw");
   VisitForStackValue(expr->exception());
@@ -1371,6 +1298,26 @@
 }
 
 
+bool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare,
+                                          Label* if_true,
+                                          Label* if_false,
+                                          Label* fall_through) {
+  Expression *expr;
+  Handle<String> check;
+  if (compare->IsLiteralCompareTypeof(&expr, &check)) {
+    EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through);
+    return true;
+  }
+
+  if (compare->IsLiteralCompareUndefined(&expr)) {
+    EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through);
+    return true;
+  }
+
+  return false;
+}
+
+
 #undef __
 
 
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 0d26e38..6b174f7 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -80,6 +80,7 @@
   explicit FullCodeGenerator(MacroAssembler* masm)
       : masm_(masm),
         info_(NULL),
+        scope_(NULL),
         nesting_stack_(NULL),
         loop_depth_(0),
         context_(NULL),
@@ -113,6 +114,7 @@
   class TryFinally;
   class Finally;
   class ForIn;
+  class TestContext;
 
   class NestedStatement BASE_EMBEDDED {
    public:
@@ -151,9 +153,11 @@
       return stack_depth;
     }
     NestedStatement* outer() { return previous_; }
-   protected:
+
+ protected:
     MacroAssembler* masm() { return codegen_->masm(); }
-   private:
+
+ private:
     FullCodeGenerator* codegen_;
     NestedStatement* previous_;
     DISALLOW_COPY_AND_ASSIGN(NestedStatement);
@@ -296,7 +300,11 @@
   // Helper function to convert a pure value into a test context.  The value
   // is expected on the stack or the accumulator, depending on the platform.
   // See the platform-specific implementation for details.
-  void DoTest(Label* if_true, Label* if_false, Label* fall_through);
+  void DoTest(Expression* condition,
+              Label* if_true,
+              Label* if_false,
+              Label* fall_through);
+  void DoTest(const TestContext* context);
 
   // Helper function to split control flow and avoid a branch to the
   // fall-through label if it is set up.
@@ -328,48 +336,55 @@
 
   void VisitForEffect(Expression* expr) {
     EffectContext context(this);
-    HandleInNonTestContext(expr, NO_REGISTERS);
+    VisitInCurrentContext(expr);
   }
 
   void VisitForAccumulatorValue(Expression* expr) {
     AccumulatorValueContext context(this);
-    HandleInNonTestContext(expr, TOS_REG);
+    VisitInCurrentContext(expr);
   }
 
   void VisitForStackValue(Expression* expr) {
     StackValueContext context(this);
-    HandleInNonTestContext(expr, NO_REGISTERS);
+    VisitInCurrentContext(expr);
   }
 
   void VisitForControl(Expression* expr,
                        Label* if_true,
                        Label* if_false,
                        Label* fall_through) {
-    TestContext context(this, if_true, if_false, fall_through);
-    VisitInTestContext(expr);
-    // Forwarding bailouts to children is a one shot operation. It
-    // should have been processed at this point.
-    ASSERT(forward_bailout_pending_ == NULL);
+    TestContext context(this, expr, if_true, if_false, fall_through);
+    VisitInCurrentContext(expr);
   }
 
-  void HandleInNonTestContext(Expression* expr, State state);
-  void VisitInTestContext(Expression* expr);
-
   void VisitDeclarations(ZoneList<Declaration*>* declarations);
   void DeclareGlobals(Handle<FixedArray> pairs);
 
   // Try to perform a comparison as a fast inlined literal compare if
   // the operands allow it.  Returns true if the compare operations
   // has been matched and all code generated; false otherwise.
-  bool TryLiteralCompare(Token::Value op,
-                         Expression* left,
-                         Expression* right,
+  bool TryLiteralCompare(CompareOperation* compare,
                          Label* if_true,
                          Label* if_false,
                          Label* fall_through);
 
+  // Platform-specific code for comparing the type of a value with
+  // a given literal string.
+  void EmitLiteralCompareTypeof(Expression* expr,
+                                Handle<String> check,
+                                Label* if_true,
+                                Label* if_false,
+                                Label* fall_through);
+
+  // Platform-specific code for strict equality comparison with
+  // the undefined value.
+  void EmitLiteralCompareUndefined(Expression* expr,
+                                   Label* if_true,
+                                   Label* if_false,
+                                   Label* fall_through);
+
   // Bailout support.
-  void PrepareForBailout(AstNode* node, State state);
+  void PrepareForBailout(Expression* node, State state);
   void PrepareForBailoutForId(int id, State state);
 
   // Record a call's return site offset, used to rebuild the frame if the
@@ -429,7 +444,7 @@
                                        TypeofState typeof_state,
                                        Label* slow,
                                        Label* done);
-  void EmitVariableLoad(Variable* expr);
+  void EmitVariableLoad(VariableProxy* proxy);
 
   enum ResolveEvalFlag {
     SKIP_CONTEXT_LOOKUP,
@@ -517,23 +532,11 @@
     return is_strict_mode() ? kStrictMode : kNonStrictMode;
   }
   FunctionLiteral* function() { return info_->function(); }
-  Scope* scope() { return info_->scope(); }
+  Scope* scope() { return scope_; }
 
   static Register result_register();
   static Register context_register();
 
-  // Helper for calling an IC stub.
-  void EmitCallIC(Handle<Code> ic,
-                  RelocInfo::Mode mode,
-                  unsigned ast_id);
-
-  // Calling an IC stub with a patch site. Passing NULL for patch_site
-  // or non NULL patch_site which is not activated indicates no inlined smi code
-  // and emits a nop after the IC call.
-  void EmitCallIC(Handle<Code> ic,
-                  JumpPatchSite* patch_site,
-                  unsigned ast_id);
-
   // Set fields in the stack frame. Offsets are the frame pointer relative
   // offsets defined in, e.g., StandardFrameConstants.
   void StoreToFrameField(int frame_offset, Register value);
@@ -542,6 +545,10 @@
   // in v8::internal::Context.
   void LoadContextField(Register dst, int context_index);
 
+  // Push the function argument for the runtime functions PushWithContext
+  // and PushCatchContext.
+  void PushFunctionArgumentForContextAllocation();
+
   // AST node visit functions.
 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
   AST_NODE_LIST(DECLARE_VISIT)
@@ -549,8 +556,10 @@
 
   void EmitUnaryOperation(UnaryOperation* expr, const char* comment);
 
-  // Handles the shortcutted logical binary operations in VisitBinaryOperation.
-  void EmitLogicalOperation(BinaryOperation* expr);
+  void VisitComma(BinaryOperation* expr);
+  void VisitLogicalExpression(BinaryOperation* expr);
+  void VisitArithmeticExpression(BinaryOperation* expr);
+  void VisitInCurrentContext(Expression* expr);
 
   void VisitForTypeofValue(Expression* expr);
 
@@ -598,11 +607,6 @@
     // context.
     virtual void DropAndPlug(int count, Register reg) const = 0;
 
-    // For shortcutting operations || and &&.
-    virtual void EmitLogicalLeft(BinaryOperation* expr,
-                                 Label* eval_right,
-                                 Label* done) const = 0;
-
     // Set up branch labels for a test expression.  The three Label** parameters
     // are output parameters.
     virtual void PrepareTest(Label* materialize_true,
@@ -611,12 +615,14 @@
                              Label** if_false,
                              Label** fall_through) const = 0;
 
-    virtual void HandleExpression(Expression* expr) const = 0;
-
     // Returns true if we are evaluating only for side effects (ie if the result
     // will be discarded).
     virtual bool IsEffect() const { return false; }
 
+    // Returns true if we are evaluating for the value (in accu/on stack).
+    virtual bool IsAccumulatorValue() const { return false; }
+    virtual bool IsStackValue() const { return false; }
+
     // Returns true if we are branching on the value rather than materializing
     // it.  Only used for asserts.
     virtual bool IsTest() const { return false; }
@@ -644,15 +650,12 @@
     virtual void Plug(Heap::RootListIndex) const;
     virtual void PlugTOS() const;
     virtual void DropAndPlug(int count, Register reg) const;
-    virtual void EmitLogicalLeft(BinaryOperation* expr,
-                                 Label* eval_right,
-                                 Label* done) const;
     virtual void PrepareTest(Label* materialize_true,
                              Label* materialize_false,
                              Label** if_true,
                              Label** if_false,
                              Label** fall_through) const;
-    virtual void HandleExpression(Expression* expr) const;
+    virtual bool IsAccumulatorValue() const { return true; }
   };
 
   class StackValueContext : public ExpressionContext {
@@ -668,24 +671,23 @@
     virtual void Plug(Heap::RootListIndex) const;
     virtual void PlugTOS() const;
     virtual void DropAndPlug(int count, Register reg) const;
-    virtual void EmitLogicalLeft(BinaryOperation* expr,
-                                 Label* eval_right,
-                                 Label* done) const;
     virtual void PrepareTest(Label* materialize_true,
                              Label* materialize_false,
                              Label** if_true,
                              Label** if_false,
                              Label** fall_through) const;
-    virtual void HandleExpression(Expression* expr) const;
+    virtual bool IsStackValue() const { return true; }
   };
 
   class TestContext : public ExpressionContext {
    public:
-    explicit TestContext(FullCodeGenerator* codegen,
-                         Label* true_label,
-                         Label* false_label,
-                         Label* fall_through)
+    TestContext(FullCodeGenerator* codegen,
+                Expression* condition,
+                Label* true_label,
+                Label* false_label,
+                Label* fall_through)
         : ExpressionContext(codegen),
+          condition_(condition),
           true_label_(true_label),
           false_label_(false_label),
           fall_through_(fall_through) { }
@@ -695,6 +697,7 @@
       return reinterpret_cast<const TestContext*>(context);
     }
 
+    Expression* condition() const { return condition_; }
     Label* true_label() const { return true_label_; }
     Label* false_label() const { return false_label_; }
     Label* fall_through() const { return fall_through_; }
@@ -707,18 +710,15 @@
     virtual void Plug(Heap::RootListIndex) const;
     virtual void PlugTOS() const;
     virtual void DropAndPlug(int count, Register reg) const;
-    virtual void EmitLogicalLeft(BinaryOperation* expr,
-                                 Label* eval_right,
-                                 Label* done) const;
     virtual void PrepareTest(Label* materialize_true,
                              Label* materialize_false,
                              Label** if_true,
                              Label** if_false,
                              Label** fall_through) const;
-    virtual void HandleExpression(Expression* expr) const;
     virtual bool IsTest() const { return true; }
 
    private:
+    Expression* condition_;
     Label* true_label_;
     Label* false_label_;
     Label* fall_through_;
@@ -737,20 +737,17 @@
     virtual void Plug(Heap::RootListIndex) const;
     virtual void PlugTOS() const;
     virtual void DropAndPlug(int count, Register reg) const;
-    virtual void EmitLogicalLeft(BinaryOperation* expr,
-                                 Label* eval_right,
-                                 Label* done) const;
     virtual void PrepareTest(Label* materialize_true,
                              Label* materialize_false,
                              Label** if_true,
                              Label** if_false,
                              Label** fall_through) const;
-    virtual void HandleExpression(Expression* expr) const;
     virtual bool IsEffect() const { return true; }
   };
 
   MacroAssembler* masm_;
   CompilationInfo* info_;
+  Scope* scope_;
   Label return_label_;
   NestedStatement* nesting_stack_;
   int loop_depth_;
diff --git a/src/func-name-inferrer.cc b/src/func-name-inferrer.cc
index ebac4b9..239358d 100644
--- a/src/func-name-inferrer.cc
+++ b/src/func-name-inferrer.cc
@@ -34,48 +34,62 @@
 namespace v8 {
 namespace internal {
 
+FuncNameInferrer::FuncNameInferrer(Isolate* isolate)
+    : isolate_(isolate),
+      entries_stack_(10),
+      names_stack_(5),
+      funcs_to_infer_(4) {
+}
+
 
 void FuncNameInferrer::PushEnclosingName(Handle<String> name) {
   // Enclosing name is a name of a constructor function. To check
   // that it is really a constructor, we check that it is not empty
   // and starts with a capital letter.
   if (name->length() > 0 && Runtime::IsUpperCaseChar(
-      Isolate::Current()->runtime_state(), name->Get(0))) {
-    names_stack_.Add(name);
+          isolate()->runtime_state(), name->Get(0))) {
+    names_stack_.Add(Name(name, kEnclosingConstructorName));
   }
 }
 
 
 void FuncNameInferrer::PushLiteralName(Handle<String> name) {
-  if (IsOpen() && !HEAP->prototype_symbol()->Equals(*name)) {
-    names_stack_.Add(name);
+  if (IsOpen() && !isolate()->heap()->prototype_symbol()->Equals(*name)) {
+    names_stack_.Add(Name(name, kLiteralName));
   }
 }
 
 
 void FuncNameInferrer::PushVariableName(Handle<String> name) {
-  if (IsOpen() && !HEAP->result_symbol()->Equals(*name)) {
-    names_stack_.Add(name);
+  if (IsOpen() && !isolate()->heap()->result_symbol()->Equals(*name)) {
+    names_stack_.Add(Name(name, kVariableName));
   }
 }
 
 
 Handle<String> FuncNameInferrer::MakeNameFromStack() {
-  if (names_stack_.is_empty()) {
-    return FACTORY->empty_string();
-  } else {
-    return MakeNameFromStackHelper(1, names_stack_.at(0));
-  }
+  return MakeNameFromStackHelper(0, isolate()->factory()->empty_string());
 }
 
 
 Handle<String> FuncNameInferrer::MakeNameFromStackHelper(int pos,
                                                          Handle<String> prev) {
-  if (pos >= names_stack_.length()) {
-    return prev;
+  if (pos >= names_stack_.length()) return prev;
+  if (pos < names_stack_.length() - 1 &&
+      names_stack_.at(pos).type == kVariableName &&
+      names_stack_.at(pos + 1).type == kVariableName) {
+    // Skip consecutive variable declarations.
+    return MakeNameFromStackHelper(pos + 1, prev);
   } else {
-    Handle<String> curr = FACTORY->NewConsString(dot_, names_stack_.at(pos));
-    return MakeNameFromStackHelper(pos + 1, FACTORY->NewConsString(prev, curr));
+    if (prev->length() > 0) {
+      Factory* factory = isolate()->factory();
+      Handle<String> curr = factory->NewConsString(
+          factory->dot_symbol(), names_stack_.at(pos).name);
+      return MakeNameFromStackHelper(pos + 1,
+                                     factory->NewConsString(prev, curr));
+    } else {
+      return MakeNameFromStackHelper(pos + 1, names_stack_.at(pos).name);
+    }
   }
 }
 
diff --git a/src/func-name-inferrer.h b/src/func-name-inferrer.h
index 5aa2b35..bec3a5c 100644
--- a/src/func-name-inferrer.h
+++ b/src/func-name-inferrer.h
@@ -31,6 +31,8 @@
 namespace v8 {
 namespace internal {
 
+class Isolate;
+
 // FuncNameInferrer is a stateful class that is used to perform name
 // inference for anonymous functions during static analysis of source code.
 // Inference is performed in cases when an anonymous function is assigned
@@ -43,12 +45,7 @@
 // a name.
 class FuncNameInferrer : public ZoneObject {
  public:
-  FuncNameInferrer()
-      : entries_stack_(10),
-        names_stack_(5),
-        funcs_to_infer_(4),
-        dot_(FACTORY->NewStringFromAscii(CStrVector("."))) {
-  }
+  explicit FuncNameInferrer(Isolate* isolate);
 
   // Returns whether we have entered name collection state.
   bool IsOpen() const { return !entries_stack_.is_empty(); }
@@ -81,13 +78,26 @@
     }
   }
 
-  // Infers a function name and leaves names collection state.
+  // Leaves names collection state.
   void Leave() {
     ASSERT(IsOpen());
     names_stack_.Rewind(entries_stack_.RemoveLast());
   }
 
  private:
+  enum NameType {
+    kEnclosingConstructorName,
+    kLiteralName,
+    kVariableName
+  };
+  struct Name {
+    Name(Handle<String> name, NameType type) : name(name), type(type) { }
+    Handle<String> name;
+    NameType type;
+  };
+
+  Isolate* isolate() { return isolate_; }
+
   // Constructs a full name in dotted notation from gathered names.
   Handle<String> MakeNameFromStack();
 
@@ -97,10 +107,10 @@
   // Performs name inferring for added functions.
   void InferFunctionsNames();
 
+  Isolate* isolate_;
   ZoneList<int> entries_stack_;
-  ZoneList<Handle<String> > names_stack_;
+  ZoneList<Name> names_stack_;
   ZoneList<FunctionLiteral*> funcs_to_infer_;
-  Handle<String> dot_;
 
   DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
 };
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index bf8ac19..4d57e25 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -34,16 +34,29 @@
 #include "global-handles.h"
 #include "messages.h"
 #include "natives.h"
+#include "scopeinfo.h"
 
 namespace v8 {
 namespace internal {
 
+#ifdef __APPLE__
+#define __MACH_O
+class MachO;
+class MachOSection;
+typedef MachO DebugObject;
+typedef MachOSection DebugSection;
+#else
+#define __ELF
 class ELF;
+class ELFSection;
+typedef ELF DebugObject;
+typedef ELFSection DebugSection;
+#endif
 
 class Writer BASE_EMBEDDED {
  public:
-  explicit Writer(ELF* elf)
-      : elf_(elf),
+  explicit Writer(DebugObject* debug_object)
+      : debug_object_(debug_object),
         position_(0),
         capacity_(1024),
         buffer_(reinterpret_cast<byte*>(malloc(capacity_))) {
@@ -112,7 +125,7 @@
     }
   }
 
-  ELF* elf() { return elf_; }
+  DebugObject* debug_object() { return debug_object_; }
 
   byte* buffer() { return buffer_; }
 
@@ -165,7 +178,7 @@
     return reinterpret_cast<T*>(&buffer_[offset]);
   }
 
-  ELF* elf_;
+  DebugObject* debug_object_;
   uintptr_t position_;
   uintptr_t capacity_;
   byte* buffer_;
@@ -173,21 +186,120 @@
 
 class StringTable;
 
-class ELFSection : public ZoneObject {
+template<typename THeader>
+class DebugSectionBase : public ZoneObject {
  public:
-  struct Header {
-    uint32_t name;
-    uint32_t type;
-    uintptr_t flags;
-    uintptr_t address;
-    uintptr_t offset;
-    uintptr_t size;
-    uint32_t link;
-    uint32_t info;
-    uintptr_t alignment;
-    uintptr_t entry_size;
+  virtual ~DebugSectionBase() { }
+
+  virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) {
+    uintptr_t start = writer->position();
+    if (WriteBody(writer)) {
+      uintptr_t end = writer->position();
+      header->offset = start;
+#if defined(__MACH_O)
+      header->addr = 0;
+#endif
+      header->size = end - start;
+    }
+  }
+
+  virtual bool WriteBody(Writer* writer) {
+    return false;
+  }
+
+  typedef THeader Header;
+};
+
+
+struct MachOSectionHeader {
+  char sectname[16];
+  char segname[16];
+#if defined(V8_TARGET_ARCH_IA32)
+  uint32_t addr;
+  uint32_t size;
+#else
+  uint64_t addr;
+  uint64_t size;
+#endif
+  uint32_t offset;
+  uint32_t align;
+  uint32_t reloff;
+  uint32_t nreloc;
+  uint32_t flags;
+  uint32_t reserved1;
+  uint32_t reserved2;
+};
+
+
+class MachOSection : public DebugSectionBase<MachOSectionHeader> {
+ public:
+  enum Type {
+    S_REGULAR = 0x0u,
+    S_ATTR_COALESCED = 0xbu,
+    S_ATTR_SOME_INSTRUCTIONS = 0x400u,
+    S_ATTR_DEBUG = 0x02000000u,
+    S_ATTR_PURE_INSTRUCTIONS = 0x80000000u
   };
 
+  MachOSection(const char* name,
+               const char* segment,
+               uintptr_t align,
+               uint32_t flags)
+    : name_(name),
+      segment_(segment),
+      align_(align),
+      flags_(flags) {
+    ASSERT(IsPowerOf2(align));
+    if (align_ != 0) {
+      align_ = WhichPowerOf2(align_);
+    }
+  }
+
+  virtual ~MachOSection() { }
+
+  virtual void PopulateHeader(Writer::Slot<Header> header) {
+    header->addr = 0;
+    header->size = 0;
+    header->offset = 0;
+    header->align = align_;
+    header->reloff = 0;
+    header->nreloc = 0;
+    header->flags = flags_;
+    header->reserved1 = 0;
+    header->reserved2 = 0;
+    memset(header->sectname, 0, sizeof(header->sectname));
+    memset(header->segname, 0, sizeof(header->segname));
+    ASSERT(strlen(name_) < sizeof(header->sectname));
+    ASSERT(strlen(segment_) < sizeof(header->segname));
+    strncpy(header->sectname, name_, sizeof(header->sectname));
+    strncpy(header->segname, segment_, sizeof(header->segname));
+  }
+
+ private:
+  const char* name_;
+  const char* segment_;
+  uintptr_t align_;
+  uint32_t flags_;
+};
+
+
+struct ELFSectionHeader {
+  uint32_t name;
+  uint32_t type;
+  uintptr_t flags;
+  uintptr_t address;
+  uintptr_t offset;
+  uintptr_t size;
+  uint32_t link;
+  uint32_t info;
+  uintptr_t alignment;
+  uintptr_t entry_size;
+};
+
+
+#if defined(__ELF)
+class ELFSection : public DebugSectionBase<ELFSectionHeader> {
+ public:
   enum Type {
     TYPE_NULL = 0,
     TYPE_PROGBITS = 1,
@@ -252,15 +364,45 @@
     header->entry_size = 0;
   }
 
-
  private:
   const char* name_;
   Type type_;
   uintptr_t align_;
   uint16_t index_;
 };
+#endif  // defined(__ELF)
 
 
+#if defined(__MACH_O)
+class MachOTextSection : public MachOSection {
+ public:
+  MachOTextSection(uintptr_t align,
+                   uintptr_t addr,
+                   uintptr_t size)
+      : MachOSection("__text",
+                     "__TEXT",
+                     align,
+                     MachOSection::S_REGULAR |
+                         MachOSection::S_ATTR_SOME_INSTRUCTIONS |
+                         MachOSection::S_ATTR_PURE_INSTRUCTIONS),
+        addr_(addr),
+        size_(size) { }
+
+ protected:
+  virtual void PopulateHeader(Writer::Slot<Header> header) {
+    MachOSection::PopulateHeader(header);
+    header->addr = addr_;
+    header->size = size_;
+  }
+
+ private:
+  uintptr_t addr_;
+  uintptr_t size_;
+};
+#endif  // defined(__MACH_O)
+
+
+#if defined(__ELF)
 class FullHeaderELFSection : public ELFSection {
  public:
   FullHeaderELFSection(const char* name,
@@ -349,8 +491,139 @@
   header->alignment = align_;
   PopulateHeader(header);
 }
+#endif  // defined(__ELF)
 
 
+#if defined(__MACH_O)
+class MachO BASE_EMBEDDED {
+ public:
+  MachO() : sections_(6) { }
+
+  uint32_t AddSection(MachOSection* section) {
+    sections_.Add(section);
+    return sections_.length() - 1;
+  }
+
+  void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) {
+    Writer::Slot<MachOHeader> header = WriteHeader(w);
+    uintptr_t load_command_start = w->position();
+    Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w,
+                                                                code_start,
+                                                                code_size);
+    WriteSections(w, cmd, header, load_command_start);
+  }
+
+ private:
+  struct MachOHeader {
+    uint32_t magic;
+    uint32_t cputype;
+    uint32_t cpusubtype;
+    uint32_t filetype;
+    uint32_t ncmds;
+    uint32_t sizeofcmds;
+    uint32_t flags;
+#if defined(V8_TARGET_ARCH_X64)
+    uint32_t reserved;
+#endif
+  };
+
+  struct MachOSegmentCommand {
+    uint32_t cmd;
+    uint32_t cmdsize;
+    char segname[16];
+#if defined(V8_TARGET_ARCH_IA32)
+    uint32_t vmaddr;
+    uint32_t vmsize;
+    uint32_t fileoff;
+    uint32_t filesize;
+#else
+    uint64_t vmaddr;
+    uint64_t vmsize;
+    uint64_t fileoff;
+    uint64_t filesize;
+#endif
+    uint32_t maxprot;
+    uint32_t initprot;
+    uint32_t nsects;
+    uint32_t flags;
+  };
+
+  enum MachOLoadCommandCmd {
+    LC_SEGMENT_32 = 0x00000001u,
+    LC_SEGMENT_64 = 0x00000019u
+  };
+
+
+  Writer::Slot<MachOHeader> WriteHeader(Writer* w) {
+    ASSERT(w->position() == 0);
+    Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>();
+#if defined(V8_TARGET_ARCH_IA32)
+    header->magic = 0xFEEDFACEu;
+    header->cputype = 7;  // i386
+    header->cpusubtype = 3;  // CPU_SUBTYPE_I386_ALL
+#elif defined(V8_TARGET_ARCH_X64)
+    header->magic = 0xFEEDFACFu;
+    header->cputype = 7 | 0x01000000;  // i386 | 64-bit ABI
+    header->cpusubtype = 3;  // CPU_SUBTYPE_I386_ALL
+    header->reserved = 0;
+#else
+#error Unsupported target architecture.
+#endif
+    header->filetype = 0x1;  // MH_OBJECT
+    header->ncmds = 1;
+    header->sizeofcmds = 0;
+    header->flags = 0;
+    return header;
+  }
+
+
+  Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w,
+                                                        uintptr_t code_start,
+                                                        uintptr_t code_size) {
+    Writer::Slot<MachOSegmentCommand> cmd =
+        w->CreateSlotHere<MachOSegmentCommand>();
+#if defined(V8_TARGET_ARCH_IA32)
+    cmd->cmd = LC_SEGMENT_32;
+#else
+    cmd->cmd = LC_SEGMENT_64;
+#endif
+    cmd->vmaddr = code_start;
+    cmd->vmsize = code_size;
+    cmd->fileoff = 0;
+    cmd->filesize = 0;
+    cmd->maxprot = 7;
+    cmd->initprot = 7;
+    cmd->flags = 0;
+    cmd->nsects = sections_.length();
+    memset(cmd->segname, 0, 16);
+    cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) *
+        cmd->nsects;
+    return cmd;
+  }
+
+
+  void WriteSections(Writer* w,
+                     Writer::Slot<MachOSegmentCommand> cmd,
+                     Writer::Slot<MachOHeader> header,
+                     uintptr_t load_command_start) {
+    Writer::Slot<MachOSection::Header> headers =
+        w->CreateSlotsHere<MachOSection::Header>(sections_.length());
+    cmd->fileoff = w->position();
+    header->sizeofcmds = w->position() - load_command_start;
+    for (int section = 0; section < sections_.length(); ++section) {
+      sections_[section]->PopulateHeader(headers.at(section));
+      sections_[section]->WriteBody(headers.at(section), w);
+    }
+    cmd->filesize = w->position() - (uintptr_t)cmd->fileoff;
+  }
+
+
+  ZoneList<MachOSection*> sections_;
+};
+#endif  // defined(__MACH_O)
+
+
+#if defined(__ELF)
 class ELF BASE_EMBEDDED {
  public:
   ELF() : sections_(6) {
@@ -596,7 +869,7 @@
 
     // String table for this symbol table should follow it in the section table.
     StringTable* strtab =
-        static_cast<StringTable*>(w->elf()->SectionAt(index() + 1));
+        static_cast<StringTable*>(w->debug_object()->SectionAt(index() + 1));
     strtab->AttachWriter(w);
     symbols.at(0).set(ELFSymbol::SerializedLayout(0,
                                                   0,
@@ -640,11 +913,11 @@
   ZoneList<ELFSymbol> locals_;
   ZoneList<ELFSymbol> globals_;
 };
+#endif  // defined(__ELF)
 
 
 class CodeDescription BASE_EMBEDDED {
  public:
-
 #ifdef V8_TARGET_ARCH_X64
   enum StackState {
     POST_RBP_PUSH,
@@ -658,12 +931,14 @@
                   Code* code,
                   Handle<Script> script,
                   GDBJITLineInfo* lineinfo,
-                  GDBJITInterface::CodeTag tag)
+                  GDBJITInterface::CodeTag tag,
+                  CompilationInfo* info)
       : name_(name),
         code_(code),
         script_(script),
         lineinfo_(lineinfo),
-        tag_(tag) {
+        tag_(tag),
+        info_(info) {
   }
 
   const char* name() const {
@@ -678,6 +953,14 @@
     return tag_;
   }
 
+  CompilationInfo* info() const {
+    return info_;
+  }
+
+  bool IsInfoAvailable() const {
+    return info_ != NULL;
+  }
+
   uintptr_t CodeStart() const {
     return reinterpret_cast<uintptr_t>(code_->instruction_start());
   }
@@ -725,12 +1008,13 @@
   Handle<Script> script_;
   GDBJITLineInfo* lineinfo_;
   GDBJITInterface::CodeTag tag_;
+  CompilationInfo* info_;
 #ifdef V8_TARGET_ARCH_X64
   uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
 #endif
 };
 
-
+#if defined(__ELF)
 static void CreateSymbolsTable(CodeDescription* desc,
                                ELF* elf,
                                int text_section_index) {
@@ -755,14 +1039,42 @@
                         ELFSymbol::TYPE_FUNC,
                         text_section_index));
 }
+#endif  // defined(__ELF)
 
 
-class DebugInfoSection : public ELFSection {
+class DebugInfoSection : public DebugSection {
  public:
   explicit DebugInfoSection(CodeDescription* desc)
-      : ELFSection(".debug_info", TYPE_PROGBITS, 1), desc_(desc) { }
+#if defined(__ELF)
+      : ELFSection(".debug_info", TYPE_PROGBITS, 1),
+#else
+      : MachOSection("__debug_info",
+                     "__DWARF",
+                     1,
+                     MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
+#endif
+        desc_(desc) { }
+
+  // DWARF2 standard
+  enum DWARF2LocationOp {
+    DW_OP_reg0 = 0x50,
+    DW_OP_reg1 = 0x51,
+    DW_OP_reg2 = 0x52,
+    DW_OP_reg3 = 0x53,
+    DW_OP_reg4 = 0x54,
+    DW_OP_reg5 = 0x55,
+    DW_OP_reg6 = 0x56,
+    DW_OP_reg7 = 0x57,
+    DW_OP_fbreg = 0x91  // 1 param: SLEB128 offset
+  };
+
+  enum DWARF2Encoding {
+    DW_ATE_ADDRESS = 0x1,
+    DW_ATE_SIGNED = 0x5
+  };
 
   bool WriteBody(Writer* w) {
+    uintptr_t cu_start = w->position();
     Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
     uintptr_t start = w->position();
     w->Write<uint16_t>(2);  // DWARF version.
@@ -774,6 +1086,123 @@
     w->Write<intptr_t>(desc_->CodeStart());
     w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
     w->Write<uint32_t>(0);
+
+    uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start);
+    w->WriteULEB128(3);
+    w->Write<uint8_t>(kPointerSize);
+    w->WriteString("v8value");
+
+    if (desc_->IsInfoAvailable()) {
+      CompilationInfo* info = desc_->info();
+      ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
+      w->WriteULEB128(2);
+      w->WriteString(desc_->name());
+      w->Write<intptr_t>(desc_->CodeStart());
+      w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
+      Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>();
+      uintptr_t fb_block_start = w->position();
+#if defined(V8_TARGET_ARCH_IA32)
+      w->Write<uint8_t>(DW_OP_reg5);  // The frame pointer's here on ia32
+#elif defined(V8_TARGET_ARCH_X64)
+      w->Write<uint8_t>(DW_OP_reg6);  // and here on x64.
+#else
+#error Unsupported target architecture.
+#endif
+      fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start));
+
+      int params = scope_info.number_of_parameters();
+      int slots = scope_info.number_of_stack_slots();
+      int context_slots = scope_info.number_of_context_slots();
+      // The real slot ID is internal_slots + context_slot_id.
+      int internal_slots = Context::MIN_CONTEXT_SLOTS;
+      int locals = scope_info.NumberOfLocals();
+      int current_abbreviation = 4;
+
+      for (int param = 0; param < params; ++param) {
+        w->WriteULEB128(current_abbreviation++);
+        w->WriteString(
+            *scope_info.parameter_name(param)->ToCString(DISALLOW_NULLS));
+        w->Write<uint32_t>(ty_offset);
+        Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+        uintptr_t block_start = w->position();
+        w->Write<uint8_t>(DW_OP_fbreg);
+        w->WriteSLEB128(
+          JavaScriptFrameConstants::kLastParameterOffset +
+              kPointerSize * (params - param - 1));
+        block_size.set(static_cast<uint32_t>(w->position() - block_start));
+      }
+
+      EmbeddedVector<char, 256> buffer;
+      StringBuilder builder(buffer.start(), buffer.length());
+
+      for (int slot = 0; slot < slots; ++slot) {
+        w->WriteULEB128(current_abbreviation++);
+        builder.Reset();
+        builder.AddFormatted("slot%d", slot);
+        w->WriteString(builder.Finalize());
+      }
+
+      // See contexts.h for more information.
+      ASSERT(Context::MIN_CONTEXT_SLOTS == 4);
+      ASSERT(Context::CLOSURE_INDEX == 0);
+      ASSERT(Context::PREVIOUS_INDEX == 1);
+      ASSERT(Context::EXTENSION_INDEX == 2);
+      ASSERT(Context::GLOBAL_INDEX == 3);
+      w->WriteULEB128(current_abbreviation++);
+      w->WriteString(".closure");
+      w->WriteULEB128(current_abbreviation++);
+      w->WriteString(".previous");
+      w->WriteULEB128(current_abbreviation++);
+      w->WriteString(".extension");
+      w->WriteULEB128(current_abbreviation++);
+      w->WriteString(".global");
+
+      for (int context_slot = 0;
+           context_slot < context_slots;
+           ++context_slot) {
+        w->WriteULEB128(current_abbreviation++);
+        builder.Reset();
+        builder.AddFormatted("context_slot%d", context_slot + internal_slots);
+        w->WriteString(builder.Finalize());
+      }
+
+      for (int local = 0; local < locals; ++local) {
+        w->WriteULEB128(current_abbreviation++);
+        w->WriteString(
+            *scope_info.LocalName(local)->ToCString(DISALLOW_NULLS));
+        w->Write<uint32_t>(ty_offset);
+        Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+        uintptr_t block_start = w->position();
+        w->Write<uint8_t>(DW_OP_fbreg);
+        w->WriteSLEB128(
+          JavaScriptFrameConstants::kLocal0Offset -
+              kPointerSize * local);
+        block_size.set(static_cast<uint32_t>(w->position() - block_start));
+      }
+
+      {
+        w->WriteULEB128(current_abbreviation++);
+        w->WriteString("__function");
+        w->Write<uint32_t>(ty_offset);
+        Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+        uintptr_t block_start = w->position();
+        w->Write<uint8_t>(DW_OP_fbreg);
+        w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset);
+        block_size.set(static_cast<uint32_t>(w->position() - block_start));
+      }
+
+      {
+        w->WriteULEB128(current_abbreviation++);
+        w->WriteString("__context");
+        w->Write<uint32_t>(ty_offset);
+        Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+        uintptr_t block_start = w->position();
+        w->Write<uint8_t>(DW_OP_fbreg);
+        w->WriteSLEB128(StandardFrameConstants::kContextOffset);
+        block_size.set(static_cast<uint32_t>(w->position() - block_start));
+      }
+    }
+
     size.set(static_cast<uint32_t>(w->position() - start));
     return true;
   }
@@ -783,13 +1212,28 @@
 };
 
 
-class DebugAbbrevSection : public ELFSection {
+class DebugAbbrevSection : public DebugSection {
  public:
-  DebugAbbrevSection() : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1) { }
+  explicit DebugAbbrevSection(CodeDescription* desc)
+#ifdef __ELF
+      : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1),
+#else
+      : MachOSection("__debug_abbrev",
+                     "__DWARF",
+                     1,
+                     MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
+#endif
+        desc_(desc) { }
 
   // DWARF2 standard, figure 14.
   enum DWARF2Tags {
-    DW_TAG_COMPILE_UNIT = 0x11
+    DW_TAG_FORMAL_PARAMETER = 0x05,
+    DW_TAG_POINTER_TYPE = 0xf,
+    DW_TAG_COMPILE_UNIT = 0x11,
+    DW_TAG_STRUCTURE_TYPE = 0x13,
+    DW_TAG_BASE_TYPE = 0x24,
+    DW_TAG_SUBPROGRAM = 0x2e,
+    DW_TAG_VARIABLE = 0x34
   };
 
   // DWARF2 standard, figure 16.
@@ -800,25 +1244,57 @@
 
   // DWARF standard, figure 17.
   enum DWARF2Attribute {
+    DW_AT_LOCATION = 0x2,
     DW_AT_NAME = 0x3,
+    DW_AT_BYTE_SIZE = 0xb,
     DW_AT_STMT_LIST = 0x10,
     DW_AT_LOW_PC = 0x11,
-    DW_AT_HIGH_PC = 0x12
+    DW_AT_HIGH_PC = 0x12,
+    DW_AT_ENCODING = 0x3e,
+    DW_AT_FRAME_BASE = 0x40,
+    DW_AT_TYPE = 0x49
   };
 
   // DWARF2 standard, figure 19.
   enum DWARF2AttributeForm {
     DW_FORM_ADDR = 0x1,
+    DW_FORM_BLOCK4 = 0x4,
     DW_FORM_STRING = 0x8,
-    DW_FORM_DATA4 = 0x6
+    DW_FORM_DATA4 = 0x6,
+    DW_FORM_BLOCK = 0x9,
+    DW_FORM_DATA1 = 0xb,
+    DW_FORM_FLAG = 0xc,
+    DW_FORM_REF4 = 0x13
   };
 
-  bool WriteBody(Writer* w) {
-    w->WriteULEB128(1);
-    w->WriteULEB128(DW_TAG_COMPILE_UNIT);
+  void WriteVariableAbbreviation(Writer* w,
+                                 int abbreviation_code,
+                                 bool has_value,
+                                 bool is_parameter) {
+    w->WriteULEB128(abbreviation_code);
+    w->WriteULEB128(is_parameter ? DW_TAG_FORMAL_PARAMETER : DW_TAG_VARIABLE);
     w->Write<uint8_t>(DW_CHILDREN_NO);
     w->WriteULEB128(DW_AT_NAME);
     w->WriteULEB128(DW_FORM_STRING);
+    if (has_value) {
+      w->WriteULEB128(DW_AT_TYPE);
+      w->WriteULEB128(DW_FORM_REF4);
+      w->WriteULEB128(DW_AT_LOCATION);
+      w->WriteULEB128(DW_FORM_BLOCK4);
+    }
+    w->WriteULEB128(0);
+    w->WriteULEB128(0);
+  }
+
+  bool WriteBody(Writer* w) {
+    int current_abbreviation = 1;
+    bool extra_info = desc_->IsInfoAvailable();
+    ASSERT(desc_->IsLineInfoAvailable());
+    w->WriteULEB128(current_abbreviation++);
+    w->WriteULEB128(DW_TAG_COMPILE_UNIT);
+    w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO);
+    w->WriteULEB128(DW_AT_NAME);
+    w->WriteULEB128(DW_FORM_STRING);
     w->WriteULEB128(DW_AT_LOW_PC);
     w->WriteULEB128(DW_FORM_ADDR);
     w->WriteULEB128(DW_AT_HIGH_PC);
@@ -827,16 +1303,101 @@
     w->WriteULEB128(DW_FORM_DATA4);
     w->WriteULEB128(0);
     w->WriteULEB128(0);
-    w->WriteULEB128(0);
+
+    if (extra_info) {
+      CompilationInfo* info = desc_->info();
+      ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
+      int params = scope_info.number_of_parameters();
+      int slots = scope_info.number_of_stack_slots();
+      int context_slots = scope_info.number_of_context_slots();
+      // The real slot ID is internal_slots + context_slot_id.
+      int internal_slots = Context::MIN_CONTEXT_SLOTS;
+      int locals = scope_info.NumberOfLocals();
+      int total_children =
+          params + slots + context_slots + internal_slots + locals + 2;
+
+      // The extra duplication below seems to be necessary to keep
+      // gdb from getting upset on OSX.
+      w->WriteULEB128(current_abbreviation++);  // Abbreviation code.
+      w->WriteULEB128(DW_TAG_SUBPROGRAM);
+      w->Write<uint8_t>(
+          total_children != 0 ? DW_CHILDREN_YES : DW_CHILDREN_NO);
+      w->WriteULEB128(DW_AT_NAME);
+      w->WriteULEB128(DW_FORM_STRING);
+      w->WriteULEB128(DW_AT_LOW_PC);
+      w->WriteULEB128(DW_FORM_ADDR);
+      w->WriteULEB128(DW_AT_HIGH_PC);
+      w->WriteULEB128(DW_FORM_ADDR);
+      w->WriteULEB128(DW_AT_FRAME_BASE);
+      w->WriteULEB128(DW_FORM_BLOCK4);
+      w->WriteULEB128(0);
+      w->WriteULEB128(0);
+
+      w->WriteULEB128(current_abbreviation++);
+      w->WriteULEB128(DW_TAG_STRUCTURE_TYPE);
+      w->Write<uint8_t>(DW_CHILDREN_NO);
+      w->WriteULEB128(DW_AT_BYTE_SIZE);
+      w->WriteULEB128(DW_FORM_DATA1);
+      w->WriteULEB128(DW_AT_NAME);
+      w->WriteULEB128(DW_FORM_STRING);
+      w->WriteULEB128(0);
+      w->WriteULEB128(0);
+
+      for (int param = 0; param < params; ++param) {
+        WriteVariableAbbreviation(w, current_abbreviation++, true, true);
+      }
+
+      for (int slot = 0; slot < slots; ++slot) {
+        WriteVariableAbbreviation(w, current_abbreviation++, false, false);
+      }
+
+      for (int internal_slot = 0;
+           internal_slot < internal_slots;
+           ++internal_slot) {
+        WriteVariableAbbreviation(w, current_abbreviation++, false, false);
+      }
+
+      for (int context_slot = 0;
+           context_slot < context_slots;
+           ++context_slot) {
+        WriteVariableAbbreviation(w, current_abbreviation++, false, false);
+      }
+
+      for (int local = 0; local < locals; ++local) {
+        WriteVariableAbbreviation(w, current_abbreviation++, true, false);
+      }
+
+      // The function.
+      WriteVariableAbbreviation(w, current_abbreviation++, true, false);
+
+      // The context.
+      WriteVariableAbbreviation(w, current_abbreviation++, true, false);
+
+      if (total_children != 0) {
+        w->WriteULEB128(0);  // Terminate the sibling list.
+      }
+    }
+
+    w->WriteULEB128(0);  // Terminate the table.
     return true;
   }
+
+ private:
+  CodeDescription* desc_;
 };
 
 
-class DebugLineSection : public ELFSection {
+class DebugLineSection : public DebugSection {
  public:
   explicit DebugLineSection(CodeDescription* desc)
+#ifdef __ELF
       : ELFSection(".debug_line", TYPE_PROGBITS, 1),
+#else
+      : MachOSection("__debug_line",
+                     "__DWARF",
+                     1,
+                     MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
+#endif
         desc_(desc) { }
 
   // DWARF2 standard, figure 34.
@@ -993,8 +1554,7 @@
 
 #ifdef V8_TARGET_ARCH_X64
 
-
-class UnwindInfoSection : public ELFSection {
+class UnwindInfoSection : public DebugSection {
  public:
   explicit UnwindInfoSection(CodeDescription *desc);
   virtual bool WriteBody(Writer *w);
@@ -1080,8 +1640,13 @@
 
 
 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc)
-    : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), desc_(desc)
-{ }
+#ifdef __ELF
+    : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1),
+#else
+    : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t),
+                   MachOSection::S_REGULAR),
+#endif
+      desc_(desc) { }
 
 int UnwindInfoSection::WriteCIE(Writer *w) {
   Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
@@ -1213,15 +1778,14 @@
 
 #endif  // V8_TARGET_ARCH_X64
 
-
-static void CreateDWARFSections(CodeDescription* desc, ELF* elf) {
+static void CreateDWARFSections(CodeDescription* desc, DebugObject* obj) {
   if (desc->IsLineInfoAvailable()) {
-    elf->AddSection(new DebugInfoSection(desc));
-    elf->AddSection(new DebugAbbrevSection);
-    elf->AddSection(new DebugLineSection(desc));
+    obj->AddSection(new DebugInfoSection(desc));
+    obj->AddSection(new DebugAbbrevSection(desc));
+    obj->AddSection(new DebugLineSection(desc));
   }
 #ifdef V8_TARGET_ARCH_X64
-  elf->AddSection(new UnwindInfoSection(desc));
+  obj->AddSection(new UnwindInfoSection(desc));
 #endif
 }
 
@@ -1261,6 +1825,13 @@
   // Static initialization is necessary to prevent GDB from seeing
   // uninitialized descriptor.
   JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
+
+#ifdef OBJECT_PRINT
+  void __gdb_print_v8_object(MaybeObject* object) {
+    object->Print();
+    fprintf(stdout, "\n");
+  }
+#endif
 }
 
 
@@ -1284,17 +1855,23 @@
 }
 
 
-static void RegisterCodeEntry(JITCodeEntry* entry) {
+static void RegisterCodeEntry(JITCodeEntry* entry,
+                              bool dump_if_enabled,
+                              const char* name_hint) {
 #if defined(DEBUG) && !defined(WIN32)
   static int file_num = 0;
-  if (FLAG_gdbjit_dump) {
+  if (FLAG_gdbjit_dump && dump_if_enabled) {
     static const int kMaxFileNameSize = 64;
     static const char* kElfFilePrefix = "/tmp/elfdump";
     static const char* kObjFileExt = ".o";
     char file_name[64];
 
-    OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%d%s",
-                 kElfFilePrefix, file_num++, kObjFileExt);
+    OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize),
+                 "%s%s%d%s",
+                 kElfFilePrefix,
+                 (name_hint != NULL) ? name_hint : "",
+                 file_num++,
+                 kObjFileExt);
     WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_);
   }
 #endif
@@ -1327,8 +1904,19 @@
 
 
 static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
-  ZoneScope zone_scope(DELETE_ON_EXIT);
+  ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+#ifdef __MACH_O
+  MachO mach_o;
+  Writer w(&mach_o);
 
+  mach_o.AddSection(new MachOTextSection(kCodeAlignment,
+                                         desc->CodeStart(),
+                                         desc->CodeSize()));
+
+  CreateDWARFSections(desc, &mach_o);
+
+  mach_o.Write(&w, desc->CodeStart(), desc->CodeSize());
+#else
   ELF elf;
   Writer w(&elf);
 
@@ -1346,6 +1934,7 @@
   CreateDWARFSections(desc, &elf);
 
   elf.Write(&w);
+#endif
 
   return CreateCodeEntry(w.buffer(), w.position());
 }
@@ -1394,7 +1983,8 @@
 
 void GDBJITInterface::AddCode(Handle<String> name,
                               Handle<Script> script,
-                              Handle<Code> code) {
+                              Handle<Code> code,
+                              CompilationInfo* info) {
   if (!FLAG_gdbjit) return;
 
   // Force initialization of line_ends array.
@@ -1402,9 +1992,9 @@
 
   if (!name.is_null()) {
     SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS);
-    AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script);
+    AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info);
   } else {
-    AddCode("", *code, GDBJITInterface::FUNCTION, *script);
+    AddCode("", *code, GDBJITInterface::FUNCTION, *script, info);
   }
 }
 
@@ -1451,7 +2041,8 @@
 void GDBJITInterface::AddCode(const char* name,
                               Code* code,
                               GDBJITInterface::CodeTag tag,
-                              Script* script) {
+                              Script* script,
+                              CompilationInfo* info) {
   if (!FLAG_gdbjit) return;
 
   ScopedLock lock(mutex_);
@@ -1466,7 +2057,8 @@
                             script != NULL ? Handle<Script>(script)
                                            : Handle<Script>(),
                             lineinfo,
-                            tag);
+                            tag,
+                            info);
 
   if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) {
     delete lineinfo;
@@ -1481,7 +2073,18 @@
   delete lineinfo;
   e->value = entry;
 
-  RegisterCodeEntry(entry);
+  const char* name_hint = NULL;
+  bool should_dump = false;
+  if (FLAG_gdbjit_dump) {
+    if (strlen(FLAG_gdbjit_dump_filter) == 0) {
+      name_hint = name;
+      should_dump = true;
+    } else if (name != NULL) {
+      name_hint = strstr(name, FLAG_gdbjit_dump_filter);
+      should_dump = (name_hint != NULL);
+    }
+  }
+  RegisterCodeEntry(entry, should_dump, name_hint);
 }
 
 
@@ -1501,7 +2104,7 @@
     builder.AddFormatted(": code object %p", static_cast<void*>(code));
   }
 
-  AddCode(builder.Finalize(), code, tag);
+  AddCode(builder.Finalize(), code, tag, NULL, NULL);
 }
 
 
diff --git a/src/gdb-jit.h b/src/gdb-jit.h
index 0c80fb6..2cf15bc 100644
--- a/src/gdb-jit.h
+++ b/src/gdb-jit.h
@@ -43,6 +43,8 @@
 namespace v8 {
 namespace internal {
 
+class CompilationInfo;
+
 #define CODE_TAGS_LIST(V)                       \
   V(LOAD_IC)                                    \
   V(KEYED_LOAD_IC)                              \
@@ -113,11 +115,13 @@
   static void AddCode(const char* name,
                       Code* code,
                       CodeTag tag,
-                      Script* script = NULL);
+                      Script* script,
+                      CompilationInfo* info);
 
   static void AddCode(Handle<String> name,
                       Handle<Script> script,
-                      Handle<Code> code);
+                      Handle<Code> code,
+                      CompilationInfo* info);
 
   static void AddCode(CodeTag tag, String* name, Code* code);
 
diff --git a/src/global-handles.cc b/src/global-handles.cc
index e4bbc95..87066fa 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -41,80 +41,151 @@
 }
 
 
-class GlobalHandles::Node : public Malloced {
+class GlobalHandles::Node {
  public:
+  // State transition diagram:
+  // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
+  enum State {
+    FREE,
+    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.
+  };
 
-  void Initialize(Object* object) {
-    // Set the initial value of the handle.
+  // Maps handle location (slot) to the containing node.
+  static Node* FromLocation(Object** location) {
+    ASSERT(OFFSET_OF(Node, object_) == 0);
+    return reinterpret_cast<Node*>(location);
+  }
+
+  Node() {}
+
+#ifdef DEBUG
+  ~Node() {
+    // TODO(1428): if it's a weak handle we should have invoked its callback.
+    // Zap the values for eager trapping.
+    object_ = NULL;
+    class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
+    index_ = 0;
+    independent_ = false;
+    in_new_space_list_ = false;
+    parameter_or_next_free_.next_free = NULL;
+    callback_ = NULL;
+  }
+#endif
+
+  void Initialize(int index, Node** first_free) {
+    index_ = static_cast<uint8_t>(index);
+    ASSERT(static_cast<int>(index_) == index);
+    state_ = FREE;
+    in_new_space_list_ = false;
+    parameter_or_next_free_.next_free = *first_free;
+    *first_free = this;
+  }
+
+  void Acquire(Object* object, GlobalHandles* global_handles) {
+    ASSERT(state_ == FREE);
     object_ = object;
     class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
     independent_ = false;
     state_  = NORMAL;
     parameter_or_next_free_.parameter = NULL;
     callback_ = NULL;
+    IncreaseBlockUses(global_handles);
   }
 
-  Node() {
-    state_ = DESTROYED;
-  }
-
-  explicit Node(Object* object) {
-    Initialize(object);
-    // Initialize link structure.
-    next_ = NULL;
-  }
-
-  ~Node() {
-    if (state_ != DESTROYED) Destroy(Isolate::Current()->global_handles());
-#ifdef DEBUG
-    // Zap the values for eager trapping.
-    object_ = NULL;
-    next_ = NULL;
-    parameter_or_next_free_.next_free = NULL;
-#endif
-  }
-
-  void Destroy(GlobalHandles* global_handles) {
-    if (state_ == WEAK || IsNearDeath()) {
+  void Release(GlobalHandles* global_handles) {
+    ASSERT(state_ != FREE);
+    if (IsWeakRetainer()) {
       global_handles->number_of_weak_handles_--;
       if (object_->IsJSGlobalObject()) {
         global_handles->number_of_global_object_weak_handles_--;
       }
     }
-    state_ = DESTROYED;
+    state_ = FREE;
+    parameter_or_next_free_.next_free = global_handles->first_free_;
+    global_handles->first_free_ = this;
+    DecreaseBlockUses(global_handles);
   }
 
-  // Accessors for next_.
-  Node* next() { return next_; }
-  void set_next(Node* value) { next_ = value; }
-  Node** next_addr() { return &next_; }
+  // Object slot accessors.
+  Object* object() const { return object_; }
+  Object** location() { return &object_; }
+  Handle<Object> handle() { return Handle<Object>(location()); }
+
+  // Wrapper class ID accessors.
+  bool has_wrapper_class_id() const {
+    return class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId;
+  }
+  uint16_t wrapper_class_id() const { return class_id_; }
+  void set_wrapper_class_id(uint16_t class_id) {
+    class_id_ = class_id;
+  }
+
+  // State accessors.
+
+  State state() const { return state_; }
+
+  bool IsNearDeath() const {
+    // Check for PENDING to ensure correct answer when processing callbacks.
+    return state_ == PENDING || state_ == NEAR_DEATH;
+  }
+
+  bool IsWeak() const { return state_ == WEAK; }
+
+  bool IsRetainer() const { return state_ != FREE; }
+
+  bool IsStrongRetainer() const { return state_ == NORMAL; }
+
+  bool IsWeakRetainer() const {
+    return state_ == WEAK || state_ == PENDING || state_ == NEAR_DEATH;
+  }
+
+  void MarkPending() {
+    ASSERT(state_ == WEAK);
+    state_ = PENDING;
+  }
+
+  // Independent flag accessors.
+  void MarkIndependent() {
+    ASSERT(state_ != FREE);
+    independent_ = true;
+  }
+  bool is_independent() const { return independent_; }
+
+  // In-new-space-list flag accessors.
+  void set_in_new_space_list(bool v) { in_new_space_list_ = v; }
+  bool is_in_new_space_list() const { return in_new_space_list_; }
+
+  // Callback accessor.
+  WeakReferenceCallback callback() { return callback_; }
+
+  // Callback parameter accessors.
+  void set_parameter(void* parameter) {
+    ASSERT(state_ != FREE);
+    parameter_or_next_free_.parameter = parameter;
+  }
+  void* parameter() const {
+    ASSERT(state_ != FREE);
+    return parameter_or_next_free_.parameter;
+  }
 
   // Accessors for next free node in the free list.
   Node* next_free() {
-    ASSERT(state_ == DESTROYED);
+    ASSERT(state_ == FREE);
     return parameter_or_next_free_.next_free;
   }
   void set_next_free(Node* value) {
-    ASSERT(state_ == DESTROYED);
+    ASSERT(state_ == FREE);
     parameter_or_next_free_.next_free = value;
   }
 
-  // Returns a link from the handle.
-  static Node* FromLocation(Object** location) {
-    ASSERT(OFFSET_OF(Node, object_) == 0);
-    return reinterpret_cast<Node*>(location);
-  }
-
-  // Returns the handle.
-  Handle<Object> handle() { return Handle<Object>(&object_); }
-
-  // Make this handle weak.
-  void MakeWeak(GlobalHandles* global_handles, void* parameter,
+  void MakeWeak(GlobalHandles* global_handles,
+                void* parameter,
                 WeakReferenceCallback callback) {
-    LOG(global_handles->isolate(),
-        HandleEvent("GlobalHandle::MakeWeak", handle().location()));
-    ASSERT(state_ != DESTROYED);
-    if (state_ != WEAK && !IsNearDeath()) {
+    ASSERT(state_ != FREE);
+    if (!IsWeakRetainer()) {
       global_handles->number_of_weak_handles_++;
       if (object_->IsJSGlobalObject()) {
         global_handles->number_of_global_object_weak_handles_++;
@@ -126,10 +197,8 @@
   }
 
   void ClearWeakness(GlobalHandles* global_handles) {
-    LOG(global_handles->isolate(),
-        HandleEvent("GlobalHandle::ClearWeakness", handle().location()));
-    ASSERT(state_ != DESTROYED);
-    if (state_ == WEAK || IsNearDeath()) {
+    ASSERT(state_ != FREE);
+    if (IsWeakRetainer()) {
       global_handles->number_of_weak_handles_--;
       if (object_->IsJSGlobalObject()) {
         global_handles->number_of_global_object_weak_handles_--;
@@ -139,50 +208,12 @@
     set_parameter(NULL);
   }
 
-  void MarkIndependent(GlobalHandles* global_handles) {
-    LOG(global_handles->isolate(),
-        HandleEvent("GlobalHandle::MarkIndependent", handle().location()));
-    ASSERT(state_ != DESTROYED);
-    independent_ = true;
-  }
-
-  bool IsNearDeath() {
-    // Check for PENDING to ensure correct answer when processing callbacks.
-    return state_ == PENDING || state_ == NEAR_DEATH;
-  }
-
-  bool IsWeak() {
-    return state_ == WEAK;
-  }
-
-  bool CanBeRetainer() {
-    return state_ != DESTROYED && state_ != NEAR_DEATH;
-  }
-
-  void SetWrapperClassId(uint16_t class_id) {
-    class_id_ = class_id;
-  }
-
-  // Returns the id for this weak handle.
-  void set_parameter(void* parameter) {
-    ASSERT(state_ != DESTROYED);
-    parameter_or_next_free_.parameter = parameter;
-  }
-  void* parameter() {
-    ASSERT(state_ != DESTROYED);
-    return parameter_or_next_free_.parameter;
-  }
-
-  // Returns the callback for this weak handle.
-  WeakReferenceCallback callback() { return callback_; }
-
   bool PostGarbageCollectionProcessing(Isolate* isolate,
                                        GlobalHandles* global_handles) {
     if (state_ != Node::PENDING) return false;
-    LOG(isolate, HandleEvent("GlobalHandle::Processing", handle().location()));
     WeakReferenceCallback func = callback();
     if (func == NULL) {
-      Destroy(global_handles);
+      Release(global_handles);
       return false;
     }
     void* par = parameter();
@@ -191,13 +222,6 @@
 
     v8::Persistent<v8::Object> object = ToApi<v8::Object>(handle());
     {
-      // Forbid reuse of destroyed nodes as they might be already deallocated.
-      // It's fine though to reuse nodes that were destroyed in weak callback
-      // as those cannot be deallocated until we are back from the callback.
-      global_handles->set_first_free(NULL);
-      if (global_handles->first_deallocated()) {
-        global_handles->first_deallocated()->set_next(global_handles->head());
-      }
       // Check that we are not passing a finalized external string to
       // the callback.
       ASSERT(!object_->IsExternalAsciiString() ||
@@ -214,97 +238,145 @@
     return true;
   }
 
-  // Place the handle address first to avoid offset computation.
-  Object* object_;  // Storage for object pointer.
+ private:
+  inline NodeBlock* FindBlock();
+  inline void IncreaseBlockUses(GlobalHandles* global_handles);
+  inline void DecreaseBlockUses(GlobalHandles* global_handles);
 
+  // Storage for object pointer.
+  // Placed first to avoid offset computation.
+  Object* object_;
+
+  // Next word stores class_id, index, state, and independent.
+  // Note: the most aligned fields should go first.
+
+  // Wrapper class ID.
   uint16_t class_id_;
 
-  // Transition diagram:
-  // NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, DESTROYED }
-  enum State {
-    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.
-    DESTROYED
-  };
-  State state_ : 4;  // Need one more bit for MSVC as it treats enums as signed.
+  // Index in the containing handle block.
+  uint8_t index_;
+
+  // Need one more bit for MSVC as it treats enums as signed.
+  State state_ : 4;
 
   bool independent_ : 1;
+  bool in_new_space_list_ : 1;
 
- private:
   // Handle specific callback.
   WeakReferenceCallback callback_;
-  // Provided data for callback.  In DESTROYED state, this is used for
+
+  // Provided data for callback.  In FREE state, this is used for
   // the free list link.
   union {
     void* parameter;
     Node* next_free;
   } parameter_or_next_free_;
 
-  // Linkage for the list.
-  Node* next_;
-
- public:
-  TRACK_MEMORY("GlobalHandles::Node")
+  DISALLOW_COPY_AND_ASSIGN(Node);
 };
 
 
-class GlobalHandles::Pool {
-  public:
-    Pool() {
-      current_ = new Chunk();
-      current_->previous = NULL;
-      next_ = current_->nodes;
-      limit_ = current_->nodes + kNodesPerChunk;
-    }
+class GlobalHandles::NodeBlock {
+ public:
+  static const int kSize = 256;
 
-    ~Pool() {
-      if (current_ != NULL) {
-        Release();
+  explicit NodeBlock(NodeBlock* next)
+      : next_(next), used_nodes_(0), next_used_(NULL), prev_used_(NULL) {}
+
+  void PutNodesOnFreeList(Node** first_free) {
+    for (int i = kSize - 1; i >= 0; --i) {
+      nodes_[i].Initialize(i, first_free);
+    }
+  }
+
+  Node* node_at(int index) {
+    ASSERT(0 <= index && index < kSize);
+    return &nodes_[index];
+  }
+
+  void IncreaseUses(GlobalHandles* global_handles) {
+    ASSERT(used_nodes_ < kSize);
+    if (used_nodes_++ == 0) {
+      NodeBlock* old_first = global_handles->first_used_block_;
+      global_handles->first_used_block_ = this;
+      next_used_ = old_first;
+      prev_used_ = NULL;
+      if (old_first == NULL) return;
+      old_first->prev_used_ = this;
+    }
+  }
+
+  void DecreaseUses(GlobalHandles* global_handles) {
+    ASSERT(used_nodes_ > 0);
+    if (--used_nodes_ == 0) {
+      if (next_used_ != NULL) next_used_->prev_used_ = prev_used_;
+      if (prev_used_ != NULL) prev_used_->next_used_ = next_used_;
+      if (this == global_handles->first_used_block_) {
+        global_handles->first_used_block_ = next_used_;
       }
     }
+  }
 
-    Node* Allocate() {
-      if (next_ < limit_) {
-        return next_++;
-      }
-      return SlowAllocate();
-    }
+  // Next block in the list of all blocks.
+  NodeBlock* next() const { return next_; }
 
-    void Release() {
-      Chunk* current = current_;
-      ASSERT(current != NULL);  // At least a single block must by allocated
-      do {
-        Chunk* previous = current->previous;
-        delete current;
-        current = previous;
-      } while (current != NULL);
-      current_ = NULL;
-      next_ = limit_ = NULL;
-    }
+  // Next/previous block in the list of blocks with used nodes.
+  NodeBlock* next_used() const { return next_used_; }
+  NodeBlock* prev_used() const { return prev_used_; }
 
-  private:
-    static const int kNodesPerChunk = (1 << 12) - 1;
-    struct Chunk : public Malloced {
-      Chunk* previous;
-      Node nodes[kNodesPerChunk];
-    };
+ private:
+  Node nodes_[kSize];
+  NodeBlock* const next_;
+  int used_nodes_;
+  NodeBlock* next_used_;
+  NodeBlock* prev_used_;
+};
 
-    Node* SlowAllocate() {
-      Chunk* chunk = new Chunk();
-      chunk->previous = current_;
-      current_ = chunk;
 
-      Node* new_nodes = current_->nodes;
-      next_ = new_nodes + 1;
-      limit_ = new_nodes + kNodesPerChunk;
-      return new_nodes;
-    }
+GlobalHandles::NodeBlock* GlobalHandles::Node::FindBlock() {
+  intptr_t ptr = reinterpret_cast<intptr_t>(this);
+  ptr = ptr - index_ * sizeof(Node);
+  NodeBlock* block = reinterpret_cast<NodeBlock*>(ptr);
+  ASSERT(block->node_at(index_) == this);
+  return block;
+}
 
-    Chunk* current_;
-    Node* next_;
-    Node* limit_;
+
+void GlobalHandles::Node::IncreaseBlockUses(GlobalHandles* global_handles) {
+  FindBlock()->IncreaseUses(global_handles);
+}
+
+
+void GlobalHandles::Node::DecreaseBlockUses(GlobalHandles* global_handles) {
+  FindBlock()->DecreaseUses(global_handles);
+}
+
+
+class GlobalHandles::NodeIterator {
+ public:
+  explicit NodeIterator(GlobalHandles* global_handles)
+      : block_(global_handles->first_used_block_),
+        index_(0) {}
+
+  bool done() const { return block_ == NULL; }
+
+  Node* node() const {
+    ASSERT(!done());
+    return block_->node_at(index_);
+  }
+
+  void Advance() {
+    ASSERT(!done());
+    if (++index_ < NodeBlock::kSize) return;
+    index_ = 0;
+    block_ = block_->next_used();
+  }
+
+ private:
+  NodeBlock* block_;
+  int index_;
+
+  DISALLOW_COPY_AND_ASSIGN(NodeIterator);
 };
 
 
@@ -312,41 +384,39 @@
     : isolate_(isolate),
       number_of_weak_handles_(0),
       number_of_global_object_weak_handles_(0),
-      head_(NULL),
+      first_block_(NULL),
+      first_used_block_(NULL),
       first_free_(NULL),
-      first_deallocated_(NULL),
-      pool_(new Pool()),
-      post_gc_processing_count_(0),
-      object_groups_(4) {
-}
+      post_gc_processing_count_(0) {}
 
 
 GlobalHandles::~GlobalHandles() {
-  delete pool_;
-  pool_ = 0;
+  NodeBlock* block = first_block_;
+  while (block != NULL) {
+    NodeBlock* tmp = block->next();
+    delete block;
+    block = tmp;
+  }
+  first_block_ = NULL;
 }
 
 
 Handle<Object> GlobalHandles::Create(Object* value) {
   isolate_->counters()->global_handles()->Increment();
-  Node* result;
-  if (first_free()) {
-    // Take the first node in the free list.
-    result = first_free();
-    set_first_free(result->next_free());
-  } else if (first_deallocated()) {
-    // Next try deallocated list
-    result = first_deallocated();
-    set_first_deallocated(result->next_free());
-    ASSERT(result->next() == head());
-    set_head(result);
-  } else {
-    // Allocate a new node.
-    result = pool_->Allocate();
-    result->set_next(head());
-    set_head(result);
+  if (first_free_ == NULL) {
+    first_block_ = new NodeBlock(first_block_);
+    first_block_->PutNodesOnFreeList(&first_free_);
   }
-  result->Initialize(value);
+  ASSERT(first_free_ != NULL);
+  // Take the first node in the free list.
+  Node* result = first_free_;
+  first_free_ = result->next_free();
+  result->Acquire(value, this);
+  if (isolate_->heap()->InNewSpace(value) &&
+      !result->is_in_new_space_list()) {
+    new_space_nodes_.Add(result);
+    result->set_in_new_space_list(true);
+  }
   return result->handle();
 }
 
@@ -354,11 +424,7 @@
 void GlobalHandles::Destroy(Object** location) {
   isolate_->counters()->global_handles()->Decrement();
   if (location == NULL) return;
-  Node* node = Node::FromLocation(location);
-  node->Destroy(this);
-  // Link the destroyed.
-  node->set_next_free(first_free());
-  set_first_free(node);
+  Node::FromLocation(location)->Release(this);
 }
 
 
@@ -375,7 +441,7 @@
 
 
 void GlobalHandles::MarkIndependent(Object** location) {
-  Node::FromLocation(location)->MarkIndependent(this);
+  Node::FromLocation(location)->MarkIndependent();
 }
 
 
@@ -390,68 +456,66 @@
 
 
 void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) {
-  Node::FromLocation(location)->SetWrapperClassId(class_id);
+  Node::FromLocation(location)->set_wrapper_class_id(class_id);
 }
 
 
 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
-  // Traversal of GC roots in the global handle list that are marked as
-  // WEAK, PENDING or NEAR_DEATH.
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (current->state_ == Node::WEAK
-      || current->state_ == Node::PENDING
-      || current->state_ == Node::NEAR_DEATH) {
-      v->VisitPointer(&current->object_);
-    }
-  }
-}
-
-
-void GlobalHandles::IterateWeakIndependentRoots(ObjectVisitor* v) {
-  // Traversal of GC roots in the global handle list that are independent
-  // and marked as WEAK, PENDING or NEAR_DEATH.
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (!current->independent_) continue;
-    if (current->state_ == Node::WEAK
-      || current->state_ == Node::PENDING
-      || current->state_ == Node::NEAR_DEATH) {
-      v->VisitPointer(&current->object_);
-    }
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location());
   }
 }
 
 
 void GlobalHandles::IterateWeakRoots(WeakReferenceGuest f,
                                      WeakReferenceCallback callback) {
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (current->IsWeak() && current->callback() == callback) {
-      f(current->object_, current->parameter());
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    if (it.node()->IsWeak() && it.node()->callback() == callback) {
+      f(it.node()->object(), it.node()->parameter());
     }
   }
 }
 
 
 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (current->state_ == Node::WEAK) {
-      if (f(&current->object_)) {
-        current->state_ = Node::PENDING;
-        LOG(isolate_,
-            HandleEvent("GlobalHandle::Pending", current->handle().location()));
-      }
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    if (it.node()->IsWeak() && f(it.node()->location())) {
+      it.node()->MarkPending();
     }
   }
 }
 
 
-void GlobalHandles::IdentifyWeakIndependentHandles(WeakSlotCallbackWithHeap f) {
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (current->state_ == Node::WEAK && current->independent_) {
-      if (f(isolate_->heap(), &current->object_)) {
-        current->state_ = Node::PENDING;
-        LOG(isolate_,
-            HandleEvent("GlobalHandle::Pending", current->handle().location()));
-      }
+void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) {
+  for (int i = 0; i < new_space_nodes_.length(); ++i) {
+    Node* node = new_space_nodes_[i];
+    if (node->IsStrongRetainer() ||
+        (node->IsWeakRetainer() && !node->is_independent())) {
+      v->VisitPointer(node->location());
+    }
+  }
+}
+
+
+void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles(
+    WeakSlotCallbackWithHeap f) {
+  for (int i = 0; i < new_space_nodes_.length(); ++i) {
+    Node* node = new_space_nodes_[i];
+    ASSERT(node->is_in_new_space_list());
+    if (node->is_independent() && node->IsWeak() &&
+        f(isolate_->heap(), node->location())) {
+      node->MarkPending();
+    }
+  }
+}
+
+
+void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
+  for (int i = 0; i < new_space_nodes_.length(); ++i) {
+    Node* node = new_space_nodes_[i];
+    ASSERT(node->is_in_new_space_list());
+    if (node->is_independent() && node->IsWeakRetainer()) {
+      v->VisitPointer(node->location());
     }
   }
 }
@@ -462,116 +526,103 @@
   // Process weak global handle callbacks. This must be done after the
   // GC is completely done, because the callbacks may invoke arbitrary
   // API functions.
-  // At the same time deallocate all DESTROYED nodes.
   ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
   const int initial_post_gc_processing_count = ++post_gc_processing_count_;
   bool next_gc_likely_to_collect_more = false;
-  Node** p = &head_;
-  while (*p != NULL) {
-    // 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 (collector == SCAVENGER && !(*p)->independent_) {
-      p = (*p)->next_addr();
-      continue;
-    }
-
-    if ((*p)->PostGarbageCollectionProcessing(isolate_, this)) {
-      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).
-        break;
+  if (collector == SCAVENGER) {
+    for (int i = 0; i < new_space_nodes_.length(); ++i) {
+      Node* node = new_space_nodes_[i];
+      ASSERT(node->is_in_new_space_list());
+      // 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()) continue;
+      if (node->PostGarbageCollectionProcessing(isolate_, this)) {
+        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 next_gc_likely_to_collect_more;
+        }
+      }
+      if (!node->IsRetainer()) {
+        next_gc_likely_to_collect_more = true;
       }
     }
-    if ((*p)->state_ == Node::DESTROYED) {
-      // Delete the link.
-      Node* node = *p;
-      *p = node->next();  // Update the link.
-      if (first_deallocated()) {
-        first_deallocated()->set_next(node);
+  } else {
+    for (NodeIterator it(this); !it.done(); it.Advance()) {
+      if (it.node()->PostGarbageCollectionProcessing(isolate_, this)) {
+        if (initial_post_gc_processing_count != post_gc_processing_count_) {
+          // See the comment above.
+          return next_gc_likely_to_collect_more;
+        }
       }
-      node->set_next_free(first_deallocated());
-      set_first_deallocated(node);
-      next_gc_likely_to_collect_more = true;
+      if (!it.node()->IsRetainer()) {
+        next_gc_likely_to_collect_more = true;
+      }
+    }
+  }
+  // Update the list of new space nodes.
+  int last = 0;
+  for (int i = 0; i < new_space_nodes_.length(); ++i) {
+    Node* node = new_space_nodes_[i];
+    ASSERT(node->is_in_new_space_list());
+    if (node->IsRetainer() && isolate_->heap()->InNewSpace(node->object())) {
+      new_space_nodes_[last++] = node;
     } else {
-      p = (*p)->next_addr();
+      node->set_in_new_space_list(false);
     }
   }
-  set_first_free(NULL);
-  if (first_deallocated()) {
-    first_deallocated()->set_next(head());
-  }
-
+  new_space_nodes_.Rewind(last);
   return next_gc_likely_to_collect_more;
 }
 
 
 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) {
-  // Traversal of global handles marked as NORMAL.
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (current->state_ == Node::NORMAL) {
-      v->VisitPointer(&current->object_);
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    if (it.node()->IsStrongRetainer()) {
+      v->VisitPointer(it.node()->location());
     }
   }
 }
 
 
 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) {
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (current->state_ != Node::DESTROYED) {
-      v->VisitPointer(&current->object_);
-    }
-  }
-}
-
-
-void GlobalHandles::IterateStrongAndDependentRoots(ObjectVisitor* v) {
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if ((current->independent_ && current->state_ == Node::NORMAL) ||
-        (!current->independent_ && current->state_ != Node::DESTROYED)) {
-      v->VisitPointer(&current->object_);
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    if (it.node()->IsRetainer()) {
+      v->VisitPointer(it.node()->location());
     }
   }
 }
 
 
 void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) {
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId &&
-        current->CanBeRetainer()) {
-      v->VisitEmbedderReference(&current->object_, current->class_id_);
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    if (it.node()->has_wrapper_class_id() && it.node()->IsRetainer()) {
+      v->VisitEmbedderReference(it.node()->location(),
+                                it.node()->wrapper_class_id());
     }
   }
 }
 
 
-void GlobalHandles::TearDown() {
-  // Reset all the lists.
-  set_head(NULL);
-  set_first_free(NULL);
-  set_first_deallocated(NULL);
-  pool_->Release();
-}
-
-
 void GlobalHandles::RecordStats(HeapStats* stats) {
   *stats->global_handle_count = 0;
   *stats->weak_global_handle_count = 0;
   *stats->pending_global_handle_count = 0;
   *stats->near_death_global_handle_count = 0;
-  *stats->destroyed_global_handle_count = 0;
-  for (Node* current = head_; current != NULL; current = current->next()) {
+  *stats->free_global_handle_count = 0;
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
     *stats->global_handle_count += 1;
-    if (current->state_ == Node::WEAK) {
+    if (it.node()->state() == Node::WEAK) {
       *stats->weak_global_handle_count += 1;
-    } else if (current->state_ == Node::PENDING) {
+    } else if (it.node()->state() == Node::PENDING) {
       *stats->pending_global_handle_count += 1;
-    } else if (current->state_ == Node::NEAR_DEATH) {
+    } else if (it.node()->state() == Node::NEAR_DEATH) {
       *stats->near_death_global_handle_count += 1;
-    } else if (current->state_ == Node::DESTROYED) {
-      *stats->destroyed_global_handle_count += 1;
+    } else if (it.node()->state() == Node::FREE) {
+      *stats->free_global_handle_count += 1;
     }
   }
 }
@@ -585,12 +636,12 @@
   int near_death = 0;
   int destroyed = 0;
 
-  for (Node* current = head_; current != NULL; current = current->next()) {
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
     total++;
-    if (current->state_ == Node::WEAK) weak++;
-    if (current->state_ == Node::PENDING) pending++;
-    if (current->state_ == Node::NEAR_DEATH) near_death++;
-    if (current->state_ == Node::DESTROYED) destroyed++;
+    if (it.node()->state() == Node::WEAK) weak++;
+    if (it.node()->state() == Node::PENDING) pending++;
+    if (it.node()->state() == Node::NEAR_DEATH) near_death++;
+    if (it.node()->state() == Node::FREE) destroyed++;
   }
 
   PrintF("Global Handle Statistics:\n");
@@ -598,17 +649,17 @@
   PrintF("  # weak       = %d\n", weak);
   PrintF("  # pending    = %d\n", pending);
   PrintF("  # near_death = %d\n", near_death);
-  PrintF("  # destroyed  = %d\n", destroyed);
+  PrintF("  # free       = %d\n", destroyed);
   PrintF("  # total      = %d\n", total);
 }
 
 void GlobalHandles::Print() {
   PrintF("Global handles:\n");
-  for (Node* current = head_; current != NULL; current = current->next()) {
-    PrintF("  handle %p to %p (weak=%d)\n",
-           reinterpret_cast<void*>(current->handle().location()),
-           reinterpret_cast<void*>(*current->handle()),
-           current->state_ == Node::WEAK);
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    PrintF("  handle %p to %p%s\n",
+           reinterpret_cast<void*>(it.node()->location()),
+           reinterpret_cast<void*>(it.node()->object()),
+           it.node()->IsWeak() ? " (weak)" : "");
   }
 }
 
@@ -621,7 +672,7 @@
                                    v8::RetainedObjectInfo* info) {
 #ifdef DEBUG
   for (size_t i = 0; i < length; ++i) {
-    ASSERT(!Node::FromLocation(handles[i])->independent_);
+    ASSERT(!Node::FromLocation(handles[i])->is_independent());
   }
 #endif
   if (length == 0) {
@@ -636,9 +687,9 @@
                                           Object*** children,
                                           size_t length) {
 #ifdef DEBUG
-  ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->independent_);
+  ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
   for (size_t i = 0; i < length; ++i) {
-    ASSERT(!Node::FromLocation(children[i])->independent_);
+    ASSERT(!Node::FromLocation(children[i])->is_independent());
   }
 #endif
   if (length == 0) return;
@@ -662,4 +713,9 @@
 }
 
 
+void GlobalHandles::TearDown() {
+  // TODO(1428): invoke weak callbacks.
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/global-handles.h b/src/global-handles.h
index 3477bca..153d4da 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -162,9 +162,6 @@
   // Iterates over all strong handles.
   void IterateStrongRoots(ObjectVisitor* v);
 
-  // Iterates over all strong and dependent handles.
-  void IterateStrongAndDependentRoots(ObjectVisitor* v);
-
   // Iterates over all handles.
   void IterateAllRoots(ObjectVisitor* v);
 
@@ -174,9 +171,6 @@
   // Iterates over all weak roots in heap.
   void IterateWeakRoots(ObjectVisitor* v);
 
-  // Iterates over all weak independent roots in heap.
-  void IterateWeakIndependentRoots(ObjectVisitor* v);
-
   // Iterates over weak roots that are bound to a given callback.
   void IterateWeakRoots(WeakReferenceGuest f,
                         WeakReferenceCallback callback);
@@ -185,9 +179,20 @@
   // them as pending.
   void IdentifyWeakHandles(WeakSlotCallback f);
 
-  // Find all weak independent handles satisfying the callback predicate, mark
-  // them as pending.
-  void IdentifyWeakIndependentHandles(WeakSlotCallbackWithHeap f);
+  // NOTE: Three ...NewSpace... functions below are used during
+  // scavenge collections and iterate over sets of handles that are
+  // guaranteed to contain all handles holding new space objects (but
+  // may also include old space objects).
+
+  // Iterates over strong and dependent handles. See the node above.
+  void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v);
+
+  // Finds weak independent handles satisfying the callback predicate
+  // and marks them as pending. See the note above.
+  void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
+
+  // Iterates over weak independent handles. See the note above.
+  void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
 
   // Add an object group.
   // Should be only used in GC callback function before a collection.
@@ -224,12 +229,14 @@
   void PrintStats();
   void Print();
 #endif
-  class Pool;
+
  private:
   explicit GlobalHandles(Isolate* isolate);
 
-  // Internal node structure, one for each global handle.
+  // Internal node structures.
   class Node;
+  class NodeBlock;
+  class NodeIterator;
 
   Isolate* isolate_;
 
@@ -241,35 +248,21 @@
   // number_of_weak_handles_.
   int number_of_global_object_weak_handles_;
 
-  // Global handles are kept in a single linked list pointed to by head_.
-  Node* head_;
-  Node* head() { return head_; }
-  void set_head(Node* value) { head_ = value; }
+  // List of all allocated node blocks.
+  NodeBlock* first_block_;
 
-  // Free list for DESTROYED global handles not yet deallocated.
+  // List of node blocks with used nodes.
+  NodeBlock* first_used_block_;
+
+  // Free list of nodes.
   Node* first_free_;
-  Node* first_free() { return first_free_; }
-  void set_first_free(Node* value) { first_free_ = value; }
 
-  // List of deallocated nodes.
-  // Deallocated nodes form a prefix of all the nodes and
-  // |first_deallocated| points to last deallocated node before
-  // |head|.  Those deallocated nodes are additionally linked
-  // by |next_free|:
-  //                                    1st deallocated  head
-  //                                           |          |
-  //                                           V          V
-  //    node          node        ...         node       node
-  //      .next      -> .next ->                .next ->
-  //   <- .next_free <- .next_free           <- .next_free
-  Node* first_deallocated_;
-  Node* first_deallocated() { return first_deallocated_; }
-  void set_first_deallocated(Node* value) {
-    first_deallocated_ = value;
-  }
+  // Contains all nodes holding new space objects. Note: when the list
+  // is accessed, some of the objects may have been promoted already.
+  List<Node*> new_space_nodes_;
 
-  Pool* pool_;
   int post_gc_processing_count_;
+
   List<ObjectGroup*> object_groups_;
   List<ImplicitRefGroup*> implicit_ref_groups_;
 
diff --git a/src/globals.h b/src/globals.h
index 5ab9806..7e41f97 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -199,6 +199,8 @@
 const int kIntptrSize   = sizeof(intptr_t);  // NOLINT
 const int kPointerSize  = sizeof(void*);     // NOLINT
 
+const int kDoubleSizeLog2 = 3;
+
 #if V8_HOST_ARCH_64_BIT
 const int kPointerSizeLog2 = 3;
 const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
@@ -224,6 +226,10 @@
 const int kBinary32MantissaBits = 23;
 const int kBinary32ExponentShift = 23;
 
+// Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no
+// other bits set.
+const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51;
+
 // ASCII/UC16 constants
 // Code-point values in Unicode 4.0 are 21 bits wide.
 typedef uint16_t uc16;
diff --git a/src/handles.cc b/src/handles.cc
index b03b642..b03efbd 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -214,9 +214,10 @@
 }
 
 
-void NormalizeElements(Handle<JSObject> object) {
-  CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
-                          object->NormalizeElements());
+Handle<NumberDictionary> NormalizeElements(Handle<JSObject> object) {
+  CALL_HEAP_FUNCTION(object->GetIsolate(),
+                     object->NormalizeElements(),
+                     NumberDictionary);
 }
 
 
@@ -228,12 +229,14 @@
 }
 
 
-void NumberDictionarySet(Handle<NumberDictionary> dictionary,
-                         uint32_t index,
-                         Handle<Object> value,
-                         PropertyDetails details) {
-  CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(),
-                          dictionary->Set(index, *value, details));
+Handle<NumberDictionary> NumberDictionarySet(
+    Handle<NumberDictionary> dictionary,
+    uint32_t index,
+    Handle<Object> value,
+    PropertyDetails details) {
+  CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
+                     dictionary->Set(index, *value, details),
+                     NumberDictionary);
 }
 
 
@@ -258,7 +261,7 @@
 }
 
 
-Handle<Object> SetProperty(Handle<JSObject> object,
+Handle<Object> SetProperty(Handle<JSReceiver> object,
                            Handle<String> key,
                            Handle<Object> value,
                            PropertyAttributes attributes,
@@ -353,7 +356,7 @@
 }
 
 
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
                            const char* name) {
   Isolate* isolate = obj->GetIsolate();
   Handle<String> str = isolate->factory()->LookupAsciiSymbol(name);
@@ -362,17 +365,6 @@
 
 
 Handle<Object> GetProperty(Handle<Object> obj,
-                           const char* name,
-                           LookupResult* result) {
-  Isolate* isolate = Isolate::Current();
-  Handle<String> str = isolate->factory()->LookupAsciiSymbol(name);
-  PropertyAttributes attributes;
-  CALL_HEAP_FUNCTION(
-      isolate, obj->GetProperty(*obj, result, *str, &attributes), Object);
-}
-
-
-Handle<Object> GetProperty(Handle<Object> obj,
                            Handle<Object> key) {
   Isolate* isolate = Isolate::Current();
   CALL_HEAP_FUNCTION(isolate,
@@ -380,7 +372,7 @@
 }
 
 
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
                            Handle<String> name,
                            LookupResult* result) {
   PropertyAttributes attributes;
@@ -460,6 +452,11 @@
     if (create_if_needed) {
       Handle<Object> hidden_obj =
           isolate->factory()->NewJSObject(isolate->object_function());
+
+      // Don't allow leakage of the hidden object through accessors
+      // on Object.prototype.
+      SetPrototype(Handle<JSObject>::cast(hidden_obj),
+                   isolate->factory()->null_value());
       CALL_HEAP_FUNCTION(isolate,
                          obj->SetHiddenPropertiesObject(*hidden_obj), Object);
     } else {
@@ -516,7 +513,8 @@
     }
   }
   CALL_HEAP_FUNCTION(object->GetIsolate(),
-                     object->SetElement(index, *value, strict_mode), Object);
+                     object->SetElement(index, *value, strict_mode, true),
+                     Object);
 }
 
 
@@ -550,11 +548,6 @@
 // associated with the wrapper and get rid of both the wrapper and the
 // handle.
 static void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
-#ifdef ENABLE_HEAP_PROTECTION
-  // Weak reference callbacks are called as if from outside V8.  We
-  // need to reeenter to unprotect the heap.
-  VMState state(OTHER);
-#endif
   Handle<Object> cache = Utils::OpenHandle(*handle);
   JSValue* wrapper = JSValue::cast(*cache);
   Foreign* foreign = Script::cast(wrapper->value())->wrapper();
diff --git a/src/handles.h b/src/handles.h
index 3d930fd..13c6dd6 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -170,13 +170,14 @@
 void NormalizeProperties(Handle<JSObject> object,
                          PropertyNormalizationMode mode,
                          int expected_additional_properties);
-void NormalizeElements(Handle<JSObject> object);
+Handle<NumberDictionary> NormalizeElements(Handle<JSObject> object);
 void TransformToFastProperties(Handle<JSObject> object,
                                int unused_property_fields);
-void NumberDictionarySet(Handle<NumberDictionary> dictionary,
-                         uint32_t index,
-                         Handle<Object> value,
-                         PropertyDetails details);
+MUST_USE_RESULT Handle<NumberDictionary> NumberDictionarySet(
+    Handle<NumberDictionary> dictionary,
+    uint32_t index,
+    Handle<Object> value,
+    PropertyDetails details);
 
 // Flattens a string.
 void FlattenString(Handle<String> str);
@@ -185,7 +186,7 @@
 // string.
 Handle<String> FlattenGetString(Handle<String> str);
 
-Handle<Object> SetProperty(Handle<JSObject> object,
+Handle<Object> SetProperty(Handle<JSReceiver> object,
                            Handle<String> key,
                            Handle<Object> value,
                            PropertyAttributes attributes,
@@ -239,17 +240,13 @@
                              Handle<Object> value,
                              StrictModeFlag strict_mode);
 
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
                            const char* name);
 
 Handle<Object> GetProperty(Handle<Object> obj,
-                           const char* name,
-                           LookupResult* result);
-
-Handle<Object> GetProperty(Handle<Object> obj,
                            Handle<Object> key);
 
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
                            Handle<String> name,
                            LookupResult* result);
 
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 3860fad..b0b4fbe 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -526,8 +526,6 @@
   } while (false)
 
 
-// TODO(isolates): cache isolate: either accept as a parameter or
-//                 set to some known symbol (__CUR_ISOLATE__?)
 #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE)       \
   CALL_AND_RETRY(ISOLATE,                                      \
                  FUNCTION_CALL,                                \
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
index ec078ed..7e613e9 100644
--- a/src/heap-profiler.cc
+++ b/src/heap-profiler.cc
@@ -28,294 +28,12 @@
 #include "v8.h"
 
 #include "heap-profiler.h"
-#include "frames-inl.h"
-#include "global-handles.h"
 #include "profile-generator.h"
-#include "string-stream.h"
 
 namespace v8 {
 namespace internal {
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-namespace {
-
-// Clusterizer is a set of helper functions for converting
-// object references into clusters.
-class Clusterizer : public AllStatic {
- public:
-  static JSObjectsCluster Clusterize(HeapObject* obj) {
-    return Clusterize(obj, true);
-  }
-  static void InsertIntoTree(JSObjectsClusterTree* tree,
-                             HeapObject* obj, bool fine_grain);
-  static void InsertReferenceIntoTree(JSObjectsClusterTree* tree,
-                                      const JSObjectsCluster& cluster) {
-    InsertIntoTree(tree, cluster, 0);
-  }
-
- private:
-  static JSObjectsCluster Clusterize(HeapObject* obj, bool fine_grain);
-  static int CalculateNetworkSize(JSObject* obj);
-  static int GetObjectSize(HeapObject* obj) {
-    return obj->IsJSObject() ?
-        CalculateNetworkSize(JSObject::cast(obj)) : obj->Size();
-  }
-  static void InsertIntoTree(JSObjectsClusterTree* tree,
-                             const JSObjectsCluster& cluster, int size);
-};
-
-
-JSObjectsCluster Clusterizer::Clusterize(HeapObject* obj, bool fine_grain) {
-  if (obj->IsJSObject()) {
-    JSObject* js_obj = JSObject::cast(obj);
-    String* constructor = GetConstructorNameForHeapProfile(
-        JSObject::cast(js_obj));
-    // Differentiate Object and Array instances.
-    if (fine_grain && (constructor == HEAP->Object_symbol() ||
-                       constructor == HEAP->Array_symbol())) {
-      return JSObjectsCluster(constructor, obj);
-    } else {
-      return JSObjectsCluster(constructor);
-    }
-  } else if (obj->IsString()) {
-    return JSObjectsCluster(HEAP->String_symbol());
-  } else if (obj->IsJSGlobalPropertyCell()) {
-    return JSObjectsCluster(JSObjectsCluster::GLOBAL_PROPERTY);
-  } else if (obj->IsCode() || obj->IsSharedFunctionInfo() || obj->IsScript()) {
-    return JSObjectsCluster(JSObjectsCluster::CODE);
-  }
-  return JSObjectsCluster();
-}
-
-
-void Clusterizer::InsertIntoTree(JSObjectsClusterTree* tree,
-                                 HeapObject* obj, bool fine_grain) {
-  JSObjectsCluster cluster = Clusterize(obj, fine_grain);
-  if (cluster.is_null()) return;
-  InsertIntoTree(tree, cluster, GetObjectSize(obj));
-}
-
-
-void Clusterizer::InsertIntoTree(JSObjectsClusterTree* tree,
-                                 const JSObjectsCluster& cluster, int size) {
-  JSObjectsClusterTree::Locator loc;
-  tree->Insert(cluster, &loc);
-  NumberAndSizeInfo number_and_size = loc.value();
-  number_and_size.increment_number(1);
-  number_and_size.increment_bytes(size);
-  loc.set_value(number_and_size);
-}
-
-
-int Clusterizer::CalculateNetworkSize(JSObject* obj) {
-  int size = obj->Size();
-  // If 'properties' and 'elements' are non-empty (thus, non-shared),
-  // take their size into account.
-  if (obj->properties() != HEAP->empty_fixed_array()) {
-    size += obj->properties()->Size();
-  }
-  if (obj->elements() != HEAP->empty_fixed_array()) {
-    size += obj->elements()->Size();
-  }
-  // For functions, also account non-empty context and literals sizes.
-  if (obj->IsJSFunction()) {
-    JSFunction* f = JSFunction::cast(obj);
-    if (f->unchecked_context()->IsContext()) {
-      size += f->context()->Size();
-    }
-    if (f->literals()->length() != 0) {
-      size += f->literals()->Size();
-    }
-  }
-  return size;
-}
-
-
-// A helper class for recording back references.
-class ReferencesExtractor : public ObjectVisitor {
- public:
-  ReferencesExtractor(const JSObjectsCluster& cluster,
-                      RetainerHeapProfile* profile)
-      : cluster_(cluster),
-        profile_(profile),
-        inside_array_(false) {
-  }
-
-  void VisitPointer(Object** o) {
-    if ((*o)->IsFixedArray() && !inside_array_) {
-      // Traverse one level deep for data members that are fixed arrays.
-      // This covers the case of 'elements' and 'properties' of JSObject,
-      // and function contexts.
-      inside_array_ = true;
-      FixedArray::cast(*o)->Iterate(this);
-      inside_array_ = false;
-    } else if ((*o)->IsHeapObject()) {
-      profile_->StoreReference(cluster_, HeapObject::cast(*o));
-    }
-  }
-
-  void VisitPointers(Object** start, Object** end) {
-    for (Object** p = start; p < end; p++) VisitPointer(p);
-  }
-
- private:
-  const JSObjectsCluster& cluster_;
-  RetainerHeapProfile* profile_;
-  bool inside_array_;
-};
-
-
-// A printer interface implementation for the Retainers profile.
-class RetainersPrinter : public RetainerHeapProfile::Printer {
- public:
-  void PrintRetainers(const JSObjectsCluster& cluster,
-                      const StringStream& retainers) {
-    HeapStringAllocator allocator;
-    StringStream stream(&allocator);
-    cluster.Print(&stream);
-    LOG(ISOLATE,
-        HeapSampleJSRetainersEvent(
-        *(stream.ToCString()), *(retainers.ToCString())));
-  }
-};
-
-
-// Visitor for printing a cluster tree.
-class ClusterTreePrinter BASE_EMBEDDED {
- public:
-  explicit ClusterTreePrinter(StringStream* stream) : stream_(stream) {}
-  void Call(const JSObjectsCluster& cluster,
-            const NumberAndSizeInfo& number_and_size) {
-    Print(stream_, cluster, number_and_size);
-  }
-  static void Print(StringStream* stream,
-                    const JSObjectsCluster& cluster,
-                    const NumberAndSizeInfo& number_and_size);
-
- private:
-  StringStream* stream_;
-};
-
-
-void ClusterTreePrinter::Print(StringStream* stream,
-                               const JSObjectsCluster& cluster,
-                               const NumberAndSizeInfo& number_and_size) {
-  stream->Put(',');
-  cluster.Print(stream);
-  stream->Add(";%d", number_and_size.number());
-}
-
-
-// Visitor for printing a retainer tree.
-class SimpleRetainerTreePrinter BASE_EMBEDDED {
- public:
-  explicit SimpleRetainerTreePrinter(RetainerHeapProfile::Printer* printer)
-      : printer_(printer) {}
-  void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree);
-
- private:
-  RetainerHeapProfile::Printer* printer_;
-};
-
-
-void SimpleRetainerTreePrinter::Call(const JSObjectsCluster& cluster,
-                                     JSObjectsClusterTree* tree) {
-  HeapStringAllocator allocator;
-  StringStream stream(&allocator);
-  ClusterTreePrinter retainers_printer(&stream);
-  tree->ForEach(&retainers_printer);
-  printer_->PrintRetainers(cluster, stream);
-}
-
-
-// Visitor for aggregating references count of equivalent clusters.
-class RetainersAggregator BASE_EMBEDDED {
- public:
-  RetainersAggregator(ClustersCoarser* coarser, JSObjectsClusterTree* dest_tree)
-      : coarser_(coarser), dest_tree_(dest_tree) {}
-  void Call(const JSObjectsCluster& cluster,
-            const NumberAndSizeInfo& number_and_size);
-
- private:
-  ClustersCoarser* coarser_;
-  JSObjectsClusterTree* dest_tree_;
-};
-
-
-void RetainersAggregator::Call(const JSObjectsCluster& cluster,
-                               const NumberAndSizeInfo& number_and_size) {
-  JSObjectsCluster eq = coarser_->GetCoarseEquivalent(cluster);
-  if (eq.is_null()) eq = cluster;
-  JSObjectsClusterTree::Locator loc;
-  dest_tree_->Insert(eq, &loc);
-  NumberAndSizeInfo aggregated_number = loc.value();
-  aggregated_number.increment_number(number_and_size.number());
-  loc.set_value(aggregated_number);
-}
-
-
-// Visitor for printing retainers tree. Aggregates equivalent retainer clusters.
-class AggregatingRetainerTreePrinter BASE_EMBEDDED {
- public:
-  AggregatingRetainerTreePrinter(ClustersCoarser* coarser,
-                                 RetainerHeapProfile::Printer* printer)
-      : coarser_(coarser), printer_(printer) {}
-  void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree);
-
- private:
-  ClustersCoarser* coarser_;
-  RetainerHeapProfile::Printer* printer_;
-};
-
-
-void AggregatingRetainerTreePrinter::Call(const JSObjectsCluster& cluster,
-                                          JSObjectsClusterTree* tree) {
-  if (!coarser_->GetCoarseEquivalent(cluster).is_null()) return;
-  JSObjectsClusterTree dest_tree_;
-  RetainersAggregator retainers_aggregator(coarser_, &dest_tree_);
-  tree->ForEach(&retainers_aggregator);
-  HeapStringAllocator allocator;
-  StringStream stream(&allocator);
-  ClusterTreePrinter retainers_printer(&stream);
-  dest_tree_.ForEach(&retainers_printer);
-  printer_->PrintRetainers(cluster, stream);
-}
-
-}  // namespace
-
-
-// A helper class for building a retainers tree, that aggregates
-// all equivalent clusters.
-class RetainerTreeAggregator {
- public:
-  explicit RetainerTreeAggregator(ClustersCoarser* coarser)
-      : coarser_(coarser) {}
-  void Process(JSObjectsRetainerTree* input_tree) {
-    input_tree->ForEach(this);
-  }
-  void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree);
-  JSObjectsRetainerTree& output_tree() { return output_tree_; }
-
- private:
-  ClustersCoarser* coarser_;
-  JSObjectsRetainerTree output_tree_;
-};
-
-
-void RetainerTreeAggregator::Call(const JSObjectsCluster& cluster,
-                                  JSObjectsClusterTree* tree) {
-  JSObjectsCluster eq = coarser_->GetCoarseEquivalent(cluster);
-  if (eq.is_null()) return;
-  JSObjectsRetainerTree::Locator loc;
-  if (output_tree_.Insert(eq, &loc)) {
-    loc.set_value(new JSObjectsClusterTree());
-  }
-  RetainersAggregator retainers_aggregator(coarser_, loc.value());
-  tree->ForEach(&retainers_aggregator);
-}
-
-
 HeapProfiler::HeapProfiler()
     : snapshots_(new HeapSnapshotsCollection()),
       next_snapshot_uid_(1) {
@@ -333,29 +51,21 @@
 }
 
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 void HeapProfiler::Setup() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   if (isolate->heap_profiler() == NULL) {
     isolate->set_heap_profiler(new HeapProfiler());
   }
-#endif
 }
 
 
 void HeapProfiler::TearDown() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   delete isolate->heap_profiler();
   isolate->set_heap_profiler(NULL);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 HeapSnapshot* HeapProfiler::TakeSnapshot(const char* name,
                                          int type,
                                          v8::ActivityControl* control) {
@@ -409,14 +119,6 @@
       generation_completed = generator.GenerateSnapshot();
       break;
     }
-    case HeapSnapshot::kAggregated: {
-      HEAP->CollectAllGarbage(true);
-      AggregatedHeapSnapshot agg_snapshot;
-      AggregatedHeapSnapshotGenerator generator(&agg_snapshot);
-      generator.GenerateSnapshot();
-      generator.FillHeapSnapshot(result);
-      break;
-    }
     default:
       UNREACHABLE();
   }
@@ -469,705 +171,4 @@
 }
 
 
-const JSObjectsClusterTreeConfig::Key JSObjectsClusterTreeConfig::kNoKey;
-const JSObjectsClusterTreeConfig::Value JSObjectsClusterTreeConfig::kNoValue;
-
-
-ConstructorHeapProfile::ConstructorHeapProfile()
-    : zscope_(Isolate::Current(), DELETE_ON_EXIT) {
-}
-
-
-void ConstructorHeapProfile::Call(const JSObjectsCluster& cluster,
-                                  const NumberAndSizeInfo& number_and_size) {
-  HeapStringAllocator allocator;
-  StringStream stream(&allocator);
-  cluster.Print(&stream);
-  LOG(ISOLATE,
-      HeapSampleJSConstructorEvent(*(stream.ToCString()),
-                                   number_and_size.number(),
-                                   number_and_size.bytes()));
-}
-
-
-void ConstructorHeapProfile::CollectStats(HeapObject* obj) {
-  Clusterizer::InsertIntoTree(&js_objects_info_tree_, obj, false);
-}
-
-
-void ConstructorHeapProfile::PrintStats() {
-  js_objects_info_tree_.ForEach(this);
-}
-
-
-static const char* GetConstructorName(const char* name) {
-  return name[0] != '\0' ? name : "(anonymous)";
-}
-
-
-const char* JSObjectsCluster::GetSpecialCaseName() const {
-  if (constructor_ == FromSpecialCase(ROOTS)) {
-    return "(roots)";
-  } else if (constructor_ == FromSpecialCase(GLOBAL_PROPERTY)) {
-    return "(global property)";
-  } else if (constructor_ == FromSpecialCase(CODE)) {
-    return "(code)";
-  } else if (constructor_ == FromSpecialCase(SELF)) {
-    return "(self)";
-  }
-  return NULL;
-}
-
-
-void JSObjectsCluster::Print(StringStream* accumulator) const {
-  ASSERT(!is_null());
-  const char* special_case_name = GetSpecialCaseName();
-  if (special_case_name != NULL) {
-    accumulator->Add(special_case_name);
-  } else {
-    SmartPointer<char> s_name(
-        constructor_->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL));
-    accumulator->Add("%s", GetConstructorName(*s_name));
-    if (instance_ != NULL) {
-      accumulator->Add(":%p", static_cast<void*>(instance_));
-    }
-  }
-}
-
-
-void JSObjectsCluster::DebugPrint(StringStream* accumulator) const {
-  if (!is_null()) {
-    Print(accumulator);
-  } else {
-    accumulator->Add("(null cluster)");
-  }
-}
-
-
-inline ClustersCoarser::ClusterBackRefs::ClusterBackRefs(
-    const JSObjectsCluster& cluster_)
-    : cluster(cluster_), refs(kInitialBackrefsListCapacity) {
-}
-
-
-inline ClustersCoarser::ClusterBackRefs::ClusterBackRefs(
-    const ClustersCoarser::ClusterBackRefs& src)
-    : cluster(src.cluster), refs(src.refs.capacity()) {
-  refs.AddAll(src.refs);
-}
-
-
-inline ClustersCoarser::ClusterBackRefs&
-    ClustersCoarser::ClusterBackRefs::operator=(
-    const ClustersCoarser::ClusterBackRefs& src) {
-  if (this == &src) return *this;
-  cluster = src.cluster;
-  refs.Clear();
-  refs.AddAll(src.refs);
-  return *this;
-}
-
-
-inline int ClustersCoarser::ClusterBackRefs::Compare(
-    const ClustersCoarser::ClusterBackRefs& a,
-    const ClustersCoarser::ClusterBackRefs& b) {
-  int cmp = JSObjectsCluster::CompareConstructors(a.cluster, b.cluster);
-  if (cmp != 0) return cmp;
-  if (a.refs.length() < b.refs.length()) return -1;
-  if (a.refs.length() > b.refs.length()) return 1;
-  for (int i = 0; i < a.refs.length(); ++i) {
-    int cmp = JSObjectsCluster::Compare(a.refs[i], b.refs[i]);
-    if (cmp != 0) return cmp;
-  }
-  return 0;
-}
-
-
-ClustersCoarser::ClustersCoarser()
-    : zscope_(Isolate::Current(), DELETE_ON_EXIT),
-      sim_list_(ClustersCoarser::kInitialSimilarityListCapacity),
-      current_pair_(NULL),
-      current_set_(NULL),
-      self_(NULL) {
-}
-
-
-void ClustersCoarser::Call(const JSObjectsCluster& cluster,
-                           JSObjectsClusterTree* tree) {
-  if (!cluster.can_be_coarsed()) return;
-  ClusterBackRefs pair(cluster);
-  ASSERT(current_pair_ == NULL);
-  current_pair_ = &pair;
-  current_set_ = new JSObjectsRetainerTree();
-  self_ = &cluster;
-  tree->ForEach(this);
-  sim_list_.Add(pair);
-  current_pair_ = NULL;
-  current_set_ = NULL;
-  self_ = NULL;
-}
-
-
-void ClustersCoarser::Call(const JSObjectsCluster& cluster,
-                           const NumberAndSizeInfo& number_and_size) {
-  ASSERT(current_pair_ != NULL);
-  ASSERT(current_set_ != NULL);
-  ASSERT(self_ != NULL);
-  JSObjectsRetainerTree::Locator loc;
-  if (JSObjectsCluster::Compare(*self_, cluster) == 0) {
-    current_pair_->refs.Add(JSObjectsCluster(JSObjectsCluster::SELF));
-    return;
-  }
-  JSObjectsCluster eq = GetCoarseEquivalent(cluster);
-  if (!eq.is_null()) {
-    if (current_set_->Find(eq, &loc)) return;
-    current_pair_->refs.Add(eq);
-    current_set_->Insert(eq, &loc);
-  } else {
-    current_pair_->refs.Add(cluster);
-  }
-}
-
-
-void ClustersCoarser::Process(JSObjectsRetainerTree* tree) {
-  int last_eq_clusters = -1;
-  for (int i = 0; i < kMaxPassesCount; ++i) {
-    sim_list_.Clear();
-    const int curr_eq_clusters = DoProcess(tree);
-    // If no new cluster equivalents discovered, abort processing.
-    if (last_eq_clusters == curr_eq_clusters) break;
-    last_eq_clusters = curr_eq_clusters;
-  }
-}
-
-
-int ClustersCoarser::DoProcess(JSObjectsRetainerTree* tree) {
-  tree->ForEach(this);
-  sim_list_.Iterate(ClusterBackRefs::SortRefsIterator);
-  sim_list_.Sort(ClusterBackRefsCmp);
-  return FillEqualityTree();
-}
-
-
-JSObjectsCluster ClustersCoarser::GetCoarseEquivalent(
-    const JSObjectsCluster& cluster) {
-  if (!cluster.can_be_coarsed()) return JSObjectsCluster();
-  EqualityTree::Locator loc;
-  return eq_tree_.Find(cluster, &loc) ? loc.value() : JSObjectsCluster();
-}
-
-
-bool ClustersCoarser::HasAnEquivalent(const JSObjectsCluster& cluster) {
-  // Return true for coarsible clusters that have a non-identical equivalent.
-  if (!cluster.can_be_coarsed()) return false;
-  JSObjectsCluster eq = GetCoarseEquivalent(cluster);
-  return !eq.is_null() && JSObjectsCluster::Compare(cluster, eq) != 0;
-}
-
-
-int ClustersCoarser::FillEqualityTree() {
-  int eq_clusters_count = 0;
-  int eq_to = 0;
-  bool first_added = false;
-  for (int i = 1; i < sim_list_.length(); ++i) {
-    if (ClusterBackRefs::Compare(sim_list_[i], sim_list_[eq_to]) == 0) {
-      EqualityTree::Locator loc;
-      if (!first_added) {
-        // Add self-equivalence, if we have more than one item in this
-        // equivalence class.
-        eq_tree_.Insert(sim_list_[eq_to].cluster, &loc);
-        loc.set_value(sim_list_[eq_to].cluster);
-        first_added = true;
-      }
-      eq_tree_.Insert(sim_list_[i].cluster, &loc);
-      loc.set_value(sim_list_[eq_to].cluster);
-      ++eq_clusters_count;
-    } else {
-      eq_to = i;
-      first_added = false;
-    }
-  }
-  return eq_clusters_count;
-}
-
-
-const JSObjectsCluster ClustersCoarser::ClusterEqualityConfig::kNoKey;
-const JSObjectsCluster ClustersCoarser::ClusterEqualityConfig::kNoValue;
-const JSObjectsRetainerTreeConfig::Key JSObjectsRetainerTreeConfig::kNoKey;
-const JSObjectsRetainerTreeConfig::Value JSObjectsRetainerTreeConfig::kNoValue =
-    NULL;
-
-
-RetainerHeapProfile::RetainerHeapProfile()
-    : zscope_(Isolate::Current(), DELETE_ON_EXIT),
-      aggregator_(NULL) {
-  JSObjectsCluster roots(JSObjectsCluster::ROOTS);
-  ReferencesExtractor extractor(roots, this);
-  HEAP->IterateRoots(&extractor, VISIT_ONLY_STRONG);
-}
-
-
-RetainerHeapProfile::~RetainerHeapProfile() {
-  delete aggregator_;
-}
-
-
-void RetainerHeapProfile::StoreReference(const JSObjectsCluster& cluster,
-                                         HeapObject* ref) {
-  JSObjectsCluster ref_cluster = Clusterizer::Clusterize(ref);
-  if (ref_cluster.is_null()) return;
-  JSObjectsRetainerTree::Locator ref_loc;
-  if (retainers_tree_.Insert(ref_cluster, &ref_loc)) {
-    ref_loc.set_value(new JSObjectsClusterTree());
-  }
-  JSObjectsClusterTree* referenced_by = ref_loc.value();
-  Clusterizer::InsertReferenceIntoTree(referenced_by, cluster);
-}
-
-
-void RetainerHeapProfile::CollectStats(HeapObject* obj) {
-  const JSObjectsCluster cluster = Clusterizer::Clusterize(obj);
-  if (cluster.is_null()) return;
-  ReferencesExtractor extractor(cluster, this);
-  obj->Iterate(&extractor);
-}
-
-
-void RetainerHeapProfile::CoarseAndAggregate() {
-  coarser_.Process(&retainers_tree_);
-  ASSERT(aggregator_ == NULL);
-  aggregator_ = new RetainerTreeAggregator(&coarser_);
-  aggregator_->Process(&retainers_tree_);
-}
-
-
-void RetainerHeapProfile::DebugPrintStats(
-    RetainerHeapProfile::Printer* printer) {
-  // Print clusters that have no equivalents, aggregating their retainers.
-  AggregatingRetainerTreePrinter agg_printer(&coarser_, printer);
-  retainers_tree_.ForEach(&agg_printer);
-  // Print clusters that have equivalents.
-  SimpleRetainerTreePrinter s_printer(printer);
-  aggregator_->output_tree().ForEach(&s_printer);
-}
-
-
-void RetainerHeapProfile::PrintStats() {
-  RetainersPrinter printer;
-  DebugPrintStats(&printer);
-}
-
-
-//
-// HeapProfiler class implementation.
-//
-static void StackWeakReferenceCallback(Persistent<Value> object,
-                                       void* trace) {
-  DeleteArray(static_cast<Address*>(trace));
-  object.Dispose();
-}
-
-
-static void PrintProducerStackTrace(Object* obj, void* trace) {
-  if (!obj->IsJSObject()) return;
-  String* constructor = GetConstructorNameForHeapProfile(JSObject::cast(obj));
-  SmartPointer<char> s_name(
-      constructor->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL));
-  LOG(ISOLATE,
-      HeapSampleJSProducerEvent(GetConstructorName(*s_name),
-                                reinterpret_cast<Address*>(trace)));
-}
-
-
-void HeapProfiler::WriteSample() {
-  Isolate* isolate = Isolate::Current();
-  LOG(isolate, HeapSampleBeginEvent("Heap", "allocated"));
-  LOG(isolate,
-      HeapSampleStats(
-          "Heap", "allocated", HEAP->CommittedMemory(), HEAP->SizeOfObjects()));
-
-  AggregatedHeapSnapshot snapshot;
-  AggregatedHeapSnapshotGenerator generator(&snapshot);
-  generator.GenerateSnapshot();
-
-  HistogramInfo* info = snapshot.info();
-  for (int i = FIRST_NONSTRING_TYPE;
-       i <= AggregatedHeapSnapshotGenerator::kAllStringsType;
-       ++i) {
-    if (info[i].bytes() > 0) {
-      LOG(isolate,
-          HeapSampleItemEvent(info[i].name(), info[i].number(),
-                              info[i].bytes()));
-    }
-  }
-
-  snapshot.js_cons_profile()->PrintStats();
-  snapshot.js_retainer_profile()->PrintStats();
-
-  isolate->global_handles()->IterateWeakRoots(PrintProducerStackTrace,
-                                              StackWeakReferenceCallback);
-
-  LOG(isolate, HeapSampleEndEvent("Heap", "allocated"));
-}
-
-
-AggregatedHeapSnapshot::AggregatedHeapSnapshot()
-    : info_(NewArray<HistogramInfo>(
-        AggregatedHeapSnapshotGenerator::kAllStringsType + 1)) {
-#define DEF_TYPE_NAME(name) info_[name].set_name(#name);
-  INSTANCE_TYPE_LIST(DEF_TYPE_NAME);
-#undef DEF_TYPE_NAME
-  info_[AggregatedHeapSnapshotGenerator::kAllStringsType].set_name(
-      "STRING_TYPE");
-}
-
-
-AggregatedHeapSnapshot::~AggregatedHeapSnapshot() {
-  DeleteArray(info_);
-}
-
-
-AggregatedHeapSnapshotGenerator::AggregatedHeapSnapshotGenerator(
-    AggregatedHeapSnapshot* agg_snapshot)
-    : agg_snapshot_(agg_snapshot) {
-}
-
-
-void AggregatedHeapSnapshotGenerator::CalculateStringsStats() {
-  HistogramInfo* info = agg_snapshot_->info();
-  HistogramInfo& strings = info[kAllStringsType];
-  // Lump all the string types together.
-#define INCREMENT_SIZE(type, size, name, camel_name)   \
-  strings.increment_number(info[type].number());       \
-  strings.increment_bytes(info[type].bytes());
-  STRING_TYPE_LIST(INCREMENT_SIZE);
-#undef INCREMENT_SIZE
-}
-
-
-void AggregatedHeapSnapshotGenerator::CollectStats(HeapObject* obj) {
-  InstanceType type = obj->map()->instance_type();
-  ASSERT(0 <= type && type <= LAST_TYPE);
-  agg_snapshot_->info()[type].increment_number(1);
-  agg_snapshot_->info()[type].increment_bytes(obj->Size());
-}
-
-
-void AggregatedHeapSnapshotGenerator::GenerateSnapshot() {
-  HeapIterator iterator(HeapIterator::kFilterUnreachable);
-  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
-    CollectStats(obj);
-    agg_snapshot_->js_cons_profile()->CollectStats(obj);
-    agg_snapshot_->js_retainer_profile()->CollectStats(obj);
-  }
-  CalculateStringsStats();
-  agg_snapshot_->js_retainer_profile()->CoarseAndAggregate();
-}
-
-
-class CountingConstructorHeapProfileIterator {
- public:
-  CountingConstructorHeapProfileIterator()
-      : entities_count_(0), children_count_(0) {
-  }
-
-  void Call(const JSObjectsCluster& cluster,
-            const NumberAndSizeInfo& number_and_size) {
-    ++entities_count_;
-    children_count_ += number_and_size.number();
-  }
-
-  int entities_count() { return entities_count_; }
-  int children_count() { return children_count_; }
-
- private:
-  int entities_count_;
-  int children_count_;
-};
-
-
-static HeapEntry* AddEntryFromAggregatedSnapshot(HeapSnapshot* snapshot,
-                                                 int* root_child_index,
-                                                 HeapEntry::Type type,
-                                                 const char* name,
-                                                 int count,
-                                                 int size,
-                                                 int children_count,
-                                                 int retainers_count) {
-  HeapEntry* entry = snapshot->AddEntry(
-      type, name, count, size, children_count, retainers_count);
-  ASSERT(entry != NULL);
-  snapshot->root()->SetUnidirElementReference(*root_child_index,
-                                              *root_child_index + 1,
-                                              entry);
-  *root_child_index = *root_child_index + 1;
-  return entry;
-}
-
-
-class AllocatingConstructorHeapProfileIterator {
- public:
-  AllocatingConstructorHeapProfileIterator(HeapSnapshot* snapshot,
-                                  int* root_child_index)
-      : snapshot_(snapshot),
-        root_child_index_(root_child_index) {
-  }
-
-  void Call(const JSObjectsCluster& cluster,
-            const NumberAndSizeInfo& number_and_size) {
-    const char* name = cluster.GetSpecialCaseName();
-    if (name == NULL) {
-      name = snapshot_->collection()->names()->GetFunctionName(
-          cluster.constructor());
-    }
-    AddEntryFromAggregatedSnapshot(snapshot_,
-                                   root_child_index_,
-                                   HeapEntry::kObject,
-                                   name,
-                                   number_and_size.number(),
-                                   number_and_size.bytes(),
-                                   0,
-                                   0);
-  }
-
- private:
-  HeapSnapshot* snapshot_;
-  int* root_child_index_;
-};
-
-
-static HeapObject* ClusterAsHeapObject(const JSObjectsCluster& cluster) {
-  return cluster.can_be_coarsed() ?
-      reinterpret_cast<HeapObject*>(cluster.instance()) : cluster.constructor();
-}
-
-
-static JSObjectsCluster HeapObjectAsCluster(HeapObject* object) {
-  if (object->IsString()) {
-    return JSObjectsCluster(String::cast(object));
-  } else {
-    JSObject* js_obj = JSObject::cast(object);
-    String* constructor = GetConstructorNameForHeapProfile(
-        JSObject::cast(js_obj));
-    return JSObjectsCluster(constructor, object);
-  }
-}
-
-
-class CountingRetainersIterator {
- public:
-  CountingRetainersIterator(const JSObjectsCluster& child_cluster,
-                            HeapEntriesAllocator* allocator,
-                            HeapEntriesMap* map)
-      : child_(ClusterAsHeapObject(child_cluster)),
-        allocator_(allocator),
-        map_(map) {
-    if (map_->Map(child_) == NULL)
-      map_->Pair(child_, allocator_, HeapEntriesMap::kHeapEntryPlaceholder);
-  }
-
-  void Call(const JSObjectsCluster& cluster,
-            const NumberAndSizeInfo& number_and_size) {
-    if (map_->Map(ClusterAsHeapObject(cluster)) == NULL)
-      map_->Pair(ClusterAsHeapObject(cluster),
-                 allocator_,
-                 HeapEntriesMap::kHeapEntryPlaceholder);
-    map_->CountReference(ClusterAsHeapObject(cluster), child_);
-  }
-
- private:
-  HeapObject* child_;
-  HeapEntriesAllocator* allocator_;
-  HeapEntriesMap* map_;
-};
-
-
-class AllocatingRetainersIterator {
- public:
-  AllocatingRetainersIterator(const JSObjectsCluster& child_cluster,
-                              HeapEntriesAllocator*,
-                              HeapEntriesMap* map)
-      : child_(ClusterAsHeapObject(child_cluster)), map_(map) {
-    child_entry_ = map_->Map(child_);
-    ASSERT(child_entry_ != NULL);
-  }
-
-  void Call(const JSObjectsCluster& cluster,
-            const NumberAndSizeInfo& number_and_size) {
-    int child_index, retainer_index;
-    map_->CountReference(ClusterAsHeapObject(cluster),
-                         child_,
-                         &child_index,
-                         &retainer_index);
-    map_->Map(ClusterAsHeapObject(cluster))->SetIndexedReference(
-        HeapGraphEdge::kElement,
-        child_index,
-        number_and_size.number(),
-        child_entry_,
-        retainer_index);
-  }
-
- private:
-  HeapObject* child_;
-  HeapEntriesMap* map_;
-  HeapEntry* child_entry_;
-};
-
-
-template<class RetainersIterator>
-class AggregatingRetainerTreeIterator {
- public:
-  explicit AggregatingRetainerTreeIterator(ClustersCoarser* coarser,
-                                           HeapEntriesAllocator* allocator,
-                                           HeapEntriesMap* map)
-      : coarser_(coarser), allocator_(allocator), map_(map) {
-  }
-
-  void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree) {
-    if (coarser_ != NULL &&
-        !coarser_->GetCoarseEquivalent(cluster).is_null()) return;
-    JSObjectsClusterTree* tree_to_iterate = tree;
-    ZoneScope zs(Isolate::Current(), DELETE_ON_EXIT);
-    JSObjectsClusterTree dest_tree_;
-    if (coarser_ != NULL) {
-      RetainersAggregator retainers_aggregator(coarser_, &dest_tree_);
-      tree->ForEach(&retainers_aggregator);
-      tree_to_iterate = &dest_tree_;
-    }
-    RetainersIterator iterator(cluster, allocator_, map_);
-    tree_to_iterate->ForEach(&iterator);
-  }
-
- private:
-  ClustersCoarser* coarser_;
-  HeapEntriesAllocator* allocator_;
-  HeapEntriesMap* map_;
-};
-
-
-class AggregatedRetainerTreeAllocator : public HeapEntriesAllocator {
- public:
-  AggregatedRetainerTreeAllocator(HeapSnapshot* snapshot,
-                                  int* root_child_index)
-      : snapshot_(snapshot), root_child_index_(root_child_index) {
-  }
-  ~AggregatedRetainerTreeAllocator() { }
-
-  HeapEntry* AllocateEntry(
-      HeapThing ptr, int children_count, int retainers_count) {
-    HeapObject* obj = reinterpret_cast<HeapObject*>(ptr);
-    JSObjectsCluster cluster = HeapObjectAsCluster(obj);
-    const char* name = cluster.GetSpecialCaseName();
-    if (name == NULL) {
-      name = snapshot_->collection()->names()->GetFunctionName(
-          cluster.constructor());
-    }
-    return AddEntryFromAggregatedSnapshot(
-        snapshot_, root_child_index_, HeapEntry::kObject, name,
-        0, 0, children_count, retainers_count);
-  }
-
- private:
-  HeapSnapshot* snapshot_;
-  int* root_child_index_;
-};
-
-
-template<class Iterator>
-void AggregatedHeapSnapshotGenerator::IterateRetainers(
-    HeapEntriesAllocator* allocator, HeapEntriesMap* entries_map) {
-  RetainerHeapProfile* p = agg_snapshot_->js_retainer_profile();
-  AggregatingRetainerTreeIterator<Iterator> agg_ret_iter_1(
-      p->coarser(), allocator, entries_map);
-  p->retainers_tree()->ForEach(&agg_ret_iter_1);
-  AggregatingRetainerTreeIterator<Iterator> agg_ret_iter_2(
-      NULL, allocator, entries_map);
-  p->aggregator()->output_tree().ForEach(&agg_ret_iter_2);
-}
-
-
-void AggregatedHeapSnapshotGenerator::FillHeapSnapshot(HeapSnapshot* snapshot) {
-  // Count the number of entities.
-  int histogram_entities_count = 0;
-  int histogram_children_count = 0;
-  int histogram_retainers_count = 0;
-  for (int i = FIRST_NONSTRING_TYPE; i <= kAllStringsType; ++i) {
-    if (agg_snapshot_->info()[i].bytes() > 0) {
-      ++histogram_entities_count;
-    }
-  }
-  CountingConstructorHeapProfileIterator counting_cons_iter;
-  agg_snapshot_->js_cons_profile()->ForEach(&counting_cons_iter);
-  histogram_entities_count += counting_cons_iter.entities_count();
-  HeapEntriesMap entries_map;
-  int root_child_index = 0;
-  AggregatedRetainerTreeAllocator allocator(snapshot, &root_child_index);
-  IterateRetainers<CountingRetainersIterator>(&allocator, &entries_map);
-  histogram_entities_count += entries_map.entries_count();
-  histogram_children_count += entries_map.total_children_count();
-  histogram_retainers_count += entries_map.total_retainers_count();
-
-  // Root entry references all other entries.
-  histogram_children_count += histogram_entities_count;
-  int root_children_count = histogram_entities_count;
-  ++histogram_entities_count;
-
-  // Allocate and fill entries in the snapshot, allocate references.
-  snapshot->AllocateEntries(histogram_entities_count,
-                            histogram_children_count,
-                            histogram_retainers_count);
-  snapshot->AddRootEntry(root_children_count);
-  for (int i = FIRST_NONSTRING_TYPE; i <= kAllStringsType; ++i) {
-    if (agg_snapshot_->info()[i].bytes() > 0) {
-      AddEntryFromAggregatedSnapshot(snapshot,
-                                     &root_child_index,
-                                     HeapEntry::kHidden,
-                                     agg_snapshot_->info()[i].name(),
-                                     agg_snapshot_->info()[i].number(),
-                                     agg_snapshot_->info()[i].bytes(),
-                                     0,
-                                     0);
-    }
-  }
-  AllocatingConstructorHeapProfileIterator alloc_cons_iter(
-      snapshot, &root_child_index);
-  agg_snapshot_->js_cons_profile()->ForEach(&alloc_cons_iter);
-  entries_map.AllocateEntries();
-
-  // Fill up references.
-  IterateRetainers<AllocatingRetainersIterator>(&allocator, &entries_map);
-
-  snapshot->SetDominatorsToSelf();
-}
-
-
-void ProducerHeapProfile::Setup() {
-  can_log_ = true;
-}
-
-void ProducerHeapProfile::DoRecordJSObjectAllocation(Object* obj) {
-  ASSERT(FLAG_log_producers);
-  if (!can_log_) return;
-  int framesCount = 0;
-  for (JavaScriptFrameIterator it; !it.done(); it.Advance()) {
-    ++framesCount;
-  }
-  if (framesCount == 0) return;
-  ++framesCount;  // Reserve place for the terminator item.
-  Vector<Address> stack(NewArray<Address>(framesCount), framesCount);
-  int i = 0;
-  for (JavaScriptFrameIterator it; !it.done(); it.Advance()) {
-    stack[i++] = it.frame()->pc();
-  }
-  stack[i] = NULL;
-  Handle<Object> handle = isolate_->global_handles()->Create(obj);
-  isolate_->global_handles()->MakeWeak(handle.location(),
-                                       static_cast<void*>(stack.start()),
-                                       StackWeakReferenceCallback);
-}
-
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
-
 } }  // namespace v8::internal
diff --git a/src/heap-profiler.h b/src/heap-profiler.h
index c1e93c0..b1bc91c 100644
--- a/src/heap-profiler.h
+++ b/src/heap-profiler.h
@@ -28,15 +28,11 @@
 #ifndef V8_HEAP_PROFILER_H_
 #define V8_HEAP_PROFILER_H_
 
-#include "allocation.h"
 #include "isolate.h"
-#include "zone-inl.h"
 
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 class HeapSnapshot;
 class HeapSnapshotsCollection;
 
@@ -47,9 +43,6 @@
       profiler->call;                                                        \
     }                                                                        \
   } while (false)
-#else
-#define HEAP_PROFILE(heap, call) ((void) 0)
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 // The HeapProfiler writes data to the log files, which can be postprocessed
 // to generate .hp files for use by the GHC/Valgrind tool hp2ps.
@@ -58,7 +51,6 @@
   static void Setup();
   static void TearDown();
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static HeapSnapshot* TakeSnapshot(const char* name,
                                     int type,
                                     v8::ActivityControl* control);
@@ -81,10 +73,6 @@
     return snapshots_->is_tracking_objects();
   }
 
-  // Obsolete interface.
-  // Write a single heap sample to the log file.
-  static void WriteSample();
-
  private:
   HeapProfiler();
   ~HeapProfiler();
@@ -99,299 +87,8 @@
   HeapSnapshotsCollection* snapshots_;
   unsigned next_snapshot_uid_;
   List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_;
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
 };
 
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-// JSObjectsCluster describes a group of JS objects that are
-// considered equivalent in terms of a particular profile.
-class JSObjectsCluster BASE_EMBEDDED {
- public:
-  // These special cases are used in retainer profile.
-  enum SpecialCase {
-    ROOTS = 1,
-    GLOBAL_PROPERTY = 2,
-    CODE = 3,
-    SELF = 100  // This case is used in ClustersCoarser only.
-  };
-
-  JSObjectsCluster() : constructor_(NULL), instance_(NULL) {}
-  explicit JSObjectsCluster(String* constructor)
-      : constructor_(constructor), instance_(NULL) {}
-  explicit JSObjectsCluster(SpecialCase special)
-      : constructor_(FromSpecialCase(special)), instance_(NULL) {}
-  JSObjectsCluster(String* constructor, Object* instance)
-      : constructor_(constructor), instance_(instance) {}
-
-  static int CompareConstructors(const JSObjectsCluster& a,
-                                 const JSObjectsCluster& b) {
-    // Strings are unique, so it is sufficient to compare their pointers.
-    return a.constructor_ == b.constructor_ ? 0
-        : (a.constructor_ < b.constructor_ ? -1 : 1);
-  }
-  static int Compare(const JSObjectsCluster& a, const JSObjectsCluster& b) {
-    // Strings are unique, so it is sufficient to compare their pointers.
-    const int cons_cmp = CompareConstructors(a, b);
-    return cons_cmp == 0 ?
-        (a.instance_ == b.instance_ ? 0 : (a.instance_ < b.instance_ ? -1 : 1))
-        : cons_cmp;
-  }
-  static int Compare(const JSObjectsCluster* a, const JSObjectsCluster* b) {
-    return Compare(*a, *b);
-  }
-
-  bool is_null() const { return constructor_ == NULL; }
-  bool can_be_coarsed() const { return instance_ != NULL; }
-  String* constructor() const { return constructor_; }
-  Object* instance() const { return instance_; }
-
-  const char* GetSpecialCaseName() const;
-  void Print(StringStream* accumulator) const;
-  // Allows null clusters to be printed.
-  void DebugPrint(StringStream* accumulator) const;
-
- private:
-  static String* FromSpecialCase(SpecialCase special) {
-    // We use symbols that are illegal JS identifiers to identify special cases.
-    // Their actual value is irrelevant for us.
-    switch (special) {
-      case ROOTS: return HEAP->result_symbol();
-      case GLOBAL_PROPERTY: return HEAP->code_symbol();
-      case CODE: return HEAP->arguments_shadow_symbol();
-      case SELF: return HEAP->catch_var_symbol();
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
-  }
-
-  String* constructor_;
-  Object* instance_;
-};
-
-
-struct JSObjectsClusterTreeConfig {
-  typedef JSObjectsCluster Key;
-  typedef NumberAndSizeInfo Value;
-  static const Key kNoKey;
-  static const Value kNoValue;
-  static int Compare(const Key& a, const Key& b) {
-    return Key::Compare(a, b);
-  }
-};
-typedef ZoneSplayTree<JSObjectsClusterTreeConfig> JSObjectsClusterTree;
-
-
-// ConstructorHeapProfile is responsible for gathering and logging
-// "constructor profile" of JS objects allocated on heap.
-// It is run during garbage collection cycle, thus it doesn't need
-// to use handles.
-class ConstructorHeapProfile BASE_EMBEDDED {
- public:
-  ConstructorHeapProfile();
-  virtual ~ConstructorHeapProfile() {}
-  void CollectStats(HeapObject* obj);
-  void PrintStats();
-
-  template<class Callback>
-  void ForEach(Callback* callback) { js_objects_info_tree_.ForEach(callback); }
-  // Used by ZoneSplayTree::ForEach. Made virtual to allow overriding in tests.
-  virtual void Call(const JSObjectsCluster& cluster,
-                    const NumberAndSizeInfo& number_and_size);
-
- private:
-  ZoneScope zscope_;
-  JSObjectsClusterTree js_objects_info_tree_;
-};
-
-
-// JSObjectsRetainerTree is used to represent retainer graphs using
-// adjacency list form:
-//
-//   Cluster -> (Cluster -> NumberAndSizeInfo)
-//
-// Subordinate splay trees are stored by pointer. They are zone-allocated,
-// so it isn't needed to manage their lifetime.
-//
-struct JSObjectsRetainerTreeConfig {
-  typedef JSObjectsCluster Key;
-  typedef JSObjectsClusterTree* Value;
-  static const Key kNoKey;
-  static const Value kNoValue;
-  static int Compare(const Key& a, const Key& b) {
-    return Key::Compare(a, b);
-  }
-};
-typedef ZoneSplayTree<JSObjectsRetainerTreeConfig> JSObjectsRetainerTree;
-
-
-class ClustersCoarser BASE_EMBEDDED {
- public:
-  ClustersCoarser();
-
-  // Processes a given retainer graph.
-  void Process(JSObjectsRetainerTree* tree);
-
-  // Returns an equivalent cluster (can be the cluster itself).
-  // If the given cluster doesn't have an equivalent, returns null cluster.
-  JSObjectsCluster GetCoarseEquivalent(const JSObjectsCluster& cluster);
-  // Returns whether a cluster can be substitued with an equivalent and thus,
-  // skipped in some cases.
-  bool HasAnEquivalent(const JSObjectsCluster& cluster);
-
-  // Used by JSObjectsRetainerTree::ForEach.
-  void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree);
-  void Call(const JSObjectsCluster& cluster,
-            const NumberAndSizeInfo& number_and_size);
-
- private:
-  // Stores a list of back references for a cluster.
-  struct ClusterBackRefs {
-    explicit ClusterBackRefs(const JSObjectsCluster& cluster_);
-    ClusterBackRefs(const ClusterBackRefs& src);
-    ClusterBackRefs& operator=(const ClusterBackRefs& src);
-
-    static int Compare(const ClusterBackRefs& a, const ClusterBackRefs& b);
-    void SortRefs() { refs.Sort(JSObjectsCluster::Compare); }
-    static void SortRefsIterator(ClusterBackRefs* ref) { ref->SortRefs(); }
-
-    JSObjectsCluster cluster;
-    ZoneList<JSObjectsCluster> refs;
-  };
-  typedef ZoneList<ClusterBackRefs> SimilarityList;
-
-  // A tree for storing a list of equivalents for a cluster.
-  struct ClusterEqualityConfig {
-    typedef JSObjectsCluster Key;
-    typedef JSObjectsCluster Value;
-    static const Key kNoKey;
-    static const Value kNoValue;
-    static int Compare(const Key& a, const Key& b) {
-      return Key::Compare(a, b);
-    }
-  };
-  typedef ZoneSplayTree<ClusterEqualityConfig> EqualityTree;
-
-  static int ClusterBackRefsCmp(const ClusterBackRefs* a,
-                                const ClusterBackRefs* b) {
-    return ClusterBackRefs::Compare(*a, *b);
-  }
-  int DoProcess(JSObjectsRetainerTree* tree);
-  int FillEqualityTree();
-
-  static const int kInitialBackrefsListCapacity = 2;
-  static const int kInitialSimilarityListCapacity = 2000;
-  // Number of passes for finding equivalents. Limits the length of paths
-  // that can be considered equivalent.
-  static const int kMaxPassesCount = 10;
-
-  ZoneScope zscope_;
-  SimilarityList sim_list_;
-  EqualityTree eq_tree_;
-  ClusterBackRefs* current_pair_;
-  JSObjectsRetainerTree* current_set_;
-  const JSObjectsCluster* self_;
-};
-
-
-// RetainerHeapProfile is responsible for gathering and logging
-// "retainer profile" of JS objects allocated on heap.
-// It is run during garbage collection cycle, thus it doesn't need
-// to use handles.
-class RetainerTreeAggregator;
-
-class RetainerHeapProfile BASE_EMBEDDED {
- public:
-  class Printer {
-   public:
-    virtual ~Printer() {}
-    virtual void PrintRetainers(const JSObjectsCluster& cluster,
-                                const StringStream& retainers) = 0;
-  };
-
-  RetainerHeapProfile();
-  ~RetainerHeapProfile();
-
-  RetainerTreeAggregator* aggregator() { return aggregator_; }
-  ClustersCoarser* coarser() { return &coarser_; }
-  JSObjectsRetainerTree* retainers_tree() { return &retainers_tree_; }
-
-  void CollectStats(HeapObject* obj);
-  void CoarseAndAggregate();
-  void PrintStats();
-  void DebugPrintStats(Printer* printer);
-  void StoreReference(const JSObjectsCluster& cluster, HeapObject* ref);
-
- private:
-  ZoneScope zscope_;
-  JSObjectsRetainerTree retainers_tree_;
-  ClustersCoarser coarser_;
-  RetainerTreeAggregator* aggregator_;
-};
-
-
-class AggregatedHeapSnapshot {
- public:
-  AggregatedHeapSnapshot();
-  ~AggregatedHeapSnapshot();
-
-  HistogramInfo* info() { return info_; }
-  ConstructorHeapProfile* js_cons_profile() { return &js_cons_profile_; }
-  RetainerHeapProfile* js_retainer_profile() { return &js_retainer_profile_; }
-
- private:
-  HistogramInfo* info_;
-  ConstructorHeapProfile js_cons_profile_;
-  RetainerHeapProfile js_retainer_profile_;
-};
-
-
-class HeapEntriesMap;
-class HeapEntriesAllocator;
-
-class AggregatedHeapSnapshotGenerator {
- public:
-  explicit AggregatedHeapSnapshotGenerator(AggregatedHeapSnapshot* snapshot);
-  void GenerateSnapshot();
-  void FillHeapSnapshot(HeapSnapshot* snapshot);
-
-  static const int kAllStringsType = LAST_TYPE + 1;
-
- private:
-  void CalculateStringsStats();
-  void CollectStats(HeapObject* obj);
-  template<class Iterator>
-  void IterateRetainers(
-      HeapEntriesAllocator* allocator, HeapEntriesMap* entries_map);
-
-  AggregatedHeapSnapshot* agg_snapshot_;
-};
-
-
-class ProducerHeapProfile {
- public:
-  void Setup();
-  void RecordJSObjectAllocation(Object* obj) {
-    if (FLAG_log_producers) DoRecordJSObjectAllocation(obj);
-  }
-
- private:
-  ProducerHeapProfile() : can_log_(false) { }
-
-  void DoRecordJSObjectAllocation(Object* obj);
-  Isolate* isolate_;
-  bool can_log_;
-
-  friend class Isolate;
-
-  DISALLOW_COPY_AND_ASSIGN(ProducerHeapProfile);
-};
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
 
 #endif  // V8_HEAP_PROFILER_H_
diff --git a/src/heap.cc b/src/heap.cc
index f82c83c..2d27570 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -33,6 +33,7 @@
 #include "codegen.h"
 #include "compilation-cache.h"
 #include "debug.h"
+#include "deoptimizer.h"
 #include "global-handles.h"
 #include "heap-profiler.h"
 #include "liveobjectlist-inl.h"
@@ -80,14 +81,14 @@
       reserved_semispace_size_(16*MB),
       max_semispace_size_(16*MB),
       initial_semispace_size_(1*MB),
-      max_old_generation_size_(1*GB),
+      max_old_generation_size_(1400*MB),
       max_executable_size_(256*MB),
       code_range_size_(512*MB),
 #else
       reserved_semispace_size_(8*MB),
       max_semispace_size_(8*MB),
       initial_semispace_size_(512*KB),
-      max_old_generation_size_(512*MB),
+      max_old_generation_size_(700*MB),
       max_executable_size_(128*MB),
       code_range_size_(0),
 #endif
@@ -108,6 +109,7 @@
       cell_space_(NULL),
       lo_space_(NULL),
       gc_state_(NOT_IN_GC),
+      gc_post_processing_depth_(0),
       mc_count_(0),
       ms_count_(0),
       gc_count_(0),
@@ -153,6 +155,15 @@
   max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
 #endif
 
+  intptr_t max_virtual = OS::MaxVirtualMemory();
+
+  if (max_virtual > 0) {
+    if (code_range_size_ > 0) {
+      // Reserve no more than 1/8 of the memory for the code range.
+      code_range_size_ = Min(code_range_size_, max_virtual >> 3);
+    }
+  }
+
   memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
   global_contexts_list_ = NULL;
   mark_compact_collector_.heap_ = this;
@@ -282,12 +293,11 @@
 
 // TODO(1238405): Combine the infrastructure for --heap-stats and
 // --log-gc to avoid the complicated preprocessor and flag testing.
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 void Heap::ReportStatisticsBeforeGC() {
   // Heap::ReportHeapStatistics will also log NewSpace statistics when
-  // compiled with ENABLE_LOGGING_AND_PROFILING and --log-gc is set.  The
-  // following logic is used to avoid double logging.
-#if defined(DEBUG) && defined(ENABLE_LOGGING_AND_PROFILING)
+  // compiled --log-gc is set.  The following logic is used to avoid
+  // double logging.
+#ifdef DEBUG
   if (FLAG_heap_stats || FLAG_log_gc) new_space_.CollectStatistics();
   if (FLAG_heap_stats) {
     ReportHeapStatistics("Before GC");
@@ -295,23 +305,16 @@
     new_space_.ReportStatistics();
   }
   if (FLAG_heap_stats || FLAG_log_gc) new_space_.ClearHistograms();
-#elif defined(DEBUG)
-  if (FLAG_heap_stats) {
-    new_space_.CollectStatistics();
-    ReportHeapStatistics("Before GC");
-    new_space_.ClearHistograms();
-  }
-#elif defined(ENABLE_LOGGING_AND_PROFILING)
+#else
   if (FLAG_log_gc) {
     new_space_.CollectStatistics();
     new_space_.ReportStatistics();
     new_space_.ClearHistograms();
   }
-#endif
+#endif  // DEBUG
 }
 
 
-#if defined(ENABLE_LOGGING_AND_PROFILING)
 void Heap::PrintShortHeapStatistics() {
   if (!FLAG_trace_gc_verbose) return;
   PrintF("Memory allocator,   used: %8" V8_PTR_PREFIX "d"
@@ -357,7 +360,6 @@
          lo_space_->Size(),
          lo_space_->Available());
 }
-#endif
 
 
 // TODO(1238405): Combine the infrastructure for --heap-stats and
@@ -365,20 +367,17 @@
 void Heap::ReportStatisticsAfterGC() {
   // Similar to the before GC, we use some complicated logic to ensure that
   // NewSpace statistics are logged exactly once when --log-gc is turned on.
-#if defined(DEBUG) && defined(ENABLE_LOGGING_AND_PROFILING)
+#if defined(DEBUG)
   if (FLAG_heap_stats) {
     new_space_.CollectStatistics();
     ReportHeapStatistics("After GC");
   } else if (FLAG_log_gc) {
     new_space_.ReportStatistics();
   }
-#elif defined(DEBUG)
-  if (FLAG_heap_stats) ReportHeapStatistics("After GC");
-#elif defined(ENABLE_LOGGING_AND_PROFILING)
+#else
   if (FLAG_log_gc) new_space_.ReportStatistics();
-#endif
+#endif  // DEBUG
 }
-#endif  // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 
 
 void Heap::GarbageCollectionPrologue() {
@@ -395,11 +394,11 @@
   }
 
   if (FLAG_gc_verbose) Print();
-#endif
+#endif  // DEBUG
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
+#if defined(DEBUG)
   ReportStatisticsBeforeGC();
-#endif
+#endif  // DEBUG
 
   LiveObjectList::GCPrologue();
 }
@@ -436,12 +435,10 @@
       symbol_table()->Capacity());
   isolate_->counters()->number_of_symbols()->Set(
       symbol_table()->NumberOfElements());
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
+#if defined(DEBUG)
   ReportStatisticsAfterGC();
-#endif
-#ifdef ENABLE_DEBUGGER_SUPPORT
+#endif  // DEBUG
   isolate_->debug()->AfterGarbageCollection();
-#endif
 }
 
 
@@ -514,11 +511,6 @@
     GarbageCollectionEpilogue();
   }
 
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (FLAG_log_gc) HeapProfiler::WriteSample();
-#endif
-
   return next_gc_likely_to_collect_more;
 }
 
@@ -772,11 +764,13 @@
 
   isolate_->counters()->objs_since_last_young()->Set(0);
 
+  gc_post_processing_depth_++;
   { DisableAssertNoAllocation allow_allocation;
     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
     next_gc_likely_to_collect_more =
         isolate_->global_handles()->PostGarbageCollectionProcessing(collector);
   }
+  gc_post_processing_depth_--;
 
   // Update relocatables.
   Relocatable::PostGarbageCollectionProcessing();
@@ -852,6 +846,9 @@
   CompletelyClearInstanceofCache();
 
   if (is_compacting) FlushNumberStringCache();
+  if (FLAG_cleanup_code_caches_at_gc) {
+    polymorphic_code_cache()->set_cache(undefined_value());
+  }
 
   ClearNormalizedMapCaches();
 }
@@ -1035,9 +1032,10 @@
   scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_));
 
   new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
-  isolate_->global_handles()->IdentifyWeakIndependentHandles(
+  isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
       &IsUnscavengedHeapObject);
-  isolate_->global_handles()->IterateWeakIndependentRoots(&scavenge_visitor);
+  isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
+      &scavenge_visitor);
   new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
 
 
@@ -1280,6 +1278,7 @@
     table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
     table_.Register(kVisitByteArray, &EvacuateByteArray);
     table_.Register(kVisitFixedArray, &EvacuateFixedArray);
+    table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray);
 
     table_.Register(kVisitGlobalContext,
                     &ObjectEvacuationStrategy<POINTER_OBJECT>::
@@ -1322,15 +1321,12 @@
   enum ObjectContents  { DATA_OBJECT, POINTER_OBJECT };
   enum SizeRestriction { SMALL, UNKNOWN_SIZE };
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   static void RecordCopiedObject(Heap* heap, HeapObject* obj) {
     bool should_record = false;
 #ifdef DEBUG
     should_record = FLAG_heap_stats;
 #endif
-#ifdef ENABLE_LOGGING_AND_PROFILING
     should_record = should_record || FLAG_log_gc;
-#endif
     if (should_record) {
       if (heap->new_space()->Contains(obj)) {
         heap->new_space()->RecordAllocation(obj);
@@ -1339,7 +1335,6 @@
       }
     }
   }
-#endif  // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 
   // Helper function used by CopyObject to copy a source object to an
   // allocated target object and update the forwarding pointer in the source
@@ -1355,12 +1350,9 @@
     source->set_map_word(MapWord::FromForwardingAddress(target));
 
     if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) {
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
       // Update NewSpace stats if necessary.
       RecordCopiedObject(heap, target);
-#endif
       HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
-#if defined(ENABLE_LOGGING_AND_PROFILING)
       Isolate* isolate = heap->isolate();
       if (isolate->logger()->is_logging() ||
           CpuProfiler::is_profiling(isolate)) {
@@ -1369,7 +1361,6 @@
               source->address(), target->address()));
         }
       }
-#endif
     }
 
     return target;
@@ -1431,6 +1422,18 @@
   }
 
 
+  static inline void EvacuateFixedDoubleArray(Map* map,
+                                              HeapObject** slot,
+                                              HeapObject* object) {
+    int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
+    int object_size = FixedDoubleArray::SizeFor(length);
+    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map,
+                                              slot,
+                                              object,
+                                              object_size);
+  }
+
+
   static inline void EvacuateByteArray(Map* map,
                                        HeapObject** slot,
                                        HeapObject* object) {
@@ -1613,7 +1616,8 @@
   map->set_prototype_transitions(empty_fixed_array());
   map->set_unused_property_fields(0);
   map->set_bit_field(0);
-  map->set_bit_field2((1 << Map::kIsExtensible) | (1 << Map::kHasFastElements));
+  map->set_bit_field2(1 << Map::kIsExtensible);
+  map->set_elements_kind(JSObject::FAST_ELEMENTS);
 
   // If the map object is aligned fill the padding area with Smi 0 objects.
   if (Map::kPadStart < Map::kSize) {
@@ -1637,6 +1641,11 @@
 }
 
 
+MaybeObject* Heap::AllocatePolymorphicCodeCache() {
+  return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE);
+}
+
+
 const Heap::StringTypeTable Heap::string_type_table[] = {
 #define STRING_TYPE_ELEMENT(type, size, name, camel_name)                      \
   {type, size, k##camel_name##MapRootIndex},
@@ -1762,6 +1771,12 @@
   Map::cast(obj)->set_is_undetectable();
 
   { MaybeObject* maybe_obj =
+        AllocateMap(FIXED_DOUBLE_ARRAY_TYPE, kVariableSizeSentinel);
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_fixed_double_array_map(Map::cast(obj));
+
+  { MaybeObject* maybe_obj =
         AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
@@ -1820,6 +1835,12 @@
   }
   set_external_float_array_map(Map::cast(obj));
 
+  { MaybeObject* maybe_obj =
+        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_non_strict_arguments_elements_map(Map::cast(obj));
+
   { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_DOUBLE_ARRAY_TYPE,
                                          ExternalArray::kAlignedSize);
     if (!maybe_obj->ToObject(&obj)) return false;
@@ -1865,7 +1886,7 @@
         AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_context_map(Map::cast(obj));
+  set_function_context_map(Map::cast(obj));
 
   { MaybeObject* maybe_obj =
         AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
@@ -1877,6 +1898,12 @@
         AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
+  set_with_context_map(Map::cast(obj));
+
+  { MaybeObject* maybe_obj =
+        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
   Map* global_context_map = Map::cast(obj);
   global_context_map->set_visitor_id(StaticVisitorBase::kVisitGlobalContext);
   set_global_context_map(global_context_map);
@@ -2144,6 +2171,11 @@
   }
   set_non_monomorphic_cache(NumberDictionary::cast(obj));
 
+  { MaybeObject* maybe_obj = AllocatePolymorphicCodeCache();
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj));
+
   set_instanceof_cache_function(Smi::FromInt(0));
   set_instanceof_cache_map(Smi::FromInt(0));
   set_instanceof_cache_answer(Smi::FromInt(0));
@@ -2361,40 +2393,41 @@
 
 
 MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
-  Object* result;
-  { MaybeObject* maybe_result =
-        Allocate(shared_function_info_map(), OLD_POINTER_SPACE);
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
+  SharedFunctionInfo* share;
+  MaybeObject* maybe = Allocate(shared_function_info_map(), OLD_POINTER_SPACE);
+  if (!maybe->To<SharedFunctionInfo>(&share)) return maybe;
 
-  SharedFunctionInfo* share = SharedFunctionInfo::cast(result);
+  // Set pointer fields.
   share->set_name(name);
   Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
   share->set_code(illegal);
   share->set_scope_info(SerializedScopeInfo::Empty());
-  Code* construct_stub = isolate_->builtins()->builtin(
-      Builtins::kJSConstructStubGeneric);
+  Code* construct_stub =
+      isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric);
   share->set_construct_stub(construct_stub);
-  share->set_expected_nof_properties(0);
-  share->set_length(0);
-  share->set_formal_parameter_count(0);
   share->set_instance_class_name(Object_symbol());
   share->set_function_data(undefined_value());
   share->set_script(undefined_value());
-  share->set_start_position_and_type(0);
   share->set_debug_info(undefined_value());
   share->set_inferred_name(empty_string());
-  share->set_compiler_hints(0);
-  share->set_deopt_counter(Smi::FromInt(FLAG_deopt_every_n_times));
   share->set_initial_map(undefined_value());
-  share->set_this_property_assignments_count(0);
   share->set_this_property_assignments(undefined_value());
-  share->set_opt_count(0);
+  share->set_deopt_counter(Smi::FromInt(FLAG_deopt_every_n_times));
+
+  // Set integer fields (smi or int, depending on the architecture).
+  share->set_length(0);
+  share->set_formal_parameter_count(0);
+  share->set_expected_nof_properties(0);
   share->set_num_literals(0);
+  share->set_start_position_and_type(0);
   share->set_end_position(0);
   share->set_function_token_position(0);
-  share->set_es5_native(false);
-  return result;
+  // All compiler hints default to false or 0.
+  share->set_compiler_hints(0);
+  share->set_this_property_assignments_count(0);
+  share->set_opt_count(0);
+
+  return share;
 }
 
 
@@ -2584,12 +2617,13 @@
 
 
 MaybeObject* Heap::AllocateSubString(String* buffer,
-                                int start,
-                                int end,
-                                PretenureFlag pretenure) {
+                                     int start,
+                                     int end,
+                                     PretenureFlag pretenure) {
   int length = end - start;
-
-  if (length == 1) {
+  if (length == 0) {
+    return empty_string();
+  } else if (length == 1) {
     return LookupSingleCharacterStringFromCode(buffer->Get(start));
   } else if (length == 2) {
     // Optimization for 2-byte strings often used as keys in a decompression
@@ -2929,9 +2963,6 @@
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
   HeapObject::cast(result)->set_map(map);
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  isolate_->producer_heap_profile()->RecordJSObjectAllocation(result);
-#endif
   return result;
 }
 
@@ -3237,14 +3268,13 @@
   MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize);
   if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
   map->set_prototype(prototype);
-  map->set_pre_allocated_property_fields(1);
-  map->set_inobject_properties(1);
 
   // Allocate the proxy object.
   Object* result;
   MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
   if (!maybe_result->ToObject(&result)) return maybe_result;
   JSProxy::cast(result)->set_handler(handler);
+  JSProxy::cast(result)->set_padding(Smi::FromInt(0));
   return result;
 }
 
@@ -3380,13 +3410,40 @@
     JSObject::cast(clone)->set_properties(FixedArray::cast(prop));
   }
   // Return the new clone.
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  isolate_->producer_heap_profile()->RecordJSObjectAllocation(clone);
-#endif
   return clone;
 }
 
 
+MaybeObject* Heap::ReinitializeJSProxyAsJSObject(JSProxy* object) {
+  // Allocate fresh map.
+  // TODO(rossberg): Once we optimize proxies, cache these maps.
+  Map* map;
+  MaybeObject* maybe_map_obj =
+      AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+  if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
+
+  // Check that the receiver has the same size as a fresh object.
+  ASSERT(map->instance_size() == object->map()->instance_size());
+
+  map->set_prototype(object->map()->prototype());
+
+  // Allocate the backing storage for the properties.
+  int prop_size = map->unused_property_fields() - map->inobject_properties();
+  Object* properties;
+  { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, TENURED);
+    if (!maybe_properties->ToObject(&properties)) return maybe_properties;
+  }
+
+  // Reset the map for the object.
+  object->set_map(map);
+
+  // Reinitialize the object from the constructor map.
+  InitializeJSObjectFromMap(JSObject::cast(object),
+                            FixedArray::cast(properties), map);
+  return object;
+}
+
+
 MaybeObject* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor,
                                              JSGlobalProxy* object) {
   ASSERT(constructor->has_initial_map());
@@ -3797,6 +3854,62 @@
 }
 
 
+MaybeObject* Heap::AllocateEmptyFixedDoubleArray() {
+  int size = FixedDoubleArray::SizeFor(0);
+  Object* result;
+  { MaybeObject* maybe_result =
+        AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+  }
+  // Initialize the object.
+  reinterpret_cast<FixedDoubleArray*>(result)->set_map(
+      fixed_double_array_map());
+  reinterpret_cast<FixedDoubleArray*>(result)->set_length(0);
+  return result;
+}
+
+
+MaybeObject* Heap::AllocateUninitializedFixedDoubleArray(
+    int length,
+    PretenureFlag pretenure) {
+  if (length == 0) return empty_fixed_double_array();
+
+  Object* obj;
+  { MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure);
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  }
+
+  reinterpret_cast<FixedDoubleArray*>(obj)->set_map(fixed_double_array_map());
+  FixedDoubleArray::cast(obj)->set_length(length);
+  return obj;
+}
+
+
+MaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
+                                               PretenureFlag pretenure) {
+  if (length < 0 || length > FixedDoubleArray::kMaxLength) {
+    return Failure::OutOfMemoryException();
+  }
+
+  AllocationSpace space =
+      (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
+  int size = FixedDoubleArray::SizeFor(length);
+  if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) {
+    // Too big for new space.
+    space = LO_SPACE;
+  } else if (space == OLD_DATA_SPACE &&
+             size > MaxObjectSizeInPagedSpace()) {
+    // Too big for old data space.
+    space = LO_SPACE;
+  }
+
+  AllocationSpace retry_space =
+      (size <= MaxObjectSizeInPagedSpace()) ? OLD_DATA_SPACE : LO_SPACE;
+
+  return AllocateRaw(size, space, retry_space);
+}
+
+
 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
   Object* result;
   { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure);
@@ -3829,38 +3942,50 @@
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
   Context* context = reinterpret_cast<Context*>(result);
-  context->set_map(context_map());
+  context->set_map(function_context_map());
   context->set_closure(function);
-  context->set_fcontext(context);
-  context->set_previous(NULL);
+  context->set_previous(function->context());
   context->set_extension(NULL);
   context->set_global(function->context()->global());
-  ASSERT(!context->IsGlobalContext());
-  ASSERT(context->is_function_context());
-  ASSERT(result->IsContext());
-  return result;
+  return context;
 }
 
 
-MaybeObject* Heap::AllocateWithContext(Context* previous,
-                                       JSObject* extension,
-                                       bool is_catch_context) {
+MaybeObject* Heap::AllocateCatchContext(JSFunction* function,
+                                        Context* previous,
+                                        String* name,
+                                        Object* thrown_object) {
+  STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
+  Object* result;
+  { MaybeObject* maybe_result =
+        AllocateFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+  }
+  Context* context = reinterpret_cast<Context*>(result);
+  context->set_map(catch_context_map());
+  context->set_closure(function);
+  context->set_previous(previous);
+  context->set_extension(name);
+  context->set_global(previous->global());
+  context->set(Context::THROWN_OBJECT_INDEX, thrown_object);
+  return context;
+}
+
+
+MaybeObject* Heap::AllocateWithContext(JSFunction* function,
+                                       Context* previous,
+                                       JSObject* extension) {
   Object* result;
   { MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
   Context* context = reinterpret_cast<Context*>(result);
-  context->set_map(is_catch_context ? catch_context_map() :
-      context_map());
-  context->set_closure(previous->closure());
-  context->set_fcontext(previous->fcontext());
+  context->set_map(with_context_map());
+  context->set_closure(function);
   context->set_previous(previous);
   context->set_extension(extension);
   context->set_global(previous->global());
-  ASSERT(!context->IsGlobalContext());
-  ASSERT(!context->is_function_context());
-  ASSERT(result->IsContext());
-  return result;
+  return context;
 }
 
 
@@ -4551,6 +4676,9 @@
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   isolate_->debug()->Iterate(v);
+  if (isolate_->deoptimizer_data() != NULL) {
+    isolate_->deoptimizer_data()->Iterate(v);
+  }
 #endif
   v->Synchronize("debug");
   isolate_->compilation_cache()->Iterate(v);
@@ -4575,7 +4703,7 @@
       isolate_->global_handles()->IterateStrongRoots(v);
       break;
     case VISIT_ALL_IN_SCAVENGE:
-      isolate_->global_handles()->IterateStrongAndDependentRoots(v);
+      isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
       break;
     case VISIT_ALL_IN_SWEEP_NEWSPACE:
     case VISIT_ALL:
@@ -4998,11 +5126,6 @@
   LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
   LOG(isolate_, IntPtrTEvent("heap-available", Available()));
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  // This should be called only after initial objects have been created.
-  isolate_->producer_heap_profile()->Setup();
-#endif
-
   return true;
 }
 
@@ -5096,28 +5219,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void Heap::Protect() {
-  if (HasBeenSetup()) {
-    AllSpaces spaces;
-    for (Space* space = spaces.next(); space != NULL; space = spaces.next())
-      space->Protect();
-  }
-}
-
-
-void Heap::Unprotect() {
-  if (HasBeenSetup()) {
-    AllSpaces spaces;
-    for (Space* space = spaces.next(); space != NULL; space = spaces.next())
-      space->Unprotect();
-  }
-}
-
-#endif
-
-
 void Heap::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
   ASSERT(callback != NULL);
   GCPrologueCallbackPair pair(callback, gc_type);
@@ -5813,9 +5914,7 @@
     PrintF("\n");
   }
 
-#if defined(ENABLE_LOGGING_AND_PROFILING)
   heap_->PrintShortHeapStatistics();
-#endif
 }
 
 
diff --git a/src/heap.h b/src/heap.h
index 79ae996..6cd4f84 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -66,6 +66,7 @@
   V(Map, global_context_map, GlobalContextMap)                                 \
   V(Map, fixed_array_map, FixedArrayMap)                                       \
   V(Map, fixed_cow_array_map, FixedCOWArrayMap)                                \
+  V(Map, fixed_double_array_map, FixedDoubleArrayMap)                          \
   V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel)       \
   V(Map, meta_map, MetaMap)                                                    \
   V(Map, hash_table_map, HashTableMap)                                         \
@@ -78,6 +79,7 @@
   V(Object, termination_exception, TerminationException)                       \
   V(FixedArray, empty_fixed_array, EmptyFixedArray)                            \
   V(ByteArray, empty_byte_array, EmptyByteArray)                               \
+  V(FixedDoubleArray, empty_fixed_double_array, EmptyFixedDoubleArray)         \
   V(String, empty_string, EmptyString)                                         \
   V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray)             \
   V(Map, string_map, StringMap)                                                \
@@ -105,8 +107,10 @@
   V(Map, external_unsigned_int_array_map, ExternalUnsignedIntArrayMap)         \
   V(Map, external_float_array_map, ExternalFloatArrayMap)                      \
   V(Map, external_double_array_map, ExternalDoubleArrayMap)                    \
-  V(Map, context_map, ContextMap)                                              \
+  V(Map, non_strict_arguments_elements_map, NonStrictArgumentsElementsMap)     \
+  V(Map, function_context_map, FunctionContextMap)                             \
   V(Map, catch_context_map, CatchContextMap)                                   \
+  V(Map, with_context_map, WithContextMap)                                     \
   V(Map, code_map, CodeMap)                                                    \
   V(Map, oddball_map, OddballMap)                                              \
   V(Map, global_property_cell_map, GlobalPropertyCellMap)                      \
@@ -120,6 +124,7 @@
   V(Foreign, prototype_accessors, PrototypeAccessors)                          \
   V(NumberDictionary, code_stubs, CodeStubs)                                   \
   V(NumberDictionary, non_monomorphic_cache, NonMonomorphicCache)              \
+  V(PolymorphicCodeCache, polymorphic_code_cache, PolymorphicCodeCache)        \
   V(Code, js_entry_code, JsEntryCode)                                          \
   V(Code, js_construct_entry_code, JsConstructEntryCode)                       \
   V(FixedArray, natives_source_cache, NativesSourceCache)                      \
@@ -139,7 +144,6 @@
   V(StringImpl_symbol, "StringImpl")                                     \
   V(arguments_symbol, "arguments")                                       \
   V(Arguments_symbol, "Arguments")                                       \
-  V(arguments_shadow_symbol, ".arguments")                               \
   V(call_symbol, "call")                                                 \
   V(apply_symbol, "apply")                                               \
   V(caller_symbol, "caller")                                             \
@@ -155,6 +159,7 @@
   V(function_symbol, "function")                                         \
   V(length_symbol, "length")                                             \
   V(name_symbol, "name")                                                 \
+  V(native_symbol, "native")                                             \
   V(number_symbol, "number")                                             \
   V(Number_symbol, "Number")                                             \
   V(nan_symbol, "NaN")                                                   \
@@ -178,14 +183,14 @@
   V(value_of_symbol, "valueOf")                                          \
   V(InitializeVarGlobal_symbol, "InitializeVarGlobal")                   \
   V(InitializeConstGlobal_symbol, "InitializeConstGlobal")               \
-  V(KeyedLoadSpecializedMonomorphic_symbol,                              \
-    "KeyedLoadSpecializedMonomorphic")                                   \
-  V(KeyedLoadSpecializedPolymorphic_symbol,                              \
-    "KeyedLoadSpecializedPolymorphic")                                   \
-  V(KeyedStoreSpecializedMonomorphic_symbol,                             \
-    "KeyedStoreSpecializedMonomorphic")                                  \
-  V(KeyedStoreSpecializedPolymorphic_symbol,                             \
-    "KeyedStoreSpecializedPolymorphic")                                  \
+  V(KeyedLoadElementMonomorphic_symbol,                                  \
+    "KeyedLoadElementMonomorphic")                                       \
+  V(KeyedLoadElementPolymorphic_symbol,                                  \
+    "KeyedLoadElementPolymorphic")                                       \
+  V(KeyedStoreElementMonomorphic_symbol,                                 \
+    "KeyedStoreElementMonomorphic")                                      \
+  V(KeyedStoreElementPolymorphic_symbol,                                 \
+    "KeyedStoreElementPolymorphic")                                      \
   V(stack_overflow_symbol, "kStackOverflowBoilerplate")                  \
   V(illegal_access_symbol, "illegal access")                             \
   V(out_of_memory_symbol, "out-of-memory")                               \
@@ -213,7 +218,9 @@
   V(global_eval_symbol, "GlobalEval")                                    \
   V(identity_hash_symbol, "v8::IdentityHash")                            \
   V(closure_symbol, "(closure)")                                         \
-  V(use_strict, "use strict")
+  V(use_strict, "use strict")                                            \
+  V(dot_symbol, ".")                                                     \
+  V(anonymous_function_symbol, "(anonymous function)")
 
 // Forward declarations.
 class GCTracer;
@@ -402,12 +409,6 @@
   // Uncommit unused semi space.
   bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); }
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the heap by marking all spaces read-only/writable.
-  void Protect();
-  void Unprotect();
-#endif
-
   // Allocates and initializes a new JavaScript object based on a
   // constructor.
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
@@ -440,6 +441,11 @@
   MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler,
                                                Object* prototype);
 
+  // Reinitialize a JSProxy into an (empty) JSObject.  The receiver
+  // must have the same size as an empty object.  The object is reinitialized
+  // and behaves as an object that has been freshly allocated.
+  MUST_USE_RESULT MaybeObject* ReinitializeJSProxyAsJSObject(JSProxy* object);
+
   // Reinitialize an JSGlobalProxy based on a constructor.  The object
   // must have the same size as objects allocated using the
   // constructor.  The object is reinitialized and behaves as an
@@ -477,6 +483,9 @@
   // Allocates an empty code cache.
   MUST_USE_RESULT MaybeObject* AllocateCodeCache();
 
+  // Allocates an empty PolymorphicCodeCache.
+  MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
+
   // Clear the Instanceof cache (used when a prototype changes).
   inline void ClearInstanceofCache();
 
@@ -616,6 +625,17 @@
       int length,
       PretenureFlag pretenure = NOT_TENURED);
 
+  MUST_USE_RESULT MaybeObject* AllocateRawFixedDoubleArray(
+      int length,
+      PretenureFlag pretenure);
+
+  // Allocates a fixed double array with uninitialized values. Returns
+  // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+  // Please note this does not perform a garbage collection.
+  MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedDoubleArray(
+      int length,
+      PretenureFlag pretenure = NOT_TENURED);
+
   // AllocateHashTable is identical to AllocateFixedArray except
   // that the resulting object has hash_table_map as map.
   MUST_USE_RESULT MaybeObject* AllocateHashTable(
@@ -626,12 +646,17 @@
 
   // Allocate a function context.
   MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length,
-                                                       JSFunction* closure);
+                                                       JSFunction* function);
 
+  // Allocate a catch context.
+  MUST_USE_RESULT MaybeObject* AllocateCatchContext(JSFunction* function,
+                                                    Context* previous,
+                                                    String* name,
+                                                    Object* thrown_object);
   // Allocate a 'with' context.
-  MUST_USE_RESULT MaybeObject* AllocateWithContext(Context* previous,
-                                                   JSObject* extension,
-                                                   bool is_catch_context);
+  MUST_USE_RESULT MaybeObject* AllocateWithContext(JSFunction* function,
+                                                   Context* previous,
+                                                   JSObject* extension);
 
   // Allocates a new utility object in the old generation.
   MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
@@ -1026,10 +1051,8 @@
   void ZapFromSpace();
 #endif
 
-#if defined(ENABLE_LOGGING_AND_PROFILING)
   // Print short heap statistics.
   void PrintShortHeapStatistics();
-#endif
 
   // Makes a new symbol object
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
@@ -1054,6 +1077,8 @@
   enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT };
   inline HeapState gc_state() { return gc_state_; }
 
+  inline bool IsInGCPostProcessing() { return gc_post_processing_depth_ > 0; }
+
 #ifdef DEBUG
   bool IsAllocationAllowed() { return allocation_allowed_; }
   inline bool allow_allocation(bool enable);
@@ -1285,6 +1310,7 @@
   CellSpace* cell_space_;
   LargeObjectSpace* lo_space_;
   HeapState gc_state_;
+  int gc_post_processing_depth_;
 
   // Returns the size of object residing in non new spaces.
   intptr_t PromotedSpaceSize();
@@ -1461,6 +1487,9 @@
   // Allocate empty fixed array.
   MUST_USE_RESULT MaybeObject* AllocateEmptyFixedArray();
 
+  // Allocate empty fixed double array.
+  MUST_USE_RESULT MaybeObject* AllocateEmptyFixedDoubleArray();
+
   void SwitchScavengingVisitorsTableIfProfilingWasEnabled();
 
   // Performs a minor collection in new generation.
@@ -1482,11 +1511,9 @@
   // around a GC).
   inline void CompletelyClearInstanceofCache();
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   // Record statistics before and after garbage collection.
   void ReportStatisticsBeforeGC();
   void ReportStatisticsAfterGC();
-#endif
 
   // Slow part of scavenge object.
   static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
@@ -1638,7 +1665,7 @@
   int* weak_global_handle_count;        // 15
   int* pending_global_handle_count;     // 16
   int* near_death_global_handle_count;  // 17
-  int* destroyed_global_handle_count;   // 18
+  int* free_global_handle_count;        // 18
   intptr_t* memory_allocator_size;           // 19
   intptr_t* memory_allocator_capacity;       // 20
   int* objects_per_type;                // 21
@@ -1906,6 +1933,7 @@
   void Clear();
 
   static const int kAbsent = -2;
+
  private:
   DescriptorLookupCache() {
     for (int i = 0; i < kLength; ++i) {
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 682bdb2..d282f37 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -669,7 +669,7 @@
 }
 
 
-void HClassOfTest::PrintDataTo(StringStream* stream) {
+void HClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
   stream->Add("class_of_test(");
   value()->PrintNameTo(stream);
   stream->Add(", \"%o\")", *class_name());
@@ -686,15 +686,13 @@
 
 
 void HControlInstruction::PrintDataTo(StringStream* stream) {
-  if (FirstSuccessor() != NULL) {
-    int first_id = FirstSuccessor()->block_id();
-    if (SecondSuccessor() == NULL) {
-      stream->Add(" B%d", first_id);
-    } else {
-      int second_id = SecondSuccessor()->block_id();
-      stream->Add(" goto (B%d, B%d)", first_id, second_id);
-    }
+  stream->Add(" goto (");
+  bool first_block = true;
+  for (HSuccessorIterator it(this); !it.Done(); it.Advance()) {
+    stream->Add(first_block ? "B%d" : ", B%d", it.Current()->block_id());
+    first_block = false;
   }
+  stream->Add(")");
 }
 
 
@@ -704,6 +702,11 @@
 }
 
 
+void HReturn::PrintDataTo(StringStream* stream) {
+  value()->PrintNameTo(stream);
+}
+
+
 void HCompareMap::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
   stream->Add(" (%p)", *map());
@@ -744,10 +747,10 @@
 }
 
 
-void HHasInstanceType::PrintDataTo(StringStream* stream) {
+void HHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
   switch (from_) {
-    case FIRST_JS_OBJECT_TYPE:
+    case FIRST_JS_RECEIVER_TYPE:
       if (to_ == LAST_TYPE) stream->Add(" spec_object");
       break;
     case JS_REGEXP_TYPE:
@@ -765,7 +768,7 @@
 }
 
 
-void HTypeofIs::PrintDataTo(StringStream* stream) {
+void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
   stream->Add(" == ");
   stream->Add(type_literal_->ToAsciiVector());
@@ -781,14 +784,28 @@
 }
 
 
+HValue* HCheckInstanceType::Canonicalize() {
+  if (check_ == IS_STRING &&
+      !value()->type().IsUninitialized() &&
+      value()->type().IsString()) {
+    return NULL;
+  }
+  if (check_ == IS_SYMBOL &&
+      value()->IsConstant() &&
+      HConstant::cast(value())->handle()->IsSymbol()) {
+    return NULL;
+  }
+  return this;
+}
+
+
 void HCheckInstanceType::GetCheckInterval(InstanceType* first,
                                           InstanceType* last) {
   ASSERT(is_interval_check());
   switch (check_) {
-    case IS_JS_OBJECT_OR_JS_FUNCTION:
-      STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE);
-      *first = FIRST_JS_OBJECT_TYPE;
-      *last = JS_FUNCTION_TYPE;
+    case IS_SPEC_OBJECT:
+      *first = FIRST_SPEC_OBJECT_TYPE;
+      *last = LAST_SPEC_OBJECT_TYPE;
       return;
     case IS_JS_ARRAY:
       *first = *last = JS_ARRAY_TYPE;
@@ -1084,6 +1101,16 @@
 }
 
 
+void HDeoptimize::PrintDataTo(StringStream* stream) {
+  if (OperandCount() == 0) return;
+  OperandAt(0)->PrintNameTo(stream);
+  for (int i = 1; i < OperandCount(); ++i) {
+    stream->Add(" ");
+    OperandAt(i)->PrintNameTo(stream);
+  }
+}
+
+
 void HEnterInlined::PrintDataTo(StringStream* stream) {
   SmartPointer<char> name = function()->debug_name()->ToCString();
   stream->Add("%s, id=%d", *name, function()->id());
@@ -1219,25 +1246,28 @@
 
 
 
-void HCompare::PrintDataTo(StringStream* stream) {
+void HCompareGeneric::PrintDataTo(StringStream* stream) {
   stream->Add(Token::Name(token()));
   stream->Add(" ");
   HBinaryOperation::PrintDataTo(stream);
 }
 
 
-void HCompare::SetInputRepresentation(Representation r) {
+void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add(Token::Name(token()));
+  stream->Add(" ");
+  left()->PrintNameTo(stream);
+  stream->Add(" ");
+  right()->PrintNameTo(stream);
+}
+
+
+void HCompareIDAndBranch::SetInputRepresentation(Representation r) {
   input_representation_ = r;
-  if (r.IsTagged()) {
-    SetAllSideEffects();
-    ClearFlag(kUseGVN);
-  } else if (r.IsDouble()) {
+  if (r.IsDouble()) {
     SetFlag(kDeoptimizeOnUndefined);
-    ClearAllSideEffects();
-    SetFlag(kUseGVN);
   } else {
-    ClearAllSideEffects();
-    SetFlag(kUseGVN);
+    ASSERT(r.IsInteger32());
   }
 }
 
@@ -1253,13 +1283,15 @@
 }
 
 
-HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* object,
+HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
+                                                       HValue* object,
                                                        ZoneMapList* types,
                                                        Handle<String> name)
-    : HUnaryOperation(object),
-      types_(Min(types->length(), kMaxLoadPolymorphism)),
+    : types_(Min(types->length(), kMaxLoadPolymorphism)),
       name_(name),
       need_generic_(false) {
+  SetOperandAt(0, context);
+  SetOperandAt(1, object);
   set_representation(Representation::Tagged());
   SetFlag(kDependsOnMaps);
   for (int i = 0;
@@ -1334,6 +1366,19 @@
 }
 
 
+void HLoadKeyedFastDoubleElement::PrintDataTo(StringStream* stream) {
+  elements()->PrintNameTo(stream);
+  stream->Add("[");
+  key()->PrintNameTo(stream);
+  stream->Add("]");
+}
+
+
+bool HLoadKeyedFastDoubleElement::RequiresHoleCheck() const {
+  return true;
+}
+
+
 void HLoadKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   stream->Add("[");
@@ -1346,34 +1391,40 @@
     StringStream* stream) {
   external_pointer()->PrintNameTo(stream);
   stream->Add(".");
-  switch (array_type()) {
-    case kExternalByteArray:
+  switch (elements_kind()) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
       stream->Add("byte");
       break;
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       stream->Add("u_byte");
       break;
-    case kExternalShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
       stream->Add("short");
       break;
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       stream->Add("u_short");
       break;
-    case kExternalIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
       stream->Add("int");
       break;
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       stream->Add("u_int");
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       stream->Add("float");
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       stream->Add("double");
       break;
-    case kExternalPixelArray:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       stream->Add("pixel");
       break;
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNREACHABLE();
+      break;
   }
   stream->Add("[");
   key()->PrintNameTo(stream);
@@ -1413,6 +1464,15 @@
 }
 
 
+void HStoreKeyedFastDoubleElement::PrintDataTo(StringStream* stream) {
+  elements()->PrintNameTo(stream);
+  stream->Add("[");
+  key()->PrintNameTo(stream);
+  stream->Add("] = ");
+  value()->PrintNameTo(stream);
+}
+
+
 void HStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   stream->Add("[");
@@ -1426,34 +1486,40 @@
     StringStream* stream) {
   external_pointer()->PrintNameTo(stream);
   stream->Add(".");
-  switch (array_type()) {
-    case kExternalByteArray:
+  switch (elements_kind()) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
       stream->Add("byte");
       break;
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       stream->Add("u_byte");
       break;
-    case kExternalShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
       stream->Add("short");
       break;
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       stream->Add("u_short");
       break;
-    case kExternalIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
       stream->Add("int");
       break;
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       stream->Add("u_int");
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       stream->Add("float");
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       stream->Add("double");
       break;
-    case kExternalPixelArray:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       stream->Add("pixel");
       break;
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNREACHABLE();
+      break;
   }
   stream->Add("[");
   key()->PrintNameTo(stream);
@@ -1542,17 +1608,22 @@
 }
 
 
-HType HCompare::CalculateInferredType() {
+HType HCompareGeneric::CalculateInferredType() {
   return HType::Boolean();
 }
 
 
-HType HCompareJSObjectEq::CalculateInferredType() {
+HType HInstanceOf::CalculateInferredType() {
   return HType::Boolean();
 }
 
 
-HType HUnaryPredicate::CalculateInferredType() {
+HType HDeleteProperty::CalculateInferredType() {
+  return HType::Boolean();
+}
+
+
+HType HInstanceOfKnownGlobal::CalculateInferredType() {
   return HType::Boolean();
 }
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 4d32edd..15186ff 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -35,6 +35,8 @@
 #include "data-flow.h"
 #include "small-pointer-list.h"
 #include "string-stream.h"
+#include "v8conversions.h"
+#include "v8utils.h"
 #include "zone.h"
 
 namespace v8 {
@@ -71,6 +73,7 @@
   V(BitXor)                                    \
   V(BlockEntry)                                \
   V(BoundsCheck)                               \
+  V(Branch)                                    \
   V(CallConstantFunction)                      \
   V(CallFunction)                              \
   V(CallGlobal)                                \
@@ -88,16 +91,18 @@
   V(CheckPrototypeMaps)                        \
   V(CheckSmi)                                  \
   V(ClampToUint8)                              \
-  V(ClassOfTest)                               \
-  V(Compare)                                   \
-  V(CompareJSObjectEq)                         \
+  V(ClassOfTestAndBranch)                      \
+  V(CompareIDAndBranch)                        \
+  V(CompareGeneric)                            \
+  V(CompareObjectEqAndBranch)                  \
   V(CompareMap)                                \
-  V(CompareSymbolEq)                           \
+  V(CompareConstantEqAndBranch)                \
   V(Constant)                                  \
   V(Context)                                   \
   V(DeleteProperty)                            \
   V(Deoptimize)                                \
   V(Div)                                       \
+  V(ElementsKind)                              \
   V(EnterInlined)                              \
   V(ExternalArrayLength)                       \
   V(FixedArrayLength)                          \
@@ -107,17 +112,17 @@
   V(GlobalObject)                              \
   V(GlobalReceiver)                            \
   V(Goto)                                      \
-  V(HasInstanceType)                           \
-  V(HasCachedArrayIndex)                       \
+  V(HasCachedArrayIndexAndBranch)              \
+  V(HasInstanceTypeAndBranch)                  \
   V(In)                                        \
   V(InstanceOf)                                \
   V(InstanceOfKnownGlobal)                     \
   V(InvokeFunction)                            \
-  V(IsConstructCall)                           \
-  V(IsNull)                                    \
-  V(IsObject)                                  \
-  V(IsSmi)                                     \
-  V(IsUndetectable)                            \
+  V(IsConstructCallAndBranch)                  \
+  V(IsNullAndBranch)                           \
+  V(IsObjectAndBranch)                         \
+  V(IsSmiAndBranch)                            \
+  V(IsUndetectableAndBranch)                   \
   V(JSArrayLength)                             \
   V(LeaveInlined)                              \
   V(LoadContextSlot)                           \
@@ -126,6 +131,7 @@
   V(LoadFunctionPrototype)                     \
   V(LoadGlobalCell)                            \
   V(LoadGlobalGeneric)                         \
+  V(LoadKeyedFastDoubleElement)                \
   V(LoadKeyedFastElement)                      \
   V(LoadKeyedGeneric)                          \
   V(LoadKeyedSpecializedArrayElement)          \
@@ -146,13 +152,15 @@
   V(Shl)                                       \
   V(Shr)                                       \
   V(Simulate)                                  \
+  V(SoftDeoptimize)                            \
   V(StackCheck)                                \
   V(StoreContextSlot)                          \
   V(StoreGlobalCell)                           \
   V(StoreGlobalGeneric)                        \
+  V(StoreKeyedFastDoubleElement)               \
   V(StoreKeyedFastElement)                     \
-  V(StoreKeyedSpecializedArrayElement)         \
   V(StoreKeyedGeneric)                         \
+  V(StoreKeyedSpecializedArrayElement)         \
   V(StoreNamedField)                           \
   V(StoreNamedGeneric)                         \
   V(StringAdd)                                 \
@@ -160,13 +168,15 @@
   V(StringCharFromCode)                        \
   V(StringLength)                              \
   V(Sub)                                       \
-  V(Test)                                      \
+  V(ThisFunction)                              \
   V(Throw)                                     \
   V(ToFastProperties)                          \
+  V(ToInt32)                                   \
   V(Typeof)                                    \
-  V(TypeofIs)                                  \
+  V(TypeofIsAndBranch)                         \
   V(UnaryMathOperation)                        \
   V(UnknownOSRValue)                           \
+  V(UseConst)                                  \
   V(ValueOf)
 
 #define GVN_FLAG_LIST(V)                       \
@@ -397,7 +407,7 @@
     kBoolean = 0x85,         // 0000 0000 1000 0101
     kNonPrimitive = 0x101,   // 0000 0001 0000 0001
     kJSObject = 0x301,       // 0000 0011 0000 0001
-    kJSArray = 0x701,        // 0000 0111 1000 0001
+    kJSArray = 0x701,        // 0000 0111 0000 0001
     kUninitialized = 0x1fff  // 0001 1111 1111 1111
   };
 
@@ -479,6 +489,10 @@
     GVN_FLAG_LIST(DECLARE_DO)
   #undef DECLARE_DO
     kFlexibleRepresentation,
+    // Participate in Global Value Numbering, i.e. elimination of
+    // unnecessary recomputations. If an instruction sets this flag, it must
+    // implement DataEquals(), which will be used to determine if other
+    // occurrences of the instruction are indeed the same.
     kUseGVN,
     kCanOverflow,
     kBailoutOnMinusZero,
@@ -576,9 +590,9 @@
   // it would otherwise output what should be a minus zero as an int32 zero.
   // If the operation also exists in a form that takes int32 and outputs int32
   // then the operation should return its input value so that we can propagate
-  // back.  There are two operations that need to propagate back to more than
-  // one input.  They are phi and binary add.  They always return NULL and
-  // expect the caller to take care of things.
+  // back.  There are three operations that need to propagate back to more than
+  // one input.  They are phi and binary div and mul.  They always return NULL
+  // and expect the caller to take care of things.
   virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
     visited->Add(id());
     return NULL;
@@ -723,10 +737,6 @@
   virtual void Verify();
 #endif
 
-  // Returns whether this is some kind of deoptimizing check
-  // instruction.
-  virtual bool IsCheckInstruction() const { return false; }
-
   virtual bool IsCall() { return false; }
 
   DECLARE_ABSTRACT_INSTRUCTION(Instruction)
@@ -757,53 +767,6 @@
 };
 
 
-class HControlInstruction: public HInstruction {
- public:
-  HControlInstruction(HBasicBlock* first, HBasicBlock* second)
-      : first_successor_(first), second_successor_(second) {
-  }
-
-  HBasicBlock* FirstSuccessor() const { return first_successor_; }
-  HBasicBlock* SecondSuccessor() const { return second_successor_; }
-
-  virtual void PrintDataTo(StringStream* stream);
-
-  DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
-
- private:
-  HBasicBlock* first_successor_;
-  HBasicBlock* second_successor_;
-};
-
-
-template<int NumElements>
-class HOperandContainer {
- public:
-  HOperandContainer() : elems_() { }
-
-  int length() { return NumElements; }
-  HValue*& operator[](int i) {
-    ASSERT(i < length());
-    return elems_[i];
-  }
-
- private:
-  HValue* elems_[NumElements];
-};
-
-
-template<>
-class HOperandContainer<0> {
- public:
-  int length() { return 0; }
-  HValue*& operator[](int i) {
-    UNREACHABLE();
-    static HValue* t = 0;
-    return t;
-  }
-};
-
-
 template<int V>
 class HTemplateInstruction : public HInstruction {
  public:
@@ -814,23 +777,61 @@
   void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
 
  private:
-  HOperandContainer<V> inputs_;
+  EmbeddedContainer<HValue*, V> inputs_;
 };
 
 
-template<int V>
-class HTemplateControlInstruction : public HControlInstruction {
+class HControlInstruction: public HInstruction {
  public:
-  HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
-    : HControlInstruction(first, second) { }
+  virtual HBasicBlock* SuccessorAt(int i) = 0;
+  virtual int SuccessorCount() = 0;
+  virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  HBasicBlock* FirstSuccessor() {
+    return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
+  }
+  HBasicBlock* SecondSuccessor() {
+    return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
+  }
+
+  DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
+};
+
+
+class HSuccessorIterator BASE_EMBEDDED {
+ public:
+  explicit HSuccessorIterator(HControlInstruction* instr)
+      : instr_(instr), current_(0) { }
+
+  bool Done() { return current_ >= instr_->SuccessorCount(); }
+  HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
+  void Advance() { current_++; }
+
+ private:
+  HControlInstruction* instr_;
+  int current_;
+};
+
+
+template<int S, int V>
+class HTemplateControlInstruction: public HControlInstruction {
+ public:
+  int SuccessorCount() { return S; }
+  HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
+  void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
+
   int OperandCount() { return V; }
   HValue* OperandAt(int i) { return inputs_[i]; }
 
+
  protected:
   void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
 
  private:
-  HOperandContainer<V> inputs_;
+  EmbeddedContainer<HBasicBlock*, S> successors_;
+  EmbeddedContainer<HValue*, V> inputs_;
 };
 
 
@@ -844,11 +845,22 @@
 };
 
 
+// We insert soft-deoptimize when we hit code with unknown typefeedback,
+// so that we get a chance of re-optimizing with useful typefeedback.
+// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
+class HSoftDeoptimize: public HTemplateInstruction<0> {
+ public:
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::None();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
+};
+
+
 class HDeoptimize: public HControlInstruction {
  public:
-  explicit HDeoptimize(int environment_length)
-      : HControlInstruction(NULL, NULL),
-        values_(environment_length) { }
+  explicit HDeoptimize(int environment_length) : values_(environment_length) { }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::None();
@@ -856,6 +868,16 @@
 
   virtual int OperandCount() { return values_.length(); }
   virtual HValue* OperandAt(int index) { return values_[index]; }
+  virtual void PrintDataTo(StringStream* stream);
+
+  virtual int SuccessorCount() { return 0; }
+  virtual HBasicBlock* SuccessorAt(int i) {
+    UNREACHABLE();
+    return NULL;
+  }
+  virtual void SetSuccessorAt(int i, HBasicBlock* block) {
+    UNREACHABLE();
+  }
 
   void AddEnvironmentValue(HValue* value) {
     values_.Add(NULL);
@@ -879,35 +901,28 @@
 };
 
 
-class HGoto: public HTemplateControlInstruction<0> {
+class HGoto: public HTemplateControlInstruction<1, 0> {
  public:
-  explicit HGoto(HBasicBlock* target)
-      : HTemplateControlInstruction<0>(target, NULL),
-        include_stack_check_(false) { }
-
-  void set_include_stack_check(bool include_stack_check) {
-    include_stack_check_ = include_stack_check;
-  }
-  bool include_stack_check() const { return include_stack_check_; }
+  explicit HGoto(HBasicBlock* target) {
+        SetSuccessorAt(0, target);
+      }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::None();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Goto)
-
- private:
-  bool include_stack_check_;
 };
 
 
-class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
+class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
  public:
-  explicit HUnaryControlInstruction(HValue* value,
-                                    HBasicBlock* true_target,
-                                    HBasicBlock* false_target)
-      : HTemplateControlInstruction<1>(true_target, false_target) {
+  HUnaryControlInstruction(HValue* value,
+                           HBasicBlock* true_target,
+                           HBasicBlock* false_target) {
     SetOperandAt(0, value);
+    SetSuccessorAt(0, true_target);
+    SetSuccessorAt(1, false_target);
   }
 
   virtual void PrintDataTo(StringStream* stream);
@@ -916,18 +931,21 @@
 };
 
 
-class HTest: public HUnaryControlInstruction {
+class HBranch: public HUnaryControlInstruction {
  public:
-  HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
+  HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
       : HUnaryControlInstruction(value, true_target, false_target) {
     ASSERT(true_target != NULL && false_target != NULL);
   }
+  explicit HBranch(HValue* value)
+      : HUnaryControlInstruction(value, NULL, NULL) { }
+
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::None();
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(Test)
+  DECLARE_CONCRETE_INSTRUCTION(Branch)
 };
 
 
@@ -959,24 +977,26 @@
 };
 
 
-class HReturn: public HUnaryControlInstruction {
+class HReturn: public HTemplateControlInstruction<0, 1> {
  public:
-  explicit HReturn(HValue* value)
-      : HUnaryControlInstruction(value, NULL, NULL) {
+  explicit HReturn(HValue* value) {
+    SetOperandAt(0, value);
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
+  virtual void PrintDataTo(StringStream* stream);
+
+  HValue* value() { return OperandAt(0); }
+
   DECLARE_CONCRETE_INSTRUCTION(Return)
 };
 
 
-class HAbnormalExit: public HTemplateControlInstruction<0> {
+class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
  public:
-  HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::None();
   }
@@ -991,14 +1011,24 @@
     SetOperandAt(0, value);
   }
 
+  static HUnaryOperation* cast(HValue* value) {
+    return reinterpret_cast<HUnaryOperation*>(value);
+  }
+
+  virtual bool CanTruncateToInt32() const {
+    return CheckFlag(kTruncatingToInt32);
+  }
+
   HValue* value() { return OperandAt(0); }
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class HThrow: public HUnaryOperation {
+class HThrow: public HTemplateInstruction<2> {
  public:
-  explicit HThrow(HValue* value) : HUnaryOperation(value) {
+  HThrow(HValue* context, HValue* value) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, value);
     SetAllSideEffects();
   }
 
@@ -1006,10 +1036,25 @@
     return Representation::Tagged();
   }
 
+  HValue* context() { return OperandAt(0); }
+  HValue* value() { return OperandAt(1); }
+
   DECLARE_CONCRETE_INSTRUCTION(Throw)
 };
 
 
+class HUseConst: public HUnaryOperation {
+ public:
+  explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::None();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(UseConst)
+};
+
+
 class HForceRepresentation: public HTemplateInstruction<1> {
  public:
   HForceRepresentation(HValue* value, Representation required_representation) {
@@ -1059,8 +1104,6 @@
     return from_;
   }
 
-  bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
-
   virtual void PrintDataTo(StringStream* stream);
 
   DECLARE_CONCRETE_INSTRUCTION(Change)
@@ -1069,8 +1112,7 @@
   virtual bool DataEquals(HValue* other) {
     if (!other->IsChange()) return false;
     HChange* change = HChange::cast(other);
-    return value() == change->value()
-        && to().Equals(change->to())
+    return to().Equals(change->to())
         && deoptimize_on_undefined() == change->deoptimize_on_undefined();
   }
 
@@ -1083,40 +1125,50 @@
 class HClampToUint8: public HUnaryOperation {
  public:
   explicit HClampToUint8(HValue* value)
-      : HUnaryOperation(value),
-        input_rep_(Representation::None()) {
-    SetFlag(kFlexibleRepresentation);
-    set_representation(Representation::Tagged());
+      : HUnaryOperation(value) {
+    set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    return input_rep_;
-  }
-
-  virtual Representation InferredRepresentation() {
-    // TODO(danno): Inference on input types should happen separately from
-    // return representation.
-    Representation new_rep = value()->representation();
-    if (input_rep_.IsNone()) {
-      if (!new_rep.IsNone()) {
-        input_rep_ = new_rep;
-        return Representation::Integer32();
-      } else {
-        return Representation::None();
-      }
-    } else {
-      return Representation::Integer32();
-    }
+    return Representation::None();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
 
  protected:
   virtual bool DataEquals(HValue* other) { return true; }
+};
 
- private:
-  Representation input_rep_;
+
+class HToInt32: public HUnaryOperation {
+ public:
+  explicit HToInt32(HValue* value)
+      : HUnaryOperation(value) {
+    set_representation(Representation::Integer32());
+    SetFlag(kUseGVN);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::None();
+  }
+
+  virtual bool CanTruncateToInt32() const {
+    return true;
+  }
+
+  virtual HValue* Canonicalize() {
+    if (value()->representation().IsInteger32()) {
+      return value();
+    } else {
+      return this;
+    }
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(ToInt32)
+
+ protected:
+  virtual bool DataEquals(HValue* other) { return true; }
 };
 
 
@@ -1188,15 +1240,38 @@
 };
 
 
-class HStackCheck: public HTemplateInstruction<0> {
+class HStackCheck: public HTemplateInstruction<1> {
  public:
-  HStackCheck() { }
+  enum Type {
+    kFunctionEntry,
+    kBackwardsBranch
+  };
 
-  virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::None();
+  HStackCheck(HValue* context, Type type) : type_(type) {
+    SetOperandAt(0, context);
   }
 
+  HValue* context() { return OperandAt(0); }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
+
+  void Eliminate() {
+    // The stack check eliminator might try to eliminate the same stack
+    // check instruction multiple times.
+    if (IsLinked()) {
+      DeleteFromGraph();
+    }
+  }
+
+  bool is_function_entry() { return type_ == kFunctionEntry; }
+  bool is_backwards_branch() { return type_ == kBackwardsBranch; }
+
   DECLARE_CONCRETE_INSTRUCTION(StackCheck)
+
+ private:
+  Type type_;
 };
 
 
@@ -1257,6 +1332,24 @@
 };
 
 
+class HThisFunction: public HTemplateInstruction<0> {
+ public:
+  HThisFunction() {
+    set_representation(Representation::Tagged());
+    SetFlag(kUseGVN);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::None();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
+
+ protected:
+  virtual bool DataEquals(HValue* other) { return true; }
+};
+
+
 class HContext: public HTemplateInstruction<0> {
  public:
   HContext() {
@@ -1268,7 +1361,7 @@
     return Representation::None();
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(Context);
+  DECLARE_CONCRETE_INSTRUCTION(Context)
 
  protected:
   virtual bool DataEquals(HValue* other) { return true; }
@@ -1542,19 +1635,24 @@
 };
 
 
-class HCallRuntime: public HCall<0> {
+class HCallRuntime: public HCall<1> {
  public:
-  HCallRuntime(Handle<String> name,
+  HCallRuntime(HValue* context,
+               Handle<String> name,
                const Runtime::Function* c_function,
                int argument_count)
-      : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
+      : HCall<1>(argument_count), c_function_(c_function), name_(name) {
+    SetOperandAt(0, context);
+  }
+
   virtual void PrintDataTo(StringStream* stream);
 
+  HValue* context() { return OperandAt(0); }
   const Runtime::Function* function() const { return c_function_; }
   Handle<String> name() const { return name_; }
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::None();
+    return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
@@ -1628,6 +1726,25 @@
 };
 
 
+class HElementsKind: public HUnaryOperation {
+ public:
+  explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
+    set_representation(Representation::Integer32());
+    SetFlag(kUseGVN);
+    SetFlag(kDependsOnMaps);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
+
+ protected:
+  virtual bool DataEquals(HValue* other) { return true; }
+};
+
+
 class HBitNot: public HUnaryOperation {
  public:
   explicit HBitNot(HValue* value) : HUnaryOperation(value) {
@@ -1648,10 +1765,12 @@
 };
 
 
-class HUnaryMathOperation: public HUnaryOperation {
+class HUnaryMathOperation: public HTemplateInstruction<2> {
  public:
-  HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
-      : HUnaryOperation(value), op_(op) {
+  HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
+      : op_(op) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, value);
     switch (op) {
       case kMathFloor:
       case kMathRound:
@@ -1675,6 +1794,9 @@
     SetFlag(kUseGVN);
   }
 
+  HValue* context() { return OperandAt(0); }
+  HValue* value() { return OperandAt(1); }
+
   virtual void PrintDataTo(StringStream* stream);
 
   virtual HType CalculateInferredType();
@@ -1682,21 +1804,25 @@
   virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    switch (op_) {
-      case kMathFloor:
-      case kMathRound:
-      case kMathCeil:
-      case kMathSqrt:
-      case kMathPowHalf:
-      case kMathLog:
-      case kMathSin:
-      case kMathCos:
-        return Representation::Double();
-      case kMathAbs:
-        return representation();
-      default:
-        UNREACHABLE();
-        return Representation::None();
+    if (index == 0) {
+      return Representation::Tagged();
+    } else {
+      switch (op_) {
+        case kMathFloor:
+        case kMathRound:
+        case kMathCeil:
+        case kMathSqrt:
+        case kMathPowHalf:
+        case kMathLog:
+        case kMathSin:
+        case kMathCos:
+          return Representation::Double();
+        case kMathAbs:
+          return representation();
+        default:
+          UNREACHABLE();
+          return Representation::None();
+      }
     }
   }
 
@@ -1777,8 +1903,6 @@
     SetFlag(kDependsOnMaps);
   }
 
-  virtual bool IsCheckInstruction() const { return true; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
@@ -1812,8 +1936,6 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsCheckInstruction() const { return true; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
@@ -1841,8 +1963,8 @@
 
 class HCheckInstanceType: public HUnaryOperation {
  public:
-  static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value) {
-    return new HCheckInstanceType(value, IS_JS_OBJECT_OR_JS_FUNCTION);
+  static HCheckInstanceType* NewIsSpecObject(HValue* value) {
+    return new HCheckInstanceType(value, IS_SPEC_OBJECT);
   }
   static HCheckInstanceType* NewIsJSArray(HValue* value) {
     return new HCheckInstanceType(value, IS_JS_ARRAY);
@@ -1854,8 +1976,6 @@
     return new HCheckInstanceType(value, IS_SYMBOL);
   }
 
-  virtual bool IsCheckInstruction() const { return true; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
@@ -1864,14 +1984,7 @@
   virtual void Verify();
 #endif
 
-  virtual HValue* Canonicalize() {
-    if (!value()->type().IsUninitialized() &&
-        value()->type().IsString() &&
-        check_ == IS_STRING) {
-      return NULL;
-    }
-    return this;
-  }
+  virtual HValue* Canonicalize();
 
   bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
   void GetCheckInterval(InstanceType* first, InstanceType* last);
@@ -1890,7 +2003,7 @@
 
  private:
   enum Check {
-    IS_JS_OBJECT_OR_JS_FUNCTION,
+    IS_SPEC_OBJECT,
     IS_JS_ARRAY,
     IS_STRING,
     IS_SYMBOL,
@@ -1914,8 +2027,6 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsCheckInstruction() const { return true; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
@@ -1953,8 +2064,6 @@
     SetFlag(kDependsOnMaps);
   }
 
-  virtual bool IsCheckInstruction() const { return true; }
-
 #ifdef DEBUG
   virtual void Verify();
 #endif
@@ -1995,8 +2104,6 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsCheckInstruction() const { return true; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
@@ -2211,16 +2318,18 @@
 };
 
 
-class HBinaryOperation: public HTemplateInstruction<2> {
+class HBinaryOperation: public HTemplateInstruction<3> {
  public:
-  HBinaryOperation(HValue* left, HValue* right) {
+  HBinaryOperation(HValue* context, HValue* left, HValue* right) {
     ASSERT(left != NULL && right != NULL);
-    SetOperandAt(0, left);
-    SetOperandAt(1, right);
+    SetOperandAt(0, context);
+    SetOperandAt(1, left);
+    SetOperandAt(2, right);
   }
 
-  HValue* left() { return OperandAt(0); }
-  HValue* right() { return OperandAt(1); }
+  HValue* context() { return OperandAt(0); }
+  HValue* left() { return OperandAt(1); }
+  HValue* right() { return OperandAt(2); }
 
   // TODO(kasperl): Move these helpers to the IA-32 Lithium
   // instruction sequence builder.
@@ -2336,16 +2445,15 @@
 };
 
 
-class HBoundsCheck: public HBinaryOperation {
+class HBoundsCheck: public HTemplateInstruction<2> {
  public:
-  HBoundsCheck(HValue* index, HValue* length)
-      : HBinaryOperation(index, length) {
+  HBoundsCheck(HValue* index, HValue* length) {
+    SetOperandAt(0, index);
+    SetOperandAt(1, length);
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsCheckInstruction() const { return true; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Integer32();
   }
@@ -2354,8 +2462,8 @@
   virtual void Verify();
 #endif
 
-  HValue* index() { return left(); }
-  HValue* length() { return right(); }
+  HValue* index() { return OperandAt(0); }
+  HValue* length() { return OperandAt(1); }
 
   DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
 
@@ -2366,15 +2474,17 @@
 
 class HBitwiseBinaryOperation: public HBinaryOperation {
  public:
-  HBitwiseBinaryOperation(HValue* left, HValue* right)
-      : HBinaryOperation(left, right) {
+  HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
+      : HBinaryOperation(context, left, right) {
     set_representation(Representation::Tagged());
     SetFlag(kFlexibleRepresentation);
     SetAllSideEffects();
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    return representation();
+    return index == 0
+        ? Representation::Tagged()
+        : representation();
   }
 
   virtual void RepresentationChanged(Representation to) {
@@ -2394,8 +2504,8 @@
 
 class HArithmeticBinaryOperation: public HBinaryOperation {
  public:
-  HArithmeticBinaryOperation(HValue* left, HValue* right)
-      : HBinaryOperation(left, right) {
+  HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
+      : HBinaryOperation(context, left, right) {
     set_representation(Representation::Tagged());
     SetFlag(kFlexibleRepresentation);
     SetAllSideEffects();
@@ -2410,8 +2520,11 @@
 
   virtual HType CalculateInferredType();
   virtual Representation RequiredInputRepresentation(int index) const {
-    return representation();
+    return index == 0
+        ? Representation::Tagged()
+        : representation();
   }
+
   virtual Representation InferredRepresentation() {
     if (left()->representation().Equals(right()->representation())) {
       return left()->representation();
@@ -2421,208 +2534,186 @@
 };
 
 
-class HCompare: public HBinaryOperation {
+class HCompareGeneric: public HBinaryOperation {
  public:
-  HCompare(HValue* left, HValue* right, Token::Value token)
-      : HBinaryOperation(left, right), token_(token) {
+  HCompareGeneric(HValue* context,
+                  HValue* left,
+                  HValue* right,
+                  Token::Value token)
+      : HBinaryOperation(context, left, right), token_(token) {
     ASSERT(Token::IsCompareOp(token));
     set_representation(Representation::Tagged());
     SetAllSideEffects();
   }
 
-  void SetInputRepresentation(Representation r);
-
-  virtual bool EmitAtUses() {
-    return !HasSideEffects() && !HasMultipleUses();
-  }
-
   virtual Representation RequiredInputRepresentation(int index) const {
-    return input_representation_;
+    return Representation::Tagged();
   }
+
   Representation GetInputRepresentation() const {
-    return input_representation_;
+    return Representation::Tagged();
   }
+
   Token::Value token() const { return token_; }
   virtual void PrintDataTo(StringStream* stream);
 
   virtual HType CalculateInferredType();
 
-  virtual intptr_t Hashcode() {
-    return HValue::Hashcode() * 7 + token_;
+  DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
+
+ private:
+  Token::Value token_;
+};
+
+
+class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
+ public:
+  HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
+      : token_(token) {
+    ASSERT(Token::IsCompareOp(token));
+    SetOperandAt(0, left);
+    SetOperandAt(1, right);
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(Compare)
+  HValue* left() { return OperandAt(0); }
+  HValue* right() { return OperandAt(1); }
+  Token::Value token() const { return token_; }
 
- protected:
-  virtual bool DataEquals(HValue* other) {
-    HCompare* comp = HCompare::cast(other);
-    return token_ == comp->token();
+  void SetInputRepresentation(Representation r);
+  Representation GetInputRepresentation() const {
+    return input_representation_;
   }
 
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return input_representation_;
+  }
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
+
  private:
   Representation input_representation_;
   Token::Value token_;
 };
 
 
-class HCompareJSObjectEq: public HBinaryOperation {
+class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
  public:
-  HCompareJSObjectEq(HValue* left, HValue* right)
-      : HBinaryOperation(left, right) {
-    set_representation(Representation::Tagged());
-    SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+  HCompareObjectEqAndBranch(HValue* left, HValue* right) {
+    SetOperandAt(0, left);
+    SetOperandAt(1, right);
   }
 
-  virtual bool EmitAtUses() {
-    return !HasSideEffects() && !HasMultipleUses();
-  }
+  HValue* left() { return OperandAt(0); }
+  HValue* right() { return OperandAt(1); }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
-  virtual HType CalculateInferredType();
 
-  DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
-
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
+  DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
 };
 
 
-class HCompareSymbolEq: public HBinaryOperation {
+class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
  public:
-  HCompareSymbolEq(HValue* left, HValue* right, Token::Value op)
-      : HBinaryOperation(left, right), op_(op) {
-    ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
-    set_representation(Representation::Tagged());
-    SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+  HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
+      : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
+    ASSERT(op == Token::EQ_STRICT);
   }
 
   Token::Value op() const { return op_; }
-
-  virtual bool EmitAtUses() {
-    return !HasSideEffects() && !HasMultipleUses();
-  }
+  HValue* left() { return value(); }
+  int right() const { return right_; }
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::Tagged();
+    return Representation::Integer32();
   }
 
-  virtual HType CalculateInferredType() { return HType::Boolean(); }
-
-  DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq);
-
- protected:
-  virtual bool DataEquals(HValue* other) {
-    return op_ == HCompareSymbolEq::cast(other)->op_;
-  }
+  DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
 
  private:
   const Token::Value op_;
+  const int right_;
 };
 
 
-class HUnaryPredicate: public HUnaryOperation {
+class HIsNullAndBranch: public HUnaryControlInstruction {
  public:
-  explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
-    set_representation(Representation::Tagged());
-    SetFlag(kUseGVN);
-  }
+  HIsNullAndBranch(HValue* value, bool is_strict)
+      : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
 
-  virtual bool EmitAtUses() {
-    return !HasSideEffects() && !HasMultipleUses();
-  }
+  bool is_strict() const { return is_strict_; }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
-  virtual HType CalculateInferredType();
-};
 
-
-class HIsNull: public HUnaryPredicate {
- public:
-  HIsNull(HValue* value, bool is_strict)
-      : HUnaryPredicate(value), is_strict_(is_strict) { }
-
-  bool is_strict() const { return is_strict_; }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsNull)
-
- protected:
-  virtual bool DataEquals(HValue* other) {
-    HIsNull* b = HIsNull::cast(other);
-    return is_strict_ == b->is_strict();
-  }
+  DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
 
  private:
   bool is_strict_;
 };
 
 
-class HIsObject: public HUnaryPredicate {
+class HIsObjectAndBranch: public HUnaryControlInstruction {
  public:
-  explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
+  explicit HIsObjectAndBranch(HValue* value)
+    : HUnaryControlInstruction(value, NULL, NULL) { }
 
-  DECLARE_CONCRETE_INSTRUCTION(IsObject)
-
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
-};
-
-
-class HIsSmi: public HUnaryPredicate {
- public:
-  explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsSmi)
-
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
-};
-
-
-class HIsUndetectable: public HUnaryPredicate {
- public:
-  explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
-
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
-};
-
-
-class HIsConstructCall: public HTemplateInstruction<0> {
- public:
-  HIsConstructCall() {
-    set_representation(Representation::Tagged());
-    SetFlag(kUseGVN);
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
   }
 
-  virtual bool EmitAtUses() {
-    return !HasSideEffects() && !HasMultipleUses();
+  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
+};
+
+
+class HIsSmiAndBranch: public HUnaryControlInstruction {
+ public:
+  explicit HIsSmiAndBranch(HValue* value)
+      : HUnaryControlInstruction(value, NULL, NULL) { }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
   }
 
+ protected:
+  virtual bool DataEquals(HValue* other) { return true; }
+};
+
+
+class HIsUndetectableAndBranch: public HUnaryControlInstruction {
+ public:
+  explicit HIsUndetectableAndBranch(HValue* value)
+      : HUnaryControlInstruction(value, NULL, NULL) { }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
+};
+
+
+class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
+ public:
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::None();
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
-
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
+  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
 };
 
 
-class HHasInstanceType: public HUnaryPredicate {
+class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
  public:
-  HHasInstanceType(HValue* value, InstanceType type)
-      : HUnaryPredicate(value), from_(type), to_(type) { }
-  HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
-      : HUnaryPredicate(value), from_(from), to_(to) {
+  HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
+      : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
+  HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
+      : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
     ASSERT(to == LAST_TYPE);  // Others not implemented yet in backend.
   }
 
@@ -2631,34 +2722,41 @@
 
   virtual void PrintDataTo(StringStream* stream);
 
-  DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
-
- protected:
-  virtual bool DataEquals(HValue* other) {
-    HHasInstanceType* b = HHasInstanceType::cast(other);
-    return (from_ == b->from()) && (to_ == b->to());
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
   }
 
+  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
+
  private:
   InstanceType from_;
   InstanceType to_;  // Inclusive range, not all combinations work.
 };
 
 
-class HHasCachedArrayIndex: public HUnaryPredicate {
+class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
  public:
-  explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
+  explicit HHasCachedArrayIndexAndBranch(HValue* value)
+      : HUnaryControlInstruction(value, NULL, NULL) { }
 
-  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
 
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
+  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
 };
 
 
-class HGetCachedArrayIndex: public HUnaryPredicate {
+class HGetCachedArrayIndex: public HUnaryOperation {
  public:
-  explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
+  explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
+    set_representation(Representation::Tagged());
+    SetFlag(kUseGVN);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
 
   DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
 
@@ -2667,42 +2765,40 @@
 };
 
 
-class HClassOfTest: public HUnaryPredicate {
+class HClassOfTestAndBranch: public HUnaryControlInstruction {
  public:
-  HClassOfTest(HValue* value, Handle<String> class_name)
-      : HUnaryPredicate(value), class_name_(class_name) { }
+  HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
+      : HUnaryControlInstruction(value, NULL, NULL),
+        class_name_(class_name) { }
 
-  DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
+  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
 
   virtual void PrintDataTo(StringStream* stream);
 
   Handle<String> class_name() const { return class_name_; }
 
- protected:
-  virtual bool DataEquals(HValue* other) {
-    HClassOfTest* b = HClassOfTest::cast(other);
-    return class_name_.is_identical_to(b->class_name_);
-  }
-
  private:
   Handle<String> class_name_;
 };
 
 
-class HTypeofIs: public HUnaryPredicate {
+class HTypeofIsAndBranch: public HUnaryControlInstruction {
  public:
-  HTypeofIs(HValue* value, Handle<String> type_literal)
-      : HUnaryPredicate(value), type_literal_(type_literal) { }
+  HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
+      : HUnaryControlInstruction(value, NULL, NULL),
+        type_literal_(type_literal) { }
 
   Handle<String> type_literal() { return type_literal_; }
   virtual void PrintDataTo(StringStream* stream);
 
-  DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
+  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
 
- protected:
-  virtual bool DataEquals(HValue* other) {
-    HTypeofIs* b = HTypeofIs::cast(other);
-    return type_literal_.is_identical_to(b->type_literal_);
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
   }
 
  private:
@@ -2710,48 +2806,48 @@
 };
 
 
-class HInstanceOf: public HTemplateInstruction<3> {
+class HInstanceOf: public HBinaryOperation {
  public:
-  HInstanceOf(HValue* context, HValue* left, HValue* right) {
-    SetOperandAt(0, context);
-    SetOperandAt(1, left);
-    SetOperandAt(2, right);
+  HInstanceOf(HValue* context, HValue* left, HValue* right)
+      : HBinaryOperation(context, left, right) {
     set_representation(Representation::Tagged());
     SetAllSideEffects();
   }
 
-  HValue* context() { return OperandAt(0); }
-  HValue* left() { return OperandAt(1); }
-  HValue* right() { return OperandAt(2); }
-
-  virtual bool EmitAtUses() {
-    return !HasSideEffects() && !HasMultipleUses();
-  }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
+  virtual HType CalculateInferredType();
+
   virtual void PrintDataTo(StringStream* stream);
 
   DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
 };
 
 
-class HInstanceOfKnownGlobal: public HUnaryOperation {
+class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
  public:
-  HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
-      : HUnaryOperation(left), function_(right) {
+  HInstanceOfKnownGlobal(HValue* context,
+                         HValue* left,
+                         Handle<JSFunction> right)
+      : function_(right) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, left);
     set_representation(Representation::Tagged());
     SetAllSideEffects();
   }
 
+  HValue* context() { return OperandAt(0); }
+  HValue* left() { return OperandAt(1); }
   Handle<JSFunction> function() { return function_; }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
+  virtual HType CalculateInferredType();
+
   DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
 
  private:
@@ -2759,16 +2855,22 @@
 };
 
 
-class HPower: public HBinaryOperation {
+class HPower: public HTemplateInstruction<2> {
  public:
-  HPower(HValue* left, HValue* right)
-      : HBinaryOperation(left, right) {
+  HPower(HValue* left, HValue* right) {
+    SetOperandAt(0, left);
+    SetOperandAt(1, right);
     set_representation(Representation::Double());
     SetFlag(kUseGVN);
   }
 
+  HValue* left() { return OperandAt(0); }
+  HValue* right() { return OperandAt(1); }
+
   virtual Representation RequiredInputRepresentation(int index) const {
-    return (index == 1) ? Representation::None() : Representation::Double();
+    return index == 0
+      ? Representation::Double()
+      : Representation::None();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Power)
@@ -2780,7 +2882,8 @@
 
 class HAdd: public HArithmeticBinaryOperation {
  public:
-  HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+  HAdd(HValue* context, HValue* left, HValue* right)
+      : HArithmeticBinaryOperation(context, left, right) {
     SetFlag(kCanOverflow);
   }
 
@@ -2805,7 +2908,8 @@
 
 class HSub: public HArithmeticBinaryOperation {
  public:
-  HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+  HSub(HValue* context, HValue* left, HValue* right)
+      : HArithmeticBinaryOperation(context, left, right) {
     SetFlag(kCanOverflow);
   }
 
@@ -2822,7 +2926,8 @@
 
 class HMul: public HArithmeticBinaryOperation {
  public:
-  HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+  HMul(HValue* context, HValue* left, HValue* right)
+      : HArithmeticBinaryOperation(context, left, right) {
     SetFlag(kCanOverflow);
   }
 
@@ -2844,7 +2949,8 @@
 
 class HMod: public HArithmeticBinaryOperation {
  public:
-  HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+  HMod(HValue* context, HValue* left, HValue* right)
+      : HArithmeticBinaryOperation(context, left, right) {
     SetFlag(kCanBeDivByZero);
   }
 
@@ -2871,7 +2977,8 @@
 
 class HDiv: public HArithmeticBinaryOperation {
  public:
-  HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+  HDiv(HValue* context, HValue* left, HValue* right)
+      : HArithmeticBinaryOperation(context, left, right) {
     SetFlag(kCanBeDivByZero);
     SetFlag(kCanOverflow);
   }
@@ -2889,8 +2996,8 @@
 
 class HBitAnd: public HBitwiseBinaryOperation {
  public:
-  HBitAnd(HValue* left, HValue* right)
-      : HBitwiseBinaryOperation(left, right) { }
+  HBitAnd(HValue* context, HValue* left, HValue* right)
+      : HBitwiseBinaryOperation(context, left, right) { }
 
   virtual bool IsCommutative() const { return true; }
   virtual HType CalculateInferredType();
@@ -2906,8 +3013,8 @@
 
 class HBitXor: public HBitwiseBinaryOperation {
  public:
-  HBitXor(HValue* left, HValue* right)
-      : HBitwiseBinaryOperation(left, right) { }
+  HBitXor(HValue* context, HValue* left, HValue* right)
+      : HBitwiseBinaryOperation(context, left, right) { }
 
   virtual bool IsCommutative() const { return true; }
   virtual HType CalculateInferredType();
@@ -2921,8 +3028,8 @@
 
 class HBitOr: public HBitwiseBinaryOperation {
  public:
-  HBitOr(HValue* left, HValue* right)
-      : HBitwiseBinaryOperation(left, right) { }
+  HBitOr(HValue* context, HValue* left, HValue* right)
+      : HBitwiseBinaryOperation(context, left, right) { }
 
   virtual bool IsCommutative() const { return true; }
   virtual HType CalculateInferredType();
@@ -2938,8 +3045,8 @@
 
 class HShl: public HBitwiseBinaryOperation {
  public:
-  HShl(HValue* left, HValue* right)
-      : HBitwiseBinaryOperation(left, right) { }
+  HShl(HValue* context, HValue* left, HValue* right)
+      : HBitwiseBinaryOperation(context, left, right) { }
 
   virtual Range* InferRange();
   virtual HType CalculateInferredType();
@@ -2953,8 +3060,8 @@
 
 class HShr: public HBitwiseBinaryOperation {
  public:
-  HShr(HValue* left, HValue* right)
-      : HBitwiseBinaryOperation(left, right) { }
+  HShr(HValue* context, HValue* left, HValue* right)
+      : HBitwiseBinaryOperation(context, left, right) { }
 
   virtual HType CalculateInferredType();
 
@@ -2967,8 +3074,8 @@
 
 class HSar: public HBitwiseBinaryOperation {
  public:
-  HSar(HValue* left, HValue* right)
-      : HBitwiseBinaryOperation(left, right) { }
+  HSar(HValue* context, HValue* left, HValue* right)
+      : HBitwiseBinaryOperation(context, left, right) { }
 
   virtual Range* InferRange();
   virtual HType CalculateInferredType();
@@ -3102,15 +3209,16 @@
 };
 
 
-class HLoadGlobalGeneric: public HBinaryOperation {
+class HLoadGlobalGeneric: public HTemplateInstruction<2> {
  public:
   HLoadGlobalGeneric(HValue* context,
                      HValue* global_object,
                      Handle<Object> name,
                      bool for_typeof)
-      : HBinaryOperation(context, global_object),
-        name_(name),
+      : name_(name),
         for_typeof_(for_typeof) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, global_object);
     set_representation(Representation::Tagged());
     SetAllSideEffects();
   }
@@ -3228,15 +3336,18 @@
 
 
 static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
-  return !value->type().IsSmi() &&
-      !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
+  return !value->type().IsBoolean()
+      && !value->type().IsSmi()
+      && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
 }
 
 
-class HStoreContextSlot: public HBinaryOperation {
+class HStoreContextSlot: public HTemplateInstruction<2> {
  public:
   HStoreContextSlot(HValue* context, int slot_index, HValue* value)
-      : HBinaryOperation(context, value), slot_index_(slot_index) {
+      : slot_index_(slot_index) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, value);
     SetFlag(kChangesContextSlots);
   }
 
@@ -3300,13 +3411,15 @@
 };
 
 
-class HLoadNamedFieldPolymorphic: public HUnaryOperation {
+class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
  public:
-  HLoadNamedFieldPolymorphic(HValue* object,
+  HLoadNamedFieldPolymorphic(HValue* context,
+                             HValue* object,
                              ZoneMapList* types,
                              Handle<String> name);
 
-  HValue* object() { return OperandAt(0); }
+  HValue* context() { return OperandAt(0); }
+  HValue* object() { return OperandAt(1); }
   ZoneMapList* types() { return &types_; }
   Handle<String> name() { return name_; }
   bool need_generic() { return need_generic_; }
@@ -3330,10 +3443,12 @@
 
 
 
-class HLoadNamedGeneric: public HBinaryOperation {
+class HLoadNamedGeneric: public HTemplateInstruction<2> {
  public:
   HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
-      : HBinaryOperation(context, object), name_(name) {
+      : name_(name) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, object);
     set_representation(Representation::Tagged());
     SetAllSideEffects();
   }
@@ -3375,9 +3490,11 @@
 };
 
 
-class HLoadKeyedFastElement: public HBinaryOperation {
+class HLoadKeyedFastElement: public HTemplateInstruction<2> {
  public:
-  HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
+  HLoadKeyedFastElement(HValue* obj, HValue* key) {
+    SetOperandAt(0, obj);
+    SetOperandAt(1, key);
     set_representation(Representation::Tagged());
     SetFlag(kDependsOnArrayElements);
     SetFlag(kUseGVN);
@@ -3388,8 +3505,9 @@
 
   virtual Representation RequiredInputRepresentation(int index) const {
     // The key is supposed to be Integer32.
-    return (index == 1) ? Representation::Integer32()
-        : Representation::Tagged();
+    return index == 0
+      ? Representation::Tagged()
+      : Representation::Integer32();
   }
 
   virtual void PrintDataTo(StringStream* stream);
@@ -3403,15 +3521,47 @@
 };
 
 
-class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
+class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
+ public:
+  HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
+    SetOperandAt(0, elements);
+    SetOperandAt(1, key);
+    set_representation(Representation::Double());
+    SetFlag(kDependsOnArrayElements);
+    SetFlag(kUseGVN);
+  }
+
+  HValue* elements() { return OperandAt(0); }
+  HValue* key() { return OperandAt(1); }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    // The key is supposed to be Integer32.
+    return index == 0
+      ? Representation::Tagged()
+      : Representation::Integer32();
+  }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  bool RequiresHoleCheck() const;
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
+
+ protected:
+  virtual bool DataEquals(HValue* other) { return true; }
+};
+
+
+class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
  public:
   HLoadKeyedSpecializedArrayElement(HValue* external_elements,
                                     HValue* key,
-                                    ExternalArrayType array_type)
-      : HBinaryOperation(external_elements, key),
-        array_type_(array_type) {
-    if (array_type == kExternalFloatArray ||
-        array_type == kExternalDoubleArray) {
+                                    JSObject::ElementsKind elements_kind)
+      :  elements_kind_(elements_kind) {
+    SetOperandAt(0, external_elements);
+    SetOperandAt(1, key);
+    if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+        elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
       set_representation(Representation::Double());
     } else {
       set_representation(Representation::Integer32());
@@ -3427,13 +3577,14 @@
   virtual Representation RequiredInputRepresentation(int index) const {
     // The key is supposed to be Integer32, but the base pointer
     // for the element load is a naked pointer.
-    return (index == 1) ? Representation::Integer32()
-        : Representation::External();
+    return index == 0
+      ? Representation::External()
+      : Representation::Integer32();
   }
 
   HValue* external_pointer() { return OperandAt(0); }
   HValue* key() { return OperandAt(1); }
-  ExternalArrayType array_type() const { return array_type_; }
+  JSObject::ElementsKind elements_kind() const { return elements_kind_; }
 
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
 
@@ -3442,11 +3593,11 @@
     if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
     HLoadKeyedSpecializedArrayElement* cast_other =
         HLoadKeyedSpecializedArrayElement::cast(other);
-    return array_type_ == cast_other->array_type();
+    return elements_kind_ == cast_other->elements_kind();
   }
 
  private:
-  ExternalArrayType array_type_;
+  JSObject::ElementsKind elements_kind_;
 };
 
 
@@ -3474,17 +3625,18 @@
 };
 
 
-class HStoreNamedField: public HBinaryOperation {
+class HStoreNamedField: public HTemplateInstruction<2> {
  public:
   HStoreNamedField(HValue* obj,
                    Handle<String> name,
                    HValue* val,
                    bool in_object,
                    int offset)
-      : HBinaryOperation(obj, val),
-        name_(name),
+      : name_(name),
         is_in_object_(in_object),
         offset_(offset) {
+    SetOperandAt(0, obj);
+    SetOperandAt(1, val);
     if (is_in_object_) {
       SetFlag(kChangesInobjectFields);
     } else {
@@ -3566,7 +3718,8 @@
 
   virtual Representation RequiredInputRepresentation(int index) const {
     // The key is supposed to be Integer32.
-    return (index == 1) ? Representation::Integer32()
+    return index == 1
+        ? Representation::Integer32()
         : Representation::Tagged();
   }
 
@@ -3584,13 +3737,48 @@
 };
 
 
+class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
+ public:
+  HStoreKeyedFastDoubleElement(HValue* elements,
+                               HValue* key,
+                               HValue* val) {
+    SetOperandAt(0, elements);
+    SetOperandAt(1, key);
+    SetOperandAt(2, val);
+    SetFlag(kChangesArrayElements);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    if (index == 1) {
+      return Representation::Integer32();
+    } else if (index == 2) {
+      return Representation::Double();
+    } else {
+      return Representation::Tagged();
+    }
+  }
+
+  HValue* elements() { return OperandAt(0); }
+  HValue* key() { return OperandAt(1); }
+  HValue* value() { return OperandAt(2); }
+
+  bool NeedsWriteBarrier() {
+    return StoringValueNeedsWriteBarrier(value());
+  }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
+};
+
+
 class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
  public:
   HStoreKeyedSpecializedArrayElement(HValue* external_elements,
                                      HValue* key,
                                      HValue* val,
-                                     ExternalArrayType array_type)
-      : array_type_(array_type) {
+                                     JSObject::ElementsKind elements_kind)
+      : elements_kind_(elements_kind) {
     SetFlag(kChangesSpecializedArrayElements);
     SetOperandAt(0, external_elements);
     SetOperandAt(1, key);
@@ -3603,8 +3791,10 @@
     if (index == 0) {
       return Representation::External();
     } else {
-      if (index == 2 && (array_type() == kExternalFloatArray ||
-                         array_type() == kExternalDoubleArray)) {
+      bool float_or_double_elements =
+          elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+          elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
+      if (index == 2 && float_or_double_elements) {
         return Representation::Double();
       } else {
         return Representation::Integer32();
@@ -3615,12 +3805,12 @@
   HValue* external_pointer() { return OperandAt(0); }
   HValue* key() { return OperandAt(1); }
   HValue* value() { return OperandAt(2); }
-  ExternalArrayType array_type() const { return array_type_; }
+  JSObject::ElementsKind elements_kind() const { return elements_kind_; }
 
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
 
  private:
-  ExternalArrayType array_type_;
+  JSObject::ElementsKind elements_kind_;
 };
 
 
@@ -3660,7 +3850,8 @@
 
 class HStringAdd: public HBinaryOperation {
  public:
-  HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
+  HStringAdd(HValue* context, HValue* left, HValue* right)
+      : HBinaryOperation(context, left, right) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
     SetFlag(kDependsOnMaps);
@@ -3681,10 +3872,12 @@
 };
 
 
-class HStringCharCodeAt: public HBinaryOperation {
+class HStringCharCodeAt: public HTemplateInstruction<3> {
  public:
-  HStringCharCodeAt(HValue* string, HValue* index)
-      : HBinaryOperation(string, index) {
+  HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, string);
+    SetOperandAt(2, index);
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
     SetFlag(kDependsOnMaps);
@@ -3692,12 +3885,14 @@
 
   virtual Representation RequiredInputRepresentation(int index) const {
     // The index is supposed to be Integer32.
-    return (index == 1) ? Representation::Integer32()
+    return index == 2
+        ? Representation::Integer32()
         : Representation::Tagged();
   }
 
-  HValue* string() { return OperandAt(0); }
-  HValue* index() { return OperandAt(1); }
+  HValue* context() { return OperandAt(0); }
+  HValue* string() { return OperandAt(1); }
+  HValue* index() { return OperandAt(2); }
 
   DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
 
@@ -3710,17 +3905,24 @@
 };
 
 
-class HStringCharFromCode: public HUnaryOperation {
+class HStringCharFromCode: public HTemplateInstruction<2> {
  public:
-  explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
-    set_representation(Representation::Tagged());
+  HStringCharFromCode(HValue* context, HValue* char_code) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, char_code);
+     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::Integer32();
+    return index == 0
+        ? Representation::Tagged()
+        : Representation::Integer32();
   }
 
+  HValue* context() { return OperandAt(0); }
+  HValue* value() { return OperandAt(1); }
+
   virtual bool DataEquals(HValue* other) { return true; }
 
   DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
@@ -3772,23 +3974,27 @@
 };
 
 
-class HArrayLiteral: public HMaterializedLiteral<0> {
+class HArrayLiteral: public HMaterializedLiteral<1> {
  public:
-  HArrayLiteral(Handle<FixedArray> constant_elements,
+  HArrayLiteral(HValue* context,
+                Handle<FixedArray> constant_elements,
                 int length,
                 int literal_index,
                 int depth)
-      : HMaterializedLiteral<0>(literal_index, depth),
+      : HMaterializedLiteral<1>(literal_index, depth),
         length_(length),
-        constant_elements_(constant_elements) {}
+        constant_elements_(constant_elements) {
+    SetOperandAt(0, context);
+  }
 
+  HValue* context() { return OperandAt(0); }
   Handle<FixedArray> constant_elements() const { return constant_elements_; }
   int length() const { return length_; }
 
   bool IsCopyOnWrite() const;
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::None();
+    return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
@@ -3834,20 +4040,24 @@
 };
 
 
-class HRegExpLiteral: public HMaterializedLiteral<0> {
+class HRegExpLiteral: public HMaterializedLiteral<1> {
  public:
-  HRegExpLiteral(Handle<String> pattern,
+  HRegExpLiteral(HValue* context,
+                 Handle<String> pattern,
                  Handle<String> flags,
                  int literal_index)
-      : HMaterializedLiteral<0>(literal_index, 0),
+      : HMaterializedLiteral<1>(literal_index, 0),
         pattern_(pattern),
-        flags_(flags) { }
+        flags_(flags) {
+    SetOperandAt(0, context);
+  }
 
+  HValue* context() { return OperandAt(0); }
   Handle<String> pattern() { return pattern_; }
   Handle<String> flags() { return flags_; }
 
   virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::None();
+    return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
@@ -3858,15 +4068,20 @@
 };
 
 
-class HFunctionLiteral: public HTemplateInstruction<0> {
+class HFunctionLiteral: public HTemplateInstruction<1> {
  public:
-  HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
+  HFunctionLiteral(HValue* context,
+                   Handle<SharedFunctionInfo> shared,
+                   bool pretenure)
       : shared_info_(shared), pretenure_(pretenure) {
+    SetOperandAt(0, context);
     set_representation(Representation::Tagged());
   }
 
+  HValue* context() { return OperandAt(0); }
+
   virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::None();
+    return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
@@ -3880,12 +4095,17 @@
 };
 
 
-class HTypeof: public HUnaryOperation {
+class HTypeof: public HTemplateInstruction<2> {
  public:
-  explicit HTypeof(HValue* value) : HUnaryOperation(value) {
+  explicit HTypeof(HValue* context, HValue* value) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, value);
     set_representation(Representation::Tagged());
   }
 
+  HValue* context() { return OperandAt(0); }
+  HValue* value() { return OperandAt(1); }
+
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
@@ -3928,8 +4148,8 @@
 
 class HDeleteProperty: public HBinaryOperation {
  public:
-  HDeleteProperty(HValue* obj, HValue* key)
-      : HBinaryOperation(obj, key) {
+  HDeleteProperty(HValue* context, HValue* obj, HValue* key)
+      : HBinaryOperation(context, obj, key) {
     set_representation(Representation::Tagged());
     SetAllSideEffects();
   }
@@ -3938,6 +4158,8 @@
     return Representation::Tagged();
   }
 
+  virtual HType CalculateInferredType();
+
   DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
 
   HValue* object() { return left(); }
@@ -3945,17 +4167,19 @@
 };
 
 
-class HIn: public HTemplateInstruction<2> {
+class HIn: public HTemplateInstruction<3> {
  public:
-  HIn(HValue* key, HValue* object) {
-    SetOperandAt(0, key);
-    SetOperandAt(1, object);
+  HIn(HValue* context, HValue* key, HValue* object) {
+    SetOperandAt(0, context);
+    SetOperandAt(1, key);
+    SetOperandAt(2, object);
     set_representation(Representation::Tagged());
     SetAllSideEffects();
   }
 
-  HValue* key() { return OperandAt(0); }
-  HValue* object() { return OperandAt(1); }
+  HValue* context() { return OperandAt(0); }
+  HValue* key() { return OperandAt(1); }
+  HValue* object() { return OperandAt(2); }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 1b37d93..f105703 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -33,6 +33,7 @@
 #include "hashmap.h"
 #include "lithium-allocator.h"
 #include "parser.h"
+#include "scopeinfo.h"
 #include "scopes.h"
 #include "stub-cache.h"
 
@@ -68,8 +69,8 @@
       last_instruction_index_(-1),
       deleted_phis_(4),
       parent_loop_header_(NULL),
-      is_inline_return_target_(false) {
-}
+      is_inline_return_target_(false),
+      is_deoptimizing_(false) { }
 
 
 void HBasicBlock::AttachLoopInformation() {
@@ -131,16 +132,16 @@
 }
 
 
-HSimulate* HBasicBlock::CreateSimulate(int id) {
+HSimulate* HBasicBlock::CreateSimulate(int ast_id) {
   ASSERT(HasEnvironment());
   HEnvironment* environment = last_environment();
-  ASSERT(id == AstNode::kNoNumber ||
-         environment->closure()->shared()->VerifyBailoutId(id));
+  ASSERT(ast_id == AstNode::kNoNumber ||
+         environment->closure()->shared()->VerifyBailoutId(ast_id));
 
   int push_count = environment->push_count();
   int pop_count = environment->pop_count();
 
-  HSimulate* instr = new(zone()) HSimulate(id, pop_count);
+  HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count);
   for (int i = push_count - 1; i >= 0; --i) {
     instr->AddPushedValue(environment->ExpressionStackAt(i));
   }
@@ -157,23 +158,19 @@
   ASSERT(!IsFinished());
   AddInstruction(end);
   end_ = end;
-  if (end->FirstSuccessor() != NULL) {
-    end->FirstSuccessor()->RegisterPredecessor(this);
-    if (end->SecondSuccessor() != NULL) {
-      end->SecondSuccessor()->RegisterPredecessor(this);
-    }
+  for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
+    it.Current()->RegisterPredecessor(this);
   }
 }
 
 
-void HBasicBlock::Goto(HBasicBlock* block, bool include_stack_check) {
+void HBasicBlock::Goto(HBasicBlock* block) {
   if (block->IsInlineReturnTarget()) {
     AddInstruction(new(zone()) HLeaveInlined);
     last_environment_ = last_environment()->outer();
   }
   AddSimulate(AstNode::kNoNumber);
   HGoto* instr = new(zone()) HGoto(block);
-  instr->set_include_stack_check(include_stack_check);
   Finish(instr);
 }
 
@@ -197,7 +194,7 @@
 }
 
 
-void HBasicBlock::SetJoinId(int id) {
+void HBasicBlock::SetJoinId(int ast_id) {
   int length = predecessors_.length();
   ASSERT(length > 0);
   for (int i = 0; i < length; i++) {
@@ -207,8 +204,8 @@
     // We only need to verify the ID once.
     ASSERT(i != 0 ||
            predecessor->last_environment()->closure()->shared()
-               ->VerifyBailoutId(id));
-    simulate->set_ast_id(id);
+               ->VerifyBailoutId(ast_id));
+    simulate->set_ast_id(ast_id);
   }
 }
 
@@ -401,8 +398,9 @@
   void Analyze() {
     while (!stack_.is_empty()) {
       HControlInstruction* end = stack_.RemoveLast()->end();
-      PushBlock(end->FirstSuccessor());
-      PushBlock(end->SecondSuccessor());
+      for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
+        PushBlock(it.Current());
+      }
     }
   }
 
@@ -521,6 +519,12 @@
   return GetConstant(&constant_false_, isolate()->heap()->false_value());
 }
 
+
+HConstant* HGraph::GetConstantHole() {
+  return GetConstant(&constant_hole_, isolate()->heap()->the_hole_value());
+}
+
+
 HGraphBuilder::HGraphBuilder(CompilationInfo* info,
                              TypeFeedbackOracle* oracle)
     : function_state_(NULL),
@@ -572,7 +576,7 @@
                                        HBasicBlock* body_exit,
                                        HBasicBlock* loop_successor,
                                        HBasicBlock* break_block) {
-  if (body_exit != NULL) body_exit->Goto(loop_entry, true);
+  if (body_exit != NULL) body_exit->Goto(loop_entry);
   loop_entry->PostProcessLoopHeader(statement);
   if (break_block != NULL) {
     if (loop_successor != NULL) loop_successor->Goto(break_block);
@@ -691,8 +695,9 @@
                                  HBasicBlock* loop_header) {
   for (int i = 0; i < loop->blocks()->length(); ++i) {
     HBasicBlock* b = loop->blocks()->at(i);
-    Postorder(b->end()->SecondSuccessor(), visited, order, loop_header);
-    Postorder(b->end()->FirstSuccessor(), visited, order, loop_header);
+    for (HSuccessorIterator it(b->end()); !it.Done(); it.Advance()) {
+      Postorder(it.Current(), visited, order, loop_header);
+    }
     if (b->IsLoopHeader() && b != loop->loop_header()) {
       PostorderLoopBlocks(b->loop_information(), visited, order, loop_header);
     }
@@ -709,11 +714,13 @@
   visited->Add(block->block_id());
   if (block->IsLoopHeader()) {
     PostorderLoopBlocks(block->loop_information(), visited, order, loop_header);
-    Postorder(block->end()->SecondSuccessor(), visited, order, block);
-    Postorder(block->end()->FirstSuccessor(), visited, order, block);
+    for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
+      Postorder(it.Current(), visited, order, block);
+    }
   } else {
-    Postorder(block->end()->SecondSuccessor(), visited, order, loop_header);
-    Postorder(block->end()->FirstSuccessor(), visited, order, loop_header);
+    for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
+      Postorder(it.Current(), visited, order, loop_header);
+    }
   }
   ASSERT(block->end()->FirstSuccessor() == NULL ||
          order->Contains(block->end()->FirstSuccessor()) ||
@@ -736,9 +743,21 @@
       }
     }
   }
+
+  // Propagate flag marking blocks containing unconditional deoptimize.
+  MarkAsDeoptimizingRecursively(entry_block());
 }
 
 
+// Mark all blocks that are dominated by an unconditional deoptimize.
+void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) {
+  for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
+    HBasicBlock* dominated = block->dominated_blocks()->at(i);
+    if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing();
+    MarkAsDeoptimizingRecursively(dominated);
+  }
+}
+
 void HGraph::EliminateRedundantPhis() {
   HPhase phase("Redundant phi elimination", this);
 
@@ -817,7 +836,7 @@
 }
 
 
-bool HGraph::CheckPhis() {
+bool HGraph::CheckArgumentsPhiUses() {
   int block_count = blocks_.length();
   for (int i = 0; i < block_count; ++i) {
     for (int j = 0; j < blocks_[i]->phis()->length(); ++j) {
@@ -830,7 +849,22 @@
 }
 
 
-bool HGraph::CollectPhis() {
+bool HGraph::CheckConstPhiUses() {
+  int block_count = blocks_.length();
+  for (int i = 0; i < block_count; ++i) {
+    for (int j = 0; j < blocks_[i]->phis()->length(); ++j) {
+      HPhi* phi = blocks_[i]->phis()->at(j);
+      // Check for the hole value (from an uninitialized const).
+      for (int k = 0; k < phi->OperandCount(); k++) {
+        if (phi->OperandAt(k) == GetConstantHole()) return false;
+      }
+    }
+  }
+  return true;
+}
+
+
+void HGraph::CollectPhis() {
   int block_count = blocks_.length();
   phi_list_ = new ZoneList<HPhi*>(block_count);
   for (int i = 0; i < block_count; ++i) {
@@ -839,7 +873,6 @@
       phi_list_->Add(phi);
     }
   }
-  return true;
 }
 
 
@@ -875,9 +908,8 @@
  private:
   void TraceRange(const char* msg, ...);
   void Analyze(HBasicBlock* block);
-  void InferControlFlowRange(HTest* test, HBasicBlock* dest);
-  void InferControlFlowRange(Token::Value op, HValue* value, HValue* other);
-  void InferPhiRange(HPhi* phi);
+  void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest);
+  void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other);
   void InferRange(HValue* value);
   void RollBackTo(int index);
   void AddRange(HValue* value, Range* range);
@@ -899,7 +931,7 @@
 
 void HRangeAnalysis::Analyze() {
   HPhase phase("Range analysis", graph_);
-  Analyze(graph_->blocks()->at(0));
+  Analyze(graph_->entry_block());
 }
 
 
@@ -911,15 +943,15 @@
   // Infer range based on control flow.
   if (block->predecessors()->length() == 1) {
     HBasicBlock* pred = block->predecessors()->first();
-    if (pred->end()->IsTest()) {
-      InferControlFlowRange(HTest::cast(pred->end()), block);
+    if (pred->end()->IsCompareIDAndBranch()) {
+      InferControlFlowRange(HCompareIDAndBranch::cast(pred->end()), block);
     }
   }
 
   // Process phi instructions.
   for (int i = 0; i < block->phis()->length(); ++i) {
     HPhi* phi = block->phis()->at(i);
-    InferPhiRange(phi);
+    InferRange(phi);
   }
 
   // Go through all instructions of the current block.
@@ -938,28 +970,26 @@
 }
 
 
-void HRangeAnalysis::InferControlFlowRange(HTest* test, HBasicBlock* dest) {
+void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test,
+                                           HBasicBlock* dest) {
   ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
-  if (test->value()->IsCompare()) {
-    HCompare* compare = HCompare::cast(test->value());
-    if (compare->GetInputRepresentation().IsInteger32()) {
-      Token::Value op = compare->token();
-      if (test->SecondSuccessor() == dest) {
-        op = Token::NegateCompareOp(op);
-      }
-      Token::Value inverted_op = Token::InvertCompareOp(op);
-      InferControlFlowRange(op, compare->left(), compare->right());
-      InferControlFlowRange(inverted_op, compare->right(), compare->left());
+  if (test->GetInputRepresentation().IsInteger32()) {
+    Token::Value op = test->token();
+    if (test->SecondSuccessor() == dest) {
+      op = Token::NegateCompareOp(op);
     }
+    Token::Value inverted_op = Token::InvertCompareOp(op);
+    UpdateControlFlowRange(op, test->left(), test->right());
+    UpdateControlFlowRange(inverted_op, test->right(), test->left());
   }
 }
 
 
 // We know that value [op] other. Use this information to update the range on
 // value.
-void HRangeAnalysis::InferControlFlowRange(Token::Value op,
-                                           HValue* value,
-                                           HValue* other) {
+void HRangeAnalysis::UpdateControlFlowRange(Token::Value op,
+                                            HValue* value,
+                                            HValue* other) {
   Range temp_range;
   Range* range = other->range() != NULL ? other->range() : &temp_range;
   Range* new_range = NULL;
@@ -990,12 +1020,6 @@
 }
 
 
-void HRangeAnalysis::InferPhiRange(HPhi* phi) {
-  // TODO(twuerthinger): Infer loop phi ranges.
-  InferRange(phi);
-}
-
-
 void HRangeAnalysis::InferRange(HValue* value) {
   ASSERT(!value->HasRange());
   if (!value->representation().IsNone()) {
@@ -1222,8 +1246,6 @@
   void Process();
 
  private:
-  void RemoveStackCheck(HBasicBlock* block);
-
   HGraph* graph_;
 };
 
@@ -1238,16 +1260,20 @@
     if (block->IsLoopHeader()) {
       HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge();
       HBasicBlock* dominator = back_edge;
-      bool back_edge_dominated_by_call = false;
-      while (dominator != block && !back_edge_dominated_by_call) {
+      while (true) {
         HInstruction* instr = dominator->first();
-        while (instr != NULL && !back_edge_dominated_by_call) {
+        while (instr != NULL) {
           if (instr->IsCall()) {
-            RemoveStackCheck(back_edge);
-            back_edge_dominated_by_call = true;
+            block->loop_information()->stack_check()->Eliminate();
+            break;
           }
           instr = instr->next();
         }
+
+        // Done when the loop header is processed.
+        if (dominator == block) break;
+
+        // Move up the dominator tree.
         dominator = dominator->dominator();
       }
     }
@@ -1255,18 +1281,6 @@
 }
 
 
-void HStackCheckEliminator::RemoveStackCheck(HBasicBlock* block) {
-  HInstruction* instr = block->first();
-  while (instr != NULL) {
-    if (instr->IsGoto()) {
-      HGoto::cast(instr)->set_include_stack_check(false);
-      return;
-    }
-    instr = instr->next();
-  }
-}
-
-
 // Simple sparse set with O(1) add, contains, and clear.
 class SparseSet {
  public:
@@ -1274,7 +1288,12 @@
       : capacity_(capacity),
         length_(0),
         dense_(zone->NewArray<int>(capacity)),
-        sparse_(zone->NewArray<int>(capacity)) {}
+        sparse_(zone->NewArray<int>(capacity)) {
+#ifndef NVALGRIND
+    // Initialize the sparse array to make valgrind happy.
+    memset(sparse_, 0, sizeof(sparse_[0]) * capacity);
+#endif
+  }
 
   bool Contains(int n) const {
     ASSERT(0 <= n && n < capacity_);
@@ -1357,7 +1376,7 @@
     LoopInvariantCodeMotion();
   }
   HValueMap* map = new(zone()) HValueMap();
-  AnalyzeBlock(graph_->blocks()->at(0), map);
+  AnalyzeBlock(graph_->entry_block(), map);
 }
 
 
@@ -1449,37 +1468,9 @@
 
 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr,
                                       HBasicBlock* loop_header) {
-  // If we've disabled code motion, don't move any instructions.
-  if (!AllowCodeMotion()) return false;
-
-  // If --aggressive-loop-invariant-motion, move everything except change
-  // instructions.
-  if (FLAG_aggressive_loop_invariant_motion && !instr->IsChange()) {
-    return true;
-  }
-
-  // Otherwise only move instructions that postdominate the loop header
-  // (i.e. are always executed inside the loop). This is to avoid
-  // unnecessary deoptimizations assuming the loop is executed at least
-  // once.  TODO(fschneider): Better type feedback should give us
-  // information about code that was never executed.
-  HBasicBlock* block = instr->block();
-  bool result = true;
-  if (block != loop_header) {
-    for (int i = 1; i < loop_header->predecessors()->length(); ++i) {
-      bool found = false;
-      HBasicBlock* pred = loop_header->predecessors()->at(i);
-      while (pred != loop_header) {
-        if (pred == block) found = true;
-        pred = pred->dominator();
-      }
-      if (!found) {
-        result = false;
-        break;
-      }
-    }
-  }
-  return result;
+  // If we've disabled code motion or we're in a block that unconditionally
+  // deoptimizes, don't move any instructions.
+  return AllowCodeMotion() && !instr->block()->IsDeoptimizing();
 }
 
 
@@ -1699,8 +1690,8 @@
         HValue* use = it.value();
         if (use->IsPhi()) {
           int id = HPhi::cast(use)->phi_id();
-          change = change ||
-              connected_phis[i]->UnionIsChanged(*connected_phis[id]);
+          if (connected_phis[i]->UnionIsChanged(*connected_phis[id]))
+            change = true;
         }
       }
     }
@@ -1965,7 +1956,7 @@
   HPhase phase("MarkDeoptimizeOnUndefined", this);
   // Compute DeoptimizeOnUndefined flag for phis.
   // Any phi that can reach a use with DeoptimizeOnUndefined set must
-  // have DeoptimizeOnUndefined set.  Currently only HCompare, with
+  // have DeoptimizeOnUndefined set.  Currently only HCompareIDAndBranch, with
   // double input representation, has this flag set.
   // The flag is used by HChange tagged->double, which must deoptimize
   // if one of its uses has this flag set.
@@ -2026,9 +2017,10 @@
       HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
       if_true->MarkAsInlineReturnTarget();
       if_false->MarkAsInlineReturnTarget();
+      Expression* cond = TestContext::cast(owner->ast_context())->condition();
       // The AstContext constructor pushed on the context stack.  This newed
       // instance is the reason that AstContext can't be BASE_EMBEDDED.
-      test_context_ = new TestContext(owner, if_true, if_false);
+      test_context_ = new TestContext(owner, cond, if_true, if_false);
     } else {
       function_return_ = owner->graph()->CreateBasicBlock();
       function_return()->MarkAsInlineReturnTarget();
@@ -2102,14 +2094,28 @@
 
 
 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) {
+  ASSERT(!instr->IsControlInstruction());
   owner()->AddInstruction(instr);
   if (instr->HasSideEffects()) owner()->AddSimulate(ast_id);
 }
 
 
+void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) {
+  ASSERT(!instr->HasSideEffects());
+  HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
+  HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
+  instr->SetSuccessorAt(0, empty_true);
+  instr->SetSuccessorAt(1, empty_false);
+  owner()->current_block()->Finish(instr);
+  HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id);
+  owner()->set_current_block(join);
+}
+
+
 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) {
+  ASSERT(!instr->IsControlInstruction());
   if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
-    owner()->Bailout("bad value context for arguments object value");
+    return owner()->Bailout("bad value context for arguments object value");
   }
   owner()->AddInstruction(instr);
   owner()->Push(instr);
@@ -2117,7 +2123,28 @@
 }
 
 
+void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) {
+  ASSERT(!instr->HasSideEffects());
+  if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
+    return owner()->Bailout("bad value context for arguments object value");
+  }
+  HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
+  HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock();
+  instr->SetSuccessorAt(0, materialize_true);
+  instr->SetSuccessorAt(1, materialize_false);
+  owner()->current_block()->Finish(instr);
+  owner()->set_current_block(materialize_true);
+  owner()->Push(owner()->graph()->GetConstantTrue());
+  owner()->set_current_block(materialize_false);
+  owner()->Push(owner()->graph()->GetConstantFalse());
+  HBasicBlock* join =
+    owner()->CreateJoin(materialize_true, materialize_false, ast_id);
+  owner()->set_current_block(join);
+}
+
+
 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) {
+  ASSERT(!instr->IsControlInstruction());
   HGraphBuilder* builder = owner();
   builder->AddInstruction(instr);
   // We expect a simulate after every expression with side effects, though
@@ -2131,22 +2158,35 @@
 }
 
 
+void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) {
+  ASSERT(!instr->HasSideEffects());
+  HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
+  HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
+  instr->SetSuccessorAt(0, empty_true);
+  instr->SetSuccessorAt(1, empty_false);
+  owner()->current_block()->Finish(instr);
+  empty_true->Goto(if_true());
+  empty_false->Goto(if_false());
+  owner()->set_current_block(NULL);
+}
+
+
 void TestContext::BuildBranch(HValue* value) {
   // We expect the graph to be in edge-split form: there is no edge that
   // connects a branch node to a join node.  We conservatively ensure that
   // property by always adding an empty block on the outgoing edges of this
   // branch.
   HGraphBuilder* builder = owner();
-  if (value->CheckFlag(HValue::kIsArguments)) {
+  if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
     builder->Bailout("arguments object value in a test context");
   }
   HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
   HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
-  HTest* test = new(zone()) HTest(value, empty_true, empty_false);
+  HBranch* test = new(zone()) HBranch(value, empty_true, empty_false);
   builder->current_block()->Finish(test);
 
-  empty_true->Goto(if_true(), false);
-  empty_false->Goto(if_false(), false);
+  empty_true->Goto(if_true());
+  empty_false->Goto(if_false());
   builder->set_current_block(NULL);
 }
 
@@ -2198,14 +2238,17 @@
 void HGraphBuilder::VisitForControl(Expression* expr,
                                     HBasicBlock* true_block,
                                     HBasicBlock* false_block) {
-  TestContext for_test(this, true_block, false_block);
+  TestContext for_test(this, expr, true_block, false_block);
   Visit(expr);
 }
 
 
-void HGraphBuilder::VisitArgument(Expression* expr) {
-  CHECK_ALIVE(VisitForValue(expr));
-  Push(AddInstruction(new(zone()) HPushArgument(Pop())));
+HValue* HGraphBuilder::VisitArgument(Expression* expr) {
+  VisitForValue(expr);
+  if (HasStackOverflow() || current_block() == NULL) return NULL;
+  HValue* value = Pop();
+  Push(AddInstruction(new(zone()) HPushArgument(value)));
+  return value;
 }
 
 
@@ -2238,7 +2281,9 @@
     }
     SetupScope(scope);
     VisitDeclarations(scope->declarations());
-    AddInstruction(new(zone()) HStackCheck());
+    HValue* context = environment()->LookupContext();
+    AddInstruction(
+        new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry));
 
     // Add an edge to the body entry.  This is warty: the graph's start
     // environment will be used by the Lithium translation as the initial
@@ -2272,16 +2317,17 @@
 
   graph()->OrderBlocks();
   graph()->AssignDominators();
+  if (!graph()->CheckConstPhiUses()) {
+    Bailout("Unsupported phi use of const variable");
+    return NULL;
+  }
   graph()->EliminateRedundantPhis();
-  if (!graph()->CheckPhis()) {
-    Bailout("Unsupported phi use of arguments object");
+  if (!graph()->CheckArgumentsPhiUses()) {
+    Bailout("Unsupported phi use of arguments");
     return NULL;
   }
   if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
-  if (!graph()->CollectPhis()) {
-    Bailout("Unsupported phi use of uninitialized constant");
-    return NULL;
-  }
+  graph()->CollectPhis();
 
   HInferRepresentation rep(graph());
   rep.Analyze();
@@ -2341,9 +2387,9 @@
 }
 
 
-void HGraphBuilder::AddSimulate(int id) {
+void HGraphBuilder::AddSimulate(int ast_id) {
   ASSERT(current_block() != NULL);
-  current_block()->AddSimulate(id);
+  current_block()->AddSimulate(ast_id);
 }
 
 
@@ -2375,9 +2421,6 @@
 
 
 void HGraphBuilder::SetupScope(Scope* scope) {
-  // We don't yet handle the function name for named function expressions.
-  if (scope->function() != NULL) return Bailout("named function expression");
-
   HConstant* undefined_constant = new(zone()) HConstant(
       isolate()->factory()->undefined_value(), Representation::Tagged());
   AddInstruction(undefined_constant);
@@ -2406,18 +2449,21 @@
   // Handle the arguments and arguments shadow variables specially (they do
   // not have declarations).
   if (scope->arguments() != NULL) {
-    if (!scope->arguments()->IsStackAllocated() ||
-        (scope->arguments_shadow() != NULL &&
-        !scope->arguments_shadow()->IsStackAllocated())) {
+    if (!scope->arguments()->IsStackAllocated()) {
       return Bailout("context-allocated arguments");
     }
     HArgumentsObject* object = new(zone()) HArgumentsObject;
     AddInstruction(object);
     graph()->SetArgumentsObject(object);
     environment()->Bind(scope->arguments(), object);
-    if (scope->arguments_shadow() != NULL) {
-      environment()->Bind(scope->arguments_shadow(), object);
+  }
+  // Handle implicit declaration of the function name in named function
+  // expressions before other declarations.
+  if (scope->is_function_scope() && scope->function() != NULL) {
+    if (!scope->function()->IsStackAllocated()) {
+      return Bailout("unsupported declaration");
     }
+    environment()->Bind(scope->function(), graph()->GetConstantHole());
   }
 }
 
@@ -2510,7 +2556,7 @@
       cond_false = NULL;
     }
 
-    HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->id());
+    HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId());
     set_current_block(join);
   }
 }
@@ -2588,7 +2634,7 @@
                       test->if_false());
     } else if (context->IsEffect()) {
       CHECK_ALIVE(VisitForEffect(stmt->expression()));
-      current_block()->Goto(function_return(), false);
+      current_block()->Goto(function_return());
     } else {
       ASSERT(context->IsValue());
       CHECK_ALIVE(VisitForValue(stmt->expression()));
@@ -2600,19 +2646,20 @@
 }
 
 
-void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
+void HGraphBuilder::VisitEnterWithContextStatement(
+    EnterWithContextStatement* stmt) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
-  return Bailout("WithEnterStatement");
+  return Bailout("EnterWithContextStatement");
 }
 
 
-void HGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
+void HGraphBuilder::VisitExitContextStatement(ExitContextStatement* stmt) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
-  return Bailout("WithExitStatement");
+  return Bailout("ExitContextStatement");
 }
 
 
@@ -2656,15 +2703,16 @@
     // Otherwise generate a compare and branch.
     CHECK_ALIVE(VisitForValue(clause->label()));
     HValue* label_value = Pop();
-    HCompare* compare =
-        new(zone()) HCompare(tag_value, label_value, Token::EQ_STRICT);
+    HCompareIDAndBranch* compare =
+        new(zone()) HCompareIDAndBranch(tag_value,
+                                        label_value,
+                                        Token::EQ_STRICT);
     compare->SetInputRepresentation(Representation::Integer32());
-    ASSERT(!compare->HasSideEffects());
-    AddInstruction(compare);
     HBasicBlock* body_block = graph()->CreateBasicBlock();
     HBasicBlock* next_test_block = graph()->CreateBasicBlock();
-    HTest* branch = new(zone()) HTest(compare, body_block, next_test_block);
-    current_block()->Finish(branch);
+    compare->SetSuccessorAt(0, body_block);
+    compare->SetSuccessorAt(1, next_test_block);
+    current_block()->Finish(compare);
     set_current_block(next_test_block);
   }
 
@@ -2750,7 +2798,7 @@
   HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
   HBasicBlock* osr_entry = graph()->CreateBasicBlock();
   HValue* true_value = graph()->GetConstantTrue();
-  HTest* test = new(zone()) HTest(true_value, non_osr_entry, osr_entry);
+  HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry);
   current_block()->Finish(test);
 
   HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
@@ -2778,6 +2826,21 @@
 }
 
 
+void HGraphBuilder::VisitLoopBody(IterationStatement* stmt,
+                                  HBasicBlock* loop_entry,
+                                  BreakAndContinueInfo* break_info) {
+  BreakAndContinueScope push(break_info, this);
+  AddSimulate(stmt->StackCheckId());
+  HValue* context = environment()->LookupContext();
+  HStackCheck* stack_check =
+    new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch);
+  AddInstruction(stack_check);
+  ASSERT(loop_entry->IsLoopHeader());
+  loop_entry->loop_information()->set_stack_check(stack_check);
+  CHECK_BAILOUT(Visit(stmt->body()));
+}
+
+
 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
@@ -2785,13 +2848,11 @@
   ASSERT(current_block() != NULL);
   PreProcessOsrEntry(stmt);
   HBasicBlock* loop_entry = CreateLoopHeaderBlock();
-  current_block()->Goto(loop_entry, false);
+  current_block()->Goto(loop_entry);
   set_current_block(loop_entry);
 
   BreakAndContinueInfo break_info(stmt);
-  { BreakAndContinueScope push(&break_info, this);
-    CHECK_BAILOUT(Visit(stmt->body()));
-  }
+  CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
   HBasicBlock* body_exit =
       JoinContinue(stmt, current_block(), break_info.continue_block());
   HBasicBlock* loop_successor = NULL;
@@ -2829,7 +2890,7 @@
   ASSERT(current_block() != NULL);
   PreProcessOsrEntry(stmt);
   HBasicBlock* loop_entry = CreateLoopHeaderBlock();
-  current_block()->Goto(loop_entry, false);
+  current_block()->Goto(loop_entry);
   set_current_block(loop_entry);
 
   // If the condition is constant true, do not generate a branch.
@@ -2852,7 +2913,7 @@
   BreakAndContinueInfo break_info(stmt);
   if (current_block() != NULL) {
     BreakAndContinueScope push(&break_info, this);
-    CHECK_BAILOUT(Visit(stmt->body()));
+    CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
   }
   HBasicBlock* body_exit =
       JoinContinue(stmt, current_block(), break_info.continue_block());
@@ -2875,7 +2936,7 @@
   ASSERT(current_block() != NULL);
   PreProcessOsrEntry(stmt);
   HBasicBlock* loop_entry = CreateLoopHeaderBlock();
-  current_block()->Goto(loop_entry, false);
+  current_block()->Goto(loop_entry);
   set_current_block(loop_entry);
 
   HBasicBlock* loop_successor = NULL;
@@ -2897,7 +2958,7 @@
   BreakAndContinueInfo break_info(stmt);
   if (current_block() != NULL) {
     BreakAndContinueScope push(&break_info, this);
-    CHECK_BAILOUT(Visit(stmt->body()));
+    CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
   }
   HBasicBlock* body_exit =
       JoinContinue(stmt, current_block(), break_info.continue_block());
@@ -2981,9 +3042,10 @@
   }
   // We also have a stack overflow if the recursive compilation did.
   if (HasStackOverflow()) return;
+  HValue* context = environment()->LookupContext();
   HFunctionLiteral* instr =
-      new(zone()) HFunctionLiteral(shared_info, expr->pretenure());
-  ast_context()->ReturnInstruction(instr, expr->id());
+      new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
@@ -3028,7 +3090,7 @@
     HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id());
     set_current_block(join);
     if (join != NULL && !ast_context()->IsEffect()) {
-      ast_context()->ReturnValue(Pop());
+      return ast_context()->ReturnValue(Pop());
     }
   }
 }
@@ -3073,7 +3135,12 @@
   if (variable == NULL) {
     return Bailout("reference to rewritten variable");
   } else if (variable->IsStackAllocated()) {
-    ast_context()->ReturnValue(environment()->Lookup(variable));
+    HValue* value = environment()->Lookup(variable);
+    if (variable->mode() == Variable::CONST &&
+        value == graph()->GetConstantHole()) {
+      return Bailout("reference to uninitialized const variable");
+    }
+    return ast_context()->ReturnValue(value);
   } else if (variable->IsContextSlot()) {
     if (variable->mode() == Variable::CONST) {
       return Bailout("reference to const context slot");
@@ -3081,7 +3148,7 @@
     HValue* context = BuildContextChainWalk(variable);
     int index = variable->AsSlot()->index();
     HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index);
-    ast_context()->ReturnInstruction(instr, expr->id());
+    return ast_context()->ReturnInstruction(instr, expr->id());
   } else if (variable->is_global()) {
     LookupResult lookup;
     GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false);
@@ -3096,7 +3163,7 @@
       Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
       bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
       HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole);
-      ast_context()->ReturnInstruction(instr, expr->id());
+      return ast_context()->ReturnInstruction(instr, expr->id());
     } else {
       HValue* context = environment()->LookupContext();
       HGlobalObject* global_object = new(zone()) HGlobalObject(context);
@@ -3108,7 +3175,7 @@
                                          ast_context()->is_for_typeof());
       instr->set_position(expr->position());
       ASSERT(instr->HasSideEffects());
-      ast_context()->ReturnInstruction(instr, expr->id());
+      return ast_context()->ReturnInstruction(instr, expr->id());
     }
   } else {
     return Bailout("reference to a variable which requires dynamic lookup");
@@ -3122,7 +3189,7 @@
   ASSERT(current_block()->HasPredecessor());
   HConstant* instr =
       new(zone()) HConstant(expr->handle(), Representation::Tagged());
-  ast_context()->ReturnInstruction(instr, expr->id());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
@@ -3130,10 +3197,13 @@
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
-  HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(),
+  HValue* context = environment()->LookupContext();
+
+  HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context,
+                                                     expr->pattern(),
                                                      expr->flags(),
                                                      expr->literal_index());
-  ast_context()->ReturnInstruction(instr, expr->id());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
@@ -3203,9 +3273,9 @@
     // (e.g. because of code motion).
     HToFastProperties* result = new(zone()) HToFastProperties(Pop());
     AddInstruction(result);
-    ast_context()->ReturnValue(result);
+    return ast_context()->ReturnValue(result);
   } else {
-    ast_context()->ReturnValue(Pop());
+    return ast_context()->ReturnValue(Pop());
   }
 }
 
@@ -3216,8 +3286,10 @@
   ASSERT(current_block()->HasPredecessor());
   ZoneList<Expression*>* subexprs = expr->values();
   int length = subexprs->length();
+  HValue* context = environment()->LookupContext();
 
-  HArrayLiteral* literal = new(zone()) HArrayLiteral(expr->constant_elements(),
+  HArrayLiteral* literal = new(zone()) HArrayLiteral(context,
+                                                     expr->constant_elements(),
                                                      length,
                                                      expr->literal_index(),
                                                      expr->depth());
@@ -3249,15 +3321,7 @@
     AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
     AddSimulate(expr->GetIdForElement(i));
   }
-  ast_context()->ReturnValue(Pop());
-}
-
-
-void HGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
-  ASSERT(!HasStackOverflow());
-  ASSERT(current_block() != NULL);
-  ASSERT(current_block()->HasPredecessor());
-  return Bailout("CatchExtensionObject");
+  return ast_context()->ReturnValue(Pop());
 }
 
 
@@ -3419,15 +3483,14 @@
           Drop(1);
         }
       }
-      ast_context()->ReturnValue(value);
-      return;
+      return ast_context()->ReturnValue(value);
     }
   }
 
   ASSERT(join != NULL);
   join->SetJoinId(expr->id());
   set_current_block(join);
-  if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
+  if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
 }
 
 
@@ -3471,13 +3534,21 @@
     value = Pop();
     HValue* key = Pop();
     HValue* object = Pop();
-    instr = BuildStoreKeyed(object, key, value, expr);
+    bool has_side_effects = false;
+    HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
+                             expr->position(),
+                             true,  // is_store
+                             &has_side_effects);
+    Push(value);
+    ASSERT(has_side_effects);  // Stores always have side effects.
+    AddSimulate(expr->AssignmentId());
+    return ast_context()->ReturnValue(Pop());
   }
   Push(value);
   instr->set_position(expr->position());
   AddInstruction(instr);
   if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
-  ast_context()->ReturnValue(Pop());
+  return ast_context()->ReturnValue(Pop());
 }
 
 
@@ -3528,6 +3599,10 @@
   BinaryOperation* operation = expr->binary_operation();
 
   if (var != NULL) {
+    if (var->mode() == Variable::CONST)  {
+      return Bailout("unsupported const compound assignment");
+    }
+
     CHECK_ALIVE(VisitForValue(operation));
 
     if (var->is_global()) {
@@ -3538,6 +3613,20 @@
     } else if (var->IsStackAllocated()) {
       Bind(var, Top());
     } else if (var->IsContextSlot()) {
+      // Bail out if we try to mutate a parameter value in a function using
+      // the arguments object.  We do not (yet) correctly handle the
+      // arguments property of the function.
+      if (info()->scope()->arguments() != NULL) {
+        // Parameters will rewrite to context slots.  We have no direct way
+        // to detect that the variable is a parameter.
+        int count = info()->scope()->num_parameters();
+        for (int i = 0; i < count; ++i) {
+          if (var == info()->scope()->parameter(i)) {
+            Bailout("assignment to parameter, function uses arguments object");
+          }
+        }
+      }
+
       HValue* context = BuildContextChainWalk(var);
       int index = var->AsSlot()->index();
       HStoreContextSlot* instr =
@@ -3547,7 +3636,7 @@
     } else {
       return Bailout("compound assignment to lookup slot");
     }
-    ast_context()->ReturnValue(Pop());
+    return ast_context()->ReturnValue(Pop());
 
   } else if (prop != NULL) {
     prop->RecordTypeFeedback(oracle());
@@ -3582,7 +3671,7 @@
       Drop(2);
       Push(instr);
       if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
-      ast_context()->ReturnValue(Pop());
+      return ast_context()->ReturnValue(Pop());
 
     } else {
       // Keyed property.
@@ -3591,9 +3680,14 @@
       HValue* obj = environment()->ExpressionStackAt(1);
       HValue* key = environment()->ExpressionStackAt(0);
 
-      HInstruction* load = BuildLoadKeyed(obj, key, prop);
-      PushAndAdd(load);
-      if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId());
+      bool has_side_effects = false;
+      HValue* load = HandleKeyedElementAccess(
+          obj, key, NULL, prop, expr->CompoundLoadId(), RelocInfo::kNoPosition,
+          false,  // is_store
+          &has_side_effects);
+      Push(load);
+      if (has_side_effects) AddSimulate(expr->CompoundLoadId());
+
 
       CHECK_ALIVE(VisitForValue(expr->value()));
       HValue* right = Pop();
@@ -3604,13 +3698,17 @@
       if (instr->HasSideEffects()) AddSimulate(operation->id());
 
       expr->RecordTypeFeedback(oracle());
-      HInstruction* store = BuildStoreKeyed(obj, key, instr, expr);
-      AddInstruction(store);
+      HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
+                               RelocInfo::kNoPosition,
+                               true,  // is_store
+                               &has_side_effects);
+
       // Drop the simulated receiver, key, and value.  Return the value.
       Drop(3);
       Push(instr);
-      if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
-      ast_context()->ReturnValue(Pop());
+      ASSERT(has_side_effects);  // Stores always have side effects.
+      AddSimulate(expr->AssignmentId());
+      return ast_context()->ReturnValue(Pop());
     }
 
   } else {
@@ -3634,6 +3732,19 @@
   }
 
   if (var != NULL) {
+    if (var->mode() == Variable::CONST) {
+      if (expr->op() != Token::INIT_CONST) {
+        return Bailout("non-initializer assignment to const");
+      }
+      if (!var->IsStackAllocated()) {
+        return Bailout("assignment to const context slot");
+      }
+      // We insert a use of the old value to detect unsupported uses of const
+      // variables (e.g. initialization inside a loop).
+      HValue* old_value = environment()->Lookup(var);
+      AddInstruction(new HUseConst(old_value));
+    }
+
     if (proxy->IsArguments()) return Bailout("assignment to arguments");
 
     // Handle the assignment.
@@ -3644,9 +3755,24 @@
       CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
       HValue* value = Pop();
       Bind(var, value);
-      ast_context()->ReturnValue(value);
+      return ast_context()->ReturnValue(value);
 
-    } else if (var->IsContextSlot() && var->mode() != Variable::CONST) {
+    } else if (var->IsContextSlot()) {
+      ASSERT(var->mode() != Variable::CONST);
+      // Bail out if we try to mutate a parameter value in a function using
+      // the arguments object.  We do not (yet) correctly handle the
+      // arguments property of the function.
+      if (info()->scope()->arguments() != NULL) {
+        // Parameters will rewrite to context slots.  We have no direct way
+        // to detect that the variable is a parameter.
+        int count = info()->scope()->num_parameters();
+        for (int i = 0; i < count; ++i) {
+          if (var == info()->scope()->parameter(i)) {
+            Bailout("assignment to parameter, function uses arguments object");
+          }
+        }
+      }
+
       CHECK_ALIVE(VisitForValue(expr->value()));
       HValue* context = BuildContextChainWalk(var);
       int index = var->AsSlot()->index();
@@ -3654,7 +3780,7 @@
           new(zone()) HStoreContextSlot(context, index, Top());
       AddInstruction(instr);
       if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
-      ast_context()->ReturnValue(Pop());
+      return ast_context()->ReturnValue(Pop());
 
     } else if (var->is_global()) {
       CHECK_ALIVE(VisitForValue(expr->value()));
@@ -3662,7 +3788,7 @@
                                      Top(),
                                      expr->position(),
                                      expr->AssignmentId());
-      ast_context()->ReturnValue(Pop());
+      return ast_context()->ReturnValue(Pop());
 
     } else {
       return Bailout("assignment to LOOKUP or const CONTEXT variable");
@@ -3686,8 +3812,9 @@
   ASSERT(ast_context()->IsEffect());
   CHECK_ALIVE(VisitForValue(expr->exception()));
 
+  HValue* context = environment()->LookupContext();
   HValue* value = environment()->Pop();
-  HThrow* instr = new(zone()) HThrow(value);
+  HThrow* instr = new(zone()) HThrow(context, value);
   instr->set_position(expr->position());
   AddInstruction(instr);
   AddSimulate(expr->id());
@@ -3759,72 +3886,322 @@
 }
 
 
-HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object,
-                                                       HValue* key,
-                                                       Property* expr) {
-  ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
-  AddInstruction(new(zone()) HCheckNonSmi(object));
+HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
+    HValue* external_elements,
+    HValue* checked_key,
+    HValue* val,
+    JSObject::ElementsKind elements_kind,
+    bool is_store) {
+  if (is_store) {
+    ASSERT(val != NULL);
+    switch (elements_kind) {
+      case JSObject::EXTERNAL_PIXEL_ELEMENTS: {
+        HClampToUint8* clamp = new(zone()) HClampToUint8(val);
+        AddInstruction(clamp);
+        val = clamp;
+        break;
+      }
+      case JSObject::EXTERNAL_BYTE_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+      case JSObject::EXTERNAL_SHORT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+      case JSObject::EXTERNAL_INT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: {
+        HToInt32* floor_val = new(zone()) HToInt32(val);
+        AddInstruction(floor_val);
+        val = floor_val;
+        break;
+      }
+      case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+      case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+        break;
+      case JSObject::FAST_ELEMENTS:
+      case JSObject::FAST_DOUBLE_ELEMENTS:
+      case JSObject::DICTIONARY_ELEMENTS:
+      case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+        UNREACHABLE();
+        break;
+    }
+    return new(zone()) HStoreKeyedSpecializedArrayElement(
+        external_elements, checked_key, val, elements_kind);
+  } else {
+    return new(zone()) HLoadKeyedSpecializedArrayElement(
+        external_elements, checked_key, elements_kind);
+  }
+}
+
+
+HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
+                                                           HValue* key,
+                                                           HValue* val,
+                                                           Expression* expr,
+                                                           bool is_store) {
+  ASSERT(expr->IsMonomorphic());
   Handle<Map> map = expr->GetMonomorphicReceiverType();
-  ASSERT(map->has_fast_elements());
+  if (!map->has_fast_elements() &&
+      !map->has_fast_double_elements() &&
+      !map->has_external_array_elements()) {
+    return is_store ? BuildStoreKeyedGeneric(object, key, val)
+                    : BuildLoadKeyedGeneric(object, key);
+  }
+  AddInstruction(new(zone()) HCheckNonSmi(object));
   AddInstruction(new(zone()) HCheckMap(object, map));
-  bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
-  HLoadElements* elements = new(zone()) HLoadElements(object);
+  HInstruction* elements = new(zone()) HLoadElements(object);
   HInstruction* length = NULL;
   HInstruction* checked_key = NULL;
-  if (is_array) {
+  if (map->has_external_array_elements()) {
+    AddInstruction(elements);
+    length = AddInstruction(new(zone()) HExternalArrayLength(elements));
+    checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+    HLoadExternalArrayPointer* external_elements =
+        new(zone()) HLoadExternalArrayPointer(elements);
+    AddInstruction(external_elements);
+    return BuildExternalArrayElementAccess(external_elements, checked_key,
+                                           val, map->elements_kind(), is_store);
+  }
+  bool fast_double_elements = map->has_fast_double_elements();
+  ASSERT(map->has_fast_elements() || fast_double_elements);
+  if (map->instance_type() == JS_ARRAY_TYPE) {
     length = AddInstruction(new(zone()) HJSArrayLength(object));
     checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
     AddInstruction(elements);
+    if (is_store && !fast_double_elements) {
+      AddInstruction(new(zone()) HCheckMap(
+          elements, isolate()->factory()->fixed_array_map()));
+    }
   } else {
     AddInstruction(elements);
+    if (is_store && !fast_double_elements) {
+      AddInstruction(new(zone()) HCheckMap(
+          elements, isolate()->factory()->fixed_array_map()));
+    }
     length = AddInstruction(new(zone()) HFixedArrayLength(elements));
     checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
   }
-  return new(zone()) HLoadKeyedFastElement(elements, checked_key);
-}
-
-
-HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement(
-    HValue* object,
-    HValue* key,
-    Property* expr) {
-  ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
-  AddInstruction(new(zone()) HCheckNonSmi(object));
-  Handle<Map> map = expr->GetMonomorphicReceiverType();
-  ASSERT(!map->has_fast_elements());
-  ASSERT(map->has_external_array_elements());
-  AddInstruction(new(zone()) HCheckMap(object, map));
-  HLoadElements* elements = new(zone()) HLoadElements(object);
-  AddInstruction(elements);
-  HInstruction* length = new(zone()) HExternalArrayLength(elements);
-  AddInstruction(length);
-  HInstruction* checked_key =
-      AddInstruction(new(zone()) HBoundsCheck(key, length));
-  HLoadExternalArrayPointer* external_elements =
-      new(zone()) HLoadExternalArrayPointer(elements);
-  AddInstruction(external_elements);
-  HLoadKeyedSpecializedArrayElement* pixel_array_value =
-      new(zone()) HLoadKeyedSpecializedArrayElement(
-          external_elements, checked_key, expr->external_array_type());
-  return pixel_array_value;
-}
-
-
-HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj,
-                                            HValue* key,
-                                            Property* prop) {
-  if (prop->IsMonomorphic()) {
-    Handle<Map> receiver_type(prop->GetMonomorphicReceiverType());
-    // An object has either fast elements or pixel array elements, but never
-    // both. Pixel array maps that are assigned to pixel array elements are
-    // always created with the fast elements flag cleared.
-    if (receiver_type->has_external_array_elements()) {
-      return BuildLoadKeyedSpecializedArrayElement(obj, key, prop);
-    } else if (receiver_type->has_fast_elements()) {
-      return BuildLoadKeyedFastElement(obj, key, prop);
+  if (is_store) {
+    if (fast_double_elements) {
+      return new(zone()) HStoreKeyedFastDoubleElement(elements,
+                                                      checked_key,
+                                                      val);
+    } else {
+      return new(zone()) HStoreKeyedFastElement(elements, checked_key, val);
+    }
+  } else {
+    if (fast_double_elements) {
+      return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key);
+    } else {
+      return new(zone()) HLoadKeyedFastElement(elements, checked_key);
     }
   }
-  return BuildLoadKeyedGeneric(obj, key);
+}
+
+
+HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
+                                                      HValue* key,
+                                                      HValue* val,
+                                                      Expression* prop,
+                                                      int ast_id,
+                                                      int position,
+                                                      bool is_store,
+                                                      bool* has_side_effects) {
+  *has_side_effects = false;
+  AddInstruction(new(zone()) HCheckNonSmi(object));
+  AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
+  ZoneMapList* maps = prop->GetReceiverTypes();
+  bool todo_external_array = false;
+
+  static const int kNumElementTypes = JSObject::kElementsKindCount;
+  bool type_todo[kNumElementTypes];
+  for (int i = 0; i < kNumElementTypes; ++i) {
+    type_todo[i] = false;
+  }
+
+  for (int i = 0; i < maps->length(); ++i) {
+    ASSERT(maps->at(i)->IsMap());
+    type_todo[maps->at(i)->elements_kind()] = true;
+    if (maps->at(i)->elements_kind()
+        >= JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) {
+      todo_external_array = true;
+    }
+  }
+
+  HBasicBlock* join = graph()->CreateBasicBlock();
+
+  HInstruction* elements_kind_instr =
+      AddInstruction(new(zone()) HElementsKind(object));
+  HInstruction* elements = NULL;
+  HLoadExternalArrayPointer* external_elements = NULL;
+  HInstruction* checked_key = NULL;
+
+  // FAST_ELEMENTS is assumed to be the first case.
+  STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0);
+
+  for (JSObject::ElementsKind elements_kind = JSObject::FAST_ELEMENTS;
+       elements_kind <= JSObject::LAST_ELEMENTS_KIND;
+       elements_kind = JSObject::ElementsKind(elements_kind + 1)) {
+    // After having handled FAST_ELEMENTS and DICTIONARY_ELEMENTS, we
+    // need to add some code that's executed for all external array cases.
+    STATIC_ASSERT(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND ==
+                  JSObject::LAST_ELEMENTS_KIND);
+    if (elements_kind == JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
+        && todo_external_array) {
+      elements = AddInstruction(new(zone()) HLoadElements(object));
+      // We need to forcibly prevent some ElementsKind-dependent instructions
+      // from being hoisted out of any loops they might occur in, because
+      // the current loop-invariant-code-motion algorithm isn't clever enough
+      // to deal with them properly.
+      // There's some performance to be gained by developing a smarter
+      // solution for this.
+      elements->ClearFlag(HValue::kUseGVN);
+      HInstruction* length =
+          AddInstruction(new(zone()) HExternalArrayLength(elements));
+      checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+      external_elements = new(zone()) HLoadExternalArrayPointer(elements);
+      AddInstruction(external_elements);
+    }
+    if (type_todo[elements_kind]) {
+      HBasicBlock* if_true = graph()->CreateBasicBlock();
+      HBasicBlock* if_false = graph()->CreateBasicBlock();
+      HCompareConstantEqAndBranch* compare =
+          new(zone()) HCompareConstantEqAndBranch(elements_kind_instr,
+                                                  elements_kind,
+                                                  Token::EQ_STRICT);
+      compare->SetSuccessorAt(0, if_true);
+      compare->SetSuccessorAt(1, if_false);
+      current_block()->Finish(compare);
+
+      set_current_block(if_true);
+      HInstruction* access;
+      if (elements_kind == JSObject::FAST_ELEMENTS ||
+          elements_kind == JSObject::FAST_DOUBLE_ELEMENTS) {
+        HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
+        HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
+        HHasInstanceTypeAndBranch* typecheck =
+            new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
+        typecheck->SetSuccessorAt(0, if_jsarray);
+        typecheck->SetSuccessorAt(1, if_fastobject);
+        current_block()->Finish(typecheck);
+
+        set_current_block(if_jsarray);
+        HInstruction* length = new(zone()) HJSArrayLength(object);
+        AddInstruction(length);
+        length->ClearFlag(HValue::kUseGVN);
+        checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+        elements = AddInstruction(new(zone()) HLoadElements(object));
+        elements->ClearFlag(HValue::kUseGVN);
+        bool fast_double_elements =
+            elements_kind == JSObject::FAST_DOUBLE_ELEMENTS;
+        if (is_store) {
+          if (fast_double_elements) {
+            access = AddInstruction(
+                new(zone()) HStoreKeyedFastDoubleElement(elements,
+                                                         checked_key,
+                                                         val));
+          } else {
+            AddInstruction(new(zone()) HCheckMap(
+                elements, isolate()->factory()->fixed_array_map()));
+            access = AddInstruction(
+                new(zone()) HStoreKeyedFastElement(elements, checked_key, val));
+          }
+        } else {
+          if (fast_double_elements) {
+            access = AddInstruction(
+                new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key));
+          } else {
+            access = AddInstruction(
+                new(zone()) HLoadKeyedFastElement(elements, checked_key));
+          }
+          Push(access);
+        }
+        *has_side_effects |= access->HasSideEffects();
+        if (position != -1) {
+          access->set_position(position);
+        }
+        if_jsarray->Goto(join);
+
+        set_current_block(if_fastobject);
+        elements = AddInstruction(new(zone()) HLoadElements(object));
+        elements->ClearFlag(HValue::kUseGVN);
+        if (is_store && !fast_double_elements) {
+          AddInstruction(new(zone()) HCheckMap(
+              elements, isolate()->factory()->fixed_array_map()));
+        }
+        length = AddInstruction(new(zone()) HFixedArrayLength(elements));
+        checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+        if (is_store) {
+          if (fast_double_elements) {
+            access = AddInstruction(
+                new(zone()) HStoreKeyedFastDoubleElement(elements,
+                                                         checked_key,
+                                                         val));
+          } else {
+            access = AddInstruction(
+                new(zone()) HStoreKeyedFastElement(elements, checked_key, val));
+          }
+        } else {
+          if (fast_double_elements) {
+            access = AddInstruction(
+                new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key));
+          } else {
+            access = AddInstruction(
+                new(zone()) HLoadKeyedFastElement(elements, checked_key));
+          }
+        }
+      } else if (elements_kind == JSObject::DICTIONARY_ELEMENTS) {
+        if (is_store) {
+          access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
+        } else {
+          access = AddInstruction(BuildLoadKeyedGeneric(object, key));
+        }
+      } else {  // External array elements.
+        access = AddInstruction(BuildExternalArrayElementAccess(
+            external_elements, checked_key, val, elements_kind, is_store));
+      }
+      *has_side_effects |= access->HasSideEffects();
+      access->set_position(position);
+      if (!is_store) {
+        Push(access);
+      }
+      current_block()->Goto(join);
+      set_current_block(if_false);
+    }
+  }
+
+  // Deopt if none of the cases matched.
+  current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
+  join->SetJoinId(ast_id);
+  set_current_block(join);
+  return is_store ? NULL : Pop();
+}
+
+
+HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj,
+                                                HValue* key,
+                                                HValue* val,
+                                                Expression* expr,
+                                                int ast_id,
+                                                int position,
+                                                bool is_store,
+                                                bool* has_side_effects) {
+  ASSERT(!expr->IsPropertyName());
+  HInstruction* instr = NULL;
+  if (expr->IsMonomorphic()) {
+    instr = BuildMonomorphicElementAccess(obj, key, val, expr, is_store);
+  } else if (expr->GetReceiverTypes() != NULL &&
+             !expr->GetReceiverTypes()->is_empty()) {
+    return HandlePolymorphicElementAccess(
+        obj, key, val, expr, ast_id, position, is_store, has_side_effects);
+  } else {
+    if (is_store) {
+      instr = BuildStoreKeyedGeneric(obj, key, val);
+    } else {
+      instr = BuildLoadKeyedGeneric(obj, key);
+    }
+  }
+  instr->set_position(position);
+  AddInstruction(instr);
+  *has_side_effects = instr->HasSideEffects();
+  return instr;
 }
 
 
@@ -3840,87 +4217,6 @@
                          function_strict_mode());
 }
 
-
-HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object,
-                                                        HValue* key,
-                                                        HValue* val,
-                                                        Expression* expr) {
-  ASSERT(expr->IsMonomorphic());
-  AddInstruction(new(zone()) HCheckNonSmi(object));
-  Handle<Map> map = expr->GetMonomorphicReceiverType();
-  ASSERT(map->has_fast_elements());
-  AddInstruction(new(zone()) HCheckMap(object, map));
-  HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
-  AddInstruction(new(zone()) HCheckMap(
-      elements, isolate()->factory()->fixed_array_map()));
-  bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
-  HInstruction* length = NULL;
-  if (is_array) {
-    length = AddInstruction(new(zone()) HJSArrayLength(object));
-  } else {
-    length = AddInstruction(new(zone()) HFixedArrayLength(elements));
-  }
-  HInstruction* checked_key =
-      AddInstruction(new(zone()) HBoundsCheck(key, length));
-  return new(zone()) HStoreKeyedFastElement(elements, checked_key, val);
-}
-
-
-HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement(
-    HValue* object,
-    HValue* key,
-    HValue* val,
-    Expression* expr) {
-  ASSERT(expr->IsMonomorphic());
-  AddInstruction(new(zone()) HCheckNonSmi(object));
-  Handle<Map> map = expr->GetMonomorphicReceiverType();
-  ASSERT(!map->has_fast_elements());
-  ASSERT(map->has_external_array_elements());
-  AddInstruction(new(zone()) HCheckMap(object, map));
-  HLoadElements* elements = new(zone()) HLoadElements(object);
-  AddInstruction(elements);
-  HInstruction* length = AddInstruction(
-      new(zone()) HExternalArrayLength(elements));
-  HInstruction* checked_key =
-      AddInstruction(new(zone()) HBoundsCheck(key, length));
-  HLoadExternalArrayPointer* external_elements =
-      new(zone()) HLoadExternalArrayPointer(elements);
-  AddInstruction(external_elements);
-  if (expr->external_array_type() == kExternalPixelArray) {
-    HClampToUint8* clamp = new(zone()) HClampToUint8(val);
-    AddInstruction(clamp);
-    val = clamp;
-  }
-  return new(zone()) HStoreKeyedSpecializedArrayElement(
-      external_elements,
-      checked_key,
-      val,
-      expr->external_array_type());
-}
-
-
-HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object,
-                                             HValue* key,
-                                             HValue* value,
-                                             Expression* expr) {
-  if (expr->IsMonomorphic()) {
-    Handle<Map> receiver_type(expr->GetMonomorphicReceiverType());
-    // An object has either fast elements or external array elements, but
-    // never both. Pixel array maps that are assigned to pixel array elements
-    // are always created with the fast elements flag cleared.
-    if (receiver_type->has_external_array_elements()) {
-      return BuildStoreKeyedSpecializedArrayElement(object,
-                                                    key,
-                                                    value,
-                                                    expr);
-    } else if (receiver_type->has_fast_elements()) {
-      return BuildStoreKeyedFastElement(object, key, value, expr);
-    }
-  }
-  return BuildStoreKeyedGeneric(object, key, value);
-}
-
-
 bool HGraphBuilder::TryArgumentsAccess(Property* expr) {
   VariableProxy* proxy = expr->obj()->AsVariableProxy();
   if (proxy == NULL) return false;
@@ -3986,9 +4282,11 @@
     CHECK_ALIVE(VisitForValue(expr->key()));
     HValue* index = Pop();
     HValue* string = Pop();
-    HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
+    HValue* context = environment()->LookupContext();
+    HStringCharCodeAt* char_code =
+      BuildStringCharCodeAt(context, string, index);
     AddInstruction(char_code);
-    instr = new(zone()) HStringCharFromCode(char_code);
+    instr = new(zone()) HStringCharFromCode(context, char_code);
 
   } else if (expr->IsFunctionPrototype()) {
     HValue* function = Pop();
@@ -4004,7 +4302,8 @@
       instr = BuildLoadNamed(obj, expr, types->first(), name);
     } else if (types != NULL && types->length() > 1) {
       AddInstruction(new(zone()) HCheckNonSmi(obj));
-      instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name);
+      HValue* context = environment()->LookupContext();
+      instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name);
     } else {
       instr = BuildLoadNamedGeneric(obj, expr);
     }
@@ -4014,10 +4313,25 @@
 
     HValue* key = Pop();
     HValue* obj = Pop();
-    instr = BuildLoadKeyed(obj, key, expr);
+
+    bool has_side_effects = false;
+    HValue* load = HandleKeyedElementAccess(
+        obj, key, NULL, expr, expr->id(), expr->position(),
+        false,  // is_store
+        &has_side_effects);
+    if (has_side_effects) {
+      if (ast_context()->IsEffect()) {
+        AddSimulate(expr->id());
+      } else {
+        Push(load);
+        AddSimulate(expr->id());
+        Drop(1);
+      }
+    }
+    return ast_context()->ReturnValue(load);
   }
   instr->set_position(expr->position());
-  ast_context()->ReturnInstruction(instr, expr->id());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
@@ -4105,8 +4419,7 @@
       if (!ast_context()->IsEffect()) Push(call);
       current_block()->Goto(join);
     } else {
-      ast_context()->ReturnInstruction(call, expr->id());
-      return;
+      return ast_context()->ReturnInstruction(call, expr->id());
     }
   }
 
@@ -4117,7 +4430,7 @@
   if (join->HasPredecessor()) {
     set_current_block(join);
     join->SetJoinId(expr->id());
-    if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
+    if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
   } else {
     set_current_block(NULL);
   }
@@ -4229,14 +4542,6 @@
     return false;
   }
 
-  // Check if we can handle all declarations in the inlined functions.
-  VisitDeclarations(target_info.scope()->declarations());
-  if (HasStackOverflow()) {
-    TraceInline(target, caller, "target has non-trivial declaration");
-    ClearStackOverflow();
-    return false;
-  }
-
   // Don't inline functions that uses the arguments object or that
   // have a mismatching number of parameters.
   int arity = expr->arguments()->length();
@@ -4246,6 +4551,15 @@
     return false;
   }
 
+  // All declarations must be inlineable.
+  ZoneList<Declaration*>* decls = target_info.scope()->declarations();
+  int decl_count = decls->length();
+  for (int i = 0; i < decl_count; ++i) {
+    if (!decls->at(i)->IsInlineable()) {
+      TraceInline(target, caller, "target has non-trivial declaration");
+      return false;
+    }
+  }
   // All statements in the body must be inlineable.
   for (int i = 0, count = function->body()->length(); i < count; ++i) {
     if (!function->body()->at(i)->IsInlineable()) {
@@ -4264,6 +4578,13 @@
       TraceInline(target, caller, "could not generate deoptimization info");
       return false;
     }
+    if (target_shared->scope_info() == SerializedScopeInfo::Empty()) {
+      // The scope info might not have been set if a lazily compiled
+      // function is inlined before being called for the first time.
+      Handle<SerializedScopeInfo> target_scope_info =
+          SerializedScopeInfo::Create(target_info.scope());
+      target_shared->set_scope_info(*target_scope_info);
+    }
     target_shared->EnableDeoptimizationSupport(*target_info.code());
     Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG,
                                         &target_info,
@@ -4271,6 +4592,9 @@
   }
 
   // ----------------------------------------------------------------
+  // After this point, we've made a decision to inline this function (so
+  // TryInline should always return true).
+
   // Save the pending call context and type feedback oracle. Set up new ones
   // for the inlined function.
   ASSERT(target_shared->has_deoptimization_support());
@@ -4283,17 +4607,16 @@
   HEnvironment* inner_env =
       environment()->CopyForInlining(target,
                                      function,
-                                     HEnvironment::HYDROGEN,
                                      undefined,
                                      call_kind);
   HBasicBlock* body_entry = CreateBasicBlock(inner_env);
   current_block()->Goto(body_entry);
-
   body_entry->SetJoinId(expr->ReturnId());
   set_current_block(body_entry);
   AddInstruction(new(zone()) HEnterInlined(target,
                                            function,
                                            call_kind));
+  VisitDeclarations(target_info.scope()->declarations());
   VisitStatements(function->body());
   if (HasStackOverflow()) {
     // Bail out if the inline function did, as we cannot residualize a call
@@ -4316,7 +4639,7 @@
       ASSERT(function_return() != NULL);
       ASSERT(call_context()->IsEffect() || call_context()->IsValue());
       if (call_context()->IsEffect()) {
-        current_block()->Goto(function_return(), false);
+        current_block()->Goto(function_return());
       } else {
         current_block()->AddLeaveInlined(undefined, function_return());
       }
@@ -4328,11 +4651,11 @@
       // TODO(3168478): refactor to avoid this.
       HBasicBlock* empty_true = graph()->CreateBasicBlock();
       HBasicBlock* empty_false = graph()->CreateBasicBlock();
-      HTest* test = new(zone()) HTest(undefined, empty_true, empty_false);
+      HBranch* test = new(zone()) HBranch(undefined, empty_true, empty_false);
       current_block()->Finish(test);
 
-      empty_true->Goto(inlined_test_context()->if_true(), false);
-      empty_false->Goto(inlined_test_context()->if_false(), false);
+      empty_true->Goto(inlined_test_context()->if_true());
+      empty_false->Goto(inlined_test_context()->if_false());
     }
   }
 
@@ -4340,25 +4663,22 @@
   if (inlined_test_context() != NULL) {
     HBasicBlock* if_true = inlined_test_context()->if_true();
     HBasicBlock* if_false = inlined_test_context()->if_false();
-    ASSERT(ast_context() == inlined_test_context());
+
     // Pop the return test context from the expression context stack.
+    ASSERT(ast_context() == inlined_test_context());
     ClearInlinedTestContext();
 
     // Forward to the real test context.
     if (if_true->HasPredecessor()) {
       if_true->SetJoinId(expr->id());
       HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
-      if_true->Goto(true_target, false);
+      if_true->Goto(true_target);
     }
     if (if_false->HasPredecessor()) {
       if_false->SetJoinId(expr->id());
       HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
-      if_false->Goto(false_target, false);
+      if_false->Goto(false_target);
     }
-
-    // TODO(kmillikin): Come up with a better way to handle this. It is too
-    // subtle. NULL here indicates that the enclosing context has no control
-    // flow to handle.
     set_current_block(NULL);
 
   } else if (function_return()->HasPredecessor()) {
@@ -4387,18 +4707,20 @@
       if (argument_count == 2 && check_type == STRING_CHECK) {
         HValue* index = Pop();
         HValue* string = Pop();
+        HValue* context = environment()->LookupContext();
         ASSERT(!expr->holder().is_null());
         AddInstruction(new(zone()) HCheckPrototypeMaps(
             oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK),
             expr->holder()));
-        HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
+        HStringCharCodeAt* char_code =
+            BuildStringCharCodeAt(context, string, index);
         if (id == kStringCharCodeAt) {
           ast_context()->ReturnInstruction(char_code, expr->id());
           return true;
         }
         AddInstruction(char_code);
         HStringCharFromCode* result =
-            new(zone()) HStringCharFromCode(char_code);
+            new(zone()) HStringCharFromCode(context, char_code);
         ast_context()->ReturnInstruction(result, expr->id());
         return true;
       }
@@ -4413,8 +4735,10 @@
       if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
         AddCheckConstantFunction(expr, receiver, receiver_map, true);
         HValue* argument = Pop();
+        HValue* context = environment()->LookupContext();
         Drop(1);  // Receiver.
-        HUnaryMathOperation* op = new(zone()) HUnaryMathOperation(argument, id);
+        HUnaryMathOperation* op =
+            new(zone()) HUnaryMathOperation(context, argument, id);
         op->set_position(expr->position());
         ast_context()->ReturnInstruction(op, expr->id());
         return true;
@@ -4426,31 +4750,33 @@
         HValue* right = Pop();
         HValue* left = Pop();
         Pop();  // Pop receiver.
+        HValue* context = environment()->LookupContext();
         HInstruction* result = NULL;
         // Use sqrt() if exponent is 0.5 or -0.5.
         if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
           double exponent = HConstant::cast(right)->DoubleValue();
           if (exponent == 0.5) {
-            result = new(zone()) HUnaryMathOperation(left, kMathPowHalf);
+            result =
+                new(zone()) HUnaryMathOperation(context, left, kMathPowHalf);
           } else if (exponent == -0.5) {
             HConstant* double_one =
                 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)),
                                       Representation::Double());
             AddInstruction(double_one);
             HUnaryMathOperation* square_root =
-                new(zone()) HUnaryMathOperation(left, kMathPowHalf);
+                new(zone()) HUnaryMathOperation(context, left, kMathPowHalf);
             AddInstruction(square_root);
             // MathPowHalf doesn't have side effects so there's no need for
             // an environment simulation here.
             ASSERT(!square_root->HasSideEffects());
-            result = new(zone()) HDiv(double_one, square_root);
+            result = new(zone()) HDiv(context, double_one, square_root);
           } else if (exponent == 2.0) {
-            result = new(zone()) HMul(left, left);
+            result = new(zone()) HMul(context, left, left);
           }
         } else if (right->IsConstant() &&
                    HConstant::cast(right)->HasInteger32Value() &&
                    HConstant::cast(right)->Integer32Value() == 2) {
-          result = new(zone()) HMul(left, left);
+          result = new(zone()) HMul(context, left, left);
         }
 
         if (result == NULL) {
@@ -4532,7 +4858,7 @@
   if (prop != NULL) {
     if (!prop->key()->IsPropertyName()) {
       // Keyed function call.
-      CHECK_ALIVE(VisitForValue(prop->obj()));
+      CHECK_ALIVE(VisitArgument(prop->obj()));
 
       CHECK_ALIVE(VisitForValue(prop->key()));
       // Push receiver and key like the non-optimized code generator expects it.
@@ -4541,15 +4867,13 @@
       Push(key);
       Push(receiver);
 
-      CHECK_ALIVE(VisitExpressions(expr->arguments()));
+      CHECK_ALIVE(VisitArgumentList(expr->arguments()));
 
       HValue* context = environment()->LookupContext();
-      call = PreProcessCall(
-          new(zone()) HCallKeyed(context, key, argument_count));
+      call = new(zone()) HCallKeyed(context, key, argument_count);
       call->set_position(expr->position());
-      Drop(1);  // Key.
-      ast_context()->ReturnInstruction(call, expr->id());
-      return;
+      Drop(argument_count + 1);  // 1 is the key.
+      return ast_context()->ReturnInstruction(call, expr->id());
     }
 
     // Named function call.
@@ -4607,11 +4931,6 @@
     Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
     bool global_call = (var != NULL) && var->is_global() && !var->is_this();
 
-    if (!global_call) {
-      ++argument_count;
-      CHECK_ALIVE(VisitForValue(expr->expression()));
-    }
-
     if (global_call) {
       bool known_global_function = false;
       // If there is a global property cell for the name at compile time and
@@ -4651,27 +4970,34 @@
                                                            argument_count));
       } else {
         HValue* context = environment()->LookupContext();
-        PushAndAdd(new(zone()) HGlobalObject(context));
-        CHECK_ALIVE(VisitExpressions(expr->arguments()));
+        HGlobalObject* receiver = new(zone()) HGlobalObject(context);
+        AddInstruction(receiver);
+        PushAndAdd(new(zone()) HPushArgument(receiver));
+        CHECK_ALIVE(VisitArgumentList(expr->arguments()));
 
-        call = PreProcessCall(new(zone()) HCallGlobal(context,
-                                                      var->name(),
-                                                      argument_count));
+        call = new(zone()) HCallGlobal(context, var->name(), argument_count);
+        Drop(argument_count);
       }
 
     } else {
+      CHECK_ALIVE(VisitArgument(expr->expression()));
       HValue* context = environment()->LookupContext();
       HGlobalObject* global_object = new(zone()) HGlobalObject(context);
+      HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object);
       AddInstruction(global_object);
-      PushAndAdd(new(zone()) HGlobalReceiver(global_object));
-      CHECK_ALIVE(VisitExpressions(expr->arguments()));
+      AddInstruction(receiver);
+      PushAndAdd(new(zone()) HPushArgument(receiver));
+      CHECK_ALIVE(VisitArgumentList(expr->arguments()));
 
-      call = PreProcessCall(new(zone()) HCallFunction(context, argument_count));
+      // The function to call is treated as an argument to the call function
+      // stub.
+      call = new(zone()) HCallFunction(context, argument_count + 1);
+      Drop(argument_count + 1);
     }
   }
 
   call->set_position(expr->position());
-  ast_context()->ReturnInstruction(call, expr->id());
+  return ast_context()->ReturnInstruction(call, expr->id());
 }
 
 
@@ -4681,19 +5007,19 @@
   ASSERT(current_block()->HasPredecessor());
   // The constructor function is also used as the receiver argument to the
   // JS construct call builtin.
-  CHECK_ALIVE(VisitForValue(expr->expression()));
-  CHECK_ALIVE(VisitExpressions(expr->arguments()));
+  HValue* constructor = NULL;
+  CHECK_ALIVE(constructor = VisitArgument(expr->expression()));
+  CHECK_ALIVE(VisitArgumentList(expr->arguments()));
 
   HValue* context = environment()->LookupContext();
 
   // The constructor is both an operand to the instruction and an argument
   // to the construct call.
   int arg_count = expr->arguments()->length() + 1;  // Plus constructor.
-  HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
   HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count);
   call->set_position(expr->position());
-  PreProcessCall(call);
-  ast_context()->ReturnInstruction(call, expr->id());
+  Drop(arg_count);
+  return ast_context()->ReturnInstruction(call, expr->id());
 }
 
 
@@ -4739,13 +5065,14 @@
     ASSERT(function->intrinsic_type == Runtime::RUNTIME);
     CHECK_ALIVE(VisitArgumentList(expr->arguments()));
 
+    HValue* context = environment()->LookupContext();
     Handle<String> name = expr->name();
     int argument_count = expr->arguments()->length();
     HCallRuntime* call =
-        new(zone()) HCallRuntime(name, function, argument_count);
+        new(zone()) HCallRuntime(context, name, function, argument_count);
     call->set_position(RelocInfo::kNoPosition);
     Drop(argument_count);
-    ast_context()->ReturnInstruction(call, expr->id());
+    return ast_context()->ReturnInstruction(call, expr->id());
   }
 }
 
@@ -4773,26 +5100,27 @@
     // Result of deleting non-property, non-variable reference is true.
     // Evaluate the subexpression for side effects.
     CHECK_ALIVE(VisitForEffect(expr->expression()));
-    ast_context()->ReturnValue(graph()->GetConstantTrue());
+    return ast_context()->ReturnValue(graph()->GetConstantTrue());
   } else if (var != NULL &&
              !var->is_global() &&
              var->AsSlot() != NULL &&
              var->AsSlot()->type() != Slot::LOOKUP) {
     // Result of deleting non-global, non-dynamic variables is false.
     // The subexpression does not have side effects.
-    ast_context()->ReturnValue(graph()->GetConstantFalse());
+    return ast_context()->ReturnValue(graph()->GetConstantFalse());
   } else if (prop != NULL) {
     if (prop->is_synthetic()) {
       // Result of deleting parameters is false, even when they rewrite
       // to accesses on the arguments object.
-      ast_context()->ReturnValue(graph()->GetConstantFalse());
-    } else {
+      return ast_context()->ReturnValue(graph()->GetConstantFalse());
+  } else {
       CHECK_ALIVE(VisitForValue(prop->obj()));
       CHECK_ALIVE(VisitForValue(prop->key()));
       HValue* key = Pop();
       HValue* obj = Pop();
-      HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key);
-      ast_context()->ReturnInstruction(instr, expr->id());
+      HValue* context = environment()->LookupContext();
+      HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key);
+      return ast_context()->ReturnInstruction(instr, expr->id());
     }
   } else if (var->is_global()) {
     Bailout("delete with global variable");
@@ -4804,42 +5132,58 @@
 
 void HGraphBuilder::VisitVoid(UnaryOperation* expr) {
   CHECK_ALIVE(VisitForEffect(expr->expression()));
-  ast_context()->ReturnValue(graph()->GetConstantUndefined());
+  return ast_context()->ReturnValue(graph()->GetConstantUndefined());
 }
 
 
 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) {
   CHECK_ALIVE(VisitForTypeOf(expr->expression()));
   HValue* value = Pop();
-  ast_context()->ReturnInstruction(new(zone()) HTypeof(value), expr->id());
+  HValue* context = environment()->LookupContext();
+  HInstruction* instr = new(zone()) HTypeof(context, value);
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
 void HGraphBuilder::VisitAdd(UnaryOperation* expr) {
   CHECK_ALIVE(VisitForValue(expr->expression()));
   HValue* value = Pop();
-  HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1());
-  ast_context()->ReturnInstruction(instr, expr->id());
+  HValue* context = environment()->LookupContext();
+  HInstruction* instr =
+      new(zone()) HMul(context, value, graph_->GetConstant1());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
 void HGraphBuilder::VisitSub(UnaryOperation* expr) {
   CHECK_ALIVE(VisitForValue(expr->expression()));
   HValue* value = Pop();
-  HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1());
+  HValue* context = environment()->LookupContext();
+  HInstruction* instr =
+      new(zone()) HMul(context, value, graph_->GetConstantMinus1());
   TypeInfo info = oracle()->UnaryType(expr);
+  if (info.IsUninitialized()) {
+    AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
+    info = TypeInfo::Unknown();
+  }
   Representation rep = ToRepresentation(info);
   TraceRepresentation(expr->op(), info, instr, rep);
   instr->AssumeRepresentation(rep);
-  ast_context()->ReturnInstruction(instr, expr->id());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) {
   CHECK_ALIVE(VisitForValue(expr->expression()));
   HValue* value = Pop();
+  TypeInfo info = oracle()->UnaryType(expr);
+  if (info.IsUninitialized()) {
+    AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
+  }
   HInstruction* instr = new(zone()) HBitNot(value);
-  ast_context()->ReturnInstruction(instr, expr->id());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
@@ -4884,7 +5228,7 @@
   HBasicBlock* join =
     CreateJoin(materialize_false, materialize_true, expr->id());
   set_current_block(join);
-  if (join != NULL) ast_context()->ReturnValue(Pop());
+  if (join != NULL) return ast_context()->ReturnValue(Pop());
 }
 
 
@@ -4913,7 +5257,8 @@
   HConstant* delta = (expr->op() == Token::INC)
       ? graph_->GetConstant1()
       : graph_->GetConstantMinus1();
-  HInstruction* instr = new(zone()) HAdd(Top(), delta);
+  HValue* context = environment()->LookupContext();
+  HInstruction* instr = new(zone()) HAdd(context, Top(), delta);
   TraceRepresentation(expr->op(), info, instr, rep);
   instr->AssumeRepresentation(rep);
   AddInstruction(instr);
@@ -4942,6 +5287,9 @@
   HValue* after = NULL;  // The result after incrementing or decrementing.
 
   if (var != NULL) {
+    if (var->mode() == Variable::CONST)  {
+      return Bailout("unsupported count operation with const");
+    }
     // Argument of the count operation is a variable, not a property.
     ASSERT(prop == NULL);
     CHECK_ALIVE(VisitForValue(target));
@@ -4958,6 +5306,20 @@
     } else if (var->IsStackAllocated()) {
       Bind(var, after);
     } else if (var->IsContextSlot()) {
+      // Bail out if we try to mutate a parameter value in a function using
+      // the arguments object.  We do not (yet) correctly handle the
+      // arguments property of the function.
+      if (info()->scope()->arguments() != NULL) {
+        // Parameters will rewrite to context slots.  We have no direct way
+        // to detect that the variable is a parameter.
+        int count = info()->scope()->num_parameters();
+        for (int i = 0; i < count; ++i) {
+          if (var == info()->scope()->parameter(i)) {
+            Bailout("assignment to parameter, function uses arguments object");
+          }
+        }
+      }
+
       HValue* context = BuildContextChainWalk(var);
       int index = var->AsSlot()->index();
       HStoreContextSlot* instr =
@@ -5013,16 +5375,22 @@
       HValue* obj = environment()->ExpressionStackAt(1);
       HValue* key = environment()->ExpressionStackAt(0);
 
-      HInstruction* load = BuildLoadKeyed(obj, key, prop);
-      PushAndAdd(load);
-      if (load->HasSideEffects()) AddSimulate(expr->CountId());
+      bool has_side_effects = false;
+      HValue* load = HandleKeyedElementAccess(
+          obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition,
+          false,  // is_store
+          &has_side_effects);
+      Push(load);
+      if (has_side_effects) AddSimulate(expr->CountId());
 
       after = BuildIncrement(returns_original_input, expr);
       input = Pop();
 
       expr->RecordTypeFeedback(oracle());
-      HInstruction* store = BuildStoreKeyed(obj, key, after, expr);
-      AddInstruction(store);
+      HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(),
+                               RelocInfo::kNoPosition,
+                               true,  // is_store
+                               &has_side_effects);
 
       // Drop the key from the bailout environment.  Overwrite the receiver
       // with the result of the operation, and the placeholder with the
@@ -5030,28 +5398,18 @@
       Drop(1);
       environment()->SetExpressionStackAt(0, after);
       if (returns_original_input) environment()->SetExpressionStackAt(1, input);
-      if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
+      ASSERT(has_side_effects);  // Stores always have side effects.
+      AddSimulate(expr->AssignmentId());
     }
   }
 
   Drop(returns_original_input ? 2 : 1);
-  ast_context()->ReturnValue(expr->is_postfix() ? input : after);
+  return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
 }
 
 
-HCompareSymbolEq* HGraphBuilder::BuildSymbolCompare(HValue* left,
-                                                    HValue* right,
-                                                    Token::Value op) {
-  ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
-  AddInstruction(new(zone()) HCheckNonSmi(left));
-  AddInstruction(HCheckInstanceType::NewIsSymbol(left));
-  AddInstruction(new(zone()) HCheckNonSmi(right));
-  AddInstruction(HCheckInstanceType::NewIsSymbol(right));
-  return new(zone()) HCompareSymbolEq(left, right, op);
-}
-
-
-HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string,
+HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context,
+                                                        HValue* string,
                                                         HValue* index) {
   AddInstruction(new(zone()) HCheckNonSmi(string));
   AddInstruction(HCheckInstanceType::NewIsString(string));
@@ -5059,15 +5417,67 @@
   AddInstruction(length);
   HInstruction* checked_index =
       AddInstruction(new(zone()) HBoundsCheck(index, length));
-  return new(zone()) HStringCharCodeAt(string, checked_index);
+  return new(zone()) HStringCharCodeAt(context, string, checked_index);
 }
 
 
 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
                                                   HValue* left,
                                                   HValue* right) {
+  HValue* context = environment()->LookupContext();
   TypeInfo info = oracle()->BinaryType(expr);
-  HInstruction* instr = BuildBinaryOperation(expr->op(), left, right, info);
+  if (info.IsUninitialized()) {
+    AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
+    info = TypeInfo::Unknown();
+  }
+  HInstruction* instr = NULL;
+  switch (expr->op()) {
+    case Token::ADD:
+      if (info.IsString()) {
+        AddInstruction(new(zone()) HCheckNonSmi(left));
+        AddInstruction(HCheckInstanceType::NewIsString(left));
+        AddInstruction(new(zone()) HCheckNonSmi(right));
+        AddInstruction(HCheckInstanceType::NewIsString(right));
+        instr = new(zone()) HStringAdd(context, left, right);
+      } else {
+        instr = new(zone()) HAdd(context, left, right);
+      }
+      break;
+    case Token::SUB:
+      instr = new(zone()) HSub(context, left, right);
+      break;
+    case Token::MUL:
+      instr = new(zone()) HMul(context, left, right);
+      break;
+    case Token::MOD:
+      instr = new(zone()) HMod(context, left, right);
+      break;
+    case Token::DIV:
+      instr = new(zone()) HDiv(context, left, right);
+      break;
+    case Token::BIT_XOR:
+      instr = new(zone()) HBitXor(context, left, right);
+      break;
+    case Token::BIT_AND:
+      instr = new(zone()) HBitAnd(context, left, right);
+      break;
+    case Token::BIT_OR:
+      instr = new(zone()) HBitOr(context, left, right);
+      break;
+    case Token::SAR:
+      instr = new(zone()) HSar(context, left, right);
+      break;
+    case Token::SHR:
+      instr = new(zone()) HShr(context, left, right);
+      break;
+    case Token::SHL:
+      instr = new(zone()) HShl(context, left, right);
+      break;
+    default:
+      UNREACHABLE();
+  }
+
   // If we hit an uninitialized binary op stub we will get type info
   // for a smi operation. If one of the operands is a constant string
   // do not generate code assuming it is a smi operation.
@@ -5087,36 +5497,6 @@
 }
 
 
-HInstruction* HGraphBuilder::BuildBinaryOperation(
-    Token::Value op, HValue* left, HValue* right, TypeInfo info) {
-  switch (op) {
-    case Token::ADD:
-      if (info.IsString()) {
-        AddInstruction(new(zone()) HCheckNonSmi(left));
-        AddInstruction(HCheckInstanceType::NewIsString(left));
-        AddInstruction(new(zone()) HCheckNonSmi(right));
-        AddInstruction(HCheckInstanceType::NewIsString(right));
-        return new(zone()) HStringAdd(left, right);
-      } else {
-        return new(zone()) HAdd(left, right);
-      }
-    case Token::SUB: return new(zone()) HSub(left, right);
-    case Token::MUL: return new(zone()) HMul(left, right);
-    case Token::MOD: return new(zone()) HMod(left, right);
-    case Token::DIV: return new(zone()) HDiv(left, right);
-    case Token::BIT_XOR: return new(zone()) HBitXor(left, right);
-    case Token::BIT_AND: return new(zone()) HBitAnd(left, right);
-    case Token::BIT_OR: return new(zone()) HBitOr(left, right);
-    case Token::SAR: return new(zone()) HSar(left, right);
-    case Token::SHR: return new(zone()) HShr(left, right);
-    case Token::SHL: return new(zone()) HShl(left, right);
-    default:
-      UNREACHABLE();
-      return NULL;
-  }
-}
-
-
 // Check for the form (%_ClassOf(foo) === 'BarClass').
 static bool IsClassOfTest(CompareOperation* expr) {
   if (expr->op() != Token::EQ_STRICT) return false;
@@ -5136,10 +5516,13 @@
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
   switch (expr->op()) {
-    case Token::COMMA: return VisitComma(expr);
-    case Token::OR: return VisitAndOr(expr, false);
-    case Token::AND: return VisitAndOr(expr, true);
-    default: return VisitCommon(expr);
+    case Token::COMMA:
+      return VisitComma(expr);
+    case Token::OR:
+    case Token::AND:
+      return VisitLogicalExpression(expr);
+    default:
+      return VisitArithmeticExpression(expr);
   }
 }
 
@@ -5152,7 +5535,8 @@
 }
 
 
-void HGraphBuilder::VisitAndOr(BinaryOperation* expr, bool is_logical_and) {
+void HGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
+  bool is_logical_and = expr->op() == Token::AND;
   if (ast_context()->IsTest()) {
     TestContext* context = TestContext::cast(ast_context());
     // Translate left subexpression.
@@ -5182,9 +5566,9 @@
     // We need an extra block to maintain edge-split form.
     HBasicBlock* empty_block = graph()->CreateBasicBlock();
     HBasicBlock* eval_right = graph()->CreateBasicBlock();
-    HTest* test = is_logical_and
-      ? new(zone()) HTest(Top(), eval_right, empty_block)
-      : new(zone()) HTest(Top(), empty_block, eval_right);
+    HBranch* test = is_logical_and
+      ? new(zone()) HBranch(Top(), eval_right, empty_block)
+      : new(zone()) HBranch(Top(), empty_block, eval_right);
     current_block()->Finish(test);
 
     set_current_block(eval_right);
@@ -5194,7 +5578,7 @@
     HBasicBlock* join_block =
       CreateJoin(empty_block, current_block(), expr->id());
     set_current_block(join_block);
-    ast_context()->ReturnValue(Pop());
+    return ast_context()->ReturnValue(Pop());
 
   } else {
     ASSERT(ast_context()->IsEffect());
@@ -5239,14 +5623,14 @@
 }
 
 
-void HGraphBuilder::VisitCommon(BinaryOperation* expr) {
+void HGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) {
   CHECK_ALIVE(VisitForValue(expr->left()));
   CHECK_ALIVE(VisitForValue(expr->right()));
   HValue* right = Pop();
   HValue* left = Pop();
   HInstruction* instr = BuildBinaryOperation(expr, left, right);
   instr->set_position(expr->position());
-  ast_context()->ReturnInstruction(instr, expr->id());
+  return ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
@@ -5279,46 +5663,75 @@
 }
 
 
+void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* compare_expr,
+                                               Expression* expr,
+                                               Handle<String> check) {
+  CHECK_ALIVE(VisitForTypeOf(expr));
+  HValue* expr_value = Pop();
+  HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(expr_value, check);
+  instr->set_position(compare_expr->position());
+  return ast_context()->ReturnControl(instr, compare_expr->id());
+}
+
+
+void HGraphBuilder::HandleLiteralCompareUndefined(
+    CompareOperation* compare_expr, Expression* expr) {
+  CHECK_ALIVE(VisitForValue(expr));
+  HValue* lhs = Pop();
+  HValue* rhs = graph()->GetConstantUndefined();
+  HCompareObjectEqAndBranch* instr =
+      new(zone()) HCompareObjectEqAndBranch(lhs, rhs);
+  instr->set_position(compare_expr->position());
+  return ast_context()->ReturnControl(instr, compare_expr->id());
+}
+
+
 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
   if (IsClassOfTest(expr)) {
     CallRuntime* call = expr->left()->AsCallRuntime();
+    ASSERT(call->arguments()->length() == 1);
     CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
     HValue* value = Pop();
     Literal* literal = expr->right()->AsLiteral();
     Handle<String> rhs = Handle<String>::cast(literal->handle());
-    HInstruction* instr = new(zone()) HClassOfTest(value, rhs);
+    HClassOfTestAndBranch* instr =
+        new(zone()) HClassOfTestAndBranch(value, rhs);
     instr->set_position(expr->position());
-    ast_context()->ReturnInstruction(instr, expr->id());
+    return ast_context()->ReturnControl(instr, expr->id());
+  }
+
+  // Check for special cases that compare against literals.
+  Expression *sub_expr;
+  Handle<String> check;
+  if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
+    HandleLiteralCompareTypeof(expr, sub_expr, check);
     return;
   }
 
-  // Check for the pattern: typeof <expression> == <string literal>.
-  UnaryOperation* left_unary = expr->left()->AsUnaryOperation();
-  Literal* right_literal = expr->right()->AsLiteral();
-  if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
-      left_unary != NULL && left_unary->op() == Token::TYPEOF &&
-      right_literal != NULL && right_literal->handle()->IsString()) {
-    CHECK_ALIVE(VisitForTypeOf(left_unary->expression()));
-    HValue* left = Pop();
-    HInstruction* instr = new(zone()) HTypeofIs(left,
-        Handle<String>::cast(right_literal->handle()));
-    instr->set_position(expr->position());
-    ast_context()->ReturnInstruction(instr, expr->id());
+  if (expr->IsLiteralCompareUndefined(&sub_expr)) {
+    HandleLiteralCompareUndefined(expr, sub_expr);
     return;
   }
 
+  TypeInfo type_info = oracle()->CompareType(expr);
+  // Check if this expression was ever executed according to type feedback.
+  if (type_info.IsUninitialized()) {
+    AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
+    type_info = TypeInfo::Unknown();
+  }
+
   CHECK_ALIVE(VisitForValue(expr->left()));
   CHECK_ALIVE(VisitForValue(expr->right()));
 
+  HValue* context = environment()->LookupContext();
   HValue* right = Pop();
   HValue* left = Pop();
   Token::Value op = expr->op();
 
-  TypeInfo type_info = oracle()->CompareType(expr);
-  HInstruction* instr = NULL;
   if (op == Token::INSTANCEOF) {
     // Check to see if the rhs of the instanceof is a global function not
     // residing in new space. If it is we assume that the function will stay the
@@ -5348,40 +5761,61 @@
     // If the target is not null we have found a known global function that is
     // assumed to stay the same for this instanceof.
     if (target.is_null()) {
-      HValue* context = environment()->LookupContext();
-      instr = new(zone()) HInstanceOf(context, left, right);
+      HInstanceOf* result = new(zone()) HInstanceOf(context, left, right);
+      result->set_position(expr->position());
+      return ast_context()->ReturnInstruction(result, expr->id());
     } else {
       AddInstruction(new(zone()) HCheckFunction(right, target));
-      instr = new(zone()) HInstanceOfKnownGlobal(left, target);
+      HInstanceOfKnownGlobal* result =
+          new(zone()) HInstanceOfKnownGlobal(context, left, target);
+      result->set_position(expr->position());
+      return ast_context()->ReturnInstruction(result, expr->id());
     }
   } else if (op == Token::IN) {
-    instr = new(zone()) HIn(left, right);
+    HIn* result = new(zone()) HIn(context, left, right);
+    result->set_position(expr->position());
+    return ast_context()->ReturnInstruction(result, expr->id());
   } else if (type_info.IsNonPrimitive()) {
     switch (op) {
       case Token::EQ:
       case Token::EQ_STRICT: {
         AddInstruction(new(zone()) HCheckNonSmi(left));
-        AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left));
+        AddInstruction(HCheckInstanceType::NewIsSpecObject(left));
         AddInstruction(new(zone()) HCheckNonSmi(right));
-        AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right));
-        instr = new(zone()) HCompareJSObjectEq(left, right);
-        break;
+        AddInstruction(HCheckInstanceType::NewIsSpecObject(right));
+        HCompareObjectEqAndBranch* result =
+            new(zone()) HCompareObjectEqAndBranch(left, right);
+        result->set_position(expr->position());
+        return ast_context()->ReturnControl(result, expr->id());
       }
       default:
         return Bailout("Unsupported non-primitive compare");
-        break;
     }
   } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) &&
              (op == Token::EQ || op == Token::EQ_STRICT)) {
-    instr = BuildSymbolCompare(left, right, op);
+    AddInstruction(new(zone()) HCheckNonSmi(left));
+    AddInstruction(HCheckInstanceType::NewIsSymbol(left));
+    AddInstruction(new(zone()) HCheckNonSmi(right));
+    AddInstruction(HCheckInstanceType::NewIsSymbol(right));
+    HCompareObjectEqAndBranch* result =
+        new(zone()) HCompareObjectEqAndBranch(left, right);
+    result->set_position(expr->position());
+    return ast_context()->ReturnControl(result, expr->id());
   } else {
-    HCompare* compare = new(zone()) HCompare(left, right, op);
     Representation r = ToRepresentation(type_info);
-    compare->SetInputRepresentation(r);
-    instr = compare;
+    if (r.IsTagged()) {
+      HCompareGeneric* result =
+          new(zone()) HCompareGeneric(context, left, right, op);
+      result->set_position(expr->position());
+      return ast_context()->ReturnInstruction(result, expr->id());
+    } else {
+      HCompareIDAndBranch* result =
+          new(zone()) HCompareIDAndBranch(left, right, op);
+      result->set_position(expr->position());
+      result->SetInputRepresentation(r);
+      return ast_context()->ReturnControl(result, expr->id());
+    }
   }
-  instr->set_position(expr->position());
-  ast_context()->ReturnInstruction(instr, expr->id());
 }
 
 
@@ -5390,10 +5824,10 @@
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
   CHECK_ALIVE(VisitForValue(expr->expression()));
-
   HValue* value = Pop();
-  HIsNull* compare = new(zone()) HIsNull(value, expr->is_strict());
-  ast_context()->ReturnInstruction(compare, expr->id());
+  HIsNullAndBranch* instr =
+      new(zone()) HIsNullAndBranch(value, expr->is_strict());
+  return ast_context()->ReturnControl(instr, expr->id());
 }
 
 
@@ -5401,23 +5835,22 @@
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
-  return Bailout("ThisFunction");
+  HThisFunction* self = new(zone()) HThisFunction;
+  return ast_context()->ReturnInstruction(self, expr->id());
 }
 
 
 void HGraphBuilder::VisitDeclaration(Declaration* decl) {
-  // We allow only declarations that do not require code generation.
-  // The following all require code generation: global variables and
-  // functions, variables with slot type LOOKUP, declarations with
-  // mode CONST, and functions.
+  // We support only declarations that do not require code generation.
   Variable* var = decl->proxy()->var();
-  Slot* slot = var->AsSlot();
-  if (var->is_global() ||
-      (slot != NULL && slot->type() == Slot::LOOKUP) ||
-      decl->mode() == Variable::CONST ||
-      decl->fun() != NULL) {
+  if (!var->IsStackAllocated() || decl->fun() != NULL) {
     return Bailout("unsupported declaration");
   }
+
+  if (decl->mode() == Variable::CONST) {
+    ASSERT(var->IsStackAllocated());
+    environment()->Bind(var, graph()->GetConstantHole());
+  }
 }
 
 
@@ -5427,8 +5860,8 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HIsSmi* result = new(zone()) HIsSmi(value);
-  ast_context()->ReturnInstruction(result, call->id());
+  HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5436,9 +5869,11 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HHasInstanceType* result =
-      new(zone()) HHasInstanceType(value, FIRST_JS_OBJECT_TYPE, LAST_TYPE);
-  ast_context()->ReturnInstruction(result, call->id());
+  HHasInstanceTypeAndBranch* result =
+      new(zone()) HHasInstanceTypeAndBranch(value,
+                                            FIRST_SPEC_OBJECT_TYPE,
+                                            LAST_SPEC_OBJECT_TYPE);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5446,9 +5881,9 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HHasInstanceType* result =
-      new(zone()) HHasInstanceType(value, JS_FUNCTION_TYPE);
-  ast_context()->ReturnInstruction(result, call->id());
+  HHasInstanceTypeAndBranch* result =
+      new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5456,8 +5891,9 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HHasCachedArrayIndex* result = new(zone()) HHasCachedArrayIndex(value);
-  ast_context()->ReturnInstruction(result, call->id());
+  HHasCachedArrayIndexAndBranch* result =
+      new(zone()) HHasCachedArrayIndexAndBranch(value);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5465,8 +5901,9 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HHasInstanceType* result = new(zone()) HHasInstanceType(value, JS_ARRAY_TYPE);
-  ast_context()->ReturnInstruction(result, call->id());
+  HHasInstanceTypeAndBranch* result =
+      new(zone()) HHasInstanceTypeAndBranch(value, JS_ARRAY_TYPE);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5474,9 +5911,9 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HHasInstanceType* result =
-      new(zone()) HHasInstanceType(value, JS_REGEXP_TYPE);
-  ast_context()->ReturnInstruction(result, call->id());
+  HHasInstanceTypeAndBranch* result =
+      new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5484,8 +5921,8 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HIsObject* test = new(zone()) HIsObject(value);
-  ast_context()->ReturnInstruction(test, call->id());
+  HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5498,8 +5935,9 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  ast_context()->ReturnInstruction(new(zone()) HIsUndetectable(value),
-                                   call->id());
+  HIsUndetectableAndBranch* result =
+      new(zone()) HIsUndetectableAndBranch(value);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
@@ -5517,9 +5955,10 @@
     // We are generating graph for inlined function. Currently
     // constructor inlining is not supported and we can just return
     // false from %_IsConstructCall().
-    ast_context()->ReturnValue(graph()->GetConstantFalse());
+    return ast_context()->ReturnValue(graph()->GetConstantFalse());
   } else {
-    ast_context()->ReturnInstruction(new(zone()) HIsConstructCall, call->id());
+    return ast_context()->ReturnControl(new(zone()) HIsConstructCallAndBranch,
+                                        call->id());
   }
 }
 
@@ -5533,7 +5972,7 @@
   ASSERT(call->arguments()->length() == 0);
   HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
   HArgumentsLength* result = new(zone()) HArgumentsLength(elements);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5549,7 +5988,7 @@
   HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
   HAccessArgumentsAt* result =
       new(zone()) HAccessArgumentsAt(elements, length, index);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5566,7 +6005,7 @@
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
   HValueOf* result = new(zone()) HValueOf(value);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5582,8 +6021,9 @@
   CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
   HValue* index = Pop();
   HValue* string = Pop();
-  HStringCharCodeAt* result = BuildStringCharCodeAt(string, index);
-  ast_context()->ReturnInstruction(result, call->id());
+  HValue* context = environment()->LookupContext();
+  HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index);
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5592,8 +6032,10 @@
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* char_code = Pop();
-  HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
-  ast_context()->ReturnInstruction(result, call->id());
+  HValue* context = environment()->LookupContext();
+  HStringCharFromCode* result =
+      new(zone()) HStringCharFromCode(context, char_code);
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5604,10 +6046,12 @@
   CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
   HValue* index = Pop();
   HValue* string = Pop();
-  HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
+  HValue* context = environment()->LookupContext();
+  HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index);
   AddInstruction(char_code);
-  HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
-  ast_context()->ReturnInstruction(result, call->id());
+  HStringCharFromCode* result =
+      new(zone()) HStringCharFromCode(context, char_code);
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5618,14 +6062,15 @@
   CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
   HValue* right = Pop();
   HValue* left = Pop();
-  HCompareJSObjectEq* result = new(zone()) HCompareJSObjectEq(left, right);
-  ast_context()->ReturnInstruction(result, call->id());
+  HCompareObjectEqAndBranch* result =
+      new(zone()) HCompareObjectEqAndBranch(left, right);
+  return ast_context()->ReturnControl(result, call->id());
 }
 
 
 void HGraphBuilder::GenerateLog(CallRuntime* call) {
   // %_Log is ignored in optimized code.
-  ast_context()->ReturnValue(graph()->GetConstantUndefined());
+  return ast_context()->ReturnValue(graph()->GetConstantUndefined());
 }
 
 
@@ -5642,7 +6087,7 @@
   HValue* context = environment()->LookupContext();
   HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2);
   Drop(2);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5653,7 +6098,7 @@
   HValue* context = environment()->LookupContext();
   HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
   Drop(3);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5665,7 +6110,7 @@
   HCallStub* result =
       new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
   Drop(2);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5676,7 +6121,7 @@
   HValue* context = environment()->LookupContext();
   HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
   Drop(4);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5688,7 +6133,7 @@
   HCallStub* result =
       new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
   Drop(3);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5706,7 +6151,7 @@
   HCallStub* result =
       new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
   Drop(1);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5733,7 +6178,7 @@
   HInvokeFunction* result =
       new(zone()) HInvokeFunction(context, function, arg_count);
   Drop(arg_count);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5745,7 +6190,7 @@
   HValue* right = Pop();
   HValue* left = Pop();
   HPower* result = new(zone()) HPower(left, right);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5757,7 +6202,7 @@
       new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
   result->set_transcendental_type(TranscendentalCache::SIN);
   Drop(1);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5769,7 +6214,7 @@
       new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
   result->set_transcendental_type(TranscendentalCache::COS);
   Drop(1);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5781,7 +6226,7 @@
       new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
   result->set_transcendental_type(TranscendentalCache::LOG);
   Drop(1);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5801,7 +6246,7 @@
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
   HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value);
-  ast_context()->ReturnInstruction(result, call->id());
+  return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
@@ -5810,6 +6255,11 @@
 }
 
 
+void HGraphBuilder::GenerateIsNativeOrStrictMode(CallRuntime* call) {
+  return Bailout("inlined runtime function: IsNativeOrStrictMode");
+}
+
+
 #undef CHECK_BAILOUT
 #undef CHECK_ALIVE
 
@@ -5972,7 +6422,6 @@
 HEnvironment* HEnvironment::CopyForInlining(
     Handle<JSFunction> target,
     FunctionLiteral* function,
-    CompilationPhase compilation_phase,
     HConstant* undefined,
     CallKind call_kind) const {
   // Outer environment is a copy of this one without the arguments.
@@ -5984,22 +6433,15 @@
   HEnvironment* inner =
       new(zone) HEnvironment(outer, function->scope(), target);
   // Get the argument values from the original environment.
-  if (compilation_phase == HYDROGEN) {
-    for (int i = 0; i <= arity; ++i) {  // Include receiver.
-      HValue* push = ExpressionStackAt(arity - i);
-      inner->SetValueAt(i, push);
-    }
-  } else {
-    ASSERT(compilation_phase == LITHIUM);
-    for (int i = 0; i <= arity; ++i) {  // Include receiver.
-      HValue* push = ExpressionStackAt(arity - i);
-      inner->SetValueAt(i, push);
-    }
+  for (int i = 0; i <= arity; ++i) {  // Include receiver.
+    HValue* push = ExpressionStackAt(arity - i);
+    inner->SetValueAt(i, push);
   }
-  // If the function we are inlining is a strict mode function, pass
-  // undefined as the receiver for function calls (instead of the
-  // global receiver).
-  if (function->strict_mode() && call_kind == CALL_AS_FUNCTION) {
+  // If the function we are inlining is a strict mode function or a
+  // builtin function, pass undefined as the receiver for function
+  // calls (instead of the global receiver).
+  if ((target->shared()->native() || function->strict_mode()) &&
+      call_kind == CALL_AS_FUNCTION) {
     inner->SetValueAt(0, undefined);
   }
   inner->SetValueAt(arity + 1, outer->LookupContext());
@@ -6081,15 +6523,15 @@
       PrintEmptyProperty("predecessors");
     }
 
-    if (current->end() == NULL || current->end()->FirstSuccessor() == NULL) {
+    if (current->end()->SuccessorCount() == 0) {
       PrintEmptyProperty("successors");
-    } else if (current->end()->SecondSuccessor() == NULL) {
-      PrintBlockProperty("successors",
-                             current->end()->FirstSuccessor()->block_id());
-    } else {
-      PrintBlockProperty("successors",
-                             current->end()->FirstSuccessor()->block_id(),
-                             current->end()->SecondSuccessor()->block_id());
+    } else  {
+      PrintIndent();
+      trace_.Add("successors");
+      for (HSuccessorIterator it(current->end()); !it.Done(); it.Advance()) {
+        trace_.Add(" \"B%d\"", it.Current()->block_id());
+      }
+      trace_.Add("\n");
     }
 
     PrintEmptyProperty("xhandlers");
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 4d8a153..ffa8aa7 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -116,14 +116,14 @@
 
   bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
 
-  void SetJoinId(int id);
+  void SetJoinId(int ast_id);
 
   void Finish(HControlInstruction* last);
   void FinishExit(HControlInstruction* instruction);
-  void Goto(HBasicBlock* block, bool include_stack_check = false);
+  void Goto(HBasicBlock* block);
 
   int PredecessorIndexOf(HBasicBlock* predecessor) const;
-  void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); }
+  void AddSimulate(int ast_id) { AddInstruction(CreateSimulate(ast_id)); }
   void AssignCommonDominator(HBasicBlock* other);
 
   void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) {
@@ -143,6 +143,9 @@
   bool IsInlineReturnTarget() const { return is_inline_return_target_; }
   void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; }
 
+  bool IsDeoptimizing() const { return is_deoptimizing_; }
+  void MarkAsDeoptimizing() { is_deoptimizing_ = true; }
+
   inline Zone* zone();
 
 #ifdef DEBUG
@@ -153,7 +156,7 @@
   void RegisterPredecessor(HBasicBlock* pred);
   void AddDominatedBlock(HBasicBlock* block);
 
-  HSimulate* CreateSimulate(int id);
+  HSimulate* CreateSimulate(int ast_id);
   HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
 
   int block_id_;
@@ -175,13 +178,17 @@
   ZoneList<int> deleted_phis_;
   HBasicBlock* parent_loop_header_;
   bool is_inline_return_target_;
+  bool is_deoptimizing_;
 };
 
 
 class HLoopInformation: public ZoneObject {
  public:
   explicit HLoopInformation(HBasicBlock* loop_header)
-      : back_edges_(4), loop_header_(loop_header), blocks_(8) {
+      : back_edges_(4),
+        loop_header_(loop_header),
+        blocks_(8),
+        stack_check_(NULL) {
     blocks_.Add(loop_header);
   }
   virtual ~HLoopInformation() {}
@@ -192,12 +199,18 @@
   HBasicBlock* GetLastBackEdge() const;
   void RegisterBackEdge(HBasicBlock* block);
 
+  HStackCheck* stack_check() const { return stack_check_; }
+  void set_stack_check(HStackCheck* stack_check) {
+    stack_check_ = stack_check;
+  }
+
  private:
   void AddBlock(HBasicBlock* block);
 
   ZoneList<HBasicBlock*> back_edges_;
   HBasicBlock* loop_header_;
   ZoneList<HBasicBlock*> blocks_;
+  HStackCheck* stack_check_;
 };
 
 
@@ -225,14 +238,17 @@
   void OrderBlocks();
   void AssignDominators();
   void ReplaceCheckedValues();
+  void MarkAsDeoptimizingRecursively(HBasicBlock* block);
 
   // Returns false if there are phi-uses of the arguments-object
   // which are not supported by the optimizing compiler.
-  bool CheckPhis();
+  bool CheckArgumentsPhiUses();
 
-  // Returns false if there are phi-uses of hole values comming
-  // from uninitialized consts.
-  bool CollectPhis();
+  // Returns false if there are phi-uses of an uninitialized const
+  // which are not supported by the optimizing compiler.
+  bool CheckConstPhiUses();
+
+  void CollectPhis();
 
   Handle<Code> Compile(CompilationInfo* info);
 
@@ -244,6 +260,7 @@
   HConstant* GetConstantMinus1();
   HConstant* GetConstantTrue();
   HConstant* GetConstantFalse();
+  HConstant* GetConstantHole();
 
   HBasicBlock* CreateBasicBlock();
   HArgumentsObject* GetArgumentsObject() const {
@@ -306,6 +323,7 @@
   SetOncePointer<HConstant> constant_minus1_;
   SetOncePointer<HConstant> constant_true_;
   SetOncePointer<HConstant> constant_false_;
+  SetOncePointer<HConstant> constant_hole_;
   SetOncePointer<HArgumentsObject> arguments_object_;
 
   DISALLOW_COPY_AND_ASSIGN(HGraph);
@@ -317,8 +335,6 @@
 
 class HEnvironment: public ZoneObject {
  public:
-  enum CompilationPhase { HYDROGEN, LITHIUM };
-
   HEnvironment(HEnvironment* outer,
                Scope* scope,
                Handle<JSFunction> closure);
@@ -405,12 +421,9 @@
 
   // Create an "inlined version" of this environment, where the original
   // environment is the outer environment but the top expression stack
-  // elements are moved to an inner environment as parameters. If
-  // is_speculative, the argument values are expected to be PushArgument
-  // instructions, otherwise they are the actual values.
+  // elements are moved to an inner environment as parameters.
   HEnvironment* CopyForInlining(Handle<JSFunction> target,
                                 FunctionLiteral* function,
-                                CompilationPhase compilation_phase,
                                 HConstant* undefined,
                                 CallKind call_kind) const;
 
@@ -491,6 +504,12 @@
   // the instruction as value.
   virtual void ReturnInstruction(HInstruction* instr, int ast_id) = 0;
 
+  // Finishes the current basic block and materialize a boolean for
+  // value context, nothing for effect, generate a branch for test context.
+  // Call this function in tail position in the Visit functions for
+  // expressions.
+  virtual void ReturnControl(HControlInstruction* instr, int ast_id) = 0;
+
   void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
   bool is_for_typeof() { return for_typeof_; }
 
@@ -525,6 +544,7 @@
 
   virtual void ReturnValue(HValue* value);
   virtual void ReturnInstruction(HInstruction* instr, int ast_id);
+  virtual void ReturnControl(HControlInstruction* instr, int ast_id);
 };
 
 
@@ -537,6 +557,7 @@
 
   virtual void ReturnValue(HValue* value);
   virtual void ReturnInstruction(HInstruction* instr, int ast_id);
+  virtual void ReturnControl(HControlInstruction* instr, int ast_id);
 
   bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
 
@@ -548,21 +569,25 @@
 class TestContext: public AstContext {
  public:
   TestContext(HGraphBuilder* owner,
+              Expression* condition,
               HBasicBlock* if_true,
               HBasicBlock* if_false)
       : AstContext(owner, Expression::kTest),
+        condition_(condition),
         if_true_(if_true),
         if_false_(if_false) {
   }
 
   virtual void ReturnValue(HValue* value);
   virtual void ReturnInstruction(HInstruction* instr, int ast_id);
+  virtual void ReturnControl(HControlInstruction* instr, int ast_id);
 
   static TestContext* cast(AstContext* context) {
     ASSERT(context->IsTest());
     return reinterpret_cast<TestContext*>(context);
   }
 
+  Expression* condition() const { return condition_; }
   HBasicBlock* if_true() const { return if_true_; }
   HBasicBlock* if_false() const { return if_false_; }
 
@@ -571,6 +596,7 @@
   // control flow.
   void BuildBranch(HValue* value);
 
+  Expression* condition_;
   HBasicBlock* if_true_;
   HBasicBlock* if_false_;
 };
@@ -687,7 +713,7 @@
 
   // Adding instructions.
   HInstruction* AddInstruction(HInstruction* instr);
-  void AddSimulate(int id);
+  void AddSimulate(int ast_id);
 
   // Bailout environment manipulation.
   void Push(HValue* value) { environment()->Push(value); }
@@ -695,6 +721,10 @@
 
   void Bailout(const char* reason);
 
+  HBasicBlock* CreateJoin(HBasicBlock* first,
+                          HBasicBlock* second,
+                          int join_id);
+
  private:
   // Type of a member function that generates inline code for a native function.
   typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call);
@@ -758,16 +788,15 @@
   void VisitNot(UnaryOperation* expr);
 
   void VisitComma(BinaryOperation* expr);
-  void VisitAndOr(BinaryOperation* expr, bool is_logical_and);
-  void VisitCommon(BinaryOperation* expr);
+  void VisitLogicalExpression(BinaryOperation* expr);
+  void VisitArithmeticExpression(BinaryOperation* expr);
 
   void PreProcessOsrEntry(IterationStatement* statement);
   // True iff. we are compiling for OSR and the statement is the entry.
   bool HasOsrEntryAt(IterationStatement* statement);
-
-  HBasicBlock* CreateJoin(HBasicBlock* first,
-                          HBasicBlock* second,
-                          int join_id);
+  void VisitLoopBody(IterationStatement* stmt,
+                     HBasicBlock* loop_entry,
+                     BreakAndContinueInfo* break_info);
 
   // Create a back edge in the flow graph.  body_exit is the predecessor
   // block and loop_entry is the successor block.  loop_successor is the
@@ -802,8 +831,9 @@
                        HBasicBlock* false_block);
 
   // Visit an argument subexpression and emit a push to the outgoing
-  // arguments.
-  void VisitArgument(Expression* expr);
+  // arguments.  Returns the hydrogen value that was pushed.
+  HValue* VisitArgument(Expression* expr);
+
   void VisitArgumentList(ZoneList<Expression*>* arguments);
 
   // Visit a list of expressions from left to right, each in a value context.
@@ -877,19 +907,18 @@
                                   HValue* receiver,
                                   ZoneMapList* types,
                                   Handle<String> name);
+  void HandleLiteralCompareTypeof(CompareOperation* compare_expr,
+                                  Expression* expr,
+                                  Handle<String> check);
+  void HandleLiteralCompareUndefined(CompareOperation* compare_expr,
+                                     Expression* expr);
 
-  HCompareSymbolEq* BuildSymbolCompare(HValue* left,
-                                       HValue* right,
-                                       Token::Value op);
-  HStringCharCodeAt* BuildStringCharCodeAt(HValue* string,
+  HStringCharCodeAt* BuildStringCharCodeAt(HValue* context,
+                                           HValue* string,
                                            HValue* index);
   HInstruction* BuildBinaryOperation(BinaryOperation* expr,
                                      HValue* left,
                                      HValue* right);
-  HInstruction* BuildBinaryOperation(Token::Value op,
-                                     HValue* left,
-                                     HValue* right,
-                                     TypeInfo info);
   HInstruction* BuildIncrement(bool returns_original_input,
                                CountOperation* expr);
   HLoadNamedField* BuildLoadNamedField(HValue* object,
@@ -898,18 +927,37 @@
                                        LookupResult* result,
                                        bool smi_and_map_check);
   HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr);
-  HInstruction* BuildLoadKeyedFastElement(HValue* object,
-                                          HValue* key,
-                                          Property* expr);
-  HInstruction* BuildLoadKeyedSpecializedArrayElement(HValue* object,
-                                                      HValue* key,
-                                                      Property* expr);
   HInstruction* BuildLoadKeyedGeneric(HValue* object,
                                       HValue* key);
+  HInstruction* BuildExternalArrayElementAccess(
+      HValue* external_elements,
+      HValue* checked_key,
+      HValue* val,
+      JSObject::ElementsKind elements_kind,
+      bool is_store);
 
-  HInstruction* BuildLoadKeyed(HValue* obj,
-                               HValue* key,
-                               Property* prop);
+  HInstruction* BuildMonomorphicElementAccess(HValue* object,
+                                              HValue* key,
+                                              HValue* val,
+                                              Expression* expr,
+                                              bool is_store);
+  HValue* HandlePolymorphicElementAccess(HValue* object,
+                                         HValue* key,
+                                         HValue* val,
+                                         Expression* prop,
+                                         int ast_id,
+                                         int position,
+                                         bool is_store,
+                                         bool* has_side_effects);
+
+  HValue* HandleKeyedElementAccess(HValue* obj,
+                                   HValue* key,
+                                   HValue* val,
+                                   Expression* expr,
+                                   int ast_id,
+                                   int position,
+                                   bool is_store,
+                                   bool* has_side_effects);
 
   HInstruction* BuildLoadNamed(HValue* object,
                                Property* prop,
@@ -931,22 +979,6 @@
                                        HValue* key,
                                        HValue* value);
 
-  HInstruction* BuildStoreKeyedFastElement(HValue* object,
-                                           HValue* key,
-                                           HValue* val,
-                                           Expression* expr);
-
-  HInstruction* BuildStoreKeyedSpecializedArrayElement(
-      HValue* object,
-      HValue* key,
-      HValue* val,
-      Expression* expr);
-
-  HInstruction* BuildStoreKeyed(HValue* object,
-                                HValue* key,
-                                HValue* value,
-                                Expression* assignment);
-
   HValue* BuildContextChainWalk(Variable* var);
 
   void AddCheckConstantFunction(Call* expr,
@@ -1060,7 +1092,6 @@
   }
 
  private:
-
   HStatistics()
       : timing_(5),
         names_(5),
@@ -1184,11 +1215,6 @@
     trace_.Add("%s \"B%d\"\n", name, block_id);
   }
 
-  void PrintBlockProperty(const char* name, int block_id1, int block_id2) {
-    PrintIndent();
-    trace_.Add("%s \"B%d\" \"B%d\"\n", name, block_id1, block_id2);
-  }
-
   void PrintIntProperty(const char* name, int value) {
     PrintIndent();
     trace_.Add("%s %d\n", name, value);
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index a7602e7..0dc5194 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -449,6 +449,13 @@
 }
 
 
+void Assembler::push(Handle<Object> handle) {
+  EnsureSpace ensure_space(this);
+  EMIT(0x68);
+  emit(handle);
+}
+
+
 void Assembler::pop(Register dst) {
   ASSERT(reloc_info_writer.last_pc() != NULL);
   EnsureSpace ensure_space(this);
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index e933102..da38e13 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -659,6 +659,7 @@
   void push_imm32(int32_t imm32);
   void push(Register src);
   void push(const Operand& src);
+  void push(Handle<Object> handle);
 
   void pop(Register dst);
   void pop(const Operand& dst);
@@ -834,7 +835,7 @@
   void call(const Operand& adr);
   int CallSize(Handle<Code> code, RelocInfo::Mode mode);
   void call(Handle<Code> code,
-            RelocInfo::Mode rmode,
+            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
             unsigned ast_id = kNoASTId);
 
   // Jumps
@@ -989,7 +990,9 @@
   void Print();
 
   // Check the code size generated from label to here.
-  int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); }
+  int SizeOfCodeGeneratedSince(Label* label) {
+    return pc_offset() - label->pos();
+  }
 
   // Mark address of the ExitJSFrame code.
   void RecordJSReturn();
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 1212566..f8a85de 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -82,8 +82,7 @@
 
   Label non_function_call;
   // Check that function is not a smi.
-  __ test(edi, Immediate(kSmiTagMask));
-  __ j(zero, &non_function_call);
+  __ JumpIfSmi(edi, &non_function_call);
   // Check that function is a JSFunction.
   __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
   __ j(not_equal, &non_function_call);
@@ -140,8 +139,7 @@
     // edi: constructor
     __ mov(eax, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
     // Will both indicate a NULL and a Smi
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(zero, &rt_call);
+    __ JumpIfSmi(eax, &rt_call);
     // edi: constructor
     // eax: initial map (if proven valid below)
     __ CmpObjectType(eax, MAP_TYPE, ebx);
@@ -357,12 +355,11 @@
   Label use_receiver, exit;
 
   // If the result is a smi, it is *not* an object in the ECMA sense.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &use_receiver);
+  __ JumpIfSmi(eax, &use_receiver);
 
   // If the type of the result (stored in its map) is less than
-  // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
-  __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+  // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
+  __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
   __ j(above_equal, &exit);
 
   // Throw away the result of the constructor invocation and use the
@@ -596,8 +593,7 @@
   Label non_function;
   // 1 ~ return address.
   __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
-  __ test(edi, Immediate(kSmiTagMask));
-  __ j(zero, &non_function);
+  __ JumpIfSmi(edi, &non_function);
   __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
   __ j(not_equal, &non_function);
 
@@ -615,8 +611,8 @@
     __ j(not_equal, &shift_arguments);
 
     // Do not transform the receiver for natives (shared already in ebx).
-    __ test_b(FieldOperand(ebx, SharedFunctionInfo::kES5NativeByteOffset),
-              1 << SharedFunctionInfo::kES5NativeBitWithinByte);
+    __ test_b(FieldOperand(ebx, SharedFunctionInfo::kNativeByteOffset),
+              1 << SharedFunctionInfo::kNativeBitWithinByte);
     __ j(not_equal, &shift_arguments);
 
     // Compute the receiver in non-strict mode.
@@ -624,15 +620,13 @@
 
     // Call ToObject on the receiver if it is not an object, or use the
     // global object if it is null or undefined.
-    __ test(ebx, Immediate(kSmiTagMask));
-    __ j(zero, &convert_to_object);
+    __ JumpIfSmi(ebx, &convert_to_object);
     __ cmp(ebx, factory->null_value());
     __ j(equal, &use_global_receiver);
     __ cmp(ebx, factory->undefined_value());
     __ j(equal, &use_global_receiver);
-    STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-    STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-    __ CmpObjectType(ebx, FIRST_JS_OBJECT_TYPE, ecx);
+    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+    __ CmpObjectType(ebx, FIRST_SPEC_OBJECT_TYPE, ecx);
     __ j(above_equal, &shift_arguments);
 
     __ bind(&convert_to_object);
@@ -780,22 +774,20 @@
   Factory* factory = masm->isolate()->factory();
 
   // Do not transform the receiver for natives (shared already in ecx).
-  __ test_b(FieldOperand(ecx, SharedFunctionInfo::kES5NativeByteOffset),
-            1 << SharedFunctionInfo::kES5NativeBitWithinByte);
+  __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
+            1 << SharedFunctionInfo::kNativeBitWithinByte);
   __ j(not_equal, &push_receiver);
 
   // Compute the receiver in non-strict mode.
   // Call ToObject on the receiver if it is not an object, or use the
   // global object if it is null or undefined.
-  __ test(ebx, Immediate(kSmiTagMask));
-  __ j(zero, &call_to_object);
+  __ JumpIfSmi(ebx, &call_to_object);
   __ cmp(ebx, factory->null_value());
   __ j(equal, &use_global_receiver);
   __ cmp(ebx, factory->undefined_value());
   __ j(equal, &use_global_receiver);
-  STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-  STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  __ CmpObjectType(ebx, FIRST_JS_OBJECT_TYPE, ecx);
+  STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+  __ CmpObjectType(ebx, FIRST_SPEC_OBJECT_TYPE, ecx);
   __ j(above_equal, &push_receiver);
 
   __ bind(&call_to_object);
@@ -1392,8 +1384,7 @@
   Label convert_argument;
   __ bind(&not_cached);
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &convert_argument);
+  __ JumpIfSmi(eax, &convert_argument);
   Condition is_string = masm->IsObjectStringType(eax, ebx, ecx);
   __ j(NegateCondition(is_string), &convert_argument);
   __ mov(ebx, eax);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 8bf2dd4..71aacf9 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -43,8 +43,7 @@
 void ToNumberStub::Generate(MacroAssembler* masm) {
   // The ToNumber stub takes one argument in eax.
   Label check_heap_number, call_builtin;
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &check_heap_number, Label::kNear);
+  __ JumpIfNotSmi(eax, &check_heap_number, Label::kNear);
   __ ret(0);
 
   __ bind(&check_heap_number);
@@ -129,22 +128,19 @@
 
   // Setup the object header.
   Factory* factory = masm->isolate()->factory();
-  __ mov(FieldOperand(eax, HeapObject::kMapOffset), factory->context_map());
+  __ mov(FieldOperand(eax, HeapObject::kMapOffset),
+         factory->function_context_map());
   __ mov(FieldOperand(eax, Context::kLengthOffset),
          Immediate(Smi::FromInt(length)));
 
   // Setup the fixed slots.
   __ Set(ebx, Immediate(0));  // Set to NULL.
   __ mov(Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)), ecx);
-  __ mov(Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)), eax);
-  __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), ebx);
+  __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), esi);
   __ mov(Operand(eax, Context::SlotOffset(Context::EXTENSION_INDEX)), ebx);
 
-  // Copy the global object from the surrounding context. We go through the
-  // context in the function (ecx) to match the allocation behavior we have
-  // in the runtime system (see Heap::AllocateFunctionContext).
-  __ mov(ebx, FieldOperand(ecx, JSFunction::kContextOffset));
-  __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  // Copy the global object from the previous context.
+  __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
 
   // Initialize the rest of the slots to undefined.
@@ -159,7 +155,7 @@
 
   // Need to collect. Call into runtime system.
   __ bind(&gc);
-  __ TailCallRuntime(Runtime::kNewContext, 1, 1);
+  __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1);
 }
 
 
@@ -240,56 +236,55 @@
 }
 
 
-// NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined).
+// The stub returns zero for false, and a non-zero value for true.
 void ToBooleanStub::Generate(MacroAssembler* masm) {
   Label false_result, true_result, not_string;
-  __ mov(eax, Operand(esp, 1 * kPointerSize));
   Factory* factory = masm->isolate()->factory();
+  const Register map = edx;
+
+  __ mov(eax, Operand(esp, 1 * kPointerSize));
 
   // undefined -> false
   __ cmp(eax, factory->undefined_value());
   __ j(equal, &false_result);
 
   // Boolean -> its value
-  __ cmp(eax, factory->true_value());
-  __ j(equal, &true_result);
   __ cmp(eax, factory->false_value());
   __ j(equal, &false_result);
+  __ cmp(eax, factory->true_value());
+  __ j(equal, &true_result);
 
   // Smis: 0 -> false, all other -> true
   __ test(eax, Operand(eax));
   __ j(zero, &false_result);
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &true_result);
+  __ JumpIfSmi(eax, &true_result);
 
-  // 'null' => false.
+  // 'null' -> false.
   __ cmp(eax, factory->null_value());
   __ j(equal, &false_result, Label::kNear);
 
-  // Get the map and type of the heap object.
-  __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
-  __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
+  // Get the map of the heap object.
+  __ mov(map, FieldOperand(eax, HeapObject::kMapOffset));
 
-  // Undetectable => false.
-  __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
+  // Undetectable -> false.
+  __ test_b(FieldOperand(map, Map::kBitFieldOffset),
             1 << Map::kIsUndetectable);
   __ j(not_zero, &false_result, Label::kNear);
 
-  // JavaScript object => true.
-  __ CmpInstanceType(edx, FIRST_JS_OBJECT_TYPE);
+  // JavaScript object -> true.
+  __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
   __ j(above_equal, &true_result, Label::kNear);
 
-  // String value => false iff empty.
-  __ CmpInstanceType(edx, FIRST_NONSTRING_TYPE);
+  // String value -> false iff empty.
+  __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
   __ j(above_equal, &not_string, Label::kNear);
-  STATIC_ASSERT(kSmiTag == 0);
   __ cmp(FieldOperand(eax, String::kLengthOffset), Immediate(0));
   __ j(zero, &false_result, Label::kNear);
   __ jmp(&true_result, Label::kNear);
 
   __ bind(&not_string);
-  // HeapNumber => false iff +0, -0, or NaN.
-  __ cmp(edx, factory->heap_number_map());
+  // HeapNumber -> false iff +0, -0, or NaN.
+  __ cmp(map, factory->heap_number_map());
   __ j(not_equal, &true_result, Label::kNear);
   __ fldz();
   __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
@@ -297,19 +292,18 @@
   __ j(zero, &false_result, Label::kNear);
   // Fall through to |true_result|.
 
-  // Return 1/0 for true/false in eax.
+  // Return 1/0 for true/false in tos_.
   __ bind(&true_result);
-  __ mov(eax, 1);
+  __ mov(tos_, 1);
   __ ret(1 * kPointerSize);
   __ bind(&false_result);
-  __ mov(eax, 0);
+  __ mov(tos_, 0);
   __ ret(1 * kPointerSize);
 }
 
 
 class FloatingPointHelper : public AllStatic {
  public:
-
   enum ArgLocation {
     ARGS_ON_STACK,
     ARGS_IN_REGISTERS
@@ -517,31 +511,17 @@
 }
 
 
-Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
-  UnaryOpStub stub(key, type_info);
-  return stub.GetCode();
-}
-
-
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -566,12 +546,10 @@
 
 void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
   __ pop(ecx);  // Save return address.
-  __ push(eax);
-  // the argument is now on top.
-  // Push this stub's key. Although the operation and the type info are
-  // encoded into the key, the encoding is opaque, so push them too.
-  __ push(Immediate(Smi::FromInt(MinorKey())));
+
+  __ push(eax);  // the operand
   __ push(Immediate(Smi::FromInt(op_)));
+  __ push(Immediate(Smi::FromInt(mode_)));
   __ push(Immediate(Smi::FromInt(operand_type_)));
 
   __ push(ecx);  // Push return address.
@@ -579,8 +557,7 @@
   // Patch the caller to an appropriate specialized stub and return the
   // operation result to the caller of the stub.
   __ TailCallExternalReference(
-      ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
-                        masm->isolate()), 4, 1);
+      ExternalReference(IC_Utility(IC::kUnaryOp_Patch), masm->isolate()), 4, 1);
 }
 
 
@@ -627,8 +604,7 @@
                                      Label::Distance undo_near,
                                      Label::Distance slow_near) {
   // Check whether the value is a smi.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, non_smi, non_smi_near);
+  __ JumpIfNotSmi(eax, non_smi, non_smi_near);
 
   // We can't handle -0 with smis, so use a type transition for that case.
   __ test(eax, Operand(eax));
@@ -648,8 +624,7 @@
     Label* non_smi,
     Label::Distance non_smi_near) {
   // Check whether the value is a smi.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, non_smi, non_smi_near);
+  __ JumpIfNotSmi(eax, non_smi, non_smi_near);
 
   // Flip bits and revert inverted smi-tag.
   __ not_(eax);
@@ -853,14 +828,6 @@
 }
 
 
-Handle<Code> GetBinaryOpStub(int key,
-    BinaryOpIC::TypeInfo type_info,
-    BinaryOpIC::TypeInfo result_type_info) {
-  BinaryOpStub stub(key, type_info, result_type_info);
-  return stub.GetCode();
-}
-
-
 void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
   __ pop(ecx);  // Save return address.
   __ push(edx);
@@ -939,12 +906,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -953,13 +915,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -1023,8 +982,7 @@
 
   // 3. Perform the smi check of the operands.
   STATIC_ASSERT(kSmiTag == 0);  // Adjust zero check if not the case.
-  __ test(combined, Immediate(kSmiTagMask));
-  __ j(not_zero, &not_smis);
+  __ JumpIfNotSmi(combined, &not_smis);
 
   // 4. Operands are both smis, perform the operation leaving the result in
   // eax and check the result if necessary.
@@ -1412,14 +1370,12 @@
   Register right = eax;
 
   // Test if left operand is a string.
-  __ test(left, Immediate(kSmiTagMask));
-  __ j(zero, &call_runtime);
+  __ JumpIfSmi(left, &call_runtime);
   __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
   __ j(above_equal, &call_runtime);
 
   // Test if right operand is a string.
-  __ test(right, Immediate(kSmiTagMask));
-  __ j(zero, &call_runtime);
+  __ JumpIfSmi(right, &call_runtime);
   __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
   __ j(above_equal, &call_runtime);
 
@@ -1555,8 +1511,7 @@
             // allocation of a heap number.
             __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ?
                                 1 * kPointerSize : 2 * kPointerSize));
-            __ test(eax, Immediate(kSmiTagMask));
-            __ j(not_zero, &skip_allocation, Label::kNear);
+            __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
             // Fall through!
           case NO_OVERWRITE:
             __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
@@ -1770,8 +1725,7 @@
             // allocation of a heap number.
             __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ?
                                 1 * kPointerSize : 2 * kPointerSize));
-            __ test(eax, Immediate(kSmiTagMask));
-            __ j(not_zero, &skip_allocation, Label::kNear);
+            __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
             // Fall through!
           case NO_OVERWRITE:
             __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
@@ -1970,8 +1924,7 @@
               // allocation of a heap number.
             __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ?
                                 1 * kPointerSize : 2 * kPointerSize));
-            __ test(eax, Immediate(kSmiTagMask));
-            __ j(not_zero, &skip_allocation, Label::kNear);
+            __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
             // Fall through!
           case NO_OVERWRITE:
             __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
@@ -2054,8 +2007,7 @@
   Register right = eax;
 
   // Test if left operand is a string.
-  __ test(left, Immediate(kSmiTagMask));
-  __ j(zero, &left_not_string, Label::kNear);
+  __ JumpIfSmi(left, &left_not_string, Label::kNear);
   __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
   __ j(above_equal, &left_not_string, Label::kNear);
 
@@ -2065,8 +2017,7 @@
 
   // Left operand is not a string, test right.
   __ bind(&left_not_string);
-  __ test(right, Immediate(kSmiTagMask));
-  __ j(zero, &call_runtime, Label::kNear);
+  __ JumpIfSmi(right, &call_runtime, Label::kNear);
   __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
   __ j(above_equal, &call_runtime, Label::kNear);
 
@@ -2088,8 +2039,7 @@
     case OVERWRITE_LEFT: {
       // If the argument in edx is already an object, we skip the
       // allocation of a heap number.
-      __ test(edx, Immediate(kSmiTagMask));
-      __ j(not_zero, &skip_allocation);
+      __ JumpIfNotSmi(edx, &skip_allocation, Label::kNear);
       // Allocate a heap number for the result. Keep eax and edx intact
       // for the possible runtime call.
       __ AllocateHeapNumber(ebx, ecx, no_reg, alloc_failure);
@@ -2104,8 +2054,7 @@
     case OVERWRITE_RIGHT:
       // If the argument in eax is already an object, we skip the
       // allocation of a heap number.
-      __ test(eax, Immediate(kSmiTagMask));
-      __ j(not_zero, &skip_allocation);
+      __ JumpIfNotSmi(eax, &skip_allocation, Label::kNear);
       // Fall through!
     case NO_OVERWRITE:
       // Allocate a heap number for the result. Keep eax and edx intact
@@ -2152,8 +2101,7 @@
     Label input_not_smi;
     Label loaded;
     __ mov(eax, Operand(esp, kPointerSize));
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(not_zero, &input_not_smi, Label::kNear);
+    __ JumpIfNotSmi(eax, &input_not_smi, Label::kNear);
     // Input is a smi. Untag and load it onto the FPU stack.
     // Then load the low and high words of the double into ebx, edx.
     STATIC_ASSERT(kSmiTagSize == 1);
@@ -2431,8 +2379,7 @@
   Label load_arg2, done;
 
   // Test if arg1 is a Smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(not_zero, &arg1_is_object);
+  __ JumpIfNotSmi(edx, &arg1_is_object);
 
   __ SmiUntag(edx);
   __ jmp(&load_arg2);
@@ -2458,8 +2405,7 @@
   __ bind(&load_arg2);
 
   // Test if arg2 is a Smi.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &arg2_is_object);
+  __ JumpIfNotSmi(eax, &arg2_is_object);
 
   __ SmiUntag(eax);
   __ mov(ecx, eax);
@@ -2495,8 +2441,7 @@
                                            Register number) {
   Label load_smi, done;
 
-  __ test(number, Immediate(kSmiTagMask));
-  __ j(zero, &load_smi, Label::kNear);
+  __ JumpIfSmi(number, &load_smi, Label::kNear);
   __ fld_d(FieldOperand(number, HeapNumber::kValueOffset));
   __ jmp(&done, Label::kNear);
 
@@ -2513,16 +2458,12 @@
 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm) {
   Label load_smi_edx, load_eax, load_smi_eax, done;
   // Load operand in edx into xmm0.
-  __ test(edx, Immediate(kSmiTagMask));
-  // Argument in edx is a smi.
-  __ j(zero, &load_smi_edx, Label::kNear);
+  __ JumpIfSmi(edx, &load_smi_edx, Label::kNear);
   __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
 
   __ bind(&load_eax);
   // Load operand in eax into xmm1.
-  __ test(eax, Immediate(kSmiTagMask));
-  // Argument in eax is a smi.
-  __ j(zero, &load_smi_eax, Label::kNear);
+  __ JumpIfSmi(eax, &load_smi_eax, Label::kNear);
   __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
   __ jmp(&done, Label::kNear);
 
@@ -2545,18 +2486,14 @@
                                            Label* not_numbers) {
   Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done;
   // Load operand in edx into xmm0, or branch to not_numbers.
-  __ test(edx, Immediate(kSmiTagMask));
-  // Argument in edx is a smi.
-  __ j(zero, &load_smi_edx, Label::kNear);
+  __ JumpIfSmi(edx, &load_smi_edx, Label::kNear);
   Factory* factory = masm->isolate()->factory();
   __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map());
   __ j(not_equal, not_numbers);  // Argument in edx is not a number.
   __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
   __ bind(&load_eax);
   // Load operand in eax into xmm1, or branch to not_numbers.
-  __ test(eax, Immediate(kSmiTagMask));
-  // Argument in eax is a smi.
-  __ j(zero, &load_smi_eax, Label::kNear);
+  __ JumpIfSmi(eax, &load_smi_eax, Label::kNear);
   __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map());
   __ j(equal, &load_float_eax, Label::kNear);
   __ jmp(not_numbers);  // Argument in eax is not a number.
@@ -2616,8 +2553,7 @@
   } else {
     __ mov(scratch, Operand(esp, 2 * kPointerSize));
   }
-  __ test(scratch, Immediate(kSmiTagMask));
-  __ j(zero, &load_smi_1, Label::kNear);
+  __ JumpIfSmi(scratch, &load_smi_1, Label::kNear);
   __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset));
   __ bind(&done_load_1);
 
@@ -2626,8 +2562,7 @@
   } else {
     __ mov(scratch, Operand(esp, 1 * kPointerSize));
   }
-  __ test(scratch, Immediate(kSmiTagMask));
-  __ j(zero, &load_smi_2, Label::kNear);
+  __ JumpIfSmi(scratch, &load_smi_2, Label::kNear);
   __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset));
   __ jmp(&done, Label::kNear);
 
@@ -2672,16 +2607,14 @@
   Label test_other, done;
   // Test if both operands are floats or smi -> scratch=k_is_float;
   // Otherwise scratch = k_not_float.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &test_other, Label::kNear);  // argument in edx is OK
+  __ JumpIfSmi(edx, &test_other, Label::kNear);
   __ mov(scratch, FieldOperand(edx, HeapObject::kMapOffset));
   Factory* factory = masm->isolate()->factory();
   __ cmp(scratch, factory->heap_number_map());
   __ j(not_equal, non_float);  // argument in edx is not a number -> NaN
 
   __ bind(&test_other);
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &done, Label::kNear);  // argument in eax is OK
+  __ JumpIfSmi(eax, &done, Label::kNear);
   __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
   __ cmp(scratch, factory->heap_number_map());
   __ j(not_equal, non_float);  // argument in eax is not a number -> NaN
@@ -2717,10 +2650,8 @@
   Label exponent_nonsmi;
   Label base_nonsmi;
   // If the exponent is a heap number go to that specific case.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &exponent_nonsmi);
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(not_zero, &base_nonsmi);
+  __ JumpIfNotSmi(eax, &exponent_nonsmi);
+  __ JumpIfNotSmi(edx, &base_nonsmi);
 
   // Optimized version when both exponent and base are smis.
   Label powi;
@@ -2792,8 +2723,7 @@
 
   Label base_not_smi;
   Label handle_special_cases;
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(not_zero, &base_not_smi, Label::kNear);
+  __ JumpIfNotSmi(edx, &base_not_smi, Label::kNear);
   __ SmiUntag(edx);
   __ cvtsi2sd(xmm0, Operand(edx));
   __ jmp(&handle_special_cases, Label::kNear);
@@ -2865,8 +2795,7 @@
 
   // Check that the key is a smi.
   Label slow;
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(not_zero, &slow);
+  __ JumpIfNotSmi(edx, &slow);
 
   // Check if the calling frame is an arguments adaptor frame.
   Label adaptor;
@@ -2915,16 +2844,259 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
   // esp[0] : return address
   // esp[4] : number of parameters
   // esp[8] : receiver displacement
-  // esp[16] : function
+  // esp[12] : function
 
-  // The displacement is used for skipping the return address and the
-  // frame pointer on the stack. It is the offset of the last
-  // parameter (if any) relative to the frame pointer.
-  static const int kDisplacement = 2 * kPointerSize;
+  // Check if the calling frame is an arguments adaptor frame.
+  Label runtime;
+  __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
+  __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
+  __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ j(not_equal, &runtime, Label::kNear);
+
+  // Patch the arguments.length and the parameters pointer.
+  __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ mov(Operand(esp, 1 * kPointerSize), ecx);
+  __ lea(edx, Operand(edx, ecx, times_2,
+              StandardFrameConstants::kCallerSPOffset));
+  __ mov(Operand(esp, 2 * kPointerSize), edx);
+
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+  // esp[0] : return address
+  // esp[4] : number of parameters (tagged)
+  // esp[8] : receiver displacement
+  // esp[12] : function
+
+  // ebx = parameter count (tagged)
+  __ mov(ebx, Operand(esp, 1 * kPointerSize));
+
+  // Check if the calling frame is an arguments adaptor frame.
+  // TODO(rossberg): Factor out some of the bits that are shared with the other
+  // Generate* functions.
+  Label runtime;
+  Label adaptor_frame, try_allocate;
+  __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
+  __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
+  __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ j(equal, &adaptor_frame, Label::kNear);
+
+  // No adaptor, parameter count = argument count.
+  __ mov(ecx, ebx);
+  __ jmp(&try_allocate, Label::kNear);
+
+  // We have an adaptor frame. Patch the parameters pointer.
+  __ bind(&adaptor_frame);
+  __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ lea(edx, Operand(edx, ecx, times_2,
+                      StandardFrameConstants::kCallerSPOffset));
+  __ mov(Operand(esp, 2 * kPointerSize), edx);
+
+  // ebx = parameter count (tagged)
+  // ecx = argument count (tagged)
+  // esp[4] = parameter count (tagged)
+  // esp[8] = address of receiver argument
+  // Compute the mapped parameter count = min(ebx, ecx) in ebx.
+  __ cmp(ebx, Operand(ecx));
+  __ j(less_equal, &try_allocate, Label::kNear);
+  __ mov(ebx, ecx);
+
+  __ bind(&try_allocate);
+
+  // Save mapped parameter count.
+  __ push(ebx);
+
+  // 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;
+  Label no_parameter_map;
+  __ test(ebx, Operand(ebx));
+  __ j(zero, &no_parameter_map, Label::kNear);
+  __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
+  __ bind(&no_parameter_map);
+
+  // 2. Backing store.
+  __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
+
+  // 3. Arguments object.
+  __ add(Operand(ebx), Immediate(Heap::kArgumentsObjectSize));
+
+  // Do the allocation of all three objects in one go.
+  __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
+
+  // eax = address of new object(s) (tagged)
+  // ecx = argument count (tagged)
+  // esp[0] = mapped parameter count (tagged)
+  // esp[8] = parameter count (tagged)
+  // esp[12] = address of receiver argument
+  // Get the arguments boilerplate from the current (global) context into edi.
+  Label has_mapped_parameters, copy;
+  __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
+  __ mov(ebx, Operand(esp, 0 * kPointerSize));
+  __ test(ebx, Operand(ebx));
+  __ j(not_zero, &has_mapped_parameters, Label::kNear);
+  __ mov(edi, Operand(edi,
+         Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX)));
+  __ jmp(&copy, Label::kNear);
+
+  __ bind(&has_mapped_parameters);
+  __ mov(edi, Operand(edi,
+            Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX)));
+  __ bind(&copy);
+
+  // eax = address of new object (tagged)
+  // ebx = mapped parameter count (tagged)
+  // ecx = argument count (tagged)
+  // edi = address of boilerplate object (tagged)
+  // esp[0] = mapped parameter count (tagged)
+  // esp[8] = parameter count (tagged)
+  // esp[12] = address of receiver argument
+  // Copy the JS object part.
+  for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
+    __ mov(edx, FieldOperand(edi, i));
+    __ mov(FieldOperand(eax, i), edx);
+  }
+
+  // Setup the callee in-object property.
+  STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
+  __ mov(edx, Operand(esp, 4 * kPointerSize));
+  __ mov(FieldOperand(eax, JSObject::kHeaderSize +
+                      Heap::kArgumentsCalleeIndex * kPointerSize),
+         edx);
+
+  // Use the length (smi tagged) and set that as an in-object property too.
+  STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
+  __ mov(FieldOperand(eax, JSObject::kHeaderSize +
+                      Heap::kArgumentsLengthIndex * kPointerSize),
+         ecx);
+
+  // Setup the elements pointer in the allocated arguments object.
+  // If we allocated a parameter map, edi will point there, otherwise to the
+  // backing store.
+  __ lea(edi, Operand(eax, Heap::kArgumentsObjectSize));
+  __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
+
+  // eax = address of new object (tagged)
+  // ebx = mapped parameter count (tagged)
+  // ecx = argument count (tagged)
+  // edi = address of parameter map or backing store (tagged)
+  // esp[0] = mapped parameter count (tagged)
+  // esp[8] = parameter count (tagged)
+  // esp[12] = address of receiver argument
+  // Free a register.
+  __ push(eax);
+
+  // Initialize parameter map. If there are no mapped arguments, we're done.
+  Label skip_parameter_map;
+  __ test(ebx, Operand(ebx));
+  __ j(zero, &skip_parameter_map);
+
+  __ mov(FieldOperand(edi, FixedArray::kMapOffset),
+         Immediate(FACTORY->non_strict_arguments_elements_map()));
+  __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
+  __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
+  __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
+  __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
+  __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
+
+  // 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;
+  __ push(ecx);
+  __ mov(eax, Operand(esp, 2 * kPointerSize));
+  __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
+  __ add(ebx, Operand(esp, 4 * kPointerSize));
+  __ sub(ebx, Operand(eax));
+  __ mov(ecx, FACTORY->the_hole_value());
+  __ mov(edx, edi);
+  __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
+  // eax = loop variable (tagged)
+  // ebx = mapping index (tagged)
+  // ecx = the hole value
+  // edx = address of parameter map (tagged)
+  // edi = address of backing store (tagged)
+  // esp[0] = argument count (tagged)
+  // esp[4] = address of new object (tagged)
+  // esp[8] = mapped parameter count (tagged)
+  // esp[16] = parameter count (tagged)
+  // esp[20] = address of receiver argument
+  __ jmp(&parameters_test, Label::kNear);
+
+  __ bind(&parameters_loop);
+  __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
+  __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
+  __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
+  __ add(Operand(ebx), Immediate(Smi::FromInt(1)));
+  __ bind(&parameters_test);
+  __ test(eax, Operand(eax));
+  __ j(not_zero, &parameters_loop, Label::kNear);
+  __ pop(ecx);
+
+  __ bind(&skip_parameter_map);
+
+  // ecx = argument count (tagged)
+  // edi = address of backing store (tagged)
+  // esp[0] = address of new object (tagged)
+  // esp[4] = mapped parameter count (tagged)
+  // esp[12] = parameter count (tagged)
+  // esp[16] = address of receiver argument
+  // Copy arguments header and remaining slots (if there are any).
+  __ mov(FieldOperand(edi, FixedArray::kMapOffset),
+         Immediate(FACTORY->fixed_array_map()));
+  __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
+
+  Label arguments_loop, arguments_test;
+  __ mov(ebx, Operand(esp, 1 * kPointerSize));
+  __ mov(edx, Operand(esp, 4 * kPointerSize));
+  __ sub(Operand(edx), ebx);  // Is there a smarter way to do negative scaling?
+  __ sub(Operand(edx), ebx);
+  __ jmp(&arguments_test, Label::kNear);
+
+  __ bind(&arguments_loop);
+  __ sub(Operand(edx), Immediate(kPointerSize));
+  __ mov(eax, Operand(edx, 0));
+  __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
+  __ add(Operand(ebx), Immediate(Smi::FromInt(1)));
+
+  __ bind(&arguments_test);
+  __ cmp(ebx, Operand(ecx));
+  __ j(less, &arguments_loop, Label::kNear);
+
+  // Restore.
+  __ pop(eax);  // Address of arguments object.
+  __ pop(ebx);  // Parameter count.
+
+  // Return and remove the on-stack parameters.
+  __ ret(3 * kPointerSize);
+
+  // Do the runtime call to allocate the arguments object.
+  __ bind(&runtime);
+  __ pop(eax);  // Remove saved parameter count.
+  __ mov(Operand(esp, 1 * kPointerSize), ecx);  // Patch argument count.
+  __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
+  // esp[0] : return address
+  // esp[4] : number of parameters
+  // esp[8] : receiver displacement
+  // esp[12] : function
 
   // Check if the calling frame is an arguments adaptor frame.
   Label adaptor_frame, try_allocate, runtime;
@@ -2941,7 +3113,8 @@
   __ bind(&adaptor_frame);
   __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
   __ mov(Operand(esp, 1 * kPointerSize), ecx);
-  __ lea(edx, Operand(edx, ecx, times_2, kDisplacement));
+  __ lea(edx, Operand(edx, ecx, times_2,
+                      StandardFrameConstants::kCallerSPOffset));
   __ mov(Operand(esp, 2 * kPointerSize), edx);
 
   // Try the new space allocation. Start out with computing the size of
@@ -2952,7 +3125,7 @@
   __ j(zero, &add_arguments_object, Label::kNear);
   __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize));
   __ bind(&add_arguments_object);
-  __ add(Operand(ecx), Immediate(GetArgumentsObjectSize()));
+  __ add(Operand(ecx), Immediate(Heap::kArgumentsObjectSizeStrict));
 
   // Do the allocation of both objects in one go.
   __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
@@ -2960,8 +3133,9 @@
   // Get the arguments boilerplate from the current (global) context.
   __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
-  __ mov(edi, Operand(edi,
-                      Context::SlotOffset(GetArgumentsBoilerplateIndex())));
+  const int offset =
+      Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
+  __ mov(edi, Operand(edi, offset));
 
   // Copy the JS object part.
   for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
@@ -2969,20 +3143,11 @@
     __ mov(FieldOperand(eax, i), ebx);
   }
 
-  if (type_ == NEW_NON_STRICT) {
-    // Setup the callee in-object property.
-    STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
-    __ mov(ebx, Operand(esp, 3 * kPointerSize));
-    __ mov(FieldOperand(eax, JSObject::kHeaderSize +
-                             Heap::kArgumentsCalleeIndex * kPointerSize),
-           ebx);
-  }
-
   // Get the length (smi tagged) and set that as an in-object property too.
   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
   __ mov(ecx, Operand(esp, 1 * kPointerSize));
   __ mov(FieldOperand(eax, JSObject::kHeaderSize +
-                           Heap::kArgumentsLengthIndex * kPointerSize),
+                      Heap::kArgumentsLengthIndex * kPointerSize),
          ecx);
 
   // If there are no actual arguments, we're done.
@@ -2995,10 +3160,10 @@
 
   // Setup the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ lea(edi, Operand(eax, GetArgumentsObjectSize()));
+  __ lea(edi, Operand(eax, Heap::kArgumentsObjectSizeStrict));
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
-         Immediate(masm->isolate()->factory()->fixed_array_map()));
+         Immediate(FACTORY->fixed_array_map()));
 
   __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
   // Untag the length for the loop below.
@@ -3020,7 +3185,7 @@
 
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+  __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
 }
 
 
@@ -3063,8 +3228,7 @@
   // Check that the first argument is a JSRegExp object.
   __ mov(eax, Operand(esp, kJSRegExpOffset));
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &runtime);
+  __ JumpIfSmi(eax, &runtime);
   __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx);
   __ j(not_equal, &runtime);
   // Check that the RegExp has been compiled (data contains a fixed array).
@@ -3098,8 +3262,7 @@
   // edx: Number of capture registers
   // Check that the second argument is a string.
   __ mov(eax, Operand(esp, kSubjectOffset));
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &runtime);
+  __ JumpIfSmi(eax, &runtime);
   Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
   __ j(NegateCondition(is_string), &runtime);
   // Get the length of the string to ebx.
@@ -3111,8 +3274,7 @@
   // Check that the third argument is a positive smi less than the subject
   // string length. A negative value will be greater (unsigned comparison).
   __ mov(eax, Operand(esp, kPreviousIndexOffset));
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &runtime);
+  __ JumpIfNotSmi(eax, &runtime);
   __ cmp(eax, Operand(ebx));
   __ j(above_equal, &runtime);
 
@@ -3120,8 +3282,7 @@
   // edx: Number of capture registers
   // Check that the fourth object is a JSArray object.
   __ mov(eax, Operand(esp, kLastMatchInfoOffset));
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &runtime);
+  __ JumpIfSmi(eax, &runtime);
   __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
   __ j(not_equal, &runtime);
   // Check that the JSArray is in fast case.
@@ -3392,8 +3553,7 @@
   Label slowcase;
   Label done;
   __ mov(ebx, Operand(esp, kPointerSize * 3));
-  __ test(ebx, Immediate(kSmiTagMask));
-  __ j(not_zero, &slowcase);
+  __ JumpIfNotSmi(ebx, &slowcase);
   __ cmp(Operand(ebx), Immediate(Smi::FromInt(kMaxInlineLength)));
   __ j(above, &slowcase);
   // Smi-tagging is equivalent to multiplying by 2.
@@ -3505,8 +3665,7 @@
   } else {
     Label not_smi;
     STATIC_ASSERT(kSmiTag == 0);
-    __ test(object, Immediate(kSmiTagMask));
-    __ j(not_zero, &not_smi, Label::kNear);
+    __ JumpIfNotSmi(object, &not_smi, Label::kNear);
     __ mov(scratch, object);
     __ SmiUntag(scratch);
     __ jmp(&smi_hash_calculated, Label::kNear);
@@ -3526,8 +3685,7 @@
                         index,
                         times_twice_pointer_size,
                         FixedArray::kHeaderSize));
-    __ test(probe, Immediate(kSmiTagMask));
-    __ j(zero, not_found);
+    __ JumpIfSmi(probe, not_found);
     if (CpuFeatures::IsSupported(SSE2)) {
       CpuFeatures::Scope fscope(SSE2);
       __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
@@ -3599,8 +3757,7 @@
     Label non_smi, smi_done;
     __ mov(ecx, Operand(edx));
     __ or_(ecx, Operand(eax));
-    __ test(ecx, Immediate(kSmiTagMask));
-    __ j(not_zero, &non_smi);
+    __ JumpIfNotSmi(ecx, &non_smi);
     __ sub(edx, Operand(eax));  // Return on the result of the subtraction.
     __ j(no_overflow, &smi_done);
     __ not_(edx);  // Correct sign in case of overflow. edx is never 0 here.
@@ -3649,7 +3806,7 @@
       __ j(equal, &heap_number, Label::kNear);
       if (cc_ != equal) {
         // Call runtime on identical JSObjects.  Otherwise return equal.
-        __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+        __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
         __ j(above_equal, &not_identical);
       }
       __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
@@ -3737,8 +3894,8 @@
     // Get the type of the first operand.
     // If the first object is a JS object, we have done pointer comparison.
     Label first_non_object;
-    STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-    __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+    STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
+    __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
     __ j(below, &first_non_object, Label::kNear);
 
     // Return non-zero (eax is not zero)
@@ -3752,7 +3909,7 @@
     __ CmpInstanceType(ecx, ODDBALL_TYPE);
     __ j(equal, &return_not_equal);
 
-    __ CmpObjectType(edx, FIRST_JS_OBJECT_TYPE, ecx);
+    __ CmpObjectType(edx, FIRST_SPEC_OBJECT_TYPE, ecx);
     __ j(above_equal, &return_not_equal);
 
     // Check for oddballs: true, false, null, undefined.
@@ -3876,9 +4033,9 @@
     __ lea(ecx, Operand(eax, edx, times_1, 0));
     __ test(ecx, Immediate(kSmiTagMask));
     __ j(not_zero, &not_both_objects, Label::kNear);
-    __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+    __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
     __ j(below, &not_both_objects, Label::kNear);
-    __ CmpObjectType(edx, FIRST_JS_OBJECT_TYPE, ebx);
+    __ CmpObjectType(edx, FIRST_SPEC_OBJECT_TYPE, ebx);
     __ j(below, &not_both_objects, Label::kNear);
     // We do not bail out after this point.  Both are JSObjects, and
     // they are equal if and only if both are undetectable.
@@ -3926,8 +4083,7 @@
                                     Label* label,
                                     Register object,
                                     Register scratch) {
-  __ test(object, Immediate(kSmiTagMask));
-  __ j(zero, label);
+  __ JumpIfSmi(object, label);
   __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset));
   __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
   __ and_(scratch, kIsSymbolMask | kIsNotStringMask);
@@ -3967,8 +4123,7 @@
   __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize));
 
   // Check that the function really is a JavaScript function.
-  __ test(edi, Immediate(kSmiTagMask));
-  __ j(zero, &slow);
+  __ JumpIfSmi(edi, &slow);
   // Goto slow case if we do not have a function.
   __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
   __ j(not_equal, &slow);
@@ -4003,6 +4158,7 @@
   __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
   Handle<Code> adaptor =
       masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+  __ SetCallKind(ecx, CALL_AS_METHOD);
   __ jmp(adaptor, RelocInfo::CODE_TARGET);
 }
 
@@ -4209,9 +4365,7 @@
 
 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   Label invoke, exit;
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Label not_outermost_js, not_outermost_js_2;
-#endif
 
   // Setup frame.
   __ push(ebp);
@@ -4230,7 +4384,6 @@
   ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate());
   __ push(Operand::StaticVariable(c_entry_fp));
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If this is the outermost JS call, set js_entry_sp value.
   ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
                                 masm->isolate());
@@ -4243,7 +4396,6 @@
   __ bind(&not_outermost_js);
   __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
   __ bind(&cont);
-#endif
 
   // Call a faked try-block that does the invoke.
   __ call(&invoke);
@@ -4291,7 +4443,6 @@
   __ PopTryHandler();
 
   __ bind(&exit);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Check if the current stack frame is marked as the outermost JS frame.
   __ pop(ebx);
   __ cmp(Operand(ebx),
@@ -4299,7 +4450,6 @@
   __ j(not_equal, &not_outermost_js_2);
   __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0));
   __ bind(&not_outermost_js_2);
-#endif
 
   // Restore the top frame descriptor from the stack.
   __ pop(Operand::StaticVariable(ExternalReference(
@@ -4367,8 +4517,7 @@
   }
 
   // Check that the left hand is a JS object.
-  __ test(object, Immediate(kSmiTagMask));
-  __ j(zero, &not_js_object);
+  __ 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
@@ -4395,8 +4544,7 @@
   __ TryGetFunctionPrototype(function, prototype, scratch, &slow);
 
   // Check that the function prototype is a JS object.
-  __ test(prototype, Immediate(kSmiTagMask));
-  __ j(zero, &slow);
+  __ JumpIfSmi(prototype, &slow);
   __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
 
   // Update the global instanceof or call site inlined cache with the current
@@ -4485,8 +4633,7 @@
   __ 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.
-  __ test(function, Immediate(kSmiTagMask));
-  __ j(zero, &slow);
+  __ JumpIfSmi(function, &slow);
   __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
   __ j(not_equal, &slow);
 
@@ -4498,8 +4645,7 @@
 
   __ bind(&object_not_null);
   // Smi values is not instance of anything.
-  __ test(object, Immediate(kSmiTagMask));
-  __ j(not_zero, &object_not_null_or_smi);
+  __ JumpIfNotSmi(object, &object_not_null_or_smi);
   __ Set(eax, Immediate(Smi::FromInt(1)));
   __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
 
@@ -4565,15 +4711,8 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case less: cc_name = "LT"; break;
@@ -4584,35 +4723,12 @@
     case not_equal: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == equal || cc_ == not_equal)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s%s",
-               cc_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == equal || cc_ == not_equal;
+  stream->Add("CompareStub_%s", cc_name);
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
@@ -4626,8 +4742,7 @@
 
   // If the receiver is a smi trigger the non-string case.
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(object_, Immediate(kSmiTagMask));
-  __ j(zero, receiver_not_string_);
+  __ JumpIfSmi(object_, receiver_not_string_);
 
   // Fetch the instance type of the receiver into result register.
   __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
@@ -4638,8 +4753,7 @@
 
   // If the index is non-smi trigger the non-smi case.
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(index_, Immediate(kSmiTagMask));
-  __ j(not_zero, &index_not_smi_);
+  __ JumpIfNotSmi(index_, &index_not_smi_);
 
   // Put smi-tagged index into scratch register.
   __ mov(scratch_, index_);
@@ -4737,8 +4851,7 @@
   call_helper.AfterCall(masm);
   // If index is still not a smi, it must be out of range.
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(scratch_, Immediate(kSmiTagMask));
-  __ j(not_zero, index_out_of_range_);
+  __ JumpIfNotSmi(scratch_, index_out_of_range_);
   // Otherwise, return to the fast path.
   __ jmp(&got_smi_index_);
 
@@ -4832,14 +4945,12 @@
 
   // Make sure that both arguments are strings if not known in advance.
   if (flags_ == NO_STRING_ADD_FLAGS) {
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(zero, &string_add_runtime);
+    __ JumpIfSmi(eax, &string_add_runtime);
     __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx);
     __ j(above_equal, &string_add_runtime);
 
     // First argument is a a string, test second.
-    __ test(edx, Immediate(kSmiTagMask));
-    __ j(zero, &string_add_runtime);
+    __ JumpIfSmi(edx, &string_add_runtime);
     __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx);
     __ j(above_equal, &string_add_runtime);
   } else {
@@ -5107,8 +5218,7 @@
                                             Label* slow) {
   // First check if the argument is already a string.
   Label not_string, done;
-  __ test(arg, Immediate(kSmiTagMask));
-  __ j(zero, &not_string);
+  __ JumpIfSmi(arg, &not_string);
   __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1);
   __ j(below, &done);
 
@@ -5129,8 +5239,7 @@
 
   // Check if the argument is a safe string wrapper.
   __ bind(&not_cached);
-  __ test(arg, Immediate(kSmiTagMask));
-  __ j(zero, slow);
+  __ JumpIfSmi(arg, slow);
   __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1);  // map -> scratch1.
   __ j(not_equal, slow);
   __ test_b(FieldOperand(scratch1, Map::kBitField2Offset),
@@ -5424,8 +5533,7 @@
   // Make sure first argument is a string.
   __ mov(eax, Operand(esp, 3 * kPointerSize));
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &runtime);
+  __ JumpIfSmi(eax, &runtime);
   Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
   __ j(NegateCondition(is_string), &runtime);
 
@@ -5435,11 +5543,9 @@
   // Calculate length of sub string using the smi values.
   Label result_longer_than_two;
   __ mov(ecx, Operand(esp, 1 * kPointerSize));  // To index.
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(not_zero, &runtime);
+  __ JumpIfNotSmi(ecx, &runtime);
   __ mov(edx, Operand(esp, 2 * kPointerSize));  // From index.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(not_zero, &runtime);
+  __ JumpIfNotSmi(edx, &runtime);
   __ sub(ecx, Operand(edx));
   __ cmp(ecx, FieldOperand(eax, String::kLengthOffset));
   Label return_eax;
@@ -5731,8 +5837,7 @@
   Label miss;
   __ mov(ecx, Operand(edx));
   __ or_(ecx, Operand(eax));
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(not_zero, &miss, Label::kNear);
+  __ JumpIfNotSmi(ecx, &miss, Label::kNear);
 
   if (GetCondition() == equal) {
     // For equality we do not care about the sign of the result.
@@ -5761,8 +5866,7 @@
   Label miss;
   __ mov(ecx, Operand(edx));
   __ and_(ecx, Operand(eax));
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(zero, &generic_stub, Label::kNear);
+  __ JumpIfSmi(ecx, &generic_stub, Label::kNear);
 
   __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx);
   __ j(not_equal, &miss, Label::kNear);
@@ -5821,8 +5925,7 @@
   __ mov(tmp1, Operand(left));
   STATIC_ASSERT(kSmiTag == 0);
   __ and_(tmp1, Operand(right));
-  __ test(tmp1, Immediate(kSmiTagMask));
-  __ j(zero, &miss, Label::kNear);
+  __ JumpIfSmi(tmp1, &miss, Label::kNear);
 
   // Check that both operands are symbols.
   __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset));
@@ -5868,8 +5971,7 @@
   __ mov(tmp1, Operand(left));
   STATIC_ASSERT(kSmiTag == 0);
   __ and_(tmp1, Operand(right));
-  __ test(tmp1, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(tmp1, &miss);
 
   // Check that both operands are strings. This leaves the instance
   // types loaded in tmp1 and tmp2.
@@ -5934,8 +6036,7 @@
   Label miss;
   __ mov(ecx, Operand(edx));
   __ and_(ecx, Operand(eax));
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(zero, &miss, Label::kNear);
+  __ JumpIfSmi(ecx, &miss, Label::kNear);
 
   __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx);
   __ j(not_equal, &miss, Label::kNear);
diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h
index ead7761..fa255da 100644
--- a/src/ia32/code-stubs-ia32.h
+++ b/src/ia32/code-stubs-ia32.h
@@ -60,32 +60,14 @@
 };
 
 
-class ToBooleanStub: public CodeStub {
- public:
-  ToBooleanStub() { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  Major MajorKey() { return ToBoolean; }
-  int MinorKey() { return 0; }
-};
-
-
 class UnaryOpStub: public CodeStub {
  public:
-  UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
+  UnaryOpStub(Token::Value op,
+              UnaryOverwriteMode mode,
+              UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(UnaryOpIC::UNINITIALIZED),
-        name_(NULL) {
-  }
-
-  UnaryOpStub(int key, UnaryOpIC::TypeInfo operand_type)
-      : op_(OpBits::decode(key)),
-        mode_(ModeBits::decode(key)),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -95,20 +77,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("TypeRecordingUnaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -171,8 +140,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     use_sse3_ = CpuFeatures::IsSupported(SSE3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -185,8 +153,7 @@
         mode_(ModeBits::decode(key)),
         use_sse3_(SSE3Bits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -202,20 +169,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 16 bits RRRTTTSOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
@@ -433,14 +387,6 @@
   int MinorKey() { return 0; }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "NumberToStringStub"; }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("NumberToStringStub\n");
-  }
-#endif
 };
 
 
@@ -484,13 +430,6 @@
       StringDictionary::kHeaderSize +
       StringDictionary::kElementsStartIndex * kPointerSize;
 
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("StringDictionaryLookupStub\n");
-  }
-#endif
-
   Major MajorKey() { return StringDictionaryNegativeLookup; }
 
   int MinorKey() {
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 572c36c..3a657bd 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -255,6 +255,7 @@
   ASSERT(desc.reloc_size == 0);
 
   CPU::FlushICache(buffer, actual_size);
+  OS::ProtectCode(buffer, actual_size);
   return FUNCTION_CAST<OS::MemCopyFunction>(buffer);
 }
 
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 8f090b1..c85fa83 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -53,9 +53,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static bool RecordPositions(MacroAssembler* masm,
                               int pos,
diff --git a/src/ia32/cpu-ia32.cc b/src/ia32/cpu-ia32.cc
index 615dbfe..57e66df 100644
--- a/src/ia32/cpu-ia32.cc
+++ b/src/ia32/cpu-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -67,7 +67,8 @@
   // solution is to run valgrind with --smc-check=all, but this comes at a big
   // performance cost.  We can notify valgrind to invalidate its cache.
 #ifdef VALGRIND_DISCARD_TRANSLATIONS
-  VALGRIND_DISCARD_TRANSLATIONS(start, size);
+  unsigned res = VALGRIND_DISCARD_TRANSLATIONS(start, size);
+  USE(res);
 #endif
 }
 
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 72fdac8..4ff1bfc 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -348,6 +348,9 @@
   output_ = new FrameDescription*[1];
   output_[0] = new(output_frame_size) FrameDescription(
       output_frame_size, function_);
+#ifdef DEBUG
+  output_[0]->SetKind(Code::OPTIMIZED_FUNCTION);
+#endif
 
   // Clear the incoming parameters in the optimized frame to avoid
   // confusing the garbage collector.
@@ -461,6 +464,9 @@
   // Allocate and store the output frame description.
   FrameDescription* output_frame =
       new(output_frame_size) FrameDescription(output_frame_size, function);
+#ifdef DEBUG
+  output_frame->SetKind(Code::FUNCTION);
+#endif
 
   bool is_bottommost = (0 == frame_index);
   bool is_topmost = (output_count_ - 1 == frame_index);
@@ -587,7 +593,7 @@
   output_frame->SetState(Smi::FromInt(state));
 
   // Set the continuation for the topmost frame.
-  if (is_topmost) {
+  if (is_topmost && bailout_type_ != DEBUGGER) {
     Builtins* builtins = isolate_->builtins();
     Code* continuation = (bailout_type_ == EAGER)
         ? builtins->builtin(Builtins::kNotifyDeoptimized)
@@ -600,6 +606,27 @@
 }
 
 
+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 ebp and esp are set to the correct values though.
+
+  for (int i = 0; i < Register::kNumRegisters; i++) {
+    input_->SetRegister(i, i * 4);
+  }
+  input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp()));
+  input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp()));
+  for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; 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, Memory::uint32_at(tos + i));
+  }
+}
+
+
 #define __ masm()->
 
 void Deoptimizer::EntryGenerator::Generate() {
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 5f0a0b6..7633856 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -78,16 +78,18 @@
   }
 
   void EmitPatchInfo() {
-    int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
-    ASSERT(is_int8(delta_to_patch_site));
-    __ test(eax, Immediate(delta_to_patch_site));
+    if (patch_site_.is_bound()) {
+      int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
+      ASSERT(is_int8(delta_to_patch_site));
+      __ test(eax, Immediate(delta_to_patch_site));
 #ifdef DEBUG
-    info_emitted_ = true;
+      info_emitted_ = true;
 #endif
+    } else {
+      __ nop();  // Signals no inlined code.
+    }
   }
 
-  bool is_bound() const { return patch_site_.is_bound(); }
-
  private:
   // jc will be patched with jz, jnc will become jnz.
   void EmitJump(Condition cc, Label* target, Label::Distance distance) {
@@ -121,6 +123,7 @@
 void FullCodeGenerator::Generate(CompilationInfo* info) {
   ASSERT(info_ == NULL);
   info_ = info;
+  scope_ = info->scope();
   SetFunctionPosition(function());
   Comment cmnt(masm_, "[ function compiled by full code generator");
 
@@ -131,16 +134,16 @@
   }
 #endif
 
-  // Strict mode functions need to replace the receiver with undefined
-  // when called as functions (without an explicit receiver
-  // object). ecx is zero for method calls and non-zero for function
-  // calls.
-  if (info->is_strict_mode()) {
+  // Strict mode functions and builtins need to replace the receiver
+  // with undefined when called as functions (without an explicit
+  // receiver object). ecx is zero for method calls and non-zero for
+  // function calls.
+  if (info->is_strict_mode() || info->is_native()) {
     Label ok;
     __ test(ecx, Operand(ecx));
     __ j(zero, &ok, Label::kNear);
     // +1 for return address.
-    int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
+    int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize;
     __ mov(Operand(esp, receiver_offset),
            Immediate(isolate()->factory()->undefined_value()));
     __ bind(&ok);
@@ -152,7 +155,7 @@
   __ push(edi);  // Callee's JS Function.
 
   { Comment cmnt(masm_, "[ Allocate locals");
-    int locals_count = scope()->num_stack_slots();
+    int locals_count = info->scope()->num_stack_slots();
     if (locals_count == 1) {
       __ push(Immediate(isolate()->factory()->undefined_value()));
     } else if (locals_count > 1) {
@@ -166,7 +169,7 @@
   bool function_in_register = true;
 
   // Possibly allocate a local context.
-  int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   if (heap_slots > 0) {
     Comment cmnt(masm_, "[ Allocate local context");
     // Argument to NewContext is the function, which is still in edi.
@@ -175,7 +178,7 @@
       FastNewContextStub stub(heap_slots);
       __ CallStub(&stub);
     } else {
-      __ CallRuntime(Runtime::kNewContext, 1);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
     }
     function_in_register = false;
     // Context is returned in both eax and esi.  It replaces the context
@@ -183,7 +186,7 @@
     __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
 
     // Copy parameters into context if necessary.
-    int num_parameters = scope()->num_parameters();
+    int num_parameters = info->scope()->num_parameters();
     for (int i = 0; i < num_parameters; i++) {
       Slot* slot = scope()->parameter(i)->AsSlot();
       if (slot != NULL && slot->type() == Slot::CONTEXT) {
@@ -213,25 +216,27 @@
       __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
     }
     // Receiver is just before the parameters on the caller's stack.
-    int offset = scope()->num_parameters() * kPointerSize;
+    int num_parameters = info->scope()->num_parameters();
+    int offset = num_parameters * kPointerSize;
     __ lea(edx,
            Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
     __ push(edx);
-    __ SafePush(Immediate(Smi::FromInt(scope()->num_parameters())));
-    // Arguments to ArgumentsAccessStub:
+    __ SafePush(Immediate(Smi::FromInt(num_parameters)));
+    // Arguments to ArgumentsAccessStub and/or New...:
     //   function, receiver address, parameter count.
     // The stub will rewrite receiver and parameter count if the previous
     // stack frame was an arguments adapter frame.
-    ArgumentsAccessStub stub(
-        is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT
-                         : ArgumentsAccessStub::NEW_NON_STRICT);
+    ArgumentsAccessStub::Type type;
+    if (is_strict_mode()) {
+      type = ArgumentsAccessStub::NEW_STRICT;
+    } else if (function()->has_duplicate_parameters()) {
+      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+    } else {
+      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+    }
+    ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
 
-    Variable* arguments_shadow = scope()->arguments_shadow();
-    if (arguments_shadow != NULL) {
-      __ mov(ecx, eax);  // Duplicate result.
-      Move(arguments_shadow->AsSlot(), ecx, ebx, edx);
-    }
     Move(arguments->AsSlot(), eax, ebx, edx);
   }
 
@@ -341,7 +346,7 @@
     __ mov(esp, ebp);
     __ pop(ebp);
 
-    int arguments_bytes = (scope()->num_parameters() + 1) * kPointerSize;
+    int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize;
     __ Ret(arguments_bytes, ecx);
 #ifdef ENABLE_DEBUGGER_SUPPORT
     // Check that the size of the code used for returning is large enough
@@ -374,7 +379,7 @@
   // For simplicity we always test the accumulator register.
   codegen()->Move(result_register(), slot);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -448,7 +453,7 @@
   } else {
     // For simplicity we always test the accumulator register.
     __ mov(result_register(), lit);
-    codegen()->DoTest(true_label_, false_label_, fall_through_);
+    codegen()->DoTest(this);
   }
 }
 
@@ -484,7 +489,7 @@
   __ Drop(count);
   __ Move(result_register(), reg);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -561,13 +566,14 @@
 }
 
 
-void FullCodeGenerator::DoTest(Label* if_true,
+void FullCodeGenerator::DoTest(Expression* condition,
+                               Label* if_true,
                                Label* if_false,
                                Label* fall_through) {
-  ToBooleanStub stub;
+  ToBooleanStub stub(result_register());
   __ push(result_register());
   __ CallStub(&stub);
-  __ test(eax, Operand(eax));
+  __ test(result_register(), Operand(result_register()));
   // The stub returns nonzero for true.
   Split(not_zero, if_true, if_false, fall_through);
 }
@@ -685,10 +691,12 @@
         // context.
         ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
         if (FLAG_debug_code) {
-          // Check that we're not inside a 'with'.
-          __ mov(ebx, ContextOperand(esi, Context::FCONTEXT_INDEX));
-          __ cmp(ebx, Operand(esi));
-          __ Check(equal, "Unexpected declaration in current context.");
+          // Check that we're not inside a with or catch context.
+          __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset));
+          __ cmp(ebx, isolate()->factory()->with_context_map());
+          __ Check(not_equal, "Declaration in with context.");
+          __ cmp(ebx, isolate()->factory()->catch_context_map());
+          __ Check(not_equal, "Declaration in catch context.");
         }
         if (mode == Variable::CONST) {
           __ mov(ContextOperand(esi, slot->index()),
@@ -736,7 +744,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
 
       __ push(eax);
@@ -750,7 +758,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ call(ic);
     }
   }
 }
@@ -823,7 +831,8 @@
     // Record position before stub call for type feedback.
     SetSourcePosition(clause->position());
     Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
-    EmitCallIC(ic, &patch_site, clause->CompareId());
+    __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
+    patch_site.EmitPatchInfo();
     __ test(eax, Operand(eax));
     __ j(not_equal, &next_test);
     __ Drop(1);  // Switch value is no longer needed.
@@ -873,9 +882,8 @@
 
   // Convert the object to a JS object.
   Label convert, done_convert;
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &convert, Label::kNear);
-  __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+  __ JumpIfSmi(eax, &convert, Label::kNear);
+  __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
   __ j(above_equal, &done_convert, Label::kNear);
   __ bind(&convert);
   __ push(eax);
@@ -908,8 +916,7 @@
   // descriptors (edx).  This is the case if the next enumeration
   // index field does not contain a smi.
   __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &call_runtime);
+  __ JumpIfSmi(edx, &call_runtime);
 
   // For all objects but the receiver, check that the cache is empty.
   Label check_prototype;
@@ -1057,7 +1064,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1078,8 +1085,7 @@
         __ j(not_equal, slow);
       }
       // Load next context in chain.
-      __ mov(temp, ContextOperand(context, Context::CLOSURE_INDEX));
-      __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset));
+      __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering esi.
       context = temp;
     }
@@ -1106,8 +1112,7 @@
     __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
     __ j(not_equal, slow);
     // Load next context in chain.
-    __ mov(temp, ContextOperand(temp, Context::CLOSURE_INDEX));
-    __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset));
+    __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
     __ jmp(&next);
     __ bind(&fast);
   }
@@ -1120,7 +1125,7 @@
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
-  EmitCallIC(ic, mode, AstNode::kNoNumber);
+  __ call(ic, mode);
 }
 
 
@@ -1139,8 +1144,7 @@
                Immediate(0));
         __ j(not_equal, slow);
       }
-      __ mov(temp, ContextOperand(context, Context::CLOSURE_INDEX));
-      __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset));
+      __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering esi.
       context = temp;
     }
@@ -1201,7 +1205,7 @@
           __ SafeSet(eax, Immediate(key_literal->handle()));
           Handle<Code> ic =
               isolate()->builtins()->KeyedLoadIC_Initialize();
-          EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
+          __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
           __ jmp(done);
         }
       }
@@ -1210,24 +1214,27 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
-  // Four cases: non-this global variables, lookup slots, all other
-  // types of slots, and parameters that rewrite to explicit property
-  // accesses on the arguments object.
-  Slot* slot = var->AsSlot();
-  Property* property = var->AsProperty();
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
 
-  if (var->is_global() && !var->is_this()) {
+  // Three cases: non-this global variables, lookup slots, and all other
+  // types of slots.
+  Slot* slot = var->AsSlot();
+  ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
+
+  if (slot == NULL) {
     Comment cmnt(masm_, "Global variable");
     // Use inline caching. Variable name is passed in ecx and the global
     // object on the stack.
     __ mov(eax, GlobalObjectOperand());
     __ mov(ecx, var->name());
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
     context()->Plug(eax);
 
-  } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
+  } else if (slot->type() == Slot::LOOKUP) {
     Label done, slow;
 
     // Generate code for loading from variables potentially shadowed
@@ -1243,7 +1250,7 @@
 
     context()->Plug(eax);
 
-  } else if (slot != NULL) {
+  } else {
     Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
                             ? "Context slot"
                             : "Stack slot");
@@ -1261,36 +1268,6 @@
     } else {
       context()->Plug(slot);
     }
-
-  } else {
-    Comment cmnt(masm_, "Rewritten parameter");
-    ASSERT_NOT_NULL(property);
-    // Rewritten parameter accesses are of the form "slot[literal]".
-
-    // Assert that the object is in a slot.
-    Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
-    ASSERT_NOT_NULL(object_var);
-    Slot* object_slot = object_var->AsSlot();
-    ASSERT_NOT_NULL(object_slot);
-
-    // Load the object.
-    MemOperand object_loc = EmitSlotSearch(object_slot, eax);
-    __ mov(edx, object_loc);
-
-    // Assert that the key is a smi.
-    Literal* key_literal = property->key()->AsLiteral();
-    ASSERT_NOT_NULL(key_literal);
-    ASSERT(key_literal->handle()->IsSmi());
-
-    // Load the key.
-    __ SafeSet(eax, Immediate(key_literal->handle()));
-
-    // Do a keyed property load.
-    Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
-
-    // Drop key and object left on the stack by IC.
-    context()->Plug(eax);
   }
 }
 
@@ -1400,7 +1377,7 @@
             Handle<Code> ic = is_strict_mode()
                 ? isolate()->builtins()->StoreIC_Initialize_Strict()
                 : isolate()->builtins()->StoreIC_Initialize();
-            EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id());
+            __ call(ic, RelocInfo::CODE_TARGET, key->id());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           } else {
             VisitForEffect(value);
@@ -1523,7 +1500,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
@@ -1549,29 +1526,13 @@
       break;
     case KEYED_PROPERTY: {
       if (expr->is_compound()) {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          MemOperand slot_operand =
-              EmitSlotSearch(obj_proxy->var()->AsSlot(), ecx);
-          __ push(slot_operand);
-          __ SafeSet(eax, Immediate(property->key()->AsLiteral()->handle()));
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForAccumulatorValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForAccumulatorValue(property->key());
         __ mov(edx, Operand(esp, 0));
         __ push(eax);
       } else {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          MemOperand slot_operand =
-              EmitSlotSearch(obj_proxy->var()->AsSlot(), ecx);
-          __ push(slot_operand);
-          __ SafePush(Immediate(property->key()->AsLiteral()->handle()));
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForStackValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForStackValue(property->key());
       }
       break;
     }
@@ -1583,7 +1544,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -1649,14 +1610,14 @@
   ASSERT(!key->handle()->IsSmi());
   __ mov(ecx, Immediate(key->handle()));
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
@@ -1677,7 +1638,8 @@
   __ bind(&stub_call);
   __ mov(eax, ecx);
   BinaryOpStub stub(op, mode);
-  EmitCallIC(stub.GetCode(), &patch_site, expr->id());
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   __ jmp(&done, Label::kNear);
 
   // Smi case.
@@ -1760,8 +1722,9 @@
                                      OverwriteMode mode) {
   __ pop(edx);
   BinaryOpStub stub(op, mode);
-  // NULL signals no inlined smi code.
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code.
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   context()->Plug(eax);
 }
 
@@ -1775,7 +1738,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
@@ -1801,7 +1764,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ call(ic);
       break;
     }
     case KEYED_PROPERTY: {
@@ -1810,7 +1773,7 @@
         ASSERT(prop->obj()->AsVariableProxy() != NULL);
         ASSERT(prop->key()->AsLiteral() != NULL);
         { AccumulatorValueContext for_object(this);
-          EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+          EmitVariableLoad(prop->obj()->AsVariableProxy());
         }
         __ mov(edx, eax);
         __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
@@ -1824,7 +1787,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ call(ic);
       break;
     }
   }
@@ -1835,8 +1798,6 @@
 
 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
                                                Token::Value op) {
-  // Left-hand sides that rewrite to explicit property accesses do not reach
-  // here.
   ASSERT(var != NULL);
   ASSERT(var->is_global() || var->AsSlot() != NULL);
 
@@ -1850,7 +1811,7 @@
     Handle<Code> ic = is_strict_mode()
         ? isolate()->builtins()->StoreIC_Initialize_Strict()
         : isolate()->builtins()->StoreIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
 
   } else if (op == Token::INIT_CONST) {
     // Like var declarations, const declarations are hoisted to function
@@ -1870,17 +1831,7 @@
         __ j(not_equal, &skip);
         __ mov(Operand(ebp, SlotOffset(slot)), eax);
         break;
-      case Slot::CONTEXT: {
-        __ mov(ecx, ContextOperand(esi, Context::FCONTEXT_INDEX));
-        __ mov(edx, ContextOperand(ecx, slot->index()));
-        __ cmp(edx, isolate()->factory()->the_hole_value());
-        __ j(not_equal, &skip);
-        __ mov(ContextOperand(ecx, slot->index()), eax);
-        int offset = Context::SlotOffset(slot->index());
-        __ mov(edx, eax);  // Preserve the stored value in eax.
-        __ RecordWrite(ecx, offset, edx, ebx);
-        break;
-      }
+      case Slot::CONTEXT:
       case Slot::LOOKUP:
         __ push(eax);
         __ push(esi);
@@ -1953,7 +1904,7 @@
   Handle<Code> ic = is_strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -1993,7 +1944,7 @@
   Handle<Code> ic = is_strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2044,7 +1995,7 @@
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
-  EmitCallIC(ic, mode, expr->id());
+  __ call(ic, mode, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2077,7 +2028,7 @@
   Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
       arg_count, in_loop);
   __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize));  // Key.
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2116,7 +2067,7 @@
   }
 
   // Push the receiver of the enclosing function.
-  __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
+  __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize));
 
   // Push the strict mode flag.
   __ push(Immediate(Smi::FromInt(strict_mode_flag())));
@@ -2230,9 +2181,9 @@
       __ bind(&done);
       // Push function.
       __ push(eax);
-      // Push global receiver.
-      __ mov(ebx, GlobalObjectOperand());
-      __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ push(Immediate(isolate()->factory()->the_hole_value()));
       __ bind(&call);
     }
 
@@ -2253,7 +2204,7 @@
     } else {
       // Call to a keyed property.
       // For a synthetic property use keyed load IC followed by function call,
-      // for a regular property use keyed EmitCallIC.
+      // for a regular property use EmitKeyedCallWithIC.
       if (prop->is_synthetic()) {
         // Do not visit the object and key subexpressions (they are shared
         // by all occurrences of the same rewritten parameter).
@@ -2271,7 +2222,7 @@
         SetSourcePosition(prop->position());
 
         Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-        EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+        __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
         // Push result (function).
         __ push(eax);
         // Push Global receiver.
@@ -2388,8 +2339,7 @@
   context()->PrepareTest(&materialize_true, &materialize_false,
                          &if_true, &if_false, &fall_through);
 
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, if_false);
+  __ JumpIfSmi(eax, if_false);
   __ cmp(eax, isolate()->factory()->null_value());
   __ j(equal, if_true);
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
@@ -2398,9 +2348,9 @@
   __ test(ecx, Immediate(1 << Map::kIsUndetectable));
   __ j(not_zero, if_false);
   __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset));
-  __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+  __ cmp(ecx, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
   __ j(below, if_false);
-  __ cmp(ecx, LAST_JS_OBJECT_TYPE);
+  __ cmp(ecx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(below_equal, if_true, if_false, fall_through);
 
@@ -2420,9 +2370,8 @@
   context()->PrepareTest(&materialize_true, &materialize_false,
                          &if_true, &if_false, &fall_through);
 
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(equal, if_false);
-  __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ebx);
+  __ JumpIfSmi(eax, if_false);
+  __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ebx);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(above_equal, if_true, if_false, fall_through);
 
@@ -2442,8 +2391,7 @@
   context()->PrepareTest(&materialize_true, &materialize_false,
                          &if_true, &if_false, &fall_through);
 
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, if_false);
+  __ JumpIfSmi(eax, if_false);
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
   __ test(ebx, Immediate(1 << Map::kIsUndetectable));
@@ -2517,8 +2465,7 @@
   // If a valueOf property is not found on the object check that it's
   // prototype is the un-modified String prototype. If not result is false.
   __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(zero, if_false);
+  __ JumpIfSmi(ecx, if_false);
   __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
   __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ mov(edx,
@@ -2550,8 +2497,7 @@
   context()->PrepareTest(&materialize_true, &materialize_false,
                          &if_true, &if_false, &fall_through);
 
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, if_false);
+  __ JumpIfSmi(eax, if_false);
   __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(equal, if_true, if_false, fall_through);
@@ -2572,8 +2518,7 @@
   context()->PrepareTest(&materialize_true, &materialize_false,
                          &if_true, &if_false, &fall_through);
 
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(equal, if_false);
+  __ JumpIfSmi(eax, if_false);
   __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(equal, if_true, if_false, fall_through);
@@ -2594,8 +2539,7 @@
   context()->PrepareTest(&materialize_true, &materialize_false,
                          &if_true, &if_false, &fall_through);
 
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(equal, if_false);
+  __ JumpIfSmi(eax, if_false);
   __ CmpObjectType(eax, JS_REGEXP_TYPE, ebx);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(equal, if_true, if_false, fall_through);
@@ -2666,7 +2610,7 @@
   // parameter count in eax.
   VisitForAccumulatorValue(args->at(0));
   __ mov(edx, eax);
-  __ SafeSet(eax, Immediate(Smi::FromInt(scope()->num_parameters())));
+  __ SafeSet(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
   __ CallStub(&stub);
   context()->Plug(eax);
@@ -2678,7 +2622,7 @@
 
   Label exit;
   // Get the number of formal parameters.
-  __ SafeSet(eax, Immediate(Smi::FromInt(scope()->num_parameters())));
+  __ SafeSet(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
 
   // Check if the calling frame is an arguments adaptor frame.
   __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
@@ -2703,21 +2647,22 @@
   VisitForAccumulatorValue(args->at(0));
 
   // If the object is a smi, we return null.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &null);
+  __ JumpIfSmi(eax, &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.
-  __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, eax);  // Map is now in eax.
+  __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, eax);
+  // Map is now in eax.
   __ j(below, &null);
 
-  // As long as JS_FUNCTION_TYPE is the last instance type and it is
-  // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
-  // LAST_JS_OBJECT_TYPE.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
-  __ CmpInstanceType(eax, JS_FUNCTION_TYPE);
-  __ j(equal, &function);
+  // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
+  // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
+  STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+  STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+                LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
+  __ CmpInstanceType(eax, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
+  __ j(above_equal, &function);
 
   // Check if the constructor in the map is a function.
   __ mov(eax, FieldOperand(eax, Map::kConstructorOffset));
@@ -2760,13 +2705,11 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
   // Finally, we're expected to leave a value on the top of the stack.
   __ mov(eax, isolate()->factory()->undefined_value());
   context()->Plug(eax);
@@ -2855,8 +2798,7 @@
 
   Label done;
   // If the object is a smi return the object.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &done, Label::kNear);
+  __ JumpIfSmi(eax, &done, Label::kNear);
   // If the object is not a value type, return the object.
   __ CmpObjectType(eax, JS_VALUE_TYPE, ebx);
   __ j(not_equal, &done, Label::kNear);
@@ -2892,8 +2834,7 @@
 
   Label done;
   // If the object is a smi, return the value.
-  __ test(ebx, Immediate(kSmiTagMask));
-  __ j(zero, &done, Label::kNear);
+  __ JumpIfSmi(ebx, &done, Label::kNear);
 
   // If the object is not a value type, return the value.
   __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
@@ -3167,8 +3108,7 @@
   __ mov(index_2, Operand(esp, 0));
   __ mov(temp, index_1);
   __ or_(temp, Operand(index_2));
-  __ test(temp, Immediate(kSmiTagMask));
-  __ j(not_zero, &slow_case);
+  __ JumpIfNotSmi(temp, &slow_case);
 
   // Check that both indices are valid.
   __ mov(temp, FieldOperand(object, JSArray::kLengthOffset));
@@ -3273,8 +3213,7 @@
   // Fail if either is a non-HeapObject.
   __ mov(tmp, left);
   __ and_(Operand(tmp), right);
-  __ test(Operand(tmp), Immediate(kSmiTagMask));
-  __ j(zero, &fail);
+  __ JumpIfSmi(tmp, &fail);
   __ mov(tmp, FieldOperand(left, HeapObject::kMapOffset));
   __ CmpInstanceType(tmp, JS_REGEXP_TYPE);
   __ j(not_equal, &fail);
@@ -3366,15 +3305,12 @@
   __ sub(Operand(esp), Immediate(2 * kPointerSize));
   __ cld();
   // Check that the array is a JSArray
-  __ test(array, Immediate(kSmiTagMask));
-  __ j(zero, &bailout);
+  __ JumpIfSmi(array, &bailout);
   __ CmpObjectType(array, JS_ARRAY_TYPE, scratch);
   __ j(not_equal, &bailout);
 
   // Check that the array has fast elements.
-  __ test_b(FieldOperand(scratch, Map::kBitField2Offset),
-            1 << Map::kHasFastElements);
-  __ j(zero, &bailout);
+  __ CheckFastElements(scratch, &bailout);
 
   // If the array has length zero, return the empty string.
   __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset));
@@ -3410,8 +3346,7 @@
                               index,
                               times_pointer_size,
                               FixedArray::kHeaderSize));
-  __ test(string, Immediate(kSmiTagMask));
-  __ j(zero, &bailout);
+  __ JumpIfSmi(string, &bailout);
   __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
   __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
   __ and_(scratch, Immediate(
@@ -3444,8 +3379,7 @@
 
   // Check that the separator is a flat ASCII string.
   __ mov(string, separator_operand);
-  __ test(string, Immediate(kSmiTagMask));
-  __ j(zero, &bailout);
+  __ JumpIfSmi(string, &bailout);
   __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
   __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
   __ and_(scratch, Immediate(
@@ -3602,6 +3536,39 @@
 }
 
 
+void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 1);
+
+  // Load the function into eax.
+  VisitForAccumulatorValue(args->at(0));
+
+  // Prepare for the test.
+  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);
+
+  // Test for strict mode function.
+  __ mov(ecx, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset));
+  __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
+            1 << SharedFunctionInfo::kStrictModeBitWithinByte);
+  __ j(not_equal, if_true);
+
+  // Test for native function.
+  __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
+            1 << SharedFunctionInfo::kNativeBitWithinByte);
+  __ j(not_equal, if_true);
+
+  // Not native or strict-mode function.
+  __ jmp(if_false);
+
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+  context()->Plug(if_true, if_false);
+}
+
+
 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   Handle<String> name = expr->name();
   if (name->length() > 0 && name->Get(0) == '_') {
@@ -3632,7 +3599,7 @@
     RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
     Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
         arg_count, in_loop, mode);
-    EmitCallIC(ic, mode, expr->id());
+    __ call(ic, mode, expr->id());
     // Restore context register.
     __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   } else {
@@ -3737,8 +3704,7 @@
       Comment cmt(masm_, "[ UnaryOperation (ADD)");
       VisitForAccumulatorValue(expr->expression());
       Label no_conversion;
-      __ test(result_register(), Immediate(kSmiTagMask));
-      __ j(zero, &no_conversion);
+      __ JumpIfSmi(result_register(), &no_conversion);
       ToNumberStub convert_stub;
       __ CallStub(&convert_stub);
       __ bind(&no_conversion);
@@ -3772,7 +3738,7 @@
   // accumulator register eax.
   VisitForAccumulatorValue(expr->expression());
   SetSourcePosition(expr->position());
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
   context()->Plug(eax);
 }
 
@@ -3789,7 +3755,7 @@
   }
 
   // Expression can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
@@ -3804,7 +3770,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
@@ -3816,16 +3782,8 @@
       __ push(eax);
       EmitNamedPropertyLoad(prop);
     } else {
-      if (prop->is_arguments_access()) {
-        VariableProxy* obj_proxy = prop->obj()->AsVariableProxy();
-        MemOperand slot_operand =
-            EmitSlotSearch(obj_proxy->var()->AsSlot(), ecx);
-        __ push(slot_operand);
-        __ SafeSet(eax, Immediate(prop->key()->AsLiteral()->handle()));
-      } else {
-        VisitForStackValue(prop->obj());
-        VisitForAccumulatorValue(prop->key());
-      }
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
       __ mov(edx, Operand(esp, 0));
       __ push(eax);
       EmitKeyedPropertyLoad(prop);
@@ -3843,8 +3801,7 @@
   // Call ToNumber only if operand is not a smi.
   Label no_conversion;
   if (ShouldInlineSmiCase(expr->op())) {
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(zero, &no_conversion, Label::kNear);
+    __ JumpIfSmi(eax, &no_conversion, Label::kNear);
   }
   ToNumberStub convert_stub;
   __ CallStub(&convert_stub);
@@ -3901,7 +3858,8 @@
   __ mov(edx, eax);
   __ mov(eax, Immediate(Smi::FromInt(1)));
   BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
-  EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+  patch_site.EmitPatchInfo();
   __ bind(&done);
 
   // Store the value returned in eax.
@@ -3934,7 +3892,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -3951,7 +3909,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         // Result is on the stack
@@ -3979,7 +3937,7 @@
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+    __ call(ic);
     PrepareForBailout(expr, TOS_REG);
     context()->Plug(eax);
   } else if (proxy != NULL &&
@@ -4002,30 +3960,18 @@
     context()->Plug(eax);
   } else {
     // This expression cannot throw a reference error at the top level.
-    context()->HandleExpression(expr);
+    VisitInCurrentContext(expr);
   }
 }
 
 
-bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
-                                          Expression* left,
-                                          Expression* right,
-                                          Label* if_true,
-                                          Label* if_false,
-                                          Label* fall_through) {
-  if (op != Token::EQ && op != Token::EQ_STRICT) return false;
-
-  // Check for the pattern: typeof <expression> == <string literal>.
-  Literal* right_literal = right->AsLiteral();
-  if (right_literal == NULL) return false;
-  Handle<Object> right_literal_value = right_literal->handle();
-  if (!right_literal_value->IsString()) return false;
-  UnaryOperation* left_unary = left->AsUnaryOperation();
-  if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
-  Handle<String> check = Handle<String>::cast(right_literal_value);
-
+void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
+                                                 Handle<String> check,
+                                                 Label* if_true,
+                                                 Label* if_false,
+                                                 Label* fall_through) {
   { AccumulatorValueContext context(this);
-    VisitForTypeofValue(left_unary->expression());
+    VisitForTypeofValue(expr);
   }
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
 
@@ -4058,16 +4004,16 @@
     Split(not_zero, if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->function_symbol())) {
     __ JumpIfSmi(eax, if_false);
-    __ CmpObjectType(eax, FIRST_FUNCTION_CLASS_TYPE, edx);
+    __ CmpObjectType(eax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, edx);
     Split(above_equal, if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->object_symbol())) {
     __ JumpIfSmi(eax, if_false);
     __ cmp(eax, isolate()->factory()->null_value());
     __ j(equal, if_true);
-    __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edx);
+    __ CmpObjectType(eax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, edx);
     __ j(below, if_false);
-    __ CmpInstanceType(edx, FIRST_FUNCTION_CLASS_TYPE);
-    __ j(above_equal, if_false);
+    __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ j(above, if_false);
     // Check for undetectable objects => false.
     __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
               1 << Map::kIsUndetectable);
@@ -4075,8 +4021,18 @@
   } else {
     if (if_false != fall_through) __ jmp(if_false);
   }
+}
 
-  return true;
+
+void FullCodeGenerator::EmitLiteralCompareUndefined(Expression* expr,
+                                                    Label* if_true,
+                                                    Label* if_false,
+                                                    Label* fall_through) {
+  VisitForAccumulatorValue(expr);
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+
+  __ cmp(eax, isolate()->factory()->undefined_value());
+  Split(equal, if_true, if_false, fall_through);
 }
 
 
@@ -4096,14 +4052,12 @@
 
   // First we try a fast inlined version of the compare when one of
   // the operands is a literal.
-  Token::Value op = expr->op();
-  Expression* left = expr->left();
-  Expression* right = expr->right();
-  if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) {
+  if (TryLiteralCompare(expr, if_true, if_false, fall_through)) {
     context()->Plug(if_true, if_false);
     return;
   }
 
+  Token::Value op = expr->op();
   VisitForStackValue(expr->left());
   switch (expr->op()) {
     case Token::IN:
@@ -4128,11 +4082,8 @@
     default: {
       VisitForAccumulatorValue(expr->right());
       Condition cc = no_condition;
-      bool strict = false;
       switch (op) {
         case Token::EQ_STRICT:
-          strict = true;
-          // Fall through
         case Token::EQ:
           cc = equal;
           __ pop(edx);
@@ -4178,7 +4129,8 @@
       // Record position and call the compare IC.
       SetSourcePosition(expr->position());
       Handle<Code> ic = CompareIC::GetUninitialized(op);
-      EmitCallIC(ic, &patch_site, expr->id());
+      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+      patch_site.EmitPatchInfo();
 
       PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
       __ test(eax, Operand(eax));
@@ -4210,8 +4162,7 @@
     __ j(equal, if_true);
     __ cmp(eax, isolate()->factory()->undefined_value());
     __ j(equal, if_true);
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(zero, if_false);
+    __ JumpIfSmi(eax, if_false);
     // It can be an undetectable object.
     __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
     __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset));
@@ -4238,58 +4189,6 @@
 }
 
 
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   RelocInfo::Mode mode,
-                                   unsigned ast_id) {
-  ASSERT(mode == RelocInfo::CODE_TARGET ||
-         mode == RelocInfo::CODE_TARGET_CONTEXT);
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(isolate()->counters()->named_load_full(), 1);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(isolate()->counters()->keyed_load_full(), 1);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(isolate()->counters()->named_store_full(), 1);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(isolate()->counters()->keyed_store_full(), 1);
-    default:
-      break;
-  }
-  __ call(ic, mode, ast_id);
-}
-
-
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   JumpPatchSite* patch_site,
-                                   unsigned ast_id) {
-  Counters* counters = isolate()->counters();
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(counters->named_load_full(), 1);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(counters->keyed_load_full(), 1);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(counters->named_store_full(), 1);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(counters->keyed_store_full(), 1);
-    default:
-      break;
-  }
-  __ call(ic, RelocInfo::CODE_TARGET, ast_id);
-  if (patch_site != NULL && patch_site->is_bound()) {
-    patch_site->EmitPatchInfo();
-  } else {
-    __ nop();  // Signals no inlined code.
-  }
-}
-
-
 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
   ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
   __ mov(Operand(ebp, frame_offset), value);
@@ -4301,18 +4200,38 @@
 }
 
 
+void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
+  Scope* declaration_scope = scope()->DeclarationScope();
+  if (declaration_scope->is_global_scope()) {
+    // Contexts nested in the global context have a canonical empty function
+    // as their closure, not the anonymous closure containing the global
+    // code.  Pass a smi sentinel and let the runtime look up the empty
+    // function.
+    __ push(Immediate(Smi::FromInt(0)));
+  } else if (declaration_scope->is_eval_scope()) {
+    // Contexts nested inside eval code have the same closure as the context
+    // calling eval, not the anonymous closure containing the eval code.
+    // Fetch it from the context.
+    __ push(ContextOperand(esi, Context::CLOSURE_INDEX));
+  } else {
+    ASSERT(declaration_scope->is_function_scope());
+    __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+  }
+}
+
+
 // ----------------------------------------------------------------------------
 // Non-local control flow support.
 
 void FullCodeGenerator::EnterFinallyBlock() {
   // Cook return address on top of stack (smi encoded Code* delta)
   ASSERT(!result_register().is(edx));
-  __ mov(edx, Operand(esp, 0));
+  __ pop(edx);
   __ sub(Operand(edx), Immediate(masm_->CodeObject()));
   ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
   ASSERT_EQ(0, kSmiTag);
-  __ add(edx, Operand(edx));  // Convert to smi.
-  __ mov(Operand(esp, 0), edx);
+  __ SmiTag(edx);
+  __ push(edx);
   // Store result register while executing finally block.
   __ push(result_register());
 }
@@ -4320,15 +4239,12 @@
 
 void FullCodeGenerator::ExitFinallyBlock() {
   ASSERT(!result_register().is(edx));
-  // Restore result register from stack.
   __ pop(result_register());
   // Uncook return address.
-  __ mov(edx, Operand(esp, 0));
-  __ sar(edx, 1);  // Convert smi to int.
+  __ pop(edx);
+  __ SmiUntag(edx);
   __ add(Operand(edx), Immediate(masm_->CodeObject()));
-  __ mov(Operand(esp, 0), edx);
-  // And return.
-  __ ret(0);
+  __ jmp(Operand(edx));
 }
 
 
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 3941cfc..5f143b1 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -72,17 +72,16 @@
   //   r1: used to hold receivers map.
 
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check that the receiver is a valid JS object.
   __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset));
   __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset));
-  __ cmp(r0, FIRST_JS_OBJECT_TYPE);
+  __ cmp(r0, FIRST_SPEC_OBJECT_TYPE);
   __ j(below, miss);
 
   // If this assert fails, we have to check upper bound too.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
 
   GenerateGlobalInstanceTypeCheck(masm, r0, miss);
 
@@ -217,105 +216,6 @@
 }
 
 
-static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
-                                         Label* miss,
-                                         Register elements,
-                                         Register key,
-                                         Register r0,
-                                         Register r1,
-                                         Register r2,
-                                         Register result) {
-  // Register use:
-  //
-  // elements - holds the slow-case elements of the receiver and is unchanged.
-  //
-  // key      - holds the smi key on entry and is unchanged.
-  //
-  // Scratch registers:
-  //
-  // r0 - holds the untagged key on entry and holds the hash once computed.
-  //
-  // r1 - used to hold the capacity mask of the dictionary
-  //
-  // r2 - used for the index into the dictionary.
-  //
-  // result - holds the result on exit if the load succeeds and we fall through.
-
-  Label done;
-
-  // Compute the hash code from the untagged key.  This must be kept in sync
-  // with ComputeIntegerHash in utils.h.
-  //
-  // hash = ~hash + (hash << 15);
-  __ mov(r1, r0);
-  __ not_(r0);
-  __ shl(r1, 15);
-  __ add(r0, Operand(r1));
-  // hash = hash ^ (hash >> 12);
-  __ mov(r1, r0);
-  __ shr(r1, 12);
-  __ xor_(r0, Operand(r1));
-  // hash = hash + (hash << 2);
-  __ lea(r0, Operand(r0, r0, times_4, 0));
-  // hash = hash ^ (hash >> 4);
-  __ mov(r1, r0);
-  __ shr(r1, 4);
-  __ xor_(r0, Operand(r1));
-  // hash = hash * 2057;
-  __ imul(r0, r0, 2057);
-  // hash = hash ^ (hash >> 16);
-  __ mov(r1, r0);
-  __ shr(r1, 16);
-  __ xor_(r0, Operand(r1));
-
-  // Compute capacity mask.
-  __ mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset));
-  __ shr(r1, kSmiTagSize);  // convert smi to int
-  __ dec(r1);
-
-  // Generate an unrolled loop that performs a few probes before giving up.
-  const int kProbes = 4;
-  for (int i = 0; i < kProbes; i++) {
-    // Use r2 for index calculations and keep the hash intact in r0.
-    __ mov(r2, r0);
-    // Compute the masked index: (hash + i + i * i) & mask.
-    if (i > 0) {
-      __ add(Operand(r2), Immediate(NumberDictionary::GetProbeOffset(i)));
-    }
-    __ and_(r2, Operand(r1));
-
-    // Scale the index by multiplying by the entry size.
-    ASSERT(NumberDictionary::kEntrySize == 3);
-    __ lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3
-
-    // Check if the key matches.
-    __ cmp(key, FieldOperand(elements,
-                             r2,
-                             times_pointer_size,
-                             NumberDictionary::kElementsStartOffset));
-    if (i != (kProbes - 1)) {
-      __ j(equal, &done);
-    } else {
-      __ j(not_equal, miss);
-    }
-  }
-
-  __ bind(&done);
-  // Check that the value is a normal propety.
-  const int kDetailsOffset =
-      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
-  ASSERT_EQ(NORMAL, 0);
-  __ test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
-          Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize));
-  __ j(not_zero, miss);
-
-  // Get the value at the masked, scaled index.
-  const int kValueOffset =
-      NumberDictionary::kElementsStartOffset + kPointerSize;
-  __ mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
-}
-
-
 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : receiver
@@ -373,8 +273,7 @@
   //   map - used to hold the map of the receiver.
 
   // Check that the object isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, slow);
+  __ JumpIfSmi(receiver, slow);
 
   // Get the map of the receiver.
   __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset));
@@ -465,6 +364,83 @@
 }
 
 
+static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
+                                             Register object,
+                                             Register key,
+                                             Register scratch1,
+                                             Register scratch2,
+                                             Label* unmapped_case,
+                                             Label* slow_case) {
+  Heap* heap = masm->isolate()->heap();
+  Factory* factory = masm->isolate()->factory();
+
+  // Check that the receiver is a JSObject. Because of the elements
+  // 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.
+  __ CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, scratch1);
+  __ j(below, slow_case);
+
+  // Check that the key is a positive smi.
+  __ test(key, Immediate(0x8000001));
+  __ j(not_zero, slow_case);
+
+  // Load the elements into scratch1 and check its map.
+  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  __ mov(scratch1, FieldOperand(object, JSObject::kElementsOffset));
+  __ CheckMap(scratch1, 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.
+  __ mov(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset));
+  __ sub(Operand(scratch2), Immediate(Smi::FromInt(2)));
+  __ cmp(key, Operand(scratch2));
+  __ j(greater_equal, unmapped_case);
+
+  // Load element index and check whether it is the hole.
+  const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize;
+  __ mov(scratch2, FieldOperand(scratch1,
+                                key,
+                                times_half_pointer_size,
+                                kHeaderSize));
+  __ cmp(scratch2, factory->the_hole_value());
+  __ j(equal, 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).
+  const int kContextOffset = FixedArray::kHeaderSize;
+  __ mov(scratch1, FieldOperand(scratch1, kContextOffset));
+  return FieldOperand(scratch1,
+                      scratch2,
+                      times_half_pointer_size,
+                      Context::kHeaderSize);
+}
+
+
+static Operand 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.
+  const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize;
+  Register backing_store = parameter_map;
+  __ mov(backing_store, FieldOperand(parameter_map, kBackingStoreOffset));
+  Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map());
+  __ CheckMap(backing_store, fixed_array_map, slow_case, DONT_DO_SMI_CHECK);
+  __ mov(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset));
+  __ cmp(key, Operand(scratch));
+  __ j(greater_equal, slow_case);
+  return FieldOperand(backing_store,
+                      key,
+                      times_half_pointer_size,
+                      FixedArray::kHeaderSize);
+}
+
+
 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : key
@@ -475,8 +451,7 @@
   Label probe_dictionary, check_number_dictionary;
 
   // Check that the key is a smi.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &check_string);
+  __ JumpIfNotSmi(eax, &check_string);
   __ bind(&index_smi);
   // Now the key is known to be a smi. This place is also jumped to from
   // where a numeric string is converted to a smi.
@@ -484,11 +459,8 @@
   GenerateKeyedLoadReceiverCheck(
       masm, edx, ecx, Map::kHasIndexedInterceptor, &slow);
 
-  // Check the "has fast elements" bit in the receiver's map which is
-  // now in ecx.
-  __ test_b(FieldOperand(ecx, Map::kBitField2Offset),
-            1 << Map::kHasFastElements);
-  __ j(zero, &check_number_dictionary);
+  // Check the receiver's map to see if it has fast elements.
+  __ CheckFastElements(ecx, &check_number_dictionary);
 
   GenerateFastArrayLoad(masm,
                         edx,
@@ -520,14 +492,13 @@
   // Push receiver on the stack to free up a register for the dictionary
   // probing.
   __ push(edx);
-  GenerateNumberDictionaryLoad(masm,
-                               &slow_pop_receiver,
-                               ecx,
-                               eax,
-                               ebx,
-                               edx,
-                               edi,
-                               eax);
+  __ LoadFromNumberDictionary(&slow_pop_receiver,
+                              ecx,
+                              eax,
+                              ebx,
+                              edx,
+                              edi,
+                              eax);
   // Pop receiver before returning.
   __ pop(edx);
   __ ret(0);
@@ -668,8 +639,7 @@
   Label slow;
 
   // Check that the receiver isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &slow);
+  __ JumpIfSmi(edx, &slow);
 
   // Check that the key is an array index, that is Uint32.
   __ test(eax, Immediate(kSmiTagMask | kSmiSignMask));
@@ -702,6 +672,60 @@
 }
 
 
+void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label slow, notin;
+  Factory* factory = masm->isolate()->factory();
+  Operand mapped_location =
+      GenerateMappedArgumentsLookup(masm, edx, eax, ebx, ecx, &notin, &slow);
+  __ mov(eax, mapped_location);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in ebx.
+  Operand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, eax, ebx, ecx, &slow);
+  __ cmp(unmapped_location, factory->the_hole_value());
+  __ j(equal, &slow);
+  __ mov(eax, unmapped_location);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
+void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax    : value
+  //  -- ecx    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label slow, notin;
+  Operand mapped_location =
+      GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, edi, &notin, &slow);
+  __ mov(mapped_location, eax);
+  __ lea(ecx, mapped_location);
+  __ mov(edx, eax);
+  __ RecordWrite(ebx, ecx, edx);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in ebx.
+  Operand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, ecx, ebx, edi, &slow);
+  __ mov(unmapped_location, eax);
+  __ lea(edi, unmapped_location);
+  __ mov(edx, eax);
+  __ RecordWrite(ebx, edi, edx);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
                                    StrictModeFlag strict_mode) {
   // ----------- S t a t e -------------
@@ -713,8 +737,7 @@
   Label slow, fast, array, extra;
 
   // Check that the object isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &slow);
+  __ JumpIfSmi(edx, &slow);
   // Get the map from the receiver.
   __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
   // Check that the receiver does not require access checks.  We need
@@ -723,13 +746,16 @@
             1 << Map::kIsAccessCheckNeeded);
   __ j(not_zero, &slow);
   // Check that the key is a smi.
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(not_zero, &slow);
+  __ JumpIfNotSmi(ecx, &slow);
   __ CmpInstanceType(edi, JS_ARRAY_TYPE);
   __ j(equal, &array);
-  // Check that the object is some kind of JS object.
-  __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
+  // Check that the object is some kind of JSObject.
+  __ CmpInstanceType(edi, FIRST_JS_RECEIVER_TYPE);
   __ j(below, &slow);
+  __ CmpInstanceType(edi, JS_PROXY_TYPE);
+  __ j(equal, &slow);
+  __ CmpInstanceType(edi, JS_FUNCTION_PROXY_TYPE);
+  __ j(equal, &slow);
 
   // Object case: Check key against length in the elements array.
   // eax: value
@@ -820,8 +846,7 @@
   // to probe.
   //
   // Check for number.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &number);
+  __ JumpIfSmi(edx, &number);
   __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ebx);
   __ j(not_equal, &non_number);
   __ bind(&number);
@@ -868,8 +893,7 @@
   // -----------------------------------
 
   // Check that the result is not a smi.
-  __ test(edi, Immediate(kSmiTagMask));
-  __ j(zero, miss);
+  __ JumpIfSmi(edi, miss);
 
   // Check that the value is a JavaScript function, fetching its map into eax.
   __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax);
@@ -950,8 +974,7 @@
   if (id == IC::kCallIC_Miss) {
     Label invoke, global;
     __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));  // receiver
-    __ test(edx, Immediate(kSmiTagMask));
-    __ j(zero, &invoke, Label::kNear);
+    __ JumpIfSmi(edx, &invoke, Label::kNear);
     __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
     __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
     __ cmp(ebx, JS_GLOBAL_OBJECT_TYPE);
@@ -1044,8 +1067,7 @@
   Label index_smi, index_string;
 
   // Check that the key is a smi.
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(not_zero, &check_string);
+  __ JumpIfNotSmi(ecx, &check_string);
 
   __ bind(&index_smi);
   // Now the key is known to be a smi. This place is also jumped to from
@@ -1078,8 +1100,8 @@
   __ SmiUntag(ebx);
   // ebx: untagged index
   // Receiver in edx will be clobbered, need to reload it on miss.
-  GenerateNumberDictionaryLoad(
-      masm, &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi);
+  __ LoadFromNumberDictionary(
+      &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi);
   __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
   __ jmp(&do_call);
 
@@ -1145,6 +1167,35 @@
 }
 
 
+void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
+                                             int argc) {
+  // ----------- S t a t e -------------
+  //  -- ecx                 : name
+  //  -- esp[0]              : return address
+  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
+  //  -- ...
+  //  -- esp[(argc + 1) * 4] : receiver
+  // -----------------------------------
+  Label slow, notin;
+  Factory* factory = masm->isolate()->factory();
+  __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
+  Operand mapped_location =
+      GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, &notin, &slow);
+  __ mov(edi, mapped_location);
+  GenerateFunctionTailCall(masm, argc, &slow);
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in ebx.
+  Operand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow);
+  __ cmp(unmapped_location, factory->the_hole_value());
+  __ j(equal, &slow);
+  __ mov(edi, unmapped_location);
+  GenerateFunctionTailCall(masm, argc, &slow);
+  __ bind(&slow);
+  GenerateMiss(masm, argc);
+}
+
+
 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
   //  -- ecx                 : name
@@ -1156,8 +1207,7 @@
 
   // Check if the name is a string.
   Label miss;
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(ecx, &miss);
   Condition cond = masm->IsObjectStringType(ecx, eax, eax);
   __ j(NegateCondition(cond), &miss);
   GenerateCallNormal(masm, argc);
@@ -1342,8 +1392,7 @@
   Register scratch = ebx;
 
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(receiver, &miss);
 
   // Check that the object is a JS array.
   __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
@@ -1357,8 +1406,7 @@
   __ j(not_equal, &miss);
 
   // Check that value is a smi.
-  __ test(value, Immediate(kSmiTagMask));
-  __ j(not_zero, &miss);
+  __ JumpIfNotSmi(value, &miss);
 
   // Prepare tail call to StoreIC_ArrayLength.
   __ pop(scratch);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 3e95867..982eddb 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -128,11 +128,11 @@
   }
 #endif
 
-  // Strict mode functions need to replace the receiver with undefined
-  // when called as functions (without an explicit receiver
-  // object). ecx is zero for method calls and non-zero for function
-  // calls.
-  if (info_->is_strict_mode()) {
+  // Strict mode functions and builtins need to replace the receiver
+  // with undefined when called as functions (without an explicit
+  // receiver object). ecx is zero for method calls and non-zero for
+  // function calls.
+  if (info_->is_strict_mode() || info_->is_native()) {
     Label ok;
     __ test(ecx, Operand(ecx));
     __ j(zero, &ok, Label::kNear);
@@ -184,7 +184,7 @@
       FastNewContextStub stub(heap_slots);
       __ CallStub(&stub);
     } else {
-      __ CallRuntime(Runtime::kNewContext, 1);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
     }
     RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
     // Context is returned in both eax and esi.  It replaces the context
@@ -255,11 +255,20 @@
 
 bool LCodeGen::GenerateDeferredCode() {
   ASSERT(is_generating());
-  for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
-    LDeferredCode* code = deferred_[i];
-    __ bind(code->entry());
-    code->Generate();
-    __ jmp(code->exit());
+  if (deferred_.length() > 0) {
+    for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
+      LDeferredCode* code = deferred_[i];
+      __ bind(code->entry());
+      code->Generate();
+      __ jmp(code->exit());
+    }
+
+    // Pad code to ensure that the last piece of deferred code have
+    // room for lazy bailout.
+    while ((masm()->pc_offset() - LastSafepointEnd())
+           < Deoptimizer::patch_size()) {
+      __ nop();
+    }
   }
 
   // Deferred code is the last part of the instruction sequence. Mark
@@ -428,15 +437,11 @@
 void LCodeGen::CallCodeGeneric(Handle<Code> code,
                                RelocInfo::Mode mode,
                                LInstruction* instr,
-                               ContextMode context_mode,
                                SafepointMode safepoint_mode) {
   ASSERT(instr != NULL);
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
 
-  if (context_mode == RESTORE_CONTEXT) {
-    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-  }
   __ call(code, mode);
 
   RegisterLazyDeoptimization(instr, safepoint_mode);
@@ -452,24 +457,19 @@
 
 void LCodeGen::CallCode(Handle<Code> code,
                         RelocInfo::Mode mode,
-                        LInstruction* instr,
-                        ContextMode context_mode) {
-  CallCodeGeneric(code, mode, instr, context_mode, RECORD_SIMPLE_SAFEPOINT);
+                        LInstruction* instr) {
+  CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
 }
 
 
 void LCodeGen::CallRuntime(const Runtime::Function* fun,
                            int argc,
-                           LInstruction* instr,
-                           ContextMode context_mode) {
+                           LInstruction* instr) {
   ASSERT(instr != NULL);
   ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
 
-  if (context_mode == RESTORE_CONTEXT) {
-    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-  }
   __ CallRuntime(fun, argc);
 
   RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
@@ -478,8 +478,18 @@
 
 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
                                        int argc,
-                                       LInstruction* instr) {
-  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+                                       LInstruction* instr,
+                                       LOperand* context) {
+  ASSERT(context->IsRegister() || context->IsStackSlot());
+  if (context->IsRegister()) {
+    if (!ToRegister(context).is(esi)) {
+      __ mov(esi, ToRegister(context));
+    }
+  } else {
+    // Context is stack slot.
+    __ mov(esi, ToOperand(context));
+  }
+
   __ CallRuntimeSaveDoubles(id);
   RecordSafepointWithRegisters(
       instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex);
@@ -693,7 +703,7 @@
 
 
 void LCodeGen::RecordPosition(int position) {
-  if (!FLAG_debug_info || position == RelocInfo::kNoPosition) return;
+  if (position == RelocInfo::kNoPosition) return;
   masm()->positions_recorder()->RecordPosition(position);
 }
 
@@ -748,38 +758,38 @@
   switch (instr->hydrogen()->major_key()) {
     case CodeStub::RegExpConstructResult: {
       RegExpConstructResultStub stub;
-      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
     case CodeStub::RegExpExec: {
       RegExpExecStub stub;
-      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
     case CodeStub::SubString: {
       SubStringStub stub;
-      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
     case CodeStub::NumberToString: {
       NumberToStringStub stub;
-      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
     case CodeStub::StringAdd: {
       StringAddStub stub(NO_STRING_ADD_FLAGS);
-      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
     case CodeStub::StringCompare: {
       StringCompareStub stub;
-      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
     case CodeStub::TranscendentalCache: {
       TranscendentalCacheStub stub(instr->transcendental_type(),
                                    TranscendentalCacheStub::TAGGED);
-      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
     default:
@@ -1215,6 +1225,21 @@
 }
 
 
+void LCodeGen::DoElementsKind(LElementsKind* instr) {
+  Register result = ToRegister(instr->result());
+  Register input = ToRegister(instr->InputAt(0));
+
+  // Load map into |result|.
+  __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
+  // Load the map's "bit field 2" into |result|. We only need the first byte,
+  // but the following masking takes care of that anyway.
+  __ mov(result, FieldOperand(result, Map::kBitField2Offset));
+  // Retrieve elements_kind from bit field 2.
+  __ and_(result, Map::kElementsKindMask);
+  __ shr(result, Map::kElementsKindShift);
+}
+
+
 void LCodeGen::DoValueOf(LValueOf* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register result = ToRegister(instr->result());
@@ -1222,8 +1247,7 @@
   ASSERT(input.is(result));
   Label done;
   // If the object is a smi return the object.
-  __ test(input, Immediate(kSmiTagMask));
-  __ j(zero, &done, Label::kNear);
+  __ JumpIfSmi(input, &done, Label::kNear);
 
   // If the object is not a value type, return the object.
   __ CmpObjectType(input, JS_VALUE_TYPE, map);
@@ -1242,8 +1266,9 @@
 
 
 void LCodeGen::DoThrow(LThrow* instr) {
-  __ push(ToOperand(instr->InputAt(0)));
-  CallRuntime(Runtime::kThrow, 1, instr, RESTORE_CONTEXT);
+  __ push(ToOperand(instr->value()));
+  ASSERT(ToRegister(instr->context()).is(esi));
+  CallRuntime(Runtime::kThrow, 1, instr);
 
   if (FLAG_debug_code) {
     Comment("Unreachable code.");
@@ -1313,12 +1338,13 @@
 
 
 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
-  ASSERT(ToRegister(instr->InputAt(0)).is(edx));
-  ASSERT(ToRegister(instr->InputAt(1)).is(eax));
+  ASSERT(ToRegister(instr->context()).is(esi));
+  ASSERT(ToRegister(instr->left()).is(edx));
+  ASSERT(ToRegister(instr->right()).is(eax));
   ASSERT(ToRegister(instr->result()).is(eax));
 
   BinaryOpStub stub(instr->op(), NO_OVERWRITE);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   __ nop();  // Signals no inlined code.
 }
 
@@ -1354,7 +1380,7 @@
   int true_block = chunk_->LookupDestination(instr->true_block_id());
   int false_block = chunk_->LookupDestination(instr->false_block_id());
 
-  Representation r = instr->hydrogen()->representation();
+  Representation r = instr->hydrogen()->value()->representation();
   if (r.IsInteger32()) {
     Register reg = ToRegister(instr->InputAt(0));
     __ test(reg, Operand(reg));
@@ -1367,7 +1393,7 @@
   } else {
     ASSERT(r.IsTagged());
     Register reg = ToRegister(instr->InputAt(0));
-    if (instr->hydrogen()->type().IsBoolean()) {
+    if (instr->hydrogen()->value()->type().IsBoolean()) {
       __ cmp(reg, factory()->true_value());
       EmitBranch(true_block, false_block, equal);
     } else {
@@ -1382,8 +1408,7 @@
       __ j(equal, false_label);
       __ test(reg, Operand(reg));
       __ j(equal, false_label);
-      __ test(reg, Immediate(kSmiTagMask));
-      __ j(zero, true_label);
+      __ JumpIfSmi(reg, true_label);
 
       // Test for double values. Zero is false.
       Label call_stub;
@@ -1399,7 +1424,7 @@
       // The conversion stub doesn't cause garbage collections so it's
       // safe to not record a safepoint after the call.
       __ bind(&call_stub);
-      ToBooleanStub stub;
+      ToBooleanStub stub(eax);
       __ pushad();
       __ push(reg);
       __ CallStub(&stub);
@@ -1411,45 +1436,17 @@
 }
 
 
-void LCodeGen::EmitGoto(int block, LDeferredCode* deferred_stack_check) {
+void LCodeGen::EmitGoto(int block) {
   block = chunk_->LookupDestination(block);
   int next_block = GetNextEmittedBlock(current_block_);
   if (block != next_block) {
-    // Perform stack overflow check if this goto needs it before jumping.
-    if (deferred_stack_check != NULL) {
-      ExternalReference stack_limit =
-          ExternalReference::address_of_stack_limit(isolate());
-      __ cmp(esp, Operand::StaticVariable(stack_limit));
-      __ j(above_equal, chunk_->GetAssemblyLabel(block));
-      __ jmp(deferred_stack_check->entry());
-      deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block));
-    } else {
-      __ jmp(chunk_->GetAssemblyLabel(block));
-    }
+    __ jmp(chunk_->GetAssemblyLabel(block));
   }
 }
 
 
-void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
-  PushSafepointRegistersScope scope(this);
-  CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr);
-}
-
 void LCodeGen::DoGoto(LGoto* instr) {
-  class DeferredStackCheck: public LDeferredCode {
-   public:
-    DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
-   private:
-    LGoto* instr_;
-  };
-
-  DeferredStackCheck* deferred = NULL;
-  if (instr->include_stack_check()) {
-    deferred = new DeferredStackCheck(this, instr);
-  }
-  EmitGoto(instr->block_id(), deferred);
+  EmitGoto(instr->block_id());
 }
 
 
@@ -1490,32 +1487,6 @@
 }
 
 
-void LCodeGen::DoCmpID(LCmpID* instr) {
-  LOperand* left = instr->InputAt(0);
-  LOperand* right = instr->InputAt(1);
-  LOperand* result = instr->result();
-
-  Label unordered;
-  if (instr->is_double()) {
-    // Don't base result on EFLAGS when a NaN is involved. Instead
-    // jump to the unordered case, which produces a false value.
-    __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
-    __ j(parity_even, &unordered, Label::kNear);
-  } else {
-    EmitCmpI(left, right);
-  }
-
-  Label done;
-  Condition cc = TokenToCondition(instr->op(), instr->is_double());
-  __ mov(ToRegister(result), factory()->true_value());
-  __ j(cc, &done, Label::kNear);
-
-  __ bind(&unordered);
-  __ mov(ToRegister(result), factory()->false_value());
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
@@ -1536,23 +1507,9 @@
 }
 
 
-void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
+void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
   Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  Register result = ToRegister(instr->result());
-
-  __ cmp(left, Operand(right));
-  __ mov(result, factory()->true_value());
-  Label done;
-  __ j(equal, &done, Label::kNear);
-  __ mov(result, factory()->false_value());
-  __ bind(&done);
-}
-
-
-void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
-  Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
+  Operand right = ToOperand(instr->InputAt(1));
   int false_block = chunk_->LookupDestination(instr->false_block_id());
   int true_block = chunk_->LookupDestination(instr->true_block_id());
 
@@ -1561,69 +1518,16 @@
 }
 
 
-void LCodeGen::DoCmpSymbolEq(LCmpSymbolEq* instr) {
+void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
   Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  Register result = ToRegister(instr->result());
-
-  Label done;
-  __ cmp(left, Operand(right));
-  __ mov(result, factory()->false_value());
-  __ j(not_equal, &done, Label::kNear);
-  __ mov(result, factory()->true_value());
-  __ bind(&done);
-}
-
-
-void LCodeGen::DoCmpSymbolEqAndBranch(LCmpSymbolEqAndBranch* instr) {
-  Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
   int true_block = chunk_->LookupDestination(instr->true_block_id());
+  int false_block = chunk_->LookupDestination(instr->false_block_id());
 
-  __ cmp(left, Operand(right));
+  __ cmp(left, instr->hydrogen()->right());
   EmitBranch(true_block, false_block, equal);
 }
 
 
-void LCodeGen::DoIsNull(LIsNull* instr) {
-  Register reg = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  // TODO(fsc): If the expression is known to be a smi, then it's
-  // definitely not null. Materialize false.
-
-  __ cmp(reg, factory()->null_value());
-  if (instr->is_strict()) {
-    __ mov(result, factory()->true_value());
-    Label done;
-    __ j(equal, &done, Label::kNear);
-    __ mov(result, factory()->false_value());
-    __ bind(&done);
-  } else {
-    Label true_value, false_value, done;
-    __ j(equal, &true_value, Label::kNear);
-    __ cmp(reg, factory()->undefined_value());
-    __ j(equal, &true_value, Label::kNear);
-    __ test(reg, Immediate(kSmiTagMask));
-    __ j(zero, &false_value, Label::kNear);
-    // Check for undetectable objects by looking in the bit field in
-    // the map. The object has already been smi checked.
-    Register scratch = result;
-    __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
-    __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
-    __ test(scratch, Immediate(1 << Map::kIsUndetectable));
-    __ j(not_zero, &true_value, Label::kNear);
-    __ bind(&false_value);
-    __ mov(result, factory()->false_value());
-    __ jmp(&done, Label::kNear);
-    __ bind(&true_value);
-    __ mov(result, factory()->true_value());
-    __ bind(&done);
-  }
-}
-
-
 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
   Register reg = ToRegister(instr->InputAt(0));
 
@@ -1642,8 +1546,7 @@
     __ j(equal, true_label);
     __ cmp(reg, factory()->undefined_value());
     __ j(equal, true_label);
-    __ test(reg, Immediate(kSmiTagMask));
-    __ j(zero, false_label);
+    __ JumpIfSmi(reg, false_label);
     // Check for undetectable objects by looking in the bit field in
     // the map. The object has already been smi checked.
     Register scratch = ToRegister(instr->TempAt(0));
@@ -1657,83 +1560,42 @@
 
 Condition LCodeGen::EmitIsObject(Register input,
                                  Register temp1,
-                                 Register temp2,
                                  Label* is_not_object,
                                  Label* is_object) {
-  ASSERT(!input.is(temp1));
-  ASSERT(!input.is(temp2));
-  ASSERT(!temp1.is(temp2));
-
-  __ test(input, Immediate(kSmiTagMask));
-  __ j(equal, is_not_object);
+  __ JumpIfSmi(input, is_not_object);
 
   __ cmp(input, isolate()->factory()->null_value());
   __ j(equal, is_object);
 
   __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset));
   // Undetectable objects behave like undefined.
-  __ movzx_b(temp2, FieldOperand(temp1, Map::kBitFieldOffset));
-  __ test(temp2, Immediate(1 << Map::kIsUndetectable));
+  __ test_b(FieldOperand(temp1, Map::kBitFieldOffset),
+            1 << Map::kIsUndetectable);
   __ j(not_zero, is_not_object);
 
-  __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset));
-  __ cmp(temp2, FIRST_JS_OBJECT_TYPE);
+  __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset));
+  __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
   __ j(below, is_not_object);
-  __ cmp(temp2, LAST_JS_OBJECT_TYPE);
+  __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
   return below_equal;
 }
 
 
-void LCodeGen::DoIsObject(LIsObject* instr) {
-  Register reg = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  Register temp = ToRegister(instr->TempAt(0));
-  Label is_false, is_true, done;
-
-  Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
-  __ j(true_cond, &is_true);
-
-  __ bind(&is_false);
-  __ mov(result, factory()->false_value());
-  __ jmp(&done);
-
-  __ bind(&is_true);
-  __ mov(result, factory()->true_value());
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
   Register reg = ToRegister(instr->InputAt(0));
   Register temp = ToRegister(instr->TempAt(0));
-  Register temp2 = ToRegister(instr->TempAt(1));
 
   int true_block = chunk_->LookupDestination(instr->true_block_id());
   int false_block = chunk_->LookupDestination(instr->false_block_id());
   Label* true_label = chunk_->GetAssemblyLabel(true_block);
   Label* false_label = chunk_->GetAssemblyLabel(false_block);
 
-  Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label);
+  Condition true_cond = EmitIsObject(reg, temp, false_label, true_label);
 
   EmitBranch(true_block, false_block, true_cond);
 }
 
 
-void LCodeGen::DoIsSmi(LIsSmi* instr) {
-  Operand input = ToOperand(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  __ test(input, Immediate(kSmiTagMask));
-  __ mov(result, factory()->true_value());
-  Label done;
-  __ j(zero, &done, Label::kNear);
-  __ mov(result, factory()->false_value());
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
   Operand input = ToOperand(instr->InputAt(0));
 
@@ -1745,27 +1607,6 @@
 }
 
 
-void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  Label false_label, done;
-  STATIC_ASSERT(kSmiTag == 0);
-  __ test(input, Immediate(kSmiTagMask));
-  __ j(zero, &false_label, Label::kNear);
-  __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
-  __ test_b(FieldOperand(result, Map::kBitFieldOffset),
-            1 << Map::kIsUndetectable);
-  __ j(zero, &false_label, Label::kNear);
-  __ mov(result, factory()->true_value());
-  __ jmp(&done);
-  __ bind(&false_label);
-  __ mov(result, factory()->false_value());
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register temp = ToRegister(instr->TempAt(0));
@@ -1774,8 +1615,7 @@
   int false_block = chunk_->LookupDestination(instr->false_block_id());
 
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(input, Immediate(kSmiTagMask));
-  __ j(zero, chunk_->GetAssemblyLabel(false_block));
+  __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
   __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
   __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
             1 << Map::kIsUndetectable);
@@ -1783,7 +1623,7 @@
 }
 
 
-static InstanceType TestType(HHasInstanceType* instr) {
+static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
   InstanceType from = instr->from();
   InstanceType to = instr->to();
   if (from == FIRST_TYPE) return to;
@@ -1792,7 +1632,7 @@
 }
 
 
-static Condition BranchCondition(HHasInstanceType* instr) {
+static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
   InstanceType from = instr->from();
   InstanceType to = instr->to();
   if (from == to) return equal;
@@ -1803,25 +1643,6 @@
 }
 
 
-void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  __ test(input, Immediate(kSmiTagMask));
-  Label done, is_false;
-  __ j(zero, &is_false, Label::kNear);
-  __ CmpObjectType(input, TestType(instr->hydrogen()), result);
-  __ j(NegateCondition(BranchCondition(instr->hydrogen())),
-       &is_false, Label::kNear);
-  __ mov(result, factory()->true_value());
-  __ jmp(&done, Label::kNear);
-  __ bind(&is_false);
-  __ mov(result, factory()->false_value());
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register temp = ToRegister(instr->TempAt(0));
@@ -1831,8 +1652,7 @@
 
   Label* false_label = chunk_->GetAssemblyLabel(false_block);
 
-  __ test(input, Immediate(kSmiTagMask));
-  __ j(zero, false_label);
+  __ JumpIfSmi(input, false_label);
 
   __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
   EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
@@ -1852,21 +1672,6 @@
 }
 
 
-void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  __ mov(result, factory()->true_value());
-  __ test(FieldOperand(input, String::kHashFieldOffset),
-          Immediate(String::kContainsCachedArrayIndexMask));
-  Label done;
-  __ j(zero, &done, Label::kNear);
-  __ mov(result, factory()->false_value());
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoHasCachedArrayIndexAndBranch(
     LHasCachedArrayIndexAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
@@ -1890,28 +1695,28 @@
                                Register temp2) {
   ASSERT(!input.is(temp));
   ASSERT(!temp.is(temp2));  // But input and temp2 may be the same register.
-  __ test(input, Immediate(kSmiTagMask));
-  __ j(zero, is_false);
-  __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, temp);
+  __ JumpIfSmi(input, is_false);
+  __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp);
   __ j(below, is_false);
 
   // Map is now in temp.
   // Functions have class 'Function'.
-  __ CmpInstanceType(temp, JS_FUNCTION_TYPE);
+  __ CmpInstanceType(temp, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
   if (class_name->IsEqualTo(CStrVector("Function"))) {
-    __ j(equal, is_true);
+    __ j(above_equal, is_true);
   } else {
-    __ j(equal, is_false);
+    __ j(above_equal, is_false);
   }
 
   // Check if the constructor in the map is a function.
   __ mov(temp, FieldOperand(temp, Map::kConstructorOffset));
 
-  // As long as JS_FUNCTION_TYPE is the last instance type and it is
-  // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
-  // LAST_JS_OBJECT_TYPE.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
+  // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
+  // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
+  STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+  STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+                LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
 
   // Objects with a non-function constructor have class 'Object'.
   __ CmpObjectType(temp, JS_FUNCTION_TYPE, temp2);
@@ -1937,29 +1742,6 @@
 }
 
 
-void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  ASSERT(input.is(result));
-  Register temp = ToRegister(instr->TempAt(0));
-  Handle<String> class_name = instr->hydrogen()->class_name();
-  Label done;
-  Label is_true, is_false;
-
-  EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
-
-  __ j(not_equal, &is_false, Label::kNear);
-
-  __ bind(&is_true);
-  __ mov(result, factory()->true_value());
-  __ jmp(&done, Label::kNear);
-
-  __ bind(&is_false);
-  __ mov(result, factory()->false_value());
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register temp = ToRegister(instr->TempAt(0));
@@ -1998,7 +1780,7 @@
   // Object and function are in fixed registers defined by the stub.
   ASSERT(ToRegister(instr->context()).is(esi));
   InstanceofStub stub(InstanceofStub::kArgsInRegisters);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 
   Label true_value, done;
   __ test(eax, Operand(eax));
@@ -2011,18 +1793,6 @@
 }
 
 
-void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
-  ASSERT(ToRegister(instr->context()).is(esi));
-  int true_block = chunk_->LookupDestination(instr->true_block_id());
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
-
-  InstanceofStub stub(InstanceofStub::kArgsInRegisters);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
-  __ test(eax, Operand(eax));
-  EmitBranch(true_block, false_block, zero);
-}
-
-
 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
   class DeferredInstanceOfKnownGlobal: public LDeferredCode {
    public:
@@ -2044,12 +1814,11 @@
   deferred = new DeferredInstanceOfKnownGlobal(this, instr);
 
   Label done, false_result;
-  Register object = ToRegister(instr->InputAt(0));
+  Register object = ToRegister(instr->InputAt(1));
   Register temp = ToRegister(instr->TempAt(0));
 
   // A Smi is not an instance of anything.
-  __ test(object, Immediate(kSmiTagMask));
-  __ j(zero, &false_result);
+  __ 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
@@ -2107,14 +1876,13 @@
   Register temp = ToRegister(instr->TempAt(0));
   ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
   __ mov(InstanceofStub::right(), Immediate(instr->function()));
-  static const int kAdditionalDelta = 16;
+  static const int kAdditionalDelta = 13;
   int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
   __ mov(temp, Immediate(delta));
   __ StoreToSafepointRegisterSlot(temp, temp);
   CallCodeGeneric(stub.GetCode(),
                   RelocInfo::CODE_TARGET,
                   instr,
-                  RESTORE_CONTEXT,
                   RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
   // Put the result value into the eax slot and restore all registers.
   __ StoreToSafepointRegisterSlot(eax, eax);
@@ -2145,7 +1913,7 @@
   Token::Value op = instr->op();
 
   Handle<Code> ic = CompareIC::GetUninitialized(op);
-  CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
 
   Condition condition = ComputeCompareCondition(op);
   if (op == Token::GT || op == Token::LTE) {
@@ -2162,25 +1930,6 @@
 }
 
 
-void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) {
-  Token::Value op = instr->op();
-  int true_block = chunk_->LookupDestination(instr->true_block_id());
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
-
-  Handle<Code> ic = CompareIC::GetUninitialized(op);
-  CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
-
-  // The compare stub expects compare condition and the input operands
-  // reversed for GT and LTE.
-  Condition condition = ComputeCompareCondition(op);
-  if (op == Token::GT || op == Token::LTE) {
-    condition = ReverseCondition(condition);
-  }
-  __ test(eax, Operand(eax));
-  EmitBranch(true_block, false_block, condition);
-}
-
-
 void LCodeGen::DoReturn(LReturn* instr) {
   if (FLAG_trace) {
     // Preserve the return value on the stack and rely on the runtime call
@@ -2216,7 +1965,7 @@
   RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
                                                RelocInfo::CODE_TARGET_CONTEXT;
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  CallCode(ic, mode, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, mode, instr);
 }
 
 
@@ -2247,7 +1996,7 @@
   Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
-  CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
 }
 
 
@@ -2319,7 +2068,7 @@
     ASSERT(instr->hydrogen()->need_generic());
     __ mov(ecx, name);
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+    CallCode(ic, RelocInfo::CODE_TARGET, instr);
   } else {
     Label done;
     for (int i = 0; i < map_count - 1; ++i) {
@@ -2341,7 +2090,7 @@
       __ bind(&generic);
       __ mov(ecx, name);
       Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-      CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+      CallCode(ic, RelocInfo::CODE_TARGET, instr);
     } else {
       DeoptimizeIf(not_equal, instr->environment());
       EmitLoadFieldOrConstantFunction(result, object, map, name);
@@ -2358,7 +2107,7 @@
 
   __ mov(ecx, instr->name());
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -2409,7 +2158,7 @@
   Register input = ToRegister(instr->InputAt(0));
   __ mov(result, FieldOperand(input, JSObject::kElementsOffset));
   if (FLAG_debug_code) {
-    Label done;
+    Label done, ok, fail;
     __ cmp(FieldOperand(result, HeapObject::kMapOffset),
            Immediate(factory()->fixed_array_map()));
     __ j(equal, &done, Label::kNear);
@@ -2419,11 +2168,19 @@
     Register temp((result.is(eax)) ? ebx : eax);
     __ push(temp);
     __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
-    __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
-    __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
-    __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount));
+    __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset));
+    __ and_(temp, Map::kElementsKindMask);
+    __ shr(temp, Map::kElementsKindShift);
+    __ cmp(temp, JSObject::FAST_ELEMENTS);
+    __ j(equal, &ok, Label::kNear);
+    __ cmp(temp, JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
+    __ j(less, &fail, Label::kNear);
+    __ cmp(temp, JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND);
+    __ j(less_equal, &ok, Label::kNear);
+    __ bind(&fail);
+    __ Abort("Check for fast or external elements failed.");
+    __ bind(&ok);
     __ pop(temp);
-    __ Check(below, "Check for fast elements or pixel array failed.");
     __ bind(&done);
   }
 }
@@ -2473,55 +2230,80 @@
 }
 
 
-Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer,
-                                            LOperand* key,
-                                            ExternalArrayType array_type) {
+void LCodeGen::DoLoadKeyedFastDoubleElement(
+    LLoadKeyedFastDoubleElement* instr) {
+  XMMRegister result = ToDoubleRegister(instr->result());
+
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
+        sizeof(kHoleNanLower32);
+    Operand hole_check_operand = BuildFastArrayOperand(
+        instr->elements(), instr->key(),
+        JSObject::FAST_DOUBLE_ELEMENTS,
+        offset);
+    __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
+    DeoptimizeIf(equal, instr->environment());
+  }
+
+  Operand double_load_operand = BuildFastArrayOperand(
+      instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
+      FixedDoubleArray::kHeaderSize - kHeapObjectTag);
+  __ movdbl(result, double_load_operand);
+}
+
+
+Operand LCodeGen::BuildFastArrayOperand(
+    LOperand* external_pointer,
+    LOperand* key,
+    JSObject::ElementsKind elements_kind,
+    uint32_t offset) {
   Register external_pointer_reg = ToRegister(external_pointer);
-  int shift_size = ExternalArrayTypeToShiftSize(array_type);
+  int shift_size = ElementsKindToShiftSize(elements_kind);
   if (key->IsConstantOperand()) {
     int constant_value = ToInteger32(LConstantOperand::cast(key));
     if (constant_value & 0xF0000000) {
       Abort("array index constant value too big");
     }
-    return Operand(external_pointer_reg, constant_value * (1 << shift_size));
+    return Operand(external_pointer_reg,
+                   constant_value * (1 << shift_size) + offset);
   } else {
     ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
-    return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0);
+    return Operand(external_pointer_reg, ToRegister(key), scale_factor, offset);
   }
 }
 
 
 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
     LLoadKeyedSpecializedArrayElement* instr) {
-  ExternalArrayType array_type = instr->array_type();
-  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
-                                            instr->key(), array_type));
-  if (array_type == kExternalFloatArray) {
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
+  Operand operand(BuildFastArrayOperand(instr->external_pointer(),
+                                        instr->key(), elements_kind, 0));
+  if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
     XMMRegister result(ToDoubleRegister(instr->result()));
     __ movss(result, operand);
     __ cvtss2sd(result, result);
-  } else if (array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     __ movdbl(ToDoubleRegister(instr->result()), operand);
   } else {
     Register result(ToRegister(instr->result()));
-    switch (array_type) {
-      case kExternalByteArray:
+    switch (elements_kind) {
+      case JSObject::EXTERNAL_BYTE_ELEMENTS:
         __ movsx_b(result, operand);
         break;
-      case kExternalUnsignedByteArray:
-      case kExternalPixelArray:
+      case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
         __ movzx_b(result, operand);
         break;
-      case kExternalShortArray:
+      case JSObject::EXTERNAL_SHORT_ELEMENTS:
         __ movsx_w(result, operand);
         break;
-      case kExternalUnsignedShortArray:
+      case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
         __ movzx_w(result, operand);
         break;
-      case kExternalIntArray:
+      case JSObject::EXTERNAL_INT_ELEMENTS:
         __ mov(result, operand);
         break;
-      case kExternalUnsignedIntArray:
+      case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
         __ mov(result, operand);
         __ test(result, Operand(result));
         // TODO(danno): we could be more clever here, perhaps having a special
@@ -2529,8 +2311,12 @@
         // happens, and generate code that returns a double rather than int.
         DeoptimizeIf(negative, instr->environment());
         break;
-      case kExternalFloatArray:
-      case kExternalDoubleArray:
+      case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+      case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+      case JSObject::FAST_ELEMENTS:
+      case JSObject::FAST_DOUBLE_ELEMENTS:
+      case JSObject::DICTIONARY_ELEMENTS:
+      case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -2544,7 +2330,7 @@
   ASSERT(ToRegister(instr->key()).is(eax));
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-  CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -2605,12 +2391,25 @@
   ASSERT(function.is(edi));  // Required by InvokeFunction.
   ASSERT(ToRegister(instr->result()).is(eax));
 
-  // TODO(1412): This is not correct if the called function is a
-  // strict mode function or a native.
-  //
-  // If the receiver is null or undefined, we have to pass the global object
-  // as a receiver.
+  // 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, receiver_ok;
+
+  // Do not transform the receiver to object for strict mode
+  // functions.
+  __ mov(scratch,
+         FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
+  __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
+            1 << SharedFunctionInfo::kStrictModeBitWithinByte);
+  __ j(not_equal, &receiver_ok, Label::kNear);
+
+  // Do not transform the receiver to object for builtins.
+  __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
+            1 << SharedFunctionInfo::kNativeBitWithinByte);
+  __ j(not_equal, &receiver_ok, Label::kNear);
+
+  // Normal function. Replace undefined or null with global receiver.
   __ cmp(receiver, factory()->null_value());
   __ j(equal, &global_object, Label::kNear);
   __ cmp(receiver, factory()->undefined_value());
@@ -2619,7 +2418,7 @@
   // The receiver should be a JS object.
   __ test(receiver, Immediate(kSmiTagMask));
   DeoptimizeIf(equal, instr->environment());
-  __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch);
+  __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch);
   DeoptimizeIf(below, instr->environment());
   __ jmp(&receiver_ok, Label::kNear);
 
@@ -2679,6 +2478,12 @@
 }
 
 
+void LCodeGen::DoThisFunction(LThisFunction* instr) {
+  Register result = ToRegister(instr->result());
+  __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+}
+
+
 void LCodeGen::DoContext(LContext* instr) {
   Register result = ToRegister(instr->result());
   __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2688,8 +2493,8 @@
 void LCodeGen::DoOuterContext(LOuterContext* instr) {
   Register context = ToRegister(instr->context());
   Register result = ToRegister(instr->result());
-  __ mov(result, Operand(context, Context::SlotOffset(Context::CLOSURE_INDEX)));
-  __ mov(result, FieldOperand(result, JSFunction::kContextOffset));
+  __ mov(result,
+         Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
 }
 
 
@@ -2755,7 +2560,7 @@
 
 
 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
-  Register input_reg = ToRegister(instr->InputAt(0));
+  Register input_reg = ToRegister(instr->value());
   __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
          factory()->heap_number_map());
   DeoptimizeIf(not_equal, instr->environment());
@@ -2786,7 +2591,8 @@
   // Slow case: Call the runtime system to do the number allocation.
   __ bind(&slow);
 
-  CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
+  CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0,
+                          instr, instr->context());
 
   // Set the pointer to the new heap number in tmp.
   if (!tmp.is(eax)) __ mov(tmp, eax);
@@ -2807,7 +2613,7 @@
 
 
 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
-  Register input_reg = ToRegister(instr->InputAt(0));
+  Register input_reg = ToRegister(instr->value());
   __ test(input_reg, Operand(input_reg));
   Label is_positive;
   __ j(not_sign, &is_positive);
@@ -2832,12 +2638,12 @@
     LUnaryMathOperation* instr_;
   };
 
-  ASSERT(instr->InputAt(0)->Equals(instr->result()));
+  ASSERT(instr->value()->Equals(instr->result()));
   Representation r = instr->hydrogen()->value()->representation();
 
   if (r.IsDouble()) {
     XMMRegister  scratch = xmm0;
-    XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+    XMMRegister input_reg = ToDoubleRegister(instr->value());
     __ xorps(scratch, scratch);
     __ subsd(scratch, input_reg);
     __ pand(input_reg, scratch);
@@ -2846,10 +2652,9 @@
   } else {  // Tagged case.
     DeferredMathAbsTaggedHeapNumber* deferred =
         new DeferredMathAbsTaggedHeapNumber(this, instr);
-    Register input_reg = ToRegister(instr->InputAt(0));
+    Register input_reg = ToRegister(instr->value());
     // Smi check.
-    __ test(input_reg, Immediate(kSmiTagMask));
-    __ j(not_zero, deferred->entry());
+    __ JumpIfNotSmi(input_reg, deferred->entry());
     EmitIntegerMathAbs(instr);
     __ bind(deferred->exit());
   }
@@ -2859,7 +2664,7 @@
 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
   XMMRegister xmm_scratch = xmm0;
   Register output_reg = ToRegister(instr->result());
-  XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+  XMMRegister input_reg = ToDoubleRegister(instr->value());
   __ xorps(xmm_scratch, xmm_scratch);  // Zero the register.
   __ ucomisd(input_reg, xmm_scratch);
 
@@ -2881,7 +2686,7 @@
 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
   XMMRegister xmm_scratch = xmm0;
   Register output_reg = ToRegister(instr->result());
-  XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+  XMMRegister input_reg = ToDoubleRegister(instr->value());
 
   Label below_half, done;
   // xmm_scratch = 0.5
@@ -2926,7 +2731,7 @@
 
 
 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
-  XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+  XMMRegister input_reg = ToDoubleRegister(instr->value());
   ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
   __ sqrtsd(input_reg, input_reg);
 }
@@ -2934,7 +2739,7 @@
 
 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
   XMMRegister xmm_scratch = xmm0;
-  XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+  XMMRegister input_reg = ToDoubleRegister(instr->value());
   ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
   __ xorps(xmm_scratch, xmm_scratch);
   __ addsd(input_reg, xmm_scratch);  // Convert -0 to +0.
@@ -2971,8 +2776,7 @@
     Register right_reg = ToRegister(right);
 
     Label non_smi, call;
-    __ test(right_reg, Immediate(kSmiTagMask));
-    __ j(not_zero, &non_smi);
+    __ JumpIfNotSmi(right_reg, &non_smi);
     __ SmiUntag(right_reg);
     __ cvtsi2sd(result_reg, Operand(right_reg));
     __ jmp(&call);
@@ -3003,14 +2807,15 @@
 
 
 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
-  ASSERT(instr->InputAt(0)->Equals(instr->result()));
-  XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+  ASSERT(instr->value()->Equals(instr->result()));
+  XMMRegister input_reg = ToDoubleRegister(instr->value());
   Label positive, done, zero;
   __ xorps(xmm0, xmm0);
   __ ucomisd(input_reg, xmm0);
   __ j(above, &positive, Label::kNear);
   __ j(equal, &zero, Label::kNear);
-  ExternalReference nan = ExternalReference::address_of_nan();
+  ExternalReference nan =
+      ExternalReference::address_of_canonical_non_hole_nan();
   __ movdbl(input_reg, Operand::StaticVariable(nan));
   __ jmp(&done, Label::kNear);
   __ bind(&zero);
@@ -3036,7 +2841,7 @@
   ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
   TranscendentalCacheStub stub(TranscendentalCache::COS,
                                TranscendentalCacheStub::UNTAGGED);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -3044,7 +2849,7 @@
   ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
   TranscendentalCacheStub stub(TranscendentalCache::SIN,
                                TranscendentalCacheStub::UNTAGGED);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -3104,7 +2909,7 @@
   int arity = instr->arity();
   Handle<Code> ic = isolate()->stub_cache()->
       ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
-  CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -3117,7 +2922,7 @@
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
   __ mov(ecx, instr->name());
-  CallCode(ic, mode, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, mode, instr);
 }
 
 
@@ -3127,7 +2932,7 @@
 
   int arity = instr->arity();
   CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   __ Drop(1);
 }
 
@@ -3141,7 +2946,7 @@
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
   __ mov(ecx, instr->name());
-  CallCode(ic, mode, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, mode, instr);
 }
 
 
@@ -3159,12 +2964,12 @@
 
   Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
   __ Set(eax, Immediate(instr->arity()));
-  CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr, CONTEXT_ADJUSTED);
+  CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
 }
 
 
 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
-  CallRuntime(instr->function(), instr->arity(), instr, RESTORE_CONTEXT);
+  CallRuntime(instr->function(), instr->arity(), instr);
 }
 
 
@@ -3207,7 +3012,7 @@
   Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
-  CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -3219,32 +3024,36 @@
 
 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
     LStoreKeyedSpecializedArrayElement* instr) {
-  ExternalArrayType array_type = instr->array_type();
-  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
-                                            instr->key(), array_type));
-  if (array_type == kExternalFloatArray) {
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
+  Operand operand(BuildFastArrayOperand(instr->external_pointer(),
+                                        instr->key(), elements_kind, 0));
+  if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
     __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
     __ movss(operand, xmm0);
-  } else if (array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     __ movdbl(operand, ToDoubleRegister(instr->value()));
   } else {
     Register value = ToRegister(instr->value());
-    switch (array_type) {
-      case kExternalPixelArray:
-      case kExternalByteArray:
-      case kExternalUnsignedByteArray:
+    switch (elements_kind) {
+      case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+      case JSObject::EXTERNAL_BYTE_ELEMENTS:
         __ mov_b(operand, value);
         break;
-      case kExternalShortArray:
-      case kExternalUnsignedShortArray:
+      case JSObject::EXTERNAL_SHORT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
         __ mov_w(operand, value);
         break;
-      case kExternalIntArray:
-      case kExternalUnsignedIntArray:
+      case JSObject::EXTERNAL_INT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
         __ mov(operand, value);
         break;
-      case kExternalFloatArray:
-      case kExternalDoubleArray:
+      case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+      case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+      case JSObject::FAST_ELEMENTS:
+      case JSObject::FAST_DOUBLE_ELEMENTS:
+      case JSObject::DICTIONARY_ELEMENTS:
+      case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -3284,6 +3093,26 @@
 }
 
 
+void LCodeGen::DoStoreKeyedFastDoubleElement(
+    LStoreKeyedFastDoubleElement* instr) {
+  XMMRegister value = ToDoubleRegister(instr->value());
+  Label have_value;
+
+  __ ucomisd(value, value);
+  __ j(parity_odd, &have_value);  // NaN.
+
+  ExternalReference canonical_nan_reference =
+      ExternalReference::address_of_canonical_non_hole_nan();
+  __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
+  __ bind(&have_value);
+
+  Operand double_store_operand = BuildFastArrayOperand(
+      instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
+      FixedDoubleArray::kHeaderSize - kHeapObjectTag);
+  __ movdbl(double_store_operand, value);
+}
+
+
 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
   ASSERT(ToRegister(instr->context()).is(esi));
   ASSERT(ToRegister(instr->object()).is(edx));
@@ -3293,7 +3122,7 @@
   Handle<Code> ic = instr->strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
-  CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -3424,7 +3253,8 @@
     __ SmiTag(index);
     __ push(index);
   }
-  CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
+  CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2,
+                          instr, instr->context());
   if (FLAG_debug_code) {
     __ AbortIfNotSmi(eax);
   }
@@ -3475,7 +3305,7 @@
   PushSafepointRegistersScope scope(this);
   __ SmiTag(char_code);
   __ push(char_code);
-  CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
+  CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
   __ StoreToSafepointRegisterSlot(result, eax);
 }
 
@@ -3499,7 +3329,7 @@
     __ push(ToOperand(instr->right()));
   }
   StringAddStub stub(NO_STRING_CHECK_IN_STUB);
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 }
 
 
@@ -3560,8 +3390,15 @@
   // register is stored, as this register is in the pointer map, but contains an
   // integer value.
   __ StoreToSafepointRegisterSlot(reg, Immediate(0));
-
-  CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
+  // 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.
+  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+  __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
+  RecordSafepointWithRegisters(
+      instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
   if (!reg.is(eax)) __ mov(reg, eax);
 
   // Done. Put the value in xmm0 into the value of the allocated heap
@@ -3605,7 +3442,15 @@
   __ Set(reg, Immediate(0));
 
   PushSafepointRegistersScope scope(this);
-  CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
+  // 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.
+  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+  __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
+  RecordSafepointWithRegisters(instr->pointer_map(), 0,
+                               Safepoint::kNoDeoptimizationIndex);
   __ StoreToSafepointRegisterSlot(reg, eax);
 }
 
@@ -3636,8 +3481,7 @@
   Label load_smi, done;
 
   // Smi check.
-  __ test(input_reg, Immediate(kSmiTagMask));
-  __ j(zero, &load_smi, Label::kNear);
+  __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
 
   // Heap number map check.
   __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
@@ -3652,7 +3496,8 @@
     DeoptimizeIf(not_equal, env);
 
     // Convert undefined to NaN.
-    ExternalReference nan = ExternalReference::address_of_nan();
+    ExternalReference nan =
+        ExternalReference::address_of_canonical_non_hole_nan();
     __ movdbl(result_reg, Operand::StaticVariable(nan));
     __ jmp(&done, Label::kNear);
 
@@ -3771,8 +3616,7 @@
   DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr);
 
   // Smi check.
-  __ test(input_reg, Immediate(kSmiTagMask));
-  __ j(not_zero, deferred->entry());
+  __ JumpIfNotSmi(input_reg, deferred->entry());
 
   // Smi to int32 conversion
   __ SmiUntag(input_reg);  // Untag smi.
@@ -3915,14 +3759,14 @@
 
 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
   LOperand* input = instr->InputAt(0);
-  __ test(ToRegister(input), Immediate(kSmiTagMask));
+  __ test(ToOperand(input), Immediate(kSmiTagMask));
   DeoptimizeIf(not_zero, instr->environment());
 }
 
 
 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
   LOperand* input = instr->InputAt(0);
-  __ test(ToRegister(input), Immediate(kSmiTagMask));
+  __ test(ToOperand(input), Immediate(kSmiTagMask));
   DeoptimizeIf(zero, instr->environment());
 }
 
@@ -3974,8 +3818,8 @@
 
 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
   ASSERT(instr->InputAt(0)->IsRegister());
-  Register reg = ToRegister(instr->InputAt(0));
-  __ cmp(reg, instr->hydrogen()->target());
+  Operand operand = ToOperand(instr->InputAt(0));
+  __ cmp(operand, instr->hydrogen()->target());
   DeoptimizeIf(not_equal, instr->environment());
 }
 
@@ -4077,6 +3921,7 @@
 
 
 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
+  ASSERT(ToRegister(instr->context()).is(esi));
   // Setup the parameters to the stub/runtime call.
   __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
   __ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
@@ -4090,16 +3935,16 @@
     FastCloneShallowArrayStub::Mode mode =
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
     FastCloneShallowArrayStub stub(mode, length);
-    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   } else if (instr->hydrogen()->depth() > 1) {
-    CallRuntime(Runtime::kCreateArrayLiteral, 3, instr, RESTORE_CONTEXT);
+    CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
-    CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr, RESTORE_CONTEXT);
+    CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr);
   } else {
     FastCloneShallowArrayStub::Mode mode =
         FastCloneShallowArrayStub::CLONE_ELEMENTS;
     FastCloneShallowArrayStub stub(mode, length);
-    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   }
 }
 
@@ -4121,12 +3966,9 @@
 
   // Pick the right runtime function to call.
   if (instr->hydrogen()->depth() > 1) {
-    CallRuntime(Runtime::kCreateObjectLiteral, 4, instr, CONTEXT_ADJUSTED);
+    CallRuntime(Runtime::kCreateObjectLiteral, 4, instr);
   } else {
-    CallRuntime(Runtime::kCreateObjectLiteralShallow,
-                4,
-                instr,
-                CONTEXT_ADJUSTED);
+    CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
   }
 }
 
@@ -4134,17 +3976,19 @@
 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
   ASSERT(ToRegister(instr->InputAt(0)).is(eax));
   __ push(eax);
-  CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED);
+  CallRuntime(Runtime::kToFastProperties, 1, instr);
 }
 
 
 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
+  ASSERT(ToRegister(instr->context()).is(esi));
   Label materialized;
   // Registers will be used as follows:
   // edi = JS function.
   // ecx = literals array.
   // ebx = regexp literal.
   // eax = regexp literal clone.
+  // esi = context.
   __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
   __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
   int literal_offset = FixedArray::kHeaderSize +
@@ -4159,7 +4003,7 @@
   __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
   __ push(Immediate(instr->hydrogen()->pattern()));
   __ push(Immediate(instr->hydrogen()->flags()));
-  CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT);
+  CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
   __ mov(ebx, eax);
 
   __ bind(&materialized);
@@ -4171,7 +4015,7 @@
   __ bind(&runtime_allocate);
   __ push(ebx);
   __ push(Immediate(Smi::FromInt(size)));
-  CallRuntime(Runtime::kAllocateInNewSpace, 1, instr, RESTORE_CONTEXT);
+  CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
   __ pop(ebx);
 
   __ bind(&allocated);
@@ -4191,6 +4035,7 @@
 
 
 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
+  ASSERT(ToRegister(instr->context()).is(esi));
   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
   Handle<SharedFunctionInfo> shared_info = instr->shared_info();
@@ -4199,49 +4044,26 @@
     FastNewClosureStub stub(
         shared_info->strict_mode() ? kStrictMode : kNonStrictMode);
     __ push(Immediate(shared_info));
-    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
   } else {
     __ push(Operand(ebp, StandardFrameConstants::kContextOffset));
     __ push(Immediate(shared_info));
     __ push(Immediate(pretenure
                       ? factory()->true_value()
                       : factory()->false_value()));
-    CallRuntime(Runtime::kNewClosure, 3, instr, RESTORE_CONTEXT);
+    CallRuntime(Runtime::kNewClosure, 3, instr);
   }
 }
 
 
 void LCodeGen::DoTypeof(LTypeof* instr) {
-  LOperand* input = instr->InputAt(0);
+  LOperand* input = instr->InputAt(1);
   if (input->IsConstantOperand()) {
     __ push(ToImmediate(input));
   } else {
     __ push(ToOperand(input));
   }
-  CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT);
-}
-
-
-void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  Label true_label;
-  Label false_label;
-  Label done;
-
-  Condition final_branch_condition = EmitTypeofIs(&true_label,
-                                                  &false_label,
-                                                  input,
-                                                  instr->type_literal());
-  __ j(final_branch_condition, &true_label, Label::kNear);
-  __ bind(&false_label);
-  __ mov(result, factory()->false_value());
-  __ jmp(&done, Label::kNear);
-
-  __ bind(&true_label);
-  __ mov(result, factory()->true_value());
-
-  __ bind(&done);
+  CallRuntime(Runtime::kTypeof, 1, instr);
 }
 
 
@@ -4297,22 +4119,19 @@
     final_branch_condition = not_zero;
 
   } else if (type_name->Equals(heap()->function_symbol())) {
+    STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
     __ JumpIfSmi(input, false_label);
-    __ CmpObjectType(input, JS_FUNCTION_TYPE, input);
-    __ j(equal, true_label);
-    // Regular expressions => 'function' (they are callable).
-    __ CmpInstanceType(input, JS_REGEXP_TYPE);
-    final_branch_condition = equal;
+    __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input);
+    final_branch_condition = above_equal;
 
   } else if (type_name->Equals(heap()->object_symbol())) {
     __ JumpIfSmi(input, false_label);
     __ cmp(input, factory()->null_value());
     __ j(equal, true_label);
-    // Regular expressions => 'function', not 'object'.
-    __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
+    __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
     __ j(below, false_label);
-    __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
-    __ j(above_equal, false_label);
+    __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ j(above, false_label);
     // Check for undetectable objects => false.
     __ test_b(FieldOperand(input, Map::kBitFieldOffset),
               1 << Map::kIsUndetectable);
@@ -4328,24 +4147,6 @@
 }
 
 
-void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
-  Register result = ToRegister(instr->result());
-  Label true_label;
-  Label done;
-
-  EmitIsConstructCall(result);
-  __ j(equal, &true_label, Label::kNear);
-
-  __ mov(result, factory()->false_value());
-  __ jmp(&done, Label::kNear);
-
-  __ bind(&true_label);
-  __ mov(result, factory()->true_value());
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
   Register temp = ToRegister(instr->TempAt(0));
   int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -4405,23 +4206,61 @@
   SafepointGenerator safepoint_generator(this,
                                          pointers,
                                          env->deoptimization_index());
-  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   __ push(Immediate(Smi::FromInt(strict_mode_flag())));
   __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
 }
 
 
-void LCodeGen::DoStackCheck(LStackCheck* instr) {
-  // Perform stack overflow check.
-  Label done;
-  ExternalReference stack_limit =
-      ExternalReference::address_of_stack_limit(isolate());
-  __ cmp(esp, Operand::StaticVariable(stack_limit));
-  __ j(above_equal, &done, Label::kNear);
+void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
+  {
+    PushSafepointRegistersScope scope(this);
+    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+    __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
+    RegisterLazyDeoptimization(
+        instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
+  }
 
-  StackCheckStub stub;
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
-  __ bind(&done);
+  // The gap code includes the restoring of the safepoint registers.
+  int pc = masm()->pc_offset();
+  safepoints_.SetPcAfterGap(pc);
+}
+
+
+void LCodeGen::DoStackCheck(LStackCheck* instr) {
+  class DeferredStackCheck: public LDeferredCode {
+   public:
+    DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
+        : LDeferredCode(codegen), instr_(instr) { }
+    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
+   private:
+    LStackCheck* instr_;
+  };
+
+  if (instr->hydrogen()->is_function_entry()) {
+    // Perform stack overflow check.
+    Label done;
+    ExternalReference stack_limit =
+        ExternalReference::address_of_stack_limit(isolate());
+    __ cmp(esp, Operand::StaticVariable(stack_limit));
+    __ j(above_equal, &done, Label::kNear);
+
+    ASSERT(instr->context()->IsRegister());
+    ASSERT(ToRegister(instr->context()).is(esi));
+    StackCheckStub stub;
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+    __ bind(&done);
+  } else {
+    ASSERT(instr->hydrogen()->is_backwards_branch());
+    // Perform stack overflow check if this goto needs it before jumping.
+    DeferredStackCheck* deferred_stack_check =
+        new DeferredStackCheck(this, instr);
+    ExternalReference stack_limit =
+        ExternalReference::address_of_stack_limit(isolate());
+    __ cmp(esp, Operand::StaticVariable(stack_limit));
+    __ j(below, deferred_stack_check->entry());
+    __ bind(instr->done_label());
+    deferred_stack_check->SetExit(instr->done_label());
+  }
 }
 
 
@@ -4466,7 +4305,6 @@
   SafepointGenerator safepoint_generator(this,
                                          pointers,
                                          env->deoptimization_index());
-  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
 }
 
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index 1a98d8d..c568bef 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -97,7 +97,7 @@
   void DoDeferredNumberTagI(LNumberTagI* instr);
   void DoDeferredTaggedToI(LTaggedToI* instr);
   void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
-  void DoDeferredStackCheck(LGoto* instr);
+  void DoDeferredStackCheck(LStackCheck* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
@@ -166,11 +166,6 @@
   bool GenerateRelocPadding();
   bool GenerateSafepointTable();
 
-  enum ContextMode {
-    RESTORE_CONTEXT,
-    CONTEXT_ADJUSTED
-  };
-
   enum SafepointMode {
     RECORD_SIMPLE_SAFEPOINT,
     RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
@@ -178,31 +173,28 @@
 
   void CallCode(Handle<Code> code,
                 RelocInfo::Mode mode,
-                LInstruction* instr,
-                ContextMode context_mode);
+                LInstruction* instr);
 
   void CallCodeGeneric(Handle<Code> code,
                        RelocInfo::Mode mode,
                        LInstruction* instr,
-                       ContextMode context_mode,
                        SafepointMode safepoint_mode);
 
   void CallRuntime(const Runtime::Function* fun,
                    int argc,
-                   LInstruction* instr,
-                   ContextMode context_mode);
+                   LInstruction* instr);
 
   void CallRuntime(Runtime::FunctionId id,
                    int argc,
-                   LInstruction* instr,
-                   ContextMode context_mode) {
+                   LInstruction* instr) {
     const Runtime::Function* function = Runtime::FunctionForId(id);
-    CallRuntime(function, argc, instr, context_mode);
+    CallRuntime(function, argc, instr);
   }
 
   void CallRuntimeFromDeferred(Runtime::FunctionId id,
                                int argc,
-                               LInstruction* instr);
+                               LInstruction* instr,
+                               LOperand* context);
 
   // Generate a direct call to a known function.  Expects the function
   // to be in edi.
@@ -230,9 +222,10 @@
   Register ToRegister(int index) const;
   XMMRegister ToDoubleRegister(int index) const;
   int ToInteger32(LConstantOperand* op) const;
-  Operand BuildExternalArrayOperand(LOperand* external_pointer,
-                                    LOperand* key,
-                                    ExternalArrayType array_type);
+  Operand BuildFastArrayOperand(LOperand* external_pointer,
+                                LOperand* key,
+                                JSObject::ElementsKind elements_kind,
+                                uint32_t offset);
 
   // Specific math operations - used from DoUnaryMathOperation.
   void EmitIntegerMathAbs(LUnaryMathOperation* instr);
@@ -256,9 +249,12 @@
                                     int arguments,
                                     int deoptimization_index);
   void RecordPosition(int position);
+  int LastSafepointEnd() {
+    return static_cast<int>(safepoints_.GetPcAfterGap());
+  }
 
   static Condition TokenToCondition(Token::Value op, bool is_unsigned);
-  void EmitGoto(int block, LDeferredCode* deferred_stack_check = NULL);
+  void EmitGoto(int block);
   void EmitBranch(int left_block, int right_block, Condition cc);
   void EmitCmpI(LOperand* left, LOperand* right);
   void EmitNumberUntagD(Register input,
@@ -277,7 +273,6 @@
   // true and false label should be made, to optimize fallthrough.
   Condition EmitIsObject(Register input,
                          Register temp1,
-                         Register temp2,
                          Label* is_not_object,
                          Label* is_object);
 
diff --git a/src/ia32/lithium-gap-resolver-ia32.cc b/src/ia32/lithium-gap-resolver-ia32.cc
index 9d91c61..fcf1f91 100644
--- a/src/ia32/lithium-gap-resolver-ia32.cc
+++ b/src/ia32/lithium-gap-resolver-ia32.cc
@@ -305,8 +305,13 @@
   } else if (source->IsConstantOperand()) {
     ASSERT(destination->IsRegister() || destination->IsStackSlot());
     Immediate src = cgen_->ToImmediate(source);
-    Operand dst = cgen_->ToOperand(destination);
-    __ mov(dst, src);
+    if (destination->IsRegister()) {
+      Register dst = cgen_->ToRegister(destination);
+      __ Set(dst, src);
+    } else {
+      Operand dst = cgen_->ToOperand(destination);
+      __ Set(dst, src);
+    }
 
   } else if (source->IsDoubleRegister()) {
     XMMRegister src = cgen_->ToDoubleRegister(source);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 91606ce..f0615ef 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -78,13 +78,13 @@
   ASSERT(Output() == NULL ||
          LUnallocated::cast(Output())->HasFixedPolicy() ||
          !LUnallocated::cast(Output())->HasRegisterPolicy());
-  for (UseIterator it(this); it.HasNext(); it.Advance()) {
-    LUnallocated* operand = LUnallocated::cast(it.Next());
+  for (UseIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
     ASSERT(operand->HasFixedPolicy() ||
            operand->IsUsedAtStart());
   }
-  for (TempIterator it(this); it.HasNext(); it.Advance()) {
-    LUnallocated* operand = LUnallocated::cast(it.Next());
+  for (TempIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
     ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
   }
 }
@@ -113,21 +113,18 @@
 template<int R, int I, int T>
 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
   stream->Add("= ");
-  inputs_.PrintOperandsTo(stream);
+  for (int i = 0; i < inputs_.length(); i++) {
+    if (i > 0) stream->Add(" ");
+    inputs_[i]->PrintTo(stream);
+  }
 }
 
 
 template<int R, int I, int T>
 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
-  results_.PrintOperandsTo(stream);
-}
-
-
-template<typename T, int N>
-void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
-  for (int i = 0; i < N; i++) {
+  for (int i = 0; i < results_.length(); i++) {
     if (i > 0) stream->Add(" ");
-    elems_[i]->PrintTo(stream);
+    results_[i]->PrintTo(stream);
   }
 }
 
@@ -270,12 +267,6 @@
 }
 
 
-void LTypeofIs::PrintDataTo(StringStream* stream) {
-  InputAt(0)->PrintTo(stream);
-  stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
-}
-
-
 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
   stream->Add("if typeof ");
   InputAt(0)->PrintTo(stream);
@@ -347,13 +338,6 @@
 }
 
 
-void LClassOfTest::PrintDataTo(StringStream* stream) {
-  stream->Add("= class_of_test(");
-  InputAt(0)->PrintTo(stream);
-  stream->Add(", \"%o\")", *hydrogen()->class_name());
-}
-
-
 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
   arguments()->PrintTo(stream);
 
@@ -394,8 +378,7 @@
     LLabel* label = LLabel::cast(first_instr);
     if (last_instr->IsGoto()) {
       LGoto* goto_instr = LGoto::cast(last_instr);
-      if (!goto_instr->include_stack_check() &&
-          label->IsRedundant() &&
+      if (label->IsRedundant() &&
           !label->is_loop_header()) {
         bool can_eliminate = true;
         for (int i = first + 1; i < last && can_eliminate; ++i) {
@@ -446,6 +429,15 @@
 }
 
 
+void LStoreKeyedFastDoubleElement::PrintDataTo(StringStream* stream) {
+  elements()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  stream->Add("] <- ");
+  value()->PrintTo(stream);
+}
+
+
 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add("[");
@@ -714,7 +706,9 @@
 
 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
   HEnvironment* hydrogen_env = current_block_->last_environment();
-  instr->set_environment(CreateEnvironment(hydrogen_env));
+  int argument_index_accumulator = 0;
+  instr->set_environment(CreateEnvironment(hydrogen_env,
+                                           &argument_index_accumulator));
   return instr;
 }
 
@@ -804,6 +798,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
+  return AssignEnvironment(new LDeoptimize);
+}
+
+
 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
   return AssignEnvironment(new LDeoptimize);
 }
@@ -823,9 +822,10 @@
     ASSERT(instr->left()->representation().IsTagged());
     ASSERT(instr->right()->representation().IsTagged());
 
+    LOperand* context = UseFixed(instr->context(), esi);
     LOperand* left = UseFixed(instr->left(), edx);
     LOperand* right = UseFixed(instr->right(), eax);
-    LArithmeticT* result = new LArithmeticT(op, left, right);
+    LArithmeticT* result = new LArithmeticT(op, context, left, right);
     return MarkAsCall(DefineFixed(result, eax), instr);
   }
 }
@@ -837,18 +837,19 @@
     ASSERT(instr->left()->representation().IsTagged());
     ASSERT(instr->right()->representation().IsTagged());
 
+    LOperand* context = UseFixed(instr->context(), esi);
     LOperand* left = UseFixed(instr->left(), edx);
     LOperand* right = UseFixed(instr->right(), eax);
-    LArithmeticT* result = new LArithmeticT(op, left, right);
+    LArithmeticT* result = new LArithmeticT(op, context, left, right);
     return MarkAsCall(DefineFixed(result, eax), instr);
   }
 
   ASSERT(instr->representation().IsInteger32());
-  ASSERT(instr->OperandAt(0)->representation().IsInteger32());
-  ASSERT(instr->OperandAt(1)->representation().IsInteger32());
-  LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
+  ASSERT(instr->left()->representation().IsInteger32());
+  ASSERT(instr->right()->representation().IsInteger32());
+  LOperand* left = UseRegisterAtStart(instr->left());
 
-  HValue* right_value = instr->OperandAt(1);
+  HValue* right_value = instr->right();
   LOperand* right = NULL;
   int constant_value = 0;
   if (right_value->IsConstant()) {
@@ -902,12 +903,15 @@
   HValue* right = instr->right();
   ASSERT(left->representation().IsTagged());
   ASSERT(right->representation().IsTagged());
+  LOperand* context = UseFixed(instr->context(), esi);
   LOperand* left_operand = UseFixed(left, edx);
   LOperand* right_operand = UseFixed(right, eax);
-  LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand);
+  LArithmeticT* result =
+      new LArithmeticT(op, context, left_operand, right_operand);
   return MarkAsCall(DefineFixed(result, eax), instr);
 }
 
+
 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
   ASSERT(is_building());
   current_block_ = block;
@@ -984,28 +988,20 @@
     if (FLAG_stress_environments && !instr->HasEnvironment()) {
       instr = AssignEnvironment(instr);
     }
-    if (current->IsTest() && !instr->IsGoto()) {
-      ASSERT(instr->IsControl());
-      HTest* test = HTest::cast(current);
-      instr->set_hydrogen_value(test->value());
-      HBasicBlock* first = test->FirstSuccessor();
-      HBasicBlock* second = test->SecondSuccessor();
-      ASSERT(first != NULL && second != NULL);
-      instr->SetBranchTargets(first->block_id(), second->block_id());
-    } else {
-      instr->set_hydrogen_value(current);
-    }
-
+    instr->set_hydrogen_value(current);
     chunk_->AddInstruction(instr, current_block_);
   }
   current_instruction_ = old_current;
 }
 
 
-LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
+LEnvironment* LChunkBuilder::CreateEnvironment(
+    HEnvironment* hydrogen_env,
+    int* argument_index_accumulator) {
   if (hydrogen_env == NULL) return NULL;
 
-  LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
+  LEnvironment* outer =
+      CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
   int ast_id = hydrogen_env->ast_id();
   ASSERT(ast_id != AstNode::kNoNumber);
   int value_count = hydrogen_env->length();
@@ -1015,7 +1011,6 @@
                                           argument_count_,
                                           value_count,
                                           outer);
-  int argument_index = 0;
   for (int i = 0; i < value_count; ++i) {
     if (hydrogen_env->is_special_index(i)) continue;
 
@@ -1024,7 +1019,7 @@
     if (value->IsArgumentsObject()) {
       op = NULL;
     } else if (value->IsPushArgument()) {
-      op = new LArgument(argument_index++);
+      op = new LArgument((*argument_index_accumulator)++);
     } else {
       op = UseAny(value);
     }
@@ -1036,112 +1031,21 @@
 
 
 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
-  LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(),
-                            instr->include_stack_check());
-  return (instr->include_stack_check())
-      ? AssignPointerMap(result)
-      : result;
+  return new LGoto(instr->FirstSuccessor()->block_id());
 }
 
 
-LInstruction* LChunkBuilder::DoTest(HTest* instr) {
+LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
   HValue* v = instr->value();
-  if (!v->EmitAtUses()) {
-    return new LBranch(UseRegisterAtStart(v));
-  } else if (v->IsClassOfTest()) {
-    HClassOfTest* compare = HClassOfTest::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
-                                     TempRegister(),
-                                     TempRegister());
-  } else if (v->IsCompare()) {
-    HCompare* compare = HCompare::cast(v);
-    Token::Value op = compare->token();
-    HValue* left = compare->left();
-    HValue* right = compare->right();
-    Representation r = compare->GetInputRepresentation();
-    if (r.IsInteger32()) {
-      ASSERT(left->representation().IsInteger32());
-      ASSERT(right->representation().IsInteger32());
-      return new LCmpIDAndBranch(UseRegisterAtStart(left),
-                                 UseOrConstantAtStart(right));
-    } else if (r.IsDouble()) {
-      ASSERT(left->representation().IsDouble());
-      ASSERT(right->representation().IsDouble());
-      return new LCmpIDAndBranch(UseRegisterAtStart(left),
-                                 UseRegisterAtStart(right));
-    } else {
-      ASSERT(left->representation().IsTagged());
-      ASSERT(right->representation().IsTagged());
-      bool reversed = op == Token::GT || op == Token::LTE;
-      LOperand* left_operand = UseFixed(left, reversed ? eax : edx);
-      LOperand* right_operand = UseFixed(right, reversed ? edx : eax);
-      LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, right_operand);
-      return MarkAsCall(result, instr);
-    }
-  } else if (v->IsIsSmi()) {
-    HIsSmi* compare = HIsSmi::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsSmiAndBranch(Use(compare->value()));
-  } else if (v->IsIsUndetectable()) {
-    HIsUndetectable* compare = HIsUndetectable::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()),
-                                        TempRegister());
-  } else if (v->IsHasInstanceType()) {
-    HHasInstanceType* compare = HHasInstanceType::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()),
-                                         TempRegister());
-  } else if (v->IsHasCachedArrayIndex()) {
-    HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LHasCachedArrayIndexAndBranch(
-        UseRegisterAtStart(compare->value()));
-  } else if (v->IsIsNull()) {
-    HIsNull* compare = HIsNull::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    // We only need a temp register for non-strict compare.
-    LOperand* temp = compare->is_strict() ? NULL : TempRegister();
-    return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), temp);
-  } else if (v->IsIsObject()) {
-    HIsObject* compare = HIsObject::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    LOperand* temp1 = TempRegister();
-    LOperand* temp2 = TempRegister();
-    return new LIsObjectAndBranch(UseRegister(compare->value()),
-                                  temp1,
-                                  temp2);
-  } else if (v->IsCompareJSObjectEq()) {
-    HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
-    return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
-                                       UseRegisterAtStart(compare->right()));
-  } else if (v->IsCompareSymbolEq()) {
-    HCompareSymbolEq* compare = HCompareSymbolEq::cast(v);
-    return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()),
-                                     UseRegisterAtStart(compare->right()));
-  } else if (v->IsInstanceOf()) {
-    HInstanceOf* instance_of = HInstanceOf::cast(v);
-    LOperand* left = UseFixed(instance_of->left(), InstanceofStub::left());
-    LOperand* right = UseFixed(instance_of->right(), InstanceofStub::right());
-    LOperand* context = UseFixed(instance_of->context(), esi);
-    LInstanceOfAndBranch* result =
-        new LInstanceOfAndBranch(context, left, right);
-    return MarkAsCall(result, instr);
-  } else if (v->IsTypeofIs()) {
-    HTypeofIs* typeof_is = HTypeofIs::cast(v);
-    return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
-  } else if (v->IsIsConstructCall()) {
-    return new LIsConstructCallAndBranch(TempRegister());
-  } else if (v->IsConstant()) {
+  if (v->EmitAtUses()) {
+    ASSERT(v->IsConstant());
+    ASSERT(!v->representation().IsDouble());
     HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
     return new LGoto(successor->block_id());
-  } else {
-    Abort("Undefined compare before branch");
-    return NULL;
   }
+  return new LBranch(UseRegisterAtStart(v));
 }
 
 
@@ -1175,7 +1079,8 @@
     HInstanceOfKnownGlobal* instr) {
   LInstanceOfKnownGlobal* result =
       new LInstanceOfKnownGlobal(
-          UseFixed(instr->value(), InstanceofStub::left()),
+          UseFixed(instr->context(), esi),
+          UseFixed(instr->left(), InstanceofStub::left()),
           FixedTemp(edi));
   return MarkAsCall(DefineFixed(result, eax), instr);
 }
@@ -1203,6 +1108,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
+  return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction);
+}
+
+
 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
   return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext);
 }
@@ -1247,16 +1157,19 @@
   if (op == kMathLog) {
     ASSERT(instr->representation().IsDouble());
     ASSERT(instr->value()->representation().IsDouble());
+    LOperand* context = UseAny(instr->context());  // Not actually used.
     LOperand* input = UseRegisterAtStart(instr->value());
-    LUnaryMathOperation* result = new LUnaryMathOperation(input);
+    LUnaryMathOperation* result = new LUnaryMathOperation(context, input);
     return DefineSameAsFirst(result);
   } else if (op == kMathSin || op == kMathCos) {
+    LOperand* context = UseFixed(instr->context(), esi);
     LOperand* input = UseFixedDouble(instr->value(), xmm1);
-    LUnaryMathOperation* result = new LUnaryMathOperation(input);
+    LUnaryMathOperation* result = new LUnaryMathOperation(context, input);
     return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
   } else {
     LOperand* input = UseRegisterAtStart(instr->value());
-    LUnaryMathOperation* result = new LUnaryMathOperation(input);
+    LOperand* context = UseAny(instr->context());  // Deferred use by MathAbs.
+    LUnaryMathOperation* result = new LUnaryMathOperation(context, input);
     switch (op) {
       case kMathAbs:
         return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
@@ -1327,7 +1240,8 @@
 
 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
   argument_count_ -= instr->argument_count();
-  return MarkAsCall(DefineFixed(new LCallRuntime, eax), instr);
+  LOperand* context = UseFixed(instr->context(), esi);
+  return MarkAsCall(DefineFixed(new LCallRuntime(context), eax), instr);
 }
 
 
@@ -1507,88 +1421,86 @@
 }
 
 
-LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
+LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
   Token::Value op = instr->token();
+  ASSERT(instr->left()->representation().IsTagged());
+  ASSERT(instr->right()->representation().IsTagged());
+  bool reversed = (op == Token::GT || op == Token::LTE);
+  LOperand* context = UseFixed(instr->context(), esi);
+  LOperand* left = UseFixed(instr->left(), reversed ? eax : edx);
+  LOperand* right = UseFixed(instr->right(), reversed ? edx : eax);
+  LCmpT* result = new LCmpT(context, left, right);
+  return MarkAsCall(DefineFixed(result, eax), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCompareIDAndBranch(
+    HCompareIDAndBranch* instr) {
   Representation r = instr->GetInputRepresentation();
   if (r.IsInteger32()) {
     ASSERT(instr->left()->representation().IsInteger32());
     ASSERT(instr->right()->representation().IsInteger32());
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseOrConstantAtStart(instr->right());
-    return DefineAsRegister(new LCmpID(left, right));
-  } else if (r.IsDouble()) {
+    return new LCmpIDAndBranch(left, right);
+  } else {
+    ASSERT(r.IsDouble());
     ASSERT(instr->left()->representation().IsDouble());
     ASSERT(instr->right()->representation().IsDouble());
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseRegisterAtStart(instr->right());
-    return DefineAsRegister(new LCmpID(left, right));
-  } else {
-    ASSERT(instr->left()->representation().IsTagged());
-    ASSERT(instr->right()->representation().IsTagged());
-    bool reversed = (op == Token::GT || op == Token::LTE);
-    LOperand* left = UseFixed(instr->left(), reversed ? eax : edx);
-    LOperand* right = UseFixed(instr->right(), reversed ? edx : eax);
-    LCmpT* result = new LCmpT(left, right);
-    return MarkAsCall(DefineFixed(result, eax), instr);
+    return new LCmpIDAndBranch(left, right);
   }
 }
 
 
-LInstruction* LChunkBuilder::DoCompareJSObjectEq(
-    HCompareJSObjectEq* instr) {
+LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
+    HCompareObjectEqAndBranch* instr) {
   LOperand* left = UseRegisterAtStart(instr->left());
-  LOperand* right = UseRegisterAtStart(instr->right());
-  LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right);
-  return DefineAsRegister(result);
+  LOperand* right = UseAtStart(instr->right());
+  return new LCmpObjectEqAndBranch(left, right);
 }
 
 
-LInstruction* LChunkBuilder::DoCompareSymbolEq(
-    HCompareSymbolEq* instr) {
-  LOperand* left = UseRegisterAtStart(instr->left());
-  LOperand* right = UseRegisterAtStart(instr->right());
-  LCmpSymbolEq* result = new LCmpSymbolEq(left, right);
-  return DefineAsRegister(result);
+LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
+  HCompareConstantEqAndBranch* instr) {
+  return new LCmpConstantEqAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
+LInstruction* LChunkBuilder::DoIsNullAndBranch(HIsNullAndBranch* instr) {
+  // We only need a temp register for non-strict compare.
+  LOperand* temp = instr->is_strict() ? NULL : TempRegister();
+  return new LIsNullAndBranch(UseRegisterAtStart(instr->value()), temp);
+}
+
+
+LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LIsNull(value));
+  LOperand* temp = TempRegister();
+  return new LIsObjectAndBranch(UseRegister(instr->value()), temp);
 }
 
 
-LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
+LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegister(instr->value());
-
-  return DefineAsRegister(new LIsObject(value, TempRegister()));
+  return new LIsSmiAndBranch(Use(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) {
-  ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseAtStart(instr->value());
-
-  return DefineAsRegister(new LIsSmi(value));
+LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
+    HIsUndetectableAndBranch* instr) {
+  ASSERT(instr  ->value()->representation().IsTagged());
+  return new LIsUndetectableAndBranch(UseRegisterAtStart(instr->value()),
+                                      TempRegister());
 }
 
 
-LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) {
+LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
+    HHasInstanceTypeAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LIsUndetectable(value));
-}
-
-
-LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
-  ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LHasInstanceType(value));
+  return new LHasInstanceTypeAndBranch(UseRegisterAtStart(instr->value()),
+                                       TempRegister());
 }
 
 
@@ -1601,20 +1513,20 @@
 }
 
 
-LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
-    HHasCachedArrayIndex* instr) {
+LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
+    HHasCachedArrayIndexAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegister(instr->value());
-
-  return DefineAsRegister(new LHasCachedArrayIndex(value));
+  return new LHasCachedArrayIndexAndBranch(
+      UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
+LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
+    HClassOfTestAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseTempRegister(instr->value());
-
-  return DefineSameAsFirst(new LClassOfTest(value, TempRegister()));
+  return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
+                                   TempRegister(),
+                                   TempRegister());
 }
 
 
@@ -1637,6 +1549,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
+  LOperand* object = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LElementsKind(object));
+}
+
+
 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
   LOperand* object = UseRegister(instr->value());
   LValueOf* result = new LValueOf(object, TempRegister());
@@ -1646,7 +1564,7 @@
 
 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
   return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
-                                            Use(instr->length())));
+                                            UseAtStart(instr->length())));
 }
 
 
@@ -1658,8 +1576,14 @@
 
 
 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
+  LOperand* context = UseFixed(instr->context(), esi);
   LOperand* value = UseFixed(instr->value(), eax);
-  return MarkAsCall(new LThrow(value), instr);
+  return MarkAsCall(new LThrow(context, value), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
+  return NULL;
 }
 
 
@@ -1684,8 +1608,9 @@
       LOperand* value = UseRegister(instr->value());
       bool needs_check = !instr->value()->type().IsSmi();
       if (needs_check) {
+        bool truncating = instr->CanTruncateToInt32();
         LOperand* xmm_temp =
-            (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3))
+            (truncating && CpuFeatures::IsSupported(SSE3))
             ? NULL
             : FixedTemp(xmm1);
         LTaggedToI* res = new LTaggedToI(value, xmm_temp);
@@ -1705,8 +1630,8 @@
       return AssignPointerMap(Define(result, result_temp));
     } else {
       ASSERT(to.IsInteger32());
-      bool needs_temp = instr->CanTruncateToInt32() &&
-          !CpuFeatures::IsSupported(SSE3);
+      bool truncating = instr->CanTruncateToInt32();
+      bool needs_temp = truncating && !CpuFeatures::IsSupported(SSE3);
       LOperand* value = needs_temp ?
           UseTempRegister(instr->value()) : UseRegister(instr->value());
       LOperand* temp = needs_temp ? TempRegister() : NULL;
@@ -1733,7 +1658,7 @@
 
 
 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
-  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* value = UseAtStart(instr->value());
   return AssignEnvironment(new LCheckNonSmi(value));
 }
 
@@ -1754,13 +1679,13 @@
 
 
 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
-  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* value = UseAtStart(instr->value());
   return AssignEnvironment(new LCheckSmi(value));
 }
 
 
 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
-  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* value = UseAtStart(instr->value());
   return AssignEnvironment(new LCheckFunction(value));
 }
 
@@ -1793,6 +1718,34 @@
 }
 
 
+LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
+  HValue* value = instr->value();
+  Representation input_rep = value->representation();
+
+  LInstruction* result;
+  if (input_rep.IsDouble()) {
+    LOperand* reg = UseRegister(value);
+    LOperand* temp_reg =
+        CpuFeatures::IsSupported(SSE3) ? NULL : TempRegister();
+    result = DefineAsRegister(new LDoubleToI(reg, temp_reg));
+  } else if (input_rep.IsInteger32()) {
+    // Canonicalization should already have removed the hydrogen instruction in
+    // this case, since it is a noop.
+    UNREACHABLE();
+    return NULL;
+  } else {
+    ASSERT(input_rep.IsTagged());
+    LOperand* reg = UseRegister(value);
+    // Register allocator doesn't (yet) support allocation of double
+    // temps. Reserve xmm1 explicitly.
+    LOperand* xmm_temp =
+        CpuFeatures::IsSupported(SSE3) ? NULL : FixedTemp(xmm1);
+    result = DefineSameAsFirst(new LTaggedToI(reg, xmm_temp));
+  }
+  return AssignEnvironment(result);
+}
+
+
 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
   return new LReturn(UseFixed(instr->value(), eax));
 }
@@ -1883,13 +1836,16 @@
 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
     HLoadNamedFieldPolymorphic* instr) {
   ASSERT(instr->representation().IsTagged());
+  LOperand* context = UseFixed(instr->context(), esi);
   if (instr->need_generic()) {
     LOperand* obj = UseFixed(instr->object(), eax);
-    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    LLoadNamedFieldPolymorphic* result =
+        new LLoadNamedFieldPolymorphic(context, obj);
     return MarkAsCall(DefineFixed(result, eax), instr);
   } else {
     LOperand* obj = UseRegisterAtStart(instr->object());
-    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    LLoadNamedFieldPolymorphic* result =
+        new LLoadNamedFieldPolymorphic(context, obj);
     return AssignEnvironment(DefineAsRegister(result));
   }
 }
@@ -1935,15 +1891,29 @@
 }
 
 
+LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
+    HLoadKeyedFastDoubleElement* instr) {
+  ASSERT(instr->representation().IsDouble());
+  ASSERT(instr->key()->representation().IsInteger32());
+  LOperand* elements = UseRegisterAtStart(instr->elements());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+  LLoadKeyedFastDoubleElement* result =
+      new LLoadKeyedFastDoubleElement(elements, key);
+  return AssignEnvironment(DefineAsRegister(result));
+}
+
+
 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
     HLoadKeyedSpecializedArrayElement* instr) {
-  ExternalArrayType array_type = instr->array_type();
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
   Representation representation(instr->representation());
   ASSERT(
-      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
-                                        array_type != kExternalDoubleArray)) ||
-      (representation.IsDouble() && (array_type == kExternalFloatArray ||
-                                     array_type == kExternalDoubleArray)));
+      (representation.IsInteger32() &&
+       (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
+      (representation.IsDouble() &&
+       ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
+       (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->key()->representation().IsInteger32());
   LOperand* external_pointer = UseRegister(instr->external_pointer());
   LOperand* key = UseRegisterOrConstant(instr->key());
@@ -1953,7 +1923,7 @@
   LInstruction* load_instr = DefineAsRegister(result);
   // An unsigned int array load might overflow and cause a deopt, make sure it
   // has an environment.
-  return (array_type == kExternalUnsignedIntArray)
+  return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS)
       ? AssignEnvironment(load_instr)
       : load_instr;
 }
@@ -1988,24 +1958,40 @@
 }
 
 
+LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
+    HStoreKeyedFastDoubleElement* instr) {
+  ASSERT(instr->value()->representation().IsDouble());
+  ASSERT(instr->elements()->representation().IsTagged());
+  ASSERT(instr->key()->representation().IsInteger32());
+
+  LOperand* elements = UseRegisterAtStart(instr->elements());
+  LOperand* val = UseTempRegister(instr->value());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+
+  return new LStoreKeyedFastDoubleElement(elements, key, val);
+}
+
+
 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
     HStoreKeyedSpecializedArrayElement* instr) {
   Representation representation(instr->value()->representation());
-  ExternalArrayType array_type = instr->array_type();
-  ASSERT(
-      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
-                                        array_type != kExternalDoubleArray)) ||
-      (representation.IsDouble() && (array_type == kExternalFloatArray ||
-                                     array_type == kExternalDoubleArray)));
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
+    ASSERT(
+      (representation.IsInteger32() &&
+       (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
+      (representation.IsDouble() &&
+       ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
+       (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->external_pointer()->representation().IsExternal());
   ASSERT(instr->key()->representation().IsInteger32());
 
   LOperand* external_pointer = UseRegister(instr->external_pointer());
   LOperand* key = UseRegisterOrConstant(instr->key());
   LOperand* val = NULL;
-  if (array_type == kExternalByteArray ||
-      array_type == kExternalUnsignedByteArray ||
-      array_type == kExternalPixelArray) {
+  if (elements_kind == JSObject::EXTERNAL_BYTE_ELEMENTS ||
+      elements_kind == JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
+      elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     // We need a byte register in this case for the value.
     val = UseFixed(instr->value(), eax);
   } else {
@@ -2066,23 +2052,27 @@
 
 
 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
+  LOperand* context = UseFixed(instr->context(), esi);
   LOperand* left = UseOrConstantAtStart(instr->left());
   LOperand* right = UseOrConstantAtStart(instr->right());
-  return MarkAsCall(DefineFixed(new LStringAdd(left, right), eax), instr);
+  LStringAdd* string_add = new LStringAdd(context, left, right);
+  return MarkAsCall(DefineFixed(string_add, eax), instr);
 }
 
 
 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
   LOperand* string = UseRegister(instr->string());
   LOperand* index = UseRegisterOrConstant(instr->index());
-  LStringCharCodeAt* result = new LStringCharCodeAt(string, index);
+  LOperand* context = UseAny(instr->context());
+  LStringCharCodeAt* result = new LStringCharCodeAt(context, string, index);
   return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
 }
 
 
 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
   LOperand* char_code = UseRegister(instr->value());
-  LStringCharFromCode* result = new LStringCharFromCode(char_code);
+  LOperand* context = UseAny(instr->context());
+  LStringCharFromCode* result = new LStringCharFromCode(context, char_code);
   return AssignPointerMap(DefineAsRegister(result));
 }
 
@@ -2094,7 +2084,8 @@
 
 
 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
-  return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr);
+  LOperand* context = UseFixed(instr->context(), esi);
+  return MarkAsCall(DefineFixed(new LArrayLiteral(context), eax), instr);
 }
 
 
@@ -2105,19 +2096,22 @@
 
 
 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
-  return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr);
+  LOperand* context = UseFixed(instr->context(), esi);
+  return MarkAsCall(DefineFixed(new LRegExpLiteral(context), eax), instr);
 }
 
 
 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
-  return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr);
+  LOperand* context = UseFixed(instr->context(), esi);
+  return MarkAsCall(DefineFixed(new LFunctionLiteral(context), eax), instr);
 }
 
 
 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
-  LDeleteProperty* result =
-      new LDeleteProperty(UseAtStart(instr->object()),
-                          UseOrConstantAtStart(instr->key()));
+  LOperand* context = UseFixed(instr->context(), esi);
+  LOperand* object = UseAtStart(instr->object());
+  LOperand* key = UseOrConstantAtStart(instr->key());
+  LDeleteProperty* result = new LDeleteProperty(context, object, key);
   return MarkAsCall(DefineFixed(result, eax), instr);
 }
 
@@ -2179,18 +2173,21 @@
 
 
 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
-  LTypeof* result = new LTypeof(UseAtStart(instr->value()));
+  LOperand* context = UseFixed(instr->context(), esi);
+  LOperand* value = UseAtStart(instr->value());
+  LTypeof* result = new LTypeof(context, value);
   return MarkAsCall(DefineFixed(result, eax), instr);
 }
 
 
-LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
-  return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
+LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
+  return new LTypeofIsAndBranch(UseTempRegister(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
-  return DefineAsRegister(new LIsConstructCall);
+LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
+    HIsConstructCallAndBranch* instr) {
+  return new LIsConstructCallAndBranch(TempRegister());
 }
 
 
@@ -2227,7 +2224,14 @@
 
 
 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
-  return MarkAsCall(new LStackCheck, instr);
+  if (instr->is_function_entry()) {
+    LOperand* context = UseFixed(instr->context(), esi);
+    return MarkAsCall(new LStackCheck(context), instr);
+  } else {
+    ASSERT(instr->is_backwards_branch());
+    LOperand* context = UseAny(instr->context());
+    return AssignEnvironment(AssignPointerMap(new LStackCheck(context)));
+  }
 }
 
 
@@ -2236,7 +2240,6 @@
   HConstant* undefined = graph()->GetConstantUndefined();
   HEnvironment* inner = outer->CopyForInlining(instr->closure(),
                                                instr->function(),
-                                               HEnvironment::LITHIUM,
                                                undefined,
                                                instr->call_kind());
   current_block_->UpdateEnvironment(inner);
@@ -2253,9 +2256,10 @@
 
 
 LInstruction* LChunkBuilder::DoIn(HIn* instr) {
+  LOperand* context = UseFixed(instr->context(), esi);
   LOperand* key = UseOrConstantAtStart(instr->key());
   LOperand* object = UseOrConstantAtStart(instr->object());
-  LIn* result = new LIn(key, object);
+  LIn* result = new LIn(context, key, object);
   return MarkAsCall(DefineFixed(result, eax), instr);
 }
 
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 979c494..0ea7c6b 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -32,6 +32,7 @@
 #include "lithium-allocator.h"
 #include "lithium.h"
 #include "safepoint-table.h"
+#include "utils.h"
 
 namespace v8 {
 namespace internal {
@@ -70,17 +71,12 @@
   V(ClampDToUint8)                              \
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
-  V(ClassOfTest)                                \
   V(ClassOfTestAndBranch)                       \
-  V(CmpID)                                      \
   V(CmpIDAndBranch)                             \
-  V(CmpJSObjectEq)                              \
-  V(CmpJSObjectEqAndBranch)                     \
-  V(CmpSymbolEq)                                \
-  V(CmpSymbolEqAndBranch)                       \
+  V(CmpObjectEqAndBranch)                       \
   V(CmpMapAndBranch)                            \
   V(CmpT)                                       \
-  V(CmpTAndBranch)                              \
+  V(CmpConstantEqAndBranch)                     \
   V(ConstantD)                                  \
   V(ConstantI)                                  \
   V(ConstantT)                                  \
@@ -89,6 +85,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(ElementsKind)                               \
   V(ExternalArrayLength)                        \
   V(FixedArrayLength)                           \
   V(FunctionLiteral)                            \
@@ -96,26 +93,18 @@
   V(GlobalObject)                               \
   V(GlobalReceiver)                             \
   V(Goto)                                       \
-  V(HasCachedArrayIndex)                        \
   V(HasCachedArrayIndexAndBranch)               \
-  V(HasInstanceType)                            \
   V(HasInstanceTypeAndBranch)                   \
   V(In)                                         \
   V(InstanceOf)                                 \
-  V(InstanceOfAndBranch)                        \
   V(InstanceOfKnownGlobal)                      \
   V(InstructionGap)                             \
   V(Integer32ToDouble)                          \
   V(InvokeFunction)                             \
-  V(IsConstructCall)                            \
   V(IsConstructCallAndBranch)                   \
-  V(IsNull)                                     \
   V(IsNullAndBranch)                            \
-  V(IsObject)                                   \
   V(IsObjectAndBranch)                          \
-  V(IsSmi)                                      \
   V(IsSmiAndBranch)                             \
-  V(IsUndetectable)                             \
   V(IsUndetectableAndBranch)                    \
   V(JSArrayLength)                              \
   V(Label)                                      \
@@ -127,6 +116,7 @@
   V(LoadGlobalCell)                             \
   V(LoadGlobalGeneric)                          \
   V(LoadKeyedFastElement)                       \
+  V(LoadKeyedFastDoubleElement)                 \
   V(LoadKeyedGeneric)                           \
   V(LoadKeyedSpecializedArrayElement)           \
   V(LoadNamedField)                             \
@@ -152,6 +142,7 @@
   V(StoreContextSlot)                           \
   V(StoreGlobalCell)                            \
   V(StoreGlobalGeneric)                         \
+  V(StoreKeyedFastDoubleElement)                \
   V(StoreKeyedFastElement)                      \
   V(StoreKeyedGeneric)                          \
   V(StoreKeyedSpecializedArrayElement)          \
@@ -163,10 +154,10 @@
   V(StringLength)                               \
   V(SubI)                                       \
   V(TaggedToI)                                  \
+  V(ThisFunction)                               \
   V(Throw)                                      \
   V(ToFastProperties)                           \
   V(Typeof)                                     \
-  V(TypeofIs)                                   \
   V(TypeofIsAndBranch)                          \
   V(UnaryMathOperation)                         \
   V(UnknownOSRValue)                            \
@@ -225,7 +216,6 @@
   virtual bool IsGap() const { return false; }
 
   virtual bool IsControl() const { return false; }
-  virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
 
   void set_environment(LEnvironment* env) { environment_ = env; }
   LEnvironment* environment() const { return environment_; }
@@ -281,37 +271,6 @@
 };
 
 
-template<typename ElementType, int NumElements>
-class OperandContainer {
- public:
-  OperandContainer() {
-    for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
-  }
-  int length() { return NumElements; }
-  ElementType& operator[](int i) {
-    ASSERT(i < length());
-    return elems_[i];
-  }
-  void PrintOperandsTo(StringStream* stream);
-
- private:
-  ElementType elems_[NumElements];
-};
-
-
-template<typename ElementType>
-class OperandContainer<ElementType, 0> {
- public:
-  int length() { return 0; }
-  void PrintOperandsTo(StringStream* stream) { }
-  ElementType& operator[](int i) {
-    UNREACHABLE();
-    static ElementType t = 0;
-    return t;
-  }
-};
-
-
 // R = number of result operands (0 or 1).
 // I = number of input operands.
 // T = number of temporary operands.
@@ -334,9 +293,9 @@
   virtual void PrintOutputOperandTo(StringStream* stream);
 
  protected:
-  OperandContainer<LOperand*, R> results_;
-  OperandContainer<LOperand*, I> inputs_;
-  OperandContainer<LOperand*, T> temps_;
+  EmbeddedContainer<LOperand*, R> results_;
+  EmbeddedContainer<LOperand*, I> inputs_;
+  EmbeddedContainer<LOperand*, T> temps_;
 };
 
 
@@ -395,19 +354,16 @@
 
 class LGoto: public LTemplateInstruction<0, 0, 0> {
  public:
-  LGoto(int block_id, bool include_stack_check = false)
-    : block_id_(block_id), include_stack_check_(include_stack_check) { }
+  explicit LGoto(int block_id) : block_id_(block_id) { }
 
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
   virtual void PrintDataTo(StringStream* stream);
   virtual bool IsControl() const { return true; }
 
   int block_id() const { return block_id_; }
-  bool include_stack_check() const { return include_stack_check_; }
 
  private:
   int block_id_;
-  bool include_stack_check_;
 };
 
 
@@ -489,16 +445,15 @@
  public:
   virtual bool IsControl() const { return true; }
 
-  int true_block_id() const { return true_block_id_; }
-  int false_block_id() const { return false_block_id_; }
-  void SetBranchTargets(int true_block_id, int false_block_id) {
-    true_block_id_ = true_block_id;
-    false_block_id_ = false_block_id;
-  }
+  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
+  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
+  int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); }
+  int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); }
 
  private:
-  int true_block_id_;
-  int false_block_id_;
+  HControlInstruction* hydrogen() {
+    return HControlInstruction::cast(this->hydrogen_value());
+  }
 };
 
 
@@ -600,23 +555,6 @@
 };
 
 
-class LCmpID: public LTemplateInstruction<1, 2, 0> {
- public:
-  LCmpID(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
-
-  Token::Value op() const { return hydrogen()->token(); }
-  bool is_double() const {
-    return hydrogen()->GetInputRepresentation().IsDouble();
-  }
-};
-
-
 class LCmpIDAndBranch: public LControlInstruction<2, 0> {
  public:
   LCmpIDAndBranch(LOperand* left, LOperand* right) {
@@ -625,7 +563,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
+  DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
 
   Token::Value op() const { return hydrogen()->token(); }
   bool is_double() const {
@@ -636,12 +574,16 @@
 };
 
 
-class LUnaryMathOperation: public LTemplateInstruction<1, 1, 0> {
+class LUnaryMathOperation: public LTemplateInstruction<1, 2, 0> {
  public:
-  explicit LUnaryMathOperation(LOperand* value) {
+  LUnaryMathOperation(LOperand* context, LOperand* value) {
+    inputs_[1] = context;
     inputs_[0] = value;
   }
 
+  LOperand* context() { return inputs_[1]; }
+  LOperand* value() { return inputs_[0]; }
+
   DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
   DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
 
@@ -650,61 +592,27 @@
 };
 
 
-class LCmpJSObjectEq: public LTemplateInstruction<1, 2, 0> {
+class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
  public:
-  LCmpJSObjectEq(LOperand* left, LOperand* right) {
+  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
     inputs_[0] = left;
     inputs_[1] = right;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
+  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
+                               "cmp-object-eq-and-branch")
 };
 
 
-class LCmpJSObjectEqAndBranch: public LControlInstruction<2, 0> {
+class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> {
  public:
-  LCmpJSObjectEqAndBranch(LOperand* left, LOperand* right) {
+  explicit LCmpConstantEqAndBranch(LOperand* left) {
     inputs_[0] = left;
-    inputs_[1] = right;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
-                               "cmp-jsobject-eq-and-branch")
-};
-
-
-class LCmpSymbolEq: public LTemplateInstruction<1, 2, 0> {
- public:
-  LCmpSymbolEq(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpSymbolEq, "cmp-symbol-eq")
-};
-
-
-class LCmpSymbolEqAndBranch: public LControlInstruction<2, 0> {
- public:
-  LCmpSymbolEqAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpSymbolEqAndBranch, "cmp-symbol-eq-and-branch")
-};
-
-
-class LIsNull: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsNull(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
-  DECLARE_HYDROGEN_ACCESSOR(IsNull)
-
-  bool is_strict() const { return hydrogen()->is_strict(); }
+  DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
+                               "cmp-constant-eq-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
 };
 
 
@@ -716,7 +624,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(IsNull)
+  DECLARE_HYDROGEN_ACCESSOR(IsNullAndBranch)
 
   bool is_strict() const { return hydrogen()->is_strict(); }
 
@@ -724,42 +632,19 @@
 };
 
 
-class LIsObject: public LTemplateInstruction<1, 1, 1> {
+class LIsObjectAndBranch: public LControlInstruction<1, 1> {
  public:
-  LIsObject(LOperand* value, LOperand* temp) {
+  LIsObjectAndBranch(LOperand* value, LOperand* temp) {
     inputs_[0] = value;
     temps_[0] = temp;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
-};
-
-
-class LIsObjectAndBranch: public LControlInstruction<1, 2> {
- public:
-  LIsObjectAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
-    inputs_[0] = value;
-    temps_[0] = temp;
-    temps_[1] = temp2;
-  }
-
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LIsSmi: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsSmi(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
-  DECLARE_HYDROGEN_ACCESSOR(IsSmi)
-};
-
-
 class LIsSmiAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LIsSmiAndBranch(LOperand* value) {
@@ -767,25 +652,15 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LIsUndetectable: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsUndetectable(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsUndetectable, "is-undetectable")
-  DECLARE_HYDROGEN_ACCESSOR(IsUndetectable)
-};
-
-
 class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
  public:
-  explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
+  LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
     inputs_[0] = value;
     temps_[0] = temp;
   }
@@ -797,17 +672,6 @@
 };
 
 
-class LHasInstanceType: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LHasInstanceType(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
-  DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
-};
-
-
 class LHasInstanceTypeAndBranch: public LControlInstruction<1, 1> {
  public:
   LHasInstanceTypeAndBranch(LOperand* value, LOperand* temp) {
@@ -817,7 +681,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
                                "has-instance-type-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
+  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -834,17 +698,6 @@
 };
 
 
-class LHasCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LHasCachedArrayIndex(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
-  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
-};
-
-
 class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
@@ -857,13 +710,6 @@
 };
 
 
-class LIsConstructCall: public LTemplateInstruction<1, 0, 0> {
- public:
-  DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is-construct-call")
-  DECLARE_HYDROGEN_ACCESSOR(IsConstructCall)
-};
-
-
 class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
  public:
   explicit LIsConstructCallAndBranch(LOperand* temp) {
@@ -875,20 +721,6 @@
 };
 
 
-class LClassOfTest: public LTemplateInstruction<1, 1, 1> {
- public:
-  LClassOfTest(LOperand* value, LOperand* temp) {
-    inputs_[0] = value;
-    temps_[0] = temp;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
-  DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
-
-  virtual void PrintDataTo(StringStream* stream);
-};
-
-
 class LClassOfTestAndBranch: public LControlInstruction<1, 2> {
  public:
   LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
@@ -899,35 +731,22 @@
 
   DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
                                "class-of-test-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
+  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LCmpT: public LTemplateInstruction<1, 2, 0> {
+class LCmpT: public LTemplateInstruction<1, 3, 0> {
  public:
-  LCmpT(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
+  LCmpT(LOperand* context, LOperand* left, LOperand* right) {
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
-
-  Token::Value op() const { return hydrogen()->token(); }
-};
-
-
-class LCmpTAndBranch: public LControlInstruction<2, 0> {
- public:
-  LCmpTAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
+  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
 
   Token::Value op() const { return hydrogen()->token(); }
 };
@@ -947,24 +766,11 @@
 };
 
 
-class LInstanceOfAndBranch: public LControlInstruction<3, 0> {
+class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 2, 1> {
  public:
-  LInstanceOfAndBranch(LOperand* context, LOperand* left, LOperand* right) {
+  LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) {
     inputs_[0] = context;
-    inputs_[1] = left;
-    inputs_[2] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
-
-  LOperand* context() { return inputs_[0]; }
-};
-
-
-class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
- public:
-  LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
-    inputs_[0] = value;
+    inputs_[1] = value;
     temps_[0] = temp;
   }
 
@@ -1077,7 +883,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
-  DECLARE_HYDROGEN_ACCESSOR(Value)
+  DECLARE_HYDROGEN_ACCESSOR(Branch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -1137,6 +943,17 @@
 };
 
 
+class LElementsKind: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LElementsKind(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
+  DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
+};
+
+
 class LValueOf: public LTemplateInstruction<1, 1, 1> {
  public:
   LValueOf(LOperand* value, LOperand* temp) {
@@ -1149,12 +966,16 @@
 };
 
 
-class LThrow: public LTemplateInstruction<0, 1, 0> {
+class LThrow: public LTemplateInstruction<0, 2, 0> {
  public:
-  explicit LThrow(LOperand* value) {
-    inputs_[0] = value;
+  LThrow(LOperand* context, LOperand* value) {
+    inputs_[0] = context;
+    inputs_[1] = value;
   }
 
+  LOperand* context() { return inputs_[0]; }
+  LOperand* value() { return inputs_[1]; }
+
   DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
 };
 
@@ -1212,12 +1033,16 @@
 };
 
 
-class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
+class LArithmeticT: public LTemplateInstruction<1, 3, 0> {
  public:
-  LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
+  LArithmeticT(Token::Value op,
+               LOperand* context,
+               LOperand* left,
+               LOperand* right)
       : op_(op) {
-    inputs_[0] = left;
-    inputs_[1] = right;
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
   }
 
   virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
@@ -1225,6 +1050,9 @@
   virtual const char* Mnemonic() const;
 
   Token::Value op() const { return op_; }
+  LOperand* context() { return inputs_[0]; }
+  LOperand* left() { return inputs_[1]; }
+  LOperand* right() { return inputs_[2]; }
 
  private:
   Token::Value op_;
@@ -1254,16 +1082,18 @@
 };
 
 
-class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
+class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 2, 0> {
  public:
-  explicit LLoadNamedFieldPolymorphic(LOperand* object) {
-    inputs_[0] = object;
+  LLoadNamedFieldPolymorphic(LOperand* context, LOperand* object) {
+    inputs_[0] = context;
+    inputs_[1] = object;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
   DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
 
-  LOperand* object() { return inputs_[0]; }
+  LOperand* context() { return inputs_[0]; }
+  LOperand* object() { return inputs_[1]; }
 };
 
 
@@ -1333,6 +1163,23 @@
 };
 
 
+class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
+ public:
+  LLoadKeyedFastDoubleElement(LOperand* elements,
+                              LOperand* key) {
+    inputs_[0] = elements;
+    inputs_[1] = key;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
+                               "load-keyed-fast-double-element")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
+
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+};
+
+
 class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
  public:
   LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
@@ -1347,8 +1194,8 @@
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
-  ExternalArrayType array_type() const {
-    return hydrogen()->array_type();
+  JSObject::ElementsKind elements_kind() const {
+    return hydrogen()->elements_kind();
   }
 };
 
@@ -1406,9 +1253,9 @@
 
 class LStoreGlobalGeneric: public LTemplateInstruction<0, 3, 0> {
  public:
-  explicit LStoreGlobalGeneric(LOperand* context,
-                               LOperand* global_object,
-                               LOperand* value) {
+  LStoreGlobalGeneric(LOperand* context,
+                      LOperand* global_object,
+                      LOperand* value) {
     inputs_[0] = context;
     inputs_[1] = global_object;
     inputs_[2] = value;
@@ -1471,6 +1318,11 @@
 };
 
 
+class LThisFunction: public LTemplateInstruction<1, 0, 0> {
+  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
+};
+
+
 class LContext: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(Context, "context")
@@ -1641,11 +1493,15 @@
 };
 
 
-class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
+class LCallRuntime: public LTemplateInstruction<1, 1, 0> {
  public:
+  explicit LCallRuntime(LOperand* context) {
+    inputs_[0] = context;
+  }
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
+  LOperand* context() { return inputs_[0]; }
   const Runtime::Function* function() const { return hydrogen()->function(); }
   int arity() const { return hydrogen()->argument_count(); }
 };
@@ -1691,7 +1547,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -1706,7 +1562,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -1814,6 +1670,28 @@
 };
 
 
+class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
+ public:
+  LStoreKeyedFastDoubleElement(LOperand* elements,
+                               LOperand* key,
+                               LOperand* val) {
+    inputs_[0] = elements;
+    inputs_[1] = key;
+    inputs_[2] = val;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
+                               "store-keyed-fast-double-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  LOperand* value() { return inputs_[2]; }
+};
+
+
 class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
  public:
   LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
@@ -1831,8 +1709,8 @@
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
-  ExternalArrayType array_type() const {
-    return hydrogen()->array_type();
+  JSObject::ElementsKind elements_kind() const {
+    return hydrogen()->elements_kind();
   }
 };
 
@@ -1862,46 +1740,52 @@
 };
 
 
-class LStringAdd: public LTemplateInstruction<1, 2, 0> {
+class LStringAdd: public LTemplateInstruction<1, 3, 0> {
  public:
-  LStringAdd(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
+  LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
   DECLARE_HYDROGEN_ACCESSOR(StringAdd)
 
-  LOperand* left() { return inputs_[0]; }
-  LOperand* right() { return inputs_[1]; }
+  LOperand* context() { return inputs_[0]; }
+  LOperand* left() { return inputs_[1]; }
+  LOperand* right() { return inputs_[2]; }
 };
 
 
-class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
+class LStringCharCodeAt: public LTemplateInstruction<1, 3, 0> {
  public:
-  LStringCharCodeAt(LOperand* string, LOperand* index) {
-    inputs_[0] = string;
-    inputs_[1] = index;
+  LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
+    inputs_[0] = context;
+    inputs_[1] = string;
+    inputs_[2] = index;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
   DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
 
-  LOperand* string() { return inputs_[0]; }
-  LOperand* index() { return inputs_[1]; }
+  LOperand* context() { return inputs_[0]; }
+  LOperand* string() { return inputs_[1]; }
+  LOperand* index() { return inputs_[2]; }
 };
 
 
-class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
+class LStringCharFromCode: public LTemplateInstruction<1, 2, 0> {
  public:
-  explicit LStringCharFromCode(LOperand* char_code) {
-    inputs_[0] = char_code;
+  LStringCharFromCode(LOperand* context, LOperand* char_code) {
+    inputs_[0] = context;
+    inputs_[1] = char_code;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
   DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
 
-  LOperand* char_code() { return inputs_[0]; }
+  LOperand* context() { return inputs_[0]; }
+  LOperand* char_code() { return inputs_[1]; }
 };
 
 
@@ -2023,8 +1907,14 @@
 };
 
 
-class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
+class LArrayLiteral: public LTemplateInstruction<1, 1, 0> {
  public:
+  explicit LArrayLiteral(LOperand* context) {
+    inputs_[0] = context;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+
   DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
   DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral)
 };
@@ -2036,22 +1926,34 @@
     inputs_[0] = context;
   }
 
+  LOperand* context() { return inputs_[0]; }
+
   DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
   DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
-
-  LOperand* context() { return inputs_[0]; }
 };
 
 
-class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> {
+class LRegExpLiteral: 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: public LTemplateInstruction<1, 0, 0> {
+class LFunctionLiteral: 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)
 
@@ -2070,31 +1972,17 @@
 };
 
 
-class LTypeof: public LTemplateInstruction<1, 1, 0> {
+class LTypeof: public LTemplateInstruction<1, 2, 0> {
  public:
-  explicit LTypeof(LOperand* value) {
-    inputs_[0] = value;
+  LTypeof(LOperand* context, LOperand* value) {
+    inputs_[0] = context;
+    inputs_[1] = value;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
 };
 
 
-class LTypeofIs: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LTypeofIs(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
-  DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
-
-  Handle<String> type_literal() { return hydrogen()->type_literal(); }
-
-  virtual void PrintDataTo(StringStream* stream);
-};
-
-
 class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LTypeofIsAndBranch(LOperand* value) {
@@ -2102,7 +1990,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
+  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
@@ -2110,17 +1998,19 @@
 };
 
 
-class LDeleteProperty: public LTemplateInstruction<1, 2, 0> {
+class LDeleteProperty: public LTemplateInstruction<1, 3, 0> {
  public:
-  LDeleteProperty(LOperand* obj, LOperand* key) {
-    inputs_[0] = obj;
-    inputs_[1] = key;
+  LDeleteProperty(LOperand* context, LOperand* obj, LOperand* key) {
+    inputs_[0] = context;
+    inputs_[1] = obj;
+    inputs_[2] = key;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
 
-  LOperand* object() { return inputs_[0]; }
-  LOperand* key() { return inputs_[1]; }
+  LOperand* context() { return inputs_[0]; }
+  LOperand* object() { return inputs_[1]; }
+  LOperand* key() { return inputs_[2]; }
 };
 
 
@@ -2147,21 +2037,35 @@
 };
 
 
-class LStackCheck: public LTemplateInstruction<0, 0, 0> {
+class LStackCheck: 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 LIn: public LTemplateInstruction<1, 2, 0> {
+class LIn: public LTemplateInstruction<1, 3, 0> {
  public:
-  LIn(LOperand* key, LOperand* object) {
-    inputs_[0] = key;
-    inputs_[1] = object;
+  LIn(LOperand* context, LOperand* key, LOperand* object) {
+    inputs_[0] = context;
+    inputs_[1] = key;
+    inputs_[2] = object;
   }
 
-  LOperand* key() { return inputs_[0]; }
-  LOperand* object() { return inputs_[1]; }
+  LOperand* context() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  LOperand* object() { return inputs_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(In, "in")
 };
@@ -2170,7 +2074,7 @@
 class LChunkBuilder;
 class LChunk: public ZoneObject {
  public:
-  explicit LChunk(CompilationInfo* info, HGraph* graph)
+  LChunk(CompilationInfo* info, HGraph* graph)
     : spill_slot_count_(0),
       info_(info),
       graph_(graph),
@@ -2361,7 +2265,8 @@
       LInstruction* instr, int ast_id);
   void ClearInstructionPendingDeoptimizationEnvironment();
 
-  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
+  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
+                                  int* argument_index_accumulator);
 
   void VisitInstruction(HInstruction* current);
 
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 6e66b6e..3e037d7 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -149,8 +149,7 @@
 
   // Skip barrier if writing a smi.
   ASSERT_EQ(0, kSmiTag);
-  test(value, Immediate(kSmiTagMask));
-  j(zero, &done, Label::kNear);
+  JumpIfSmi(value, &done, Label::kNear);
 
   InNewSpace(object, value, equal, &done, Label::kNear);
 
@@ -195,8 +194,7 @@
 
   // Skip barrier if writing a smi.
   ASSERT_EQ(0, kSmiTag);
-  test(value, Immediate(kSmiTagMask));
-  j(zero, &done);
+  JumpIfSmi(value, &done, Label::kNear);
 
   InNewSpace(object, value, equal, &done);
 
@@ -279,6 +277,16 @@
 }
 
 
+void MacroAssembler::CheckFastElements(Register map,
+                                       Label* fail,
+                                       Label::Distance distance) {
+  STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0);
+  cmpb(FieldOperand(map, Map::kBitField2Offset),
+       Map::kMaximumBitField2FastElementValue);
+  j(above, fail, distance);
+}
+
+
 void MacroAssembler::CheckMap(Register obj,
                               Handle<Map> map,
                               Label* fail,
@@ -330,8 +338,9 @@
                                             Register scratch,
                                             Label* fail) {
   movzx_b(scratch, FieldOperand(map, Map::kInstanceTypeOffset));
-  sub(Operand(scratch), Immediate(FIRST_JS_OBJECT_TYPE));
-  cmp(scratch, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
+  sub(Operand(scratch), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  cmp(scratch,
+      LAST_NONCALLABLE_SPEC_OBJECT_TYPE - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
   j(above, fail);
 }
 
@@ -353,8 +362,7 @@
 
 void MacroAssembler::AbortIfNotNumber(Register object) {
   Label ok;
-  test(object, Immediate(kSmiTagMask));
-  j(zero, &ok);
+  JumpIfSmi(object, &ok);
   cmp(FieldOperand(object, HeapObject::kMapOffset),
       isolate()->factory()->heap_number_map());
   Assert(equal, "Operand not a number");
@@ -726,6 +734,104 @@
 }
 
 
+void MacroAssembler::LoadFromNumberDictionary(Label* miss,
+                                              Register elements,
+                                              Register key,
+                                              Register r0,
+                                              Register r1,
+                                              Register r2,
+                                              Register result) {
+  // Register use:
+  //
+  // elements - holds the slow-case elements of the receiver and is unchanged.
+  //
+  // key      - holds the smi key on entry and is unchanged.
+  //
+  // Scratch registers:
+  //
+  // r0 - holds the untagged key on entry and holds the hash once computed.
+  //
+  // r1 - used to hold the capacity mask of the dictionary
+  //
+  // r2 - used for the index into the dictionary.
+  //
+  // result - holds the result on exit if the load succeeds and we fall through.
+
+  Label done;
+
+  // Compute the hash code from the untagged key.  This must be kept in sync
+  // with ComputeIntegerHash in utils.h.
+  //
+  // hash = ~hash + (hash << 15);
+  mov(r1, r0);
+  not_(r0);
+  shl(r1, 15);
+  add(r0, Operand(r1));
+  // hash = hash ^ (hash >> 12);
+  mov(r1, r0);
+  shr(r1, 12);
+  xor_(r0, Operand(r1));
+  // hash = hash + (hash << 2);
+  lea(r0, Operand(r0, r0, times_4, 0));
+  // hash = hash ^ (hash >> 4);
+  mov(r1, r0);
+  shr(r1, 4);
+  xor_(r0, Operand(r1));
+  // hash = hash * 2057;
+  imul(r0, r0, 2057);
+  // hash = hash ^ (hash >> 16);
+  mov(r1, r0);
+  shr(r1, 16);
+  xor_(r0, Operand(r1));
+
+  // Compute capacity mask.
+  mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset));
+  shr(r1, kSmiTagSize);  // convert smi to int
+  dec(r1);
+
+  // Generate an unrolled loop that performs a few probes before giving up.
+  const int kProbes = 4;
+  for (int i = 0; i < kProbes; i++) {
+    // Use r2 for index calculations and keep the hash intact in r0.
+    mov(r2, r0);
+    // Compute the masked index: (hash + i + i * i) & mask.
+    if (i > 0) {
+      add(Operand(r2), Immediate(NumberDictionary::GetProbeOffset(i)));
+    }
+    and_(r2, Operand(r1));
+
+    // Scale the index by multiplying by the entry size.
+    ASSERT(NumberDictionary::kEntrySize == 3);
+    lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3
+
+    // Check if the key matches.
+    cmp(key, FieldOperand(elements,
+                          r2,
+                          times_pointer_size,
+                          NumberDictionary::kElementsStartOffset));
+    if (i != (kProbes - 1)) {
+      j(equal, &done);
+    } else {
+      j(not_equal, miss);
+    }
+  }
+
+  bind(&done);
+  // Check that the value is a normal propety.
+  const int kDetailsOffset =
+      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+  ASSERT_EQ(NORMAL, 0);
+  test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
+       Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize));
+  j(not_zero, miss);
+
+  // Get the value at the masked, scaled index.
+  const int kValueOffset =
+      NumberDictionary::kElementsStartOffset + kPointerSize;
+  mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
+}
+
+
 void MacroAssembler::LoadAllocationTopHelper(Register result,
                                              Register scratch,
                                              AllocationFlags flags) {
@@ -1165,8 +1271,7 @@
                                              Register scratch,
                                              Label* miss) {
   // Check that the receiver isn't a smi.
-  test(function, Immediate(kSmiTagMask));
-  j(zero, miss);
+  JumpIfSmi(function, miss);
 
   // Check that the function really is a function.
   CmpObjectType(function, JS_FUNCTION_TYPE, result);
@@ -1405,32 +1510,30 @@
 }
 
 
-void MacroAssembler::PrepareCallApiFunction(int argc, Register scratch) {
+void MacroAssembler::PrepareCallApiFunction(int argc) {
   if (kReturnHandlesDirectly) {
     EnterApiExitFrame(argc);
     // When handles are returned directly we don't have to allocate extra
     // space for and pass an out parameter.
+    if (emit_debug_code()) {
+      mov(esi, Immediate(BitCast<int32_t>(kZapValue)));
+    }
   } else {
     // We allocate two additional slots: return value and pointer to it.
     EnterApiExitFrame(argc + 2);
 
     // The argument slots are filled as follows:
     //
-    //   n + 1: output cell
+    //   n + 1: output slot
     //   n: arg n
     //   ...
     //   1: arg1
-    //   0: pointer to the output cell
-    //
-    // Note that this is one more "argument" than the function expects
-    // so the out cell will have to be popped explicitly after returning
-    // from the function. The out cell contains Handle.
+    //   0: pointer to the output slot
 
-    // pointer to out cell.
-    lea(scratch, Operand(esp, (argc + 1) * kPointerSize));
-    mov(Operand(esp, 0 * kPointerSize), scratch);  // output.
+    lea(esi, Operand(esp, (argc + 1) * kPointerSize));
+    mov(Operand(esp, 0 * kPointerSize), esi);
     if (emit_debug_code()) {
-      mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0));  // out cell.
+      mov(Operand(esi, 0), Immediate(0));
     }
   }
 }
@@ -1454,9 +1557,9 @@
   call(function->address(), RelocInfo::RUNTIME_ENTRY);
 
   if (!kReturnHandlesDirectly) {
-    // The returned value is a pointer to the handle holding the result.
-    // Dereference this to get to the location.
-    mov(eax, Operand(eax, 0));
+    // PrepareCallApiFunction saved pointer to the output slot into
+    // callee-save register esi.
+    mov(eax, Operand(esi, 0));
   }
 
   Label empty_handle;
@@ -1748,12 +1851,9 @@
 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.
-    mov(dst, Operand(esi, Context::SlotOffset(Context::CLOSURE_INDEX)));
-    // Load the function context (which is the incoming, outer context).
-    mov(dst, FieldOperand(dst, JSFunction::kContextOffset));
+    mov(dst, Operand(esi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     for (int i = 1; i < context_chain_length; i++) {
-      mov(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX)));
-      mov(dst, FieldOperand(dst, JSFunction::kContextOffset));
+      mov(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     }
   } else {
     // Slot is in the current function context.  Move it into the
@@ -1762,14 +1862,14 @@
     mov(dst, esi);
   }
 
-  // We should not have found a 'with' context by walking the context chain
+  // We should not have found a with context by walking the context chain
   // (i.e., the static scope chain and runtime context chain do not agree).
   // A variable occurring in such a scope should have slot type LOOKUP and
   // not CONTEXT.
   if (emit_debug_code()) {
-    cmp(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
-    Check(equal, "Yo dawg, I heard you liked function contexts "
-                 "so I put function contexts in all your contexts");
+    cmp(FieldOperand(dst, HeapObject::kMapOffset),
+        isolate()->factory()->with_context_map());
+    Check(not_equal, "Variable resolved to with context.");
   }
 }
 
@@ -1944,6 +2044,9 @@
         Immediate(factory->fixed_array_map()));
     j(equal, &ok);
     cmp(FieldOperand(elements, HeapObject::kMapOffset),
+        Immediate(factory->fixed_double_array_map()));
+    j(equal, &ok);
+    cmp(FieldOperand(elements, HeapObject::kMapOffset),
         Immediate(factory->fixed_cow_array_map()));
     j(equal, &ok);
     Abort("JSObject with fast elements map has slow elements");
@@ -2048,8 +2151,7 @@
   ASSERT_EQ(0, kSmiTag);
   mov(scratch1, Operand(object1));
   and_(scratch1, Operand(object2));
-  test(scratch1, Immediate(kSmiTagMask));
-  j(zero, failure);
+  JumpIfSmi(scratch1, failure);
 
   // Load instance type for both strings.
   mov(scratch1, FieldOperand(object1, HeapObject::kMapOffset));
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 2ab98c5..dac2273 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -216,6 +216,12 @@
   // Compare instance type for map.
   void CmpInstanceType(Register map, 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,
+                         Label* fail,
+                         Label::Distance distance = Label::kFar);
+
   // 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)
@@ -283,14 +289,25 @@
   }
 
   // Jump the register contains a smi.
-  inline void JumpIfSmi(Register value, Label* smi_label) {
+  inline void JumpIfSmi(Register value,
+                        Label* smi_label,
+                        Label::Distance distance = Label::kFar) {
     test(value, Immediate(kSmiTagMask));
-    j(zero, smi_label);
+    j(zero, smi_label, distance);
+  }
+  // Jump if the operand is a smi.
+  inline void JumpIfSmi(Operand value,
+                        Label* smi_label,
+                        Label::Distance distance = Label::kFar) {
+    test(value, Immediate(kSmiTagMask));
+    j(zero, smi_label, distance);
   }
   // Jump if register contain a non-smi.
-  inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
+  inline void JumpIfNotSmi(Register value,
+                           Label* not_smi_label,
+                           Label::Distance distance = Label::kFar) {
     test(value, Immediate(kSmiTagMask));
-    j(not_zero, not_smi_label);
+    j(not_zero, not_smi_label, distance);
   }
 
   void LoadInstanceDescriptors(Register map, Register descriptors);
@@ -335,6 +352,15 @@
                               Label* miss);
 
 
+  void LoadFromNumberDictionary(Label* miss,
+                                Register elements,
+                                Register key,
+                                Register r0,
+                                Register r1,
+                                Register r2,
+                                Register result);
+
+
   // ---------------------------------------------------------------------------
   // Allocation support
 
@@ -541,10 +567,10 @@
 
   // Prepares stack to put arguments (aligns and so on). Reserves
   // space for return value if needed (assumes the return value is a handle).
-  // Uses callee-saved esi to restore stack state after call. Arguments must be
-  // stored in ApiParameterOperand(0), ApiParameterOperand(1) etc. Saves
-  // context (esi).
-  void PrepareCallApiFunction(int argc, Register scratch);
+  // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
+  // etc. Saves context (esi). If space was reserved for return value then
+  // stores the pointer to the reserved slot into esi.
+  void PrepareCallApiFunction(int argc);
 
   // Calls an API function. Allocates HandleScope, extracts
   // returned value from handle and propagates exceptions.
@@ -585,6 +611,9 @@
 
   void Move(Register target, Handle<Object> value);
 
+  // Push a handle value.
+  void Push(Handle<Object> handle) { push(handle); }
+
   Handle<Object> CodeObject() {
     ASSERT(!code_object_.is_null());
     return code_object_;
diff --git a/src/ia32/regexp-macro-assembler-ia32.h b/src/ia32/regexp-macro-assembler-ia32.h
index 21c86d0..d504470 100644
--- a/src/ia32/regexp-macro-assembler-ia32.h
+++ b/src/ia32/regexp-macro-assembler-ia32.h
@@ -28,6 +28,9 @@
 #ifndef V8_IA32_REGEXP_MACRO_ASSEMBLER_IA32_H_
 #define V8_IA32_REGEXP_MACRO_ASSEMBLER_IA32_H_
 
+#include "ia32/assembler-ia32.h"
+#include "ia32/assembler-ia32-inl.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 550a6ff..9a690d7 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -129,7 +129,7 @@
   __ j(not_zero, miss_label);
 
   // Check that receiver is a JSObject.
-  __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE);
+  __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
   __ j(below, miss_label);
 
   // Load properties array.
@@ -188,8 +188,7 @@
   ASSERT(extra2.is(no_reg));
 
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(receiver, &miss);
 
   // Get the map of the receiver and compute the hash.
   __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
@@ -249,8 +248,7 @@
                                            Register scratch,
                                            Label* miss_label) {
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, miss_label);
+  __ JumpIfSmi(receiver, miss_label);
 
   // Check that the object is a JS array.
   __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
@@ -270,8 +268,7 @@
                                 Label* smi,
                                 Label* non_string_object) {
   // Check that the object isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, smi);
+  __ JumpIfSmi(receiver, smi);
 
   // Check that the object is a string.
   __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
@@ -462,7 +459,7 @@
   // it's not controlled by GC.
   const int kApiStackSpace = 4;
 
-  __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, ebx);
+  __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
 
   __ mov(ApiParameterOperand(1), eax);  // v8::Arguments::implicit_args_.
   __ add(Operand(eax), Immediate(argc * kPointerSize));
@@ -509,8 +506,7 @@
     ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
 
     // Check that the receiver isn't a smi.
-    __ test(receiver, Immediate(kSmiTagMask));
-    __ j(zero, miss);
+    __ JumpIfSmi(receiver, miss);
 
     CallOptimization optimization(lookup);
 
@@ -738,8 +734,7 @@
                                       Register scratch,
                                       Label* miss_label) {
   // Check that the object isn't a smi.
-  __ test(receiver_reg, Immediate(kSmiTagMask));
-  __ j(zero, miss_label);
+  __ JumpIfSmi(receiver_reg, miss_label);
 
   // Check that the map of the object hasn't changed.
   __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
@@ -1020,8 +1015,7 @@
                                      String* name,
                                      Label* miss) {
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check the prototype chain.
   Register reg =
@@ -1045,8 +1039,7 @@
                                                 String* name,
                                                 Label* miss) {
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check that the maps haven't changed.
   Register reg =
@@ -1089,7 +1082,7 @@
   const int kStackSpace = 5;
   const int kApiArgc = 2;
 
-  __ PrepareCallApiFunction(kApiArgc, eax);
+  __ PrepareCallApiFunction(kApiArgc);
   __ mov(ApiParameterOperand(0), ebx);  // name.
   __ add(Operand(ebx), Immediate(kPointerSize));
   __ mov(ApiParameterOperand(1), ebx);  // arguments pointer.
@@ -1112,8 +1105,7 @@
                                         String* name,
                                         Label* miss) {
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // Check that the maps haven't changed.
   CheckPrototypes(object, receiver, holder,
@@ -1139,8 +1131,7 @@
   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
 
   // Check that the receiver isn't a smi.
-  __ test(receiver, Immediate(kSmiTagMask));
-  __ j(zero, miss);
+  __ JumpIfSmi(receiver, miss);
 
   // So far the most popular follow ups for interceptor loads are FIELD
   // and CALLBACKS, so inline only them, other cases may be added
@@ -1290,8 +1281,7 @@
   // object which can only happen for contextual calls. In this case,
   // the receiver cannot be a smi.
   if (object != holder) {
-    __ test(edx, Immediate(kSmiTagMask));
-    __ j(zero, miss);
+    __ JumpIfSmi(edx, miss);
   }
 
   // Check that the maps haven't changed.
@@ -1317,8 +1307,7 @@
     // the nice side effect that multiple closures based on the same
     // function can all use this call IC. Before we load through the
     // function, we have to verify that it still is a function.
-    __ test(edi, Immediate(kSmiTagMask));
-    __ j(zero, miss);
+    __ JumpIfSmi(edi, miss);
     __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
     __ j(not_equal, miss);
 
@@ -1366,8 +1355,7 @@
   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
 
   // Check that the receiver isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(edx, &miss);
 
   // Do the right check and compute the holder register.
   Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi,
@@ -1376,8 +1364,7 @@
   GenerateFastPropertyLoad(masm(), edi, reg, holder, index);
 
   // Check that the function really is a function.
-  __ test(edi, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(edi, &miss);
   __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
   __ j(not_equal, &miss);
 
@@ -1432,8 +1419,7 @@
   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
 
   // Check that the receiver isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(edx, &miss);
 
   CheckPrototypes(JSObject::cast(object), edx,
                   holder, ebx,
@@ -1481,8 +1467,7 @@
       __ mov(Operand(edx, 0), ecx);
 
       // Check if value is a smi.
-      __ test(ecx, Immediate(kSmiTagMask));
-      __ j(not_zero, &with_write_barrier);
+      __ JumpIfNotSmi(ecx, &with_write_barrier);
 
       __ bind(&exit);
       __ ret((argc + 1) * kPointerSize);
@@ -1585,8 +1570,7 @@
   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
 
   // Check that the receiver isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(edx, &miss);
   CheckPrototypes(JSObject::cast(object), edx,
                   holder, ebx,
                   eax, edi, name, &miss);
@@ -1845,8 +1829,7 @@
     __ mov(edx, Operand(esp, 2 * kPointerSize));
 
     STATIC_ASSERT(kSmiTag == 0);
-    __ test(edx, Immediate(kSmiTagMask));
-    __ j(zero, &miss);
+    __ JumpIfSmi(edx, &miss);
 
     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
                     &miss);
@@ -1863,8 +1846,7 @@
   // Check the code is a smi.
   Label slow;
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(code, Immediate(kSmiTagMask));
-  __ j(not_zero, &slow);
+  __ JumpIfNotSmi(code, &slow);
 
   // Convert the smi code to uint16.
   __ and_(code, Immediate(Smi::FromInt(0xffff)));
@@ -1929,8 +1911,7 @@
     __ mov(edx, Operand(esp, 2 * kPointerSize));
 
     STATIC_ASSERT(kSmiTag == 0);
-    __ test(edx, Immediate(kSmiTagMask));
-    __ j(zero, &miss);
+    __ JumpIfSmi(edx, &miss);
 
     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
                     &miss);
@@ -1946,8 +1927,7 @@
   // Check if the argument is a smi.
   Label smi;
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &smi);
+  __ JumpIfSmi(eax, &smi);
 
   // Check if the argument is a heap number and load its value into xmm0.
   Label slow;
@@ -2054,8 +2034,7 @@
     __ mov(edx, Operand(esp, 2 * kPointerSize));
 
     STATIC_ASSERT(kSmiTag == 0);
-    __ test(edx, Immediate(kSmiTagMask));
-    __ j(zero, &miss);
+    __ JumpIfSmi(edx, &miss);
 
     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
                     &miss);
@@ -2071,8 +2050,7 @@
   // Check if the argument is a smi.
   Label not_smi;
   STATIC_ASSERT(kSmiTag == 0);
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &not_smi);
+  __ JumpIfNotSmi(eax, &not_smi);
 
   // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
   // otherwise.
@@ -2158,8 +2136,7 @@
   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
 
   // Check that the receiver isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &miss_before_stack_reserved);
+  __ JumpIfSmi(edx, &miss_before_stack_reserved);
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->call_const(), 1);
@@ -2227,8 +2204,7 @@
 
   // Check that the receiver isn't a smi.
   if (check != NUMBER_CHECK) {
-    __ test(edx, Immediate(kSmiTagMask));
-    __ j(zero, &miss);
+    __ JumpIfSmi(edx, &miss);
   }
 
   // Make sure that it's okay not to patch the on stack receiver
@@ -2277,8 +2253,7 @@
       } else {
         Label fast;
         // Check that the object is a smi or a heap number.
-        __ test(edx, Immediate(kSmiTagMask));
-        __ j(zero, &fast);
+        __ JumpIfSmi(edx, &fast);
         __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax);
         __ j(not_equal, &miss);
         __ bind(&fast);
@@ -2373,8 +2348,7 @@
   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
 
   // Check that the function really is a function.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(eax, &miss);
   __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
   __ j(not_equal, &miss);
 
@@ -2522,8 +2496,7 @@
   Label miss;
 
   // Check that the object isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(edx, &miss);
 
   // Check that the map of the object hasn't changed.
   __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
@@ -2572,8 +2545,7 @@
   Label miss;
 
   // Check that the object isn't a smi.
-  __ test(edx, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(edx, &miss);
 
   // Check that the map of the object hasn't changed.
   __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
@@ -2699,18 +2671,18 @@
 }
 
 
-MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement(
-    Map* receiver_map) {
+MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
-  bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
-  MaybeObject* maybe_stub =
-      KeyedStoreFastElementStub(is_js_array).TryGetCode();
   Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
+  bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
+  MaybeObject* maybe_stub =
+      KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(edx,
                  Handle<Map>(receiver_map),
@@ -2765,8 +2737,7 @@
   Label miss;
 
   // Check that the receiver isn't a smi.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &miss);
+  __ JumpIfSmi(eax, &miss);
 
   ASSERT(last->IsGlobalObject() || last->HasFastProperties());
 
@@ -2918,8 +2889,7 @@
   // object which can only happen for contextual loads. In this case,
   // the receiver cannot be a smi.
   if (object != holder) {
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(zero, &miss);
+    __ JumpIfSmi(eax, &miss);
   }
 
   // Check that the maps haven't changed.
@@ -3163,14 +3133,15 @@
 }
 
 
-MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) {
+MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- eax    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
-  MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode();
   Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
+  MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(edx,
                  Handle<Map>(receiver_map),
@@ -3235,8 +3206,7 @@
   // Load the initial map and verify that it is in fact a map.
   __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
   // Will both indicate a NULL and a Smi.
-  __ test(ebx, Immediate(kSmiTagMask));
-  __ j(zero, &generic_stub_call);
+  __ JumpIfSmi(ebx, &generic_stub_call);
   __ CmpObjectType(ebx, MAP_TYPE, ecx);
   __ j(not_equal, &generic_stub_call);
 
@@ -3351,61 +3321,71 @@
 }
 
 
-MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
-    JSObject*receiver, ExternalArrayType array_type) {
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedLoadExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(edx,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
+  Label slow, miss_force_generic;
 
-  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+  __ JumpIfNotSmi(eax, &miss_force_generic);
+  __ mov(ebx, eax);
+  __ SmiUntag(ebx);
+  __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
 
-  // Return the generated code.
-  return GetCode();
-}
+  // Push receiver on the stack to free up a register for the dictionary
+  // probing.
+  __ push(edx);
+  __ LoadFromNumberDictionary(&slow,
+                              ecx,
+                              eax,
+                              ebx,
+                              edx,
+                              edi,
+                              eax);
+  // Pop receiver before returning.
+  __ pop(edx);
+  __ ret(0);
 
+  __ bind(&slow);
+  __ pop(edx);
 
-MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
-    JSObject* receiver, ExternalArrayType array_type) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedStoreExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(edx,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
 
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ jmp(slow_ic, RelocInfo::CODE_TARGET);
 
-  return GetCode();
+  __ bind(&miss_force_generic);
+  // ----------- S t a t e -------------
+  //  -- eax    : value
+  //  -- ecx    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+
+  Handle<Code> miss_force_generic_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET);
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ----------- S t a t e -------------
   //  -- eax    : key
   //  -- edx    : receiver
@@ -3417,8 +3397,7 @@
   // have been verified by the caller to not be a smi.
 
   // Check that the key is a smi.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &miss_force_generic);
+  __ JumpIfNotSmi(eax, &miss_force_generic);
 
   // Check that the index is in range.
   __ mov(ecx, eax);
@@ -3429,28 +3408,28 @@
   __ j(above_equal, &miss_force_generic);
   __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
   // ebx: base pointer of external storage
-  switch (array_type) {
-    case kExternalByteArray:
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
       __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
       break;
-    case kExternalUnsignedByteArray:
-    case kExternalPixelArray:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
       break;
-    case kExternalShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
       __ movsx_w(eax, Operand(ebx, ecx, times_2, 0));
       break;
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ movzx_w(eax, Operand(ebx, ecx, times_2, 0));
       break;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
       __ mov(ecx, Operand(ebx, ecx, times_4, 0));
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       __ fld_s(Operand(ebx, ecx, times_4, 0));
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       __ fld_d(Operand(ebx, ecx, times_8, 0));
       break;
     default:
@@ -3463,17 +3442,17 @@
   // For floating-point array type:
   // FP(0): value
 
-  if (array_type == kExternalIntArray ||
-      array_type == kExternalUnsignedIntArray) {
+  if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS ||
+      elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
     // For the Int and UnsignedInt array types, we need to see whether
     // the value can be represented in a Smi. If not, we need to convert
     // it to a HeapNumber.
     Label box_int;
-    if (array_type == kExternalIntArray) {
+    if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
       __ cmp(ecx, 0xC0000000);
       __ j(sign, &box_int);
     } else {
-      ASSERT_EQ(array_type, kExternalUnsignedIntArray);
+      ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
       // The test is different for unsigned int values. Since we need
       // the value to be in the range of a positive smi, we can't
       // handle either of the top two bits being set in the value.
@@ -3489,12 +3468,12 @@
 
     // Allocate a HeapNumber for the int and perform int-to-double
     // conversion.
-    if (array_type == kExternalIntArray) {
+    if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
       __ push(ecx);
       __ fild_s(Operand(esp, 0));
       __ pop(ecx);
     } else {
-      ASSERT(array_type == kExternalUnsignedIntArray);
+      ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
       // Need to zero-extend the value.
       // There's no fild variant for unsigned values, so zero-extend
       // to a 64-bit int manually.
@@ -3510,8 +3489,8 @@
     __ mov(eax, ecx);
     __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
     __ ret(0);
-  } else if (array_type == kExternalFloatArray ||
-             array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+             elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     // For the floating-point array type, we need to always allocate a
     // HeapNumber.
     __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
@@ -3561,7 +3540,7 @@
 
 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ----------- S t a t e -------------
   //  -- eax    : key
   //  -- edx    : receiver
@@ -3573,8 +3552,7 @@
   // have been verified by the caller to not be a smi.
 
   // Check that the key is a smi.
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(not_zero, &miss_force_generic);
+  __ JumpIfNotSmi(ecx, &miss_force_generic);
 
   // Check that the index is in range.
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
@@ -3591,19 +3569,19 @@
   // ecx: key
   // edi: elements array
   // ebx: untagged index
-  __ test(eax, Immediate(kSmiTagMask));
-  if (array_type == kExternalPixelArray)
-    __ j(not_equal, &slow);
-  else
-    __ j(not_equal, &check_heap_number);
+  if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
+    __ JumpIfNotSmi(eax, &slow);
+  } else {
+    __ JumpIfNotSmi(eax, &check_heap_number);
+  }
 
   // smi case
   __ mov(ecx, eax);  // Preserve the value in eax.  Key is no longer needed.
   __ SmiUntag(ecx);
   __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
   // ecx: base pointer of external storage
-  switch (array_type) {
-    case kExternalPixelArray:
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       {  // Clamp the value to [0..255].
         Label done;
         __ test(ecx, Immediate(0xFFFFFF00));
@@ -3614,27 +3592,27 @@
       }
       __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
       break;
-    case kExternalByteArray:
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
       break;
-    case kExternalShortArray:
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
       break;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       __ mov(Operand(edi, ebx, times_4, 0), ecx);
       break;
-    case kExternalFloatArray:
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       // Need to perform int-to-float conversion.
       __ push(ecx);
       __ fild_s(Operand(esp, 0));
       __ pop(ecx);
-      if (array_type == kExternalFloatArray) {
+      if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
         __ fstp_s(Operand(edi, ebx, times_4, 0));
-      } else {  // array_type == kExternalDoubleArray.
+      } else {  // elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS.
         __ fstp_d(Operand(edi, ebx, times_8, 0));
       }
       break;
@@ -3645,7 +3623,7 @@
   __ ret(0);  // Return the original value.
 
   // TODO(danno): handle heap number -> pixel array conversion
-  if (array_type != kExternalPixelArray) {
+  if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     __ bind(&check_heap_number);
     // eax: value
     // edx: receiver
@@ -3662,11 +3640,11 @@
     __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
     // ebx: untagged index
     // edi: base pointer of external storage
-    if (array_type == kExternalFloatArray) {
+    if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
       __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
       __ fstp_s(Operand(edi, ebx, times_4, 0));
       __ ret(0);
-    } else if (array_type == kExternalDoubleArray) {
+    } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
       __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
       __ fstp_d(Operand(edi, ebx, times_8, 0));
       __ ret(0);
@@ -3679,14 +3657,14 @@
       // (code-stubs-ia32.cc) is roughly what is needed here though the
       // conversion failure case does not need to be handled.
       if (CpuFeatures::IsSupported(SSE2)) {
-        if (array_type != kExternalIntArray &&
-            array_type != kExternalUnsignedIntArray) {
+        if (elements_kind != JSObject::EXTERNAL_INT_ELEMENTS &&
+            elements_kind != JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
           ASSERT(CpuFeatures::IsSupported(SSE2));
           CpuFeatures::Scope scope(SSE2);
           __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
           // ecx: untagged integer value
-          switch (array_type) {
-            case kExternalPixelArray:
+          switch (elements_kind) {
+            case JSObject::EXTERNAL_PIXEL_ELEMENTS:
               {  // Clamp the value to [0..255].
                 Label done;
                 __ test(ecx, Immediate(0xFFFFFF00));
@@ -3697,12 +3675,12 @@
               }
               __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
               break;
-            case kExternalByteArray:
-            case kExternalUnsignedByteArray:
+            case JSObject::EXTERNAL_BYTE_ELEMENTS:
+            case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
               __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
               break;
-            case kExternalShortArray:
-            case kExternalUnsignedShortArray:
+            case JSObject::EXTERNAL_SHORT_ELEMENTS:
+            case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
               __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
               break;
             default:
@@ -3775,8 +3753,6 @@
 }
 
 
-
-
 void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : key
@@ -3789,8 +3765,7 @@
   // have been verified by the caller to not be a smi.
 
   // Check that the key is a smi.
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &miss_force_generic);
+  __ JumpIfNotSmi(eax, &miss_force_generic);
 
   // Get the elements array.
   __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
@@ -3815,10 +3790,76 @@
 }
 
 
+void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
+    MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label miss_force_generic, slow_allocate_heapnumber;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(eax, &miss_force_generic);
+
+  // Get the elements array.
+  __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
+  __ AssertFastElements(ecx);
+
+  // Check that the key is within bounds.
+  __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset));
+  __ j(above_equal, &miss_force_generic);
+
+  // Check for the hole
+  uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
+  __ cmp(FieldOperand(ecx, eax, times_4, offset), Immediate(kHoleNanUpper32));
+  __ j(equal, &miss_force_generic);
+
+  // Always allocate a heap number for the result.
+  if (CpuFeatures::IsSupported(SSE2)) {
+    CpuFeatures::Scope use_sse2(SSE2);
+    __ movdbl(xmm0, FieldOperand(ecx, eax, times_4,
+                                 FixedDoubleArray::kHeaderSize));
+  } else {
+    __ fld_d(FieldOperand(ecx, eax, times_4, FixedDoubleArray::kHeaderSize));
+  }
+  __ AllocateHeapNumber(ecx, ebx, edi, &slow_allocate_heapnumber);
+  // Set the value.
+  if (CpuFeatures::IsSupported(SSE2)) {
+    CpuFeatures::Scope use_sse2(SSE2);
+    __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0);
+  } else {
+    __ fstp_d(FieldOperand(ecx, HeapNumber::kValueOffset));
+  }
+  __ mov(eax, ecx);
+  __ ret(0);
+
+  __ bind(&slow_allocate_heapnumber);
+  // A value was pushed on the floating point stack before the allocation, if
+  // the allocation fails it needs to be removed.
+  if (!CpuFeatures::IsSupported(SSE2)) {
+    __ ffree();
+    __ fincstp();
+  }
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ jmp(slow_ic, RelocInfo::CODE_TARGET);
+
+  __ bind(&miss_force_generic);
+  Handle<Code> miss_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ jmp(miss_ic, RelocInfo::CODE_TARGET);
+}
+
+
 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
                                                       bool is_js_array) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- eax    : value
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3828,8 +3869,7 @@
   // have been verified by the caller to not be a smi.
 
   // Check that the key is a smi.
-  __ test(ecx, Immediate(kSmiTagMask));
-  __ j(not_zero, &miss_force_generic);
+  __ JumpIfNotSmi(ecx, &miss_force_generic);
 
   // Get the elements array and make sure it is a fast element array, not 'cow'.
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
@@ -3864,6 +3904,98 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
+    MacroAssembler* masm,
+    bool is_js_array) {
+  // ----------- S t a t e -------------
+  //  -- eax    : value
+  //  -- ecx    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label miss_force_generic, smi_value, is_nan, maybe_nan;
+  Label have_double_value, not_nan;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(ecx, &miss_force_generic);
+
+  // Get the elements array.
+  __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
+  __ AssertFastElements(edi);
+
+  if (is_js_array) {
+    // Check that the key is within bounds.
+    __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset));  // smis.
+  } else {
+    // Check that the key is within bounds.
+    __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));  // smis.
+  }
+  __ j(above_equal, &miss_force_generic);
+
+  __ JumpIfSmi(eax, &smi_value, Label::kNear);
+
+  __ CheckMap(eax,
+              masm->isolate()->factory()->heap_number_map(),
+              &miss_force_generic,
+              DONT_DO_SMI_CHECK);
+
+  // Double value, canonicalize NaN.
+  uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32);
+  __ cmp(FieldOperand(eax, offset), Immediate(kNaNOrInfinityLowerBoundUpper32));
+  __ j(greater_equal, &maybe_nan, Label::kNear);
+
+  __ bind(&not_nan);
+  ExternalReference canonical_nan_reference =
+      ExternalReference::address_of_canonical_non_hole_nan();
+  if (CpuFeatures::IsSupported(SSE2)) {
+    CpuFeatures::Scope use_sse2(SSE2);
+    __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
+    __ bind(&have_double_value);
+    __ movdbl(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize),
+              xmm0);
+    __ ret(0);
+  } else {
+    __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
+    __ bind(&have_double_value);
+    __ fstp_d(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize));
+    __ ret(0);
+  }
+
+  __ bind(&maybe_nan);
+  // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
+  // it's an Infinity, and the non-NaN code path applies.
+  __ j(greater, &is_nan, Label::kNear);
+  __ cmp(FieldOperand(eax, HeapNumber::kValueOffset), Immediate(0));
+  __ j(zero, &not_nan);
+  __ bind(&is_nan);
+  if (CpuFeatures::IsSupported(SSE2)) {
+    CpuFeatures::Scope use_sse2(SSE2);
+    __ movdbl(xmm0, Operand::StaticVariable(canonical_nan_reference));
+  } else {
+    __ fld_d(Operand::StaticVariable(canonical_nan_reference));
+  }
+  __ jmp(&have_double_value, Label::kNear);
+
+  __ bind(&smi_value);
+  // Value is a smi. convert to a double and store.
+  __ SmiUntag(eax);
+  __ push(eax);
+  __ fild_s(Operand(esp, 0));
+  __ pop(eax);
+  __ fstp_d(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize));
+  __ ret(0);
+
+  // Handle store cache miss, replacing the ic with the generic stub.
+  __ bind(&miss_force_generic);
+  Handle<Code> ic_force_generic =
+      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
+  __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/ic.cc b/src/ic.cc
index 0e87e51..f70f75a 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -578,13 +578,7 @@
         // out of bounds, update the state to record this fact.
         if (StringStubState::decode(*extra_ic_state) == DEFAULT_STRING_STUB &&
             argc >= 1 && args[1]->IsNumber()) {
-          double index;
-          if (args[1]->IsSmi()) {
-            index = Smi::cast(args[1])->value();
-          } else {
-            ASSERT(args[1]->IsHeapNumber());
-            index = DoubleToInteger(HeapNumber::cast(args[1])->value());
-          }
+          double index = DoubleToInteger(args.number_at(1));
           if (index < 0 || index >= string->length()) {
             *extra_ic_state =
                 StringStubState::update(*extra_ic_state,
@@ -799,18 +793,35 @@
     return TypeError("non_object_property_call", object, key);
   }
 
-  if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) {
+  if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
     int argc = target()->arguments_count();
     InLoopFlag in_loop = target()->ic_in_loop();
-    MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
-        argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState);
-    Object* code;
-    if (maybe_code->ToObject(&code)) {
-      set_target(Code::cast(code));
+    Heap* heap = Handle<HeapObject>::cast(object)->GetHeap();
+    Map* map = heap->non_strict_arguments_elements_map();
+    if (object->IsJSObject() &&
+        Handle<JSObject>::cast(object)->elements()->map() == map) {
+      MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments(
+          argc, in_loop, Code::KEYED_CALL_IC);
+      Object* code;
+      if (maybe_code->ToObject(&code)) {
+        set_target(Code::cast(code));
 #ifdef DEBUG
-      TraceIC(
-          "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
+        TraceIC(
+            "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
 #endif
+      }
+    } else if (FLAG_use_ic && state != MEGAMORPHIC &&
+               !object->IsAccessCheckNeeded()) {
+      MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
+          argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState);
+      Object* code;
+      if (maybe_code->ToObject(&code)) {
+        set_target(Code::cast(code));
+#ifdef DEBUG
+        TraceIC(
+            "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
+#endif
+      }
     }
   }
 
@@ -849,37 +860,40 @@
   }
 
   if (FLAG_use_ic) {
-    Code* non_monomorphic_stub =
-        (state == UNINITIALIZED) ? pre_monomorphic_stub() : megamorphic_stub();
-
     // Use specialized code for getting the length of strings and
     // string wrapper objects.  The length property of string wrapper
     // objects is read-only and therefore always returns the length of
     // the underlying string value.  See ECMA-262 15.5.5.1.
     if ((object->IsString() || object->IsStringWrapper()) &&
         name->Equals(isolate()->heap()->length_symbol())) {
-      HandleScope scope(isolate());
-#ifdef DEBUG
-      if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
-#endif
-      if (state == PREMONOMORPHIC) {
+      AssertNoAllocation no_allocation;
+      Code* stub = NULL;
+      if (state == UNINITIALIZED) {
+        stub = pre_monomorphic_stub();
+      } else if (state == PREMONOMORPHIC) {
         if (object->IsString()) {
-          set_target(isolate()->builtins()->builtin(
-              Builtins::kLoadIC_StringLength));
+          stub = isolate()->builtins()->builtin(
+              Builtins::kLoadIC_StringLength);
         } else {
-          set_target(isolate()->builtins()->builtin(
-              Builtins::kLoadIC_StringWrapperLength));
+          stub = isolate()->builtins()->builtin(
+              Builtins::kLoadIC_StringWrapperLength);
         }
       } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
-        set_target(isolate()->builtins()->builtin(
-            Builtins::kLoadIC_StringWrapperLength));
-      } else {
-        set_target(non_monomorphic_stub);
+        stub = isolate()->builtins()->builtin(
+            Builtins::kLoadIC_StringWrapperLength);
+      } else if (state != MEGAMORPHIC) {
+        stub = megamorphic_stub();
+      }
+      if (stub != NULL) {
+        set_target(stub);
+#ifdef DEBUG
+        if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
+#endif
       }
       // Get the string if we have a string wrapper object.
       if (object->IsJSValue()) {
-        object = Handle<Object>(Handle<JSValue>::cast(object)->value(),
-                                isolate());
+        return Smi::FromInt(
+            String::cast(Handle<JSValue>::cast(object)->value())->length());
       }
       return Smi::FromInt(String::cast(*object)->length());
     }
@@ -887,14 +901,21 @@
     // Use specialized code for getting the length of arrays.
     if (object->IsJSArray() &&
         name->Equals(isolate()->heap()->length_symbol())) {
+      AssertNoAllocation no_allocation;
+      Code* stub = NULL;
+      if (state == UNINITIALIZED) {
+        stub = pre_monomorphic_stub();
+      } else if (state == PREMONOMORPHIC) {
+        stub = isolate()->builtins()->builtin(
+            Builtins::kLoadIC_ArrayLength);
+      } else if (state != MEGAMORPHIC) {
+        stub = megamorphic_stub();
+      }
+      if (stub != NULL) {
+        set_target(stub);
 #ifdef DEBUG
-      if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
+        if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
 #endif
-      if (state == PREMONOMORPHIC) {
-        set_target(isolate()->builtins()->builtin(
-            Builtins::kLoadIC_ArrayLength));
-      } else {
-        set_target(non_monomorphic_stub);
       }
       return JSArray::cast(*object)->length();
     }
@@ -903,14 +924,22 @@
     if (object->IsJSFunction() &&
         name->Equals(isolate()->heap()->prototype_symbol()) &&
         JSFunction::cast(*object)->should_have_prototype()) {
+      { AssertNoAllocation no_allocation;
+        Code* stub = NULL;
+        if (state == UNINITIALIZED) {
+          stub = pre_monomorphic_stub();
+        } else if (state == PREMONOMORPHIC) {
+          stub = isolate()->builtins()->builtin(
+              Builtins::kLoadIC_FunctionPrototype);
+        } else if (state != MEGAMORPHIC) {
+          stub = megamorphic_stub();
+        }
+        if (stub != NULL) {
+          set_target(stub);
 #ifdef DEBUG
-      if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
+          if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
 #endif
-      if (state == PREMONOMORPHIC) {
-        set_target(isolate()->builtins()->builtin(
-            Builtins::kLoadIC_FunctionPrototype));
-      } else {
-        set_target(non_monomorphic_stub);
+        }
       }
       return Accessors::FunctionGetPrototype(*object, 0);
     }
@@ -927,7 +956,7 @@
 
   // If we did not find a property, check if we need to throw an exception.
   if (!lookup.IsProperty()) {
-    if (FLAG_strict || IsContextual(object)) {
+    if (IsContextual(object)) {
       return ReferenceError("not_defined", name);
     }
     LOG(isolate(), SuspectReadEvent(*name, *object));
@@ -1068,25 +1097,10 @@
 }
 
 
-String* KeyedLoadIC::GetStubNameForCache(IC::State ic_state) {
-  if (ic_state == MONOMORPHIC) {
-    return isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol();
-  } else {
-    ASSERT(ic_state == MEGAMORPHIC);
-    return isolate()->heap()->KeyedLoadSpecializedPolymorphic_symbol();
-  }
-}
-
-
-MaybeObject* KeyedLoadIC::GetFastElementStubWithoutMapCheck(
-    bool is_js_array) {
-  return KeyedLoadFastElementStub().TryGetCode();
-}
-
-
-MaybeObject* KeyedLoadIC::GetExternalArrayStubWithoutMapCheck(
-    ExternalArrayType array_type) {
-  return KeyedLoadExternalArrayStub(array_type).TryGetCode();
+MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck(
+    bool is_js_array,
+    JSObject::ElementsKind elements_kind) {
+  return KeyedLoadElementStub(elements_kind).TryGetCode();
 }
 
 
@@ -1201,10 +1215,8 @@
     LookupForRead(*object, *name, &lookup);
 
     // If we did not find a property, check if we need to throw an exception.
-    if (!lookup.IsProperty()) {
-      if (FLAG_strict || IsContextual(object)) {
-        return ReferenceError("not_defined", name);
-      }
+    if (!lookup.IsProperty() && IsContextual(object)) {
+      return ReferenceError("not_defined", name);
     }
 
     if (FLAG_use_ic) {
@@ -1243,9 +1255,13 @@
         }
       } else if (object->IsJSObject()) {
         JSObject* receiver = JSObject::cast(*object);
-        if (receiver->HasIndexedInterceptor()) {
+        Heap* heap = Handle<JSObject>::cast(object)->GetHeap();
+        Map* elements_map = Handle<JSObject>::cast(object)->elements()->map();
+        if (elements_map == heap->non_strict_arguments_elements_map()) {
+          stub = non_strict_arguments_stub();
+        } else if (receiver->HasIndexedInterceptor()) {
           stub = indexed_interceptor_stub();
-        } else if (key->IsSmi()) {
+        } else if (key->IsSmi() && (target() != non_strict_arguments_stub())) {
           MaybeObject* maybe_stub = ComputeStub(receiver,
                                                 false,
                                                 kNonStrictMode,
@@ -1355,15 +1371,16 @@
 }
 
 
-static bool LookupForWrite(JSObject* object,
+static bool LookupForWrite(JSReceiver* receiver,
                            String* name,
                            LookupResult* lookup) {
-  object->LocalLookup(name, lookup);
+  receiver->LocalLookup(name, lookup);
   if (!StoreICableLookup(lookup)) {
     return false;
   }
 
   if (lookup->type() == INTERCEPTOR) {
+    JSObject* object = JSObject::cast(receiver);
     if (object->GetNamedInterceptor()->setter()->IsUndefined()) {
       object->LocalLookupRealNamedProperty(name, lookup);
       return StoreICableLookup(lookup);
@@ -1385,7 +1402,7 @@
     return TypeError("non_object_property_store", object, name);
   }
 
-  if (!object->IsJSObject()) {
+  if (!object->IsJSReceiver()) {
     // The length property of string values is read-only. Throw in strict mode.
     if (strict_mode == kStrictMode && object->IsString() &&
         name->Equals(isolate()->heap()->length_symbol())) {
@@ -1395,6 +1412,12 @@
     return *value;
   }
 
+  // Handle proxies.
+  if (object->IsJSProxy()) {
+    return JSReceiver::cast(*object)->
+        SetProperty(*name, *value, NONE, strict_mode);
+  }
+
   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
 
   // Check if the given name is an array index.
@@ -1409,7 +1432,7 @@
   // Use specialized code for setting the length of arrays.
   if (receiver->IsJSArray()
       && name->Equals(isolate()->heap()->length_symbol())
-      && receiver->AllowsSetElementsLength()) {
+      && JSArray::cast(*receiver)->AllowsSetElementsLength()) {
 #ifdef DEBUG
     if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
 #endif
@@ -1596,18 +1619,14 @@
                                   StrictModeFlag strict_mode,
                                   Code* generic_stub) {
   State ic_state = target()->ic_state();
-  Code* monomorphic_stub;
-  // Always compute the MONOMORPHIC stub, even if the MEGAMORPHIC stub ends up
-  // being used. This is necessary because the megamorphic stub needs to have
-  // access to more information than what is stored in the receiver map in some
-  // cases (external arrays need the array type from the MONOMORPHIC stub).
-  MaybeObject* maybe_stub = ComputeMonomorphicStub(receiver,
-                                                   is_store,
-                                                   strict_mode,
-                                                   generic_stub);
-  if (!maybe_stub->To(&monomorphic_stub)) return maybe_stub;
-
   if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
+    Code* monomorphic_stub;
+    MaybeObject* maybe_stub = ComputeMonomorphicStub(receiver,
+                                                     is_store,
+                                                     strict_mode,
+                                                     generic_stub);
+    if (!maybe_stub->To(&monomorphic_stub)) return maybe_stub;
+
     return monomorphic_stub;
   }
   ASSERT(target() != generic_stub);
@@ -1629,79 +1648,40 @@
     return generic_stub;
   }
 
-  // TODO(1385): Currently MEGAMORPHIC stubs are cached in the receiver map stub
-  // cache, but that can put receiver types together from unrelated call sites
-  // into the same stub--they always handle the union of all receiver maps seen
-  // at all call sites involving the receiver map. This is only an
-  // approximation: ideally, there would be a global cache that mapped sets of
-  // receiver maps to MEGAMORPHIC stubs. The complexity of the MEGAMORPHIC stub
-  // computation also leads to direct manipulation of the stub cache from the IC
-  // code, which the global cache solution would avoid.
-  Code::Kind kind = this->kind();
-  Code::Flags flags = Code::ComputeFlags(kind,
-                                         NOT_IN_LOOP,
-                                         MEGAMORPHIC,
-                                         strict_mode);
-  String* megamorphic_name = GetStubNameForCache(MEGAMORPHIC);
-  Object* maybe_cached_stub = receiver->map()->FindInCodeCache(megamorphic_name,
-                                                               flags);
-
-  // Create a set of all receiver maps that have been seen at the IC call site
-  // and those seen by the MEGAMORPHIC cached stub, if that's the stub that's
-  // been selected.
-  MapList receiver_maps;
-  if (!maybe_cached_stub->IsUndefined()) {
-    GetReceiverMapsForStub(Code::cast(maybe_cached_stub), &receiver_maps);
-  }
-  bool added_map = false;
-  for (int i = 0; i < target_receiver_maps.length(); ++i) {
-    if (AddOneReceiverMapIfMissing(&receiver_maps,
-                                   target_receiver_maps.at(i))) {
-      added_map = true;
-    }
-  }
-  ASSERT(receiver_maps.length() > 0);
-
-  // If the maximum number of receiver maps has been exceeded, use the Generic
+  // If the maximum number of receiver maps has been exceeded, use the generic
   // version of the IC.
-  if (receiver_maps.length() > KeyedIC::kMaxKeyedPolymorphism) {
+  if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
     return generic_stub;
   }
 
-  // If no maps have been seen at the call site that aren't in the cached
-  // stub, then use it.
-  if (!added_map) {
-    ASSERT(!maybe_cached_stub->IsUndefined());
+  PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache();
+  Code::Flags flags = Code::ComputeFlags(this->kind(),
+                                         NOT_IN_LOOP,
+                                         MEGAMORPHIC,
+                                         strict_mode);
+  Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags);
+  // If there is a cached stub, use it.
+  if (!maybe_cached_stub->IsUndefined()) {
     ASSERT(maybe_cached_stub->IsCode());
     return Code::cast(maybe_cached_stub);
   }
-
-  // Lookup all of the receiver maps in the cache, they should all already
-  // have MONOMORPHIC stubs.
-  CodeList handler_ics(KeyedIC::kMaxKeyedPolymorphism);
-  for (int current = 0; current < receiver_maps.length(); ++current) {
-    Map* receiver_map(receiver_maps.at(current));
+  // Collect MONOMORPHIC stubs for all target_receiver_maps.
+  CodeList handler_ics(target_receiver_maps.length());
+  for (int i = 0; i < target_receiver_maps.length(); ++i) {
+    Map* receiver_map(target_receiver_maps.at(i));
     MaybeObject* maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck(
-        receiver_map,
-        strict_mode,
-        generic_stub);
+        receiver_map, strict_mode);
     Code* cached_stub;
-    if (!maybe_cached_stub->To(&cached_stub)) {
-      return maybe_cached_stub;
-    }
+    if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub;
     handler_ics.Add(cached_stub);
   }
-
-  Code* stub;
   // Build the MEGAMORPHIC stub.
-  maybe_stub = ConstructMegamorphicStub(&receiver_maps,
-                                        &handler_ics,
-                                        strict_mode);
+  Code* stub;
+  MaybeObject* maybe_stub = ConstructMegamorphicStub(&target_receiver_maps,
+                                                     &handler_ics,
+                                                     strict_mode);
   if (!maybe_stub->To(&stub)) return maybe_stub;
-
-  MaybeObject* maybe_update = receiver->UpdateMapCodeCache(
-      megamorphic_name,
-      stub);
+  MaybeObject* maybe_update = cache->Update(&target_receiver_maps, flags, stub);
   if (maybe_update->IsFailure()) return maybe_update;
   return stub;
 }
@@ -1709,33 +1689,18 @@
 
 MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
     Map* receiver_map,
-    StrictModeFlag strict_mode,
-    Code* generic_stub) {
+    StrictModeFlag strict_mode) {
   if ((receiver_map->instance_type() & kNotStringTag) == 0) {
     ASSERT(string_stub() != NULL);
     return string_stub();
-  } else if (receiver_map->has_external_array_elements()) {
-    // Determine the array type from the default MONOMORPHIC already generated
-    // stub. There is no other way to determine the type of the external array
-    // directly from the receiver type.
-    Code::Kind kind = this->kind();
-    Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
-                                                      NORMAL,
-                                                      strict_mode);
-    String* monomorphic_name = GetStubNameForCache(MONOMORPHIC);
-    Object* maybe_default_stub = receiver_map->FindInCodeCache(monomorphic_name,
-                                                               flags);
-    if (maybe_default_stub->IsUndefined()) {
-      return generic_stub;
-    }
-    Code* default_stub = Code::cast(maybe_default_stub);
-    return GetExternalArrayStubWithoutMapCheck(
-        default_stub->external_array_type());
-  } else if (receiver_map->has_fast_elements()) {
-    bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
-    return GetFastElementStubWithoutMapCheck(is_js_array);
   } else {
-    return generic_stub;
+    ASSERT(receiver_map->has_dictionary_elements() ||
+           receiver_map->has_fast_elements() ||
+           receiver_map->has_fast_double_elements() ||
+           receiver_map->has_external_array_elements());
+    bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
+    return GetElementStubWithoutMapCheck(is_js_array,
+                                         receiver_map->elements_kind());
   }
 }
 
@@ -1745,14 +1710,12 @@
                                              StrictModeFlag strict_mode,
                                              Code* generic_stub) {
   Code* result = NULL;
-  if (receiver->HasExternalArrayElements()) {
+  if (receiver->HasFastElements() ||
+      receiver->HasExternalArrayElements() ||
+      receiver->HasFastDoubleElements() ||
+      receiver->HasDictionaryElements()) {
     MaybeObject* maybe_stub =
-        isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray(
-            receiver, is_store, strict_mode);
-    if (!maybe_stub->To(&result)) return maybe_stub;
-  } else if (receiver->map()->has_fast_elements()) {
-    MaybeObject* maybe_stub =
-        isolate()->stub_cache()->ComputeKeyedLoadOrStoreFastElement(
+        isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
             receiver, is_store, strict_mode);
     if (!maybe_stub->To(&result)) return maybe_stub;
   } else {
@@ -1762,25 +1725,10 @@
 }
 
 
-String* KeyedStoreIC::GetStubNameForCache(IC::State ic_state) {
-  if (ic_state == MONOMORPHIC) {
-    return isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol();
-  } else {
-    ASSERT(ic_state == MEGAMORPHIC);
-    return isolate()->heap()->KeyedStoreSpecializedPolymorphic_symbol();
-  }
-}
-
-
-MaybeObject* KeyedStoreIC::GetFastElementStubWithoutMapCheck(
-    bool is_js_array) {
-  return KeyedStoreFastElementStub(is_js_array).TryGetCode();
-}
-
-
-MaybeObject* KeyedStoreIC::GetExternalArrayStubWithoutMapCheck(
-    ExternalArrayType array_type) {
-  return KeyedStoreExternalArrayStub(array_type).TryGetCode();
+MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck(
+    bool is_js_array,
+    JSObject::ElementsKind elements_kind) {
+  return KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
 }
 
 
@@ -1851,15 +1799,22 @@
     Code* stub = (strict_mode == kStrictMode)
         ? generic_stub_strict()
         : generic_stub();
-    if (!force_generic) {
-      if (object->IsJSObject() && key->IsSmi()) {
-        JSObject* receiver = JSObject::cast(*object);
-        MaybeObject* maybe_stub = ComputeStub(receiver,
-                                              true,
-                                              strict_mode,
-                                              stub);
-        stub = maybe_stub->IsFailure() ?
-            NULL : Code::cast(maybe_stub->ToObjectUnchecked());
+    if (object->IsJSObject()) {
+      JSObject* receiver = JSObject::cast(*object);
+      Heap* heap = Handle<JSObject>::cast(object)->GetHeap();
+      Map* elements_map = Handle<JSObject>::cast(object)->elements()->map();
+      if (elements_map == heap->non_strict_arguments_elements_map()) {
+        stub = non_strict_arguments_stub();
+      } else if (!force_generic) {
+        if (key->IsSmi() && (target() != non_strict_arguments_stub())) {
+          HandleScope scope(isolate());
+          MaybeObject* maybe_stub = ComputeStub(receiver,
+                                                true,
+                                                strict_mode,
+                                                stub);
+          stub = maybe_stub->IsFailure() ?
+              NULL : Code::cast(maybe_stub->ToObjectUnchecked());
+        }
       }
     }
     if (stub != NULL) set_target(stub);
@@ -2325,25 +2280,21 @@
 }
 
 
-// defined in code-stubs-<arch>.cc
-// Only needed to remove dependency of ic.cc on code-stubs-<arch>.h.
-Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info);
-
-
 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
   ASSERT(args.length() == 4);
 
   HandleScope scope(isolate);
   Handle<Object> operand = args.at<Object>(0);
-  int key = Smi::cast(args[1])->value();
-  Token::Value op = static_cast<Token::Value>(Smi::cast(args[2])->value());
+  Token::Value op = static_cast<Token::Value>(args.smi_at(1));
+  UnaryOverwriteMode mode = static_cast<UnaryOverwriteMode>(args.smi_at(2));
   UnaryOpIC::TypeInfo previous_type =
-      static_cast<UnaryOpIC::TypeInfo>(Smi::cast(args[3])->value());
+      static_cast<UnaryOpIC::TypeInfo>(args.smi_at(3));
 
   UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand);
   type = UnaryOpIC::ComputeNewType(type, previous_type);
 
-  Handle<Code> code = GetUnaryOpStub(key, type);
+  UnaryOpStub stub(op, mode, type);
+  Handle<Code> code = stub.GetCode();
   if (!code.is_null()) {
     if (FLAG_trace_ic) {
       PrintF("[UnaryOpIC (%s->%s)#%s]\n",
@@ -2380,23 +2331,16 @@
   return *result;
 }
 
-// defined in code-stubs-<arch>.cc
-// Only needed to remove dependency of ic.cc on code-stubs-<arch>.h.
-Handle<Code> GetBinaryOpStub(int key,
-                             BinaryOpIC::TypeInfo type_info,
-                             BinaryOpIC::TypeInfo result_type);
-
-
 RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
   ASSERT(args.length() == 5);
 
   HandleScope scope(isolate);
   Handle<Object> left = args.at<Object>(0);
   Handle<Object> right = args.at<Object>(1);
-  int key = Smi::cast(args[2])->value();
-  Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value());
+  int key = args.smi_at(2);
+  Token::Value op = static_cast<Token::Value>(args.smi_at(3));
   BinaryOpIC::TypeInfo previous_type =
-      static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[4])->value());
+      static_cast<BinaryOpIC::TypeInfo>(args.smi_at(4));
 
   BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(left, right);
   type = BinaryOpIC::JoinTypes(type, previous_type);
@@ -2425,7 +2369,8 @@
     result_type = BinaryOpIC::HEAP_NUMBER;
   }
 
-  Handle<Code> code = GetBinaryOpStub(key, type, result_type);
+  BinaryOpStub stub(key, type, result_type);
+  Handle<Code> code = stub.GetCode();
   if (!code.is_null()) {
     if (FLAG_trace_ic) {
       PrintF("[BinaryOpIC (%s->(%s->%s))#%s]\n",
@@ -2555,7 +2500,7 @@
 RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
   NoHandleAllocation na;
   ASSERT(args.length() == 3);
-  CompareIC ic(isolate, static_cast<Token::Value>(Smi::cast(args[2])->value()));
+  CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2)));
   ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
   return ic.target();
 }
diff --git a/src/ic.h b/src/ic.h
index 25d0986..11c2e3a 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -66,7 +66,6 @@
 //
 class IC {
  public:
-
   // The ids for utility called from the generated code.
   enum UtilityId {
   #define CONST_NAME(name) k##name,
@@ -284,6 +283,7 @@
   static void GenerateMiss(MacroAssembler* masm, int argc);
   static void GenerateMegamorphic(MacroAssembler* masm, int argc);
   static void GenerateNormal(MacroAssembler* masm, int argc);
+  static void GenerateNonStrictArguments(MacroAssembler* masm, int argc);
 };
 
 
@@ -345,13 +345,9 @@
   explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
   virtual ~KeyedIC() {}
 
-  static const int kMaxKeyedPolymorphism = 4;
-
-  virtual MaybeObject* GetFastElementStubWithoutMapCheck(
-      bool is_js_array) = 0;
-
-  virtual MaybeObject* GetExternalArrayStubWithoutMapCheck(
-      ExternalArrayType array_type) = 0;
+  virtual MaybeObject* GetElementStubWithoutMapCheck(
+      bool is_js_array,
+      JSObject::ElementsKind elements_kind) = 0;
 
  protected:
   virtual Code* string_stub() {
@@ -360,8 +356,6 @@
 
   virtual Code::Kind kind() const = 0;
 
-  virtual String* GetStubNameForCache(IC::State ic_state) = 0;
-
   MaybeObject* ComputeStub(JSObject* receiver,
                            bool is_store,
                            StrictModeFlag strict_mode,
@@ -377,8 +371,7 @@
 
   MaybeObject* ComputeMonomorphicStubWithoutMapCheck(
       Map* receiver_map,
-      StrictModeFlag strict_mode,
-      Code* generic_stub);
+      StrictModeFlag strict_mode);
 
   MaybeObject* ComputeMonomorphicStub(JSObject* receiver,
                                       bool is_store,
@@ -409,8 +402,8 @@
   }
   static void GenerateGeneric(MacroAssembler* masm);
   static void GenerateString(MacroAssembler* masm);
-
   static void GenerateIndexedInterceptor(MacroAssembler* masm);
+  static void GenerateNonStrictArguments(MacroAssembler* masm);
 
   // Bit mask to be tested against bit field for the cases when
   // generic stub should go into slow case.
@@ -419,17 +412,13 @@
   static const int kSlowCaseBitFieldMask =
       (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
 
-  virtual MaybeObject* GetFastElementStubWithoutMapCheck(
-      bool is_js_array);
-
-  virtual MaybeObject* GetExternalArrayStubWithoutMapCheck(
-      ExternalArrayType array_type);
+  virtual MaybeObject* GetElementStubWithoutMapCheck(
+      bool is_js_array,
+      JSObject::ElementsKind elements_kind);
 
  protected:
   virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
 
-  virtual String* GetStubNameForCache(IC::State ic_state);
-
   virtual MaybeObject* ConstructMegamorphicStub(
       MapList* receiver_maps,
       CodeList* targets,
@@ -468,6 +457,10 @@
     return isolate()->builtins()->builtin(
         Builtins::kKeyedLoadIC_IndexedInterceptor);
   }
+  Code* non_strict_arguments_stub() {
+    return isolate()->builtins()->builtin(
+        Builtins::kKeyedLoadIC_NonStrictArguments);
+  }
 
   static void Clear(Address address, Code* target);
 
@@ -568,18 +561,15 @@
   static void GenerateRuntimeSetProperty(MacroAssembler* masm,
                                          StrictModeFlag strict_mode);
   static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
+  static void GenerateNonStrictArguments(MacroAssembler* masm);
 
-  virtual MaybeObject* GetFastElementStubWithoutMapCheck(
-      bool is_js_array);
-
-  virtual MaybeObject* GetExternalArrayStubWithoutMapCheck(
-      ExternalArrayType array_type);
+  virtual MaybeObject* GetElementStubWithoutMapCheck(
+      bool is_js_array,
+      JSObject::ElementsKind elements_kind);
 
  protected:
   virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
 
-  virtual String* GetStubNameForCache(IC::State ic_state);
-
   virtual MaybeObject* ConstructMegamorphicStub(
       MapList* receiver_maps,
       CodeList* targets,
@@ -626,6 +616,10 @@
     return isolate()->builtins()->builtin(
         Builtins::kKeyedStoreIC_Generic_Strict);
   }
+  Code* non_strict_arguments_stub() {
+    return isolate()->builtins()->builtin(
+        Builtins::kKeyedStoreIC_NonStrictArguments);
+  }
 
   static void Clear(Address address, Code* target);
 
@@ -635,7 +629,6 @@
 
 class UnaryOpIC: public IC {
  public:
-
   // sorted: increasingly more unspecific (ignoring UNINITIALIZED)
   // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead.
   enum TypeInfo {
@@ -662,7 +655,6 @@
 // Type Recording BinaryOpIC, that records the types of the inputs and outputs.
 class BinaryOpIC: public IC {
  public:
-
   enum TypeInfo {
     UNINITIALIZED,
     SMI,
diff --git a/src/isolate.cc b/src/isolate.cc
index a7bf7d9..8a30e79 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -85,13 +85,9 @@
 #ifdef USE_SIMULATOR
   simulator_ = NULL;
 #endif
-#ifdef ENABLE_LOGGING_AND_PROFILING
   js_entry_sp_ = NULL;
   external_callback_ = NULL;
-#endif
-#ifdef ENABLE_VMSTATE_TRACKING
   current_vm_state_ = EXTERNAL;
-#endif
   try_catch_handler_address_ = NULL;
   context_ = NULL;
   thread_id_ = ThreadId::Invalid();
@@ -190,8 +186,8 @@
 
 
  private:
-  explicit PreallocatedMemoryThread(Isolate* isolate)
-      : Thread(isolate, "v8:PreallocMem"),
+  PreallocatedMemoryThread()
+      : Thread("v8:PreallocMem"),
         keep_running_(true),
         wait_for_ever_semaphore_(OS::CreateSemaphore(0)),
         data_ready_semaphore_(OS::CreateSemaphore(0)),
@@ -219,7 +215,7 @@
 
 void Isolate::PreallocatedMemoryThreadStart() {
   if (preallocated_memory_thread_ != NULL) return;
-  preallocated_memory_thread_ = new PreallocatedMemoryThread(this);
+  preallocated_memory_thread_ = new PreallocatedMemoryThread();
   preallocated_memory_thread_->Start();
 }
 
@@ -1304,6 +1300,7 @@
   if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
     RuntimeProfiler::IsolateEnteredJS(this);
   }
+  ASSERT(context() == NULL || context()->IsContext());
   return from + sizeof(ThreadLocalTop);
 }
 
@@ -1346,6 +1343,16 @@
 }
 
 
+void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
+  PerIsolateThreadData* data = list_;
+  while (data != NULL) {
+    PerIsolateThreadData* next = data->next_;
+    if (data->isolate() == isolate) Remove(data);
+    data = next;
+  }
+}
+
+
 #ifdef DEBUG
 #define TRACE_ISOLATE(tag)                                              \
   do {                                                                  \
@@ -1396,8 +1403,6 @@
       ast_sentinels_(NULL),
       string_tracker_(NULL),
       regexp_stack_(NULL),
-      frame_element_constant_list_(0),
-      result_constant_list_(0),
       embedder_data_(NULL) {
   TRACE_ISOLATE(constructor);
 
@@ -1432,10 +1437,6 @@
   debugger_ = NULL;
 #endif
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  producer_heap_profile_ = NULL;
-#endif
-
   handle_scope_data_.Initialize();
 
 #define ISOLATE_INIT_EXECUTE(type, name, initial_value)                        \
@@ -1462,6 +1463,10 @@
 
   Deinit();
 
+  { ScopedLock lock(process_wide_mutex_);
+    thread_data_table_->RemoveAllThreads(this);
+  }
+
   if (!IsDefaultIsolate()) {
     delete this;
   }
@@ -1520,11 +1525,6 @@
 Isolate::~Isolate() {
   TRACE_ISOLATE(destructor);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  delete producer_heap_profile_;
-  producer_heap_profile_ = NULL;
-#endif
-
   delete unicode_cache_;
   unicode_cache_ = NULL;
 
@@ -1600,8 +1600,7 @@
   ASSERT(Isolate::Current() == this);
 #ifdef ENABLE_DEBUGGER_SUPPORT
   debug_ = new Debug(this);
-  debugger_ = new Debugger();
-  debugger_->isolate_ = this;
+  debugger_ = new Debugger(this);
 #endif
 
   memory_allocator_ = new MemoryAllocator();
@@ -1620,7 +1619,6 @@
 #define C(name) isolate_addresses_[Isolate::k_##name] =                        \
     reinterpret_cast<Address>(name());
   ISOLATE_ADDRESS_LIST(C)
-  ISOLATE_ADDRESS_LIST_PROF(C)
 #undef C
 
   string_tracker_ = new StringTracker();
@@ -1641,11 +1639,6 @@
   regexp_stack_ = new RegExpStack();
   regexp_stack_->isolate_ = this;
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  producer_heap_profile_ = new ProducerHeapProfile();
-  producer_heap_profile_->isolate_ = this;
-#endif
-
   state_ = PREINITIALIZED;
   return true;
 }
@@ -1729,11 +1722,11 @@
     return false;
   }
 
+  InitializeThreadLocal();
+
   bootstrapper_->Initialize(create_heap_objects);
   builtins_.Setup(create_heap_objects);
 
-  InitializeThreadLocal();
-
   // Only preallocate on the first initialization.
   if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) {
     // Start the thread which will set aside some memory.
@@ -1853,11 +1846,6 @@
 }
 
 
-void Isolate::ResetEagerOptimizingData() {
-  compilation_cache_->ResetEagerOptimizingData();
-}
-
-
 #ifdef DEBUG
 #define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
diff --git a/src/isolate.h b/src/isolate.h
index 0d36b3f..f2281aa 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -69,7 +69,6 @@
 class NoAllocationStringAllocator;
 class PcToCodeCache;
 class PreallocatedMemoryThread;
-class ProducerHeapProfile;
 class RegExpStack;
 class SaveContext;
 class UnicodeCache;
@@ -126,14 +125,8 @@
   C(c_entry_fp_address)                    \
   C(context_address)                       \
   C(pending_exception_address)             \
-  C(external_caught_exception_address)
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-#define ISOLATE_ADDRESS_LIST_PROF(C)       \
+  C(external_caught_exception_address)     \
   C(js_entry_sp_address)
-#else
-#define ISOLATE_ADDRESS_LIST_PROF(C)
-#endif
 
 
 // Platform-independent, reliable thread identifier.
@@ -253,14 +246,9 @@
 #endif
 #endif  // USE_SIMULATOR
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Address js_entry_sp_;  // the stack pointer of the bottom js entry frame
   Address external_callback_;  // the external callback we're currently in
-#endif
-
-#ifdef ENABLE_VMSTATE_TRACKING
   StateTag current_vm_state_;
-#endif
 
   // Generated code scratch locations.
   int32_t formal_count_;
@@ -314,18 +302,6 @@
 
 #endif
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-#define ISOLATE_LOGGING_INIT_LIST(V)                                           \
-  V(CpuProfiler*, cpu_profiler, NULL)                                          \
-  V(HeapProfiler*, heap_profiler, NULL)
-
-#else
-
-#define ISOLATE_LOGGING_INIT_LIST(V)
-
-#endif
-
 #define ISOLATE_INIT_ARRAY_LIST(V)                                             \
   /* SerializerDeserializer state. */                                          \
   V(Object*, serialize_partial_snapshot_cache, kPartialSnapshotCacheCapacity)  \
@@ -333,6 +309,8 @@
   V(int, bad_char_shift_table, kUC16AlphabetSize)                              \
   V(int, good_suffix_shift_table, (kBMMaxShift + 1))                           \
   V(int, suffix_table, (kBMMaxShift + 1))                                      \
+  V(uint32_t, random_seed, 2)                                                  \
+  V(uint32_t, private_random_seed, 2)                                          \
   ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
 
 typedef List<HeapObject*, PreallocatedStorage> DebugObjectCache;
@@ -372,8 +350,9 @@
   /* SafeStackFrameIterator activations count. */                              \
   V(int, safe_stack_iterator_counter, 0)                                       \
   V(uint64_t, enabled_cpu_features, 0)                                         \
+  V(CpuProfiler*, cpu_profiler, NULL)                                          \
+  V(HeapProfiler*, heap_profiler, NULL)                                        \
   ISOLATE_PLATFORM_INIT_LIST(V)                                                \
-  ISOLATE_LOGGING_INIT_LIST(V)                                                 \
   ISOLATE_DEBUGGER_INIT_LIST(V)
 
 class Isolate {
@@ -444,7 +423,6 @@
   enum AddressId {
 #define C(name) k_##name,
     ISOLATE_ADDRESS_LIST(C)
-    ISOLATE_ADDRESS_LIST_PROF(C)
 #undef C
     k_isolate_address_count
   };
@@ -529,6 +507,7 @@
   // Access to top context (where the current function object was created).
   Context* context() { return thread_local_top_.context_; }
   void set_context(Context* context) {
+    ASSERT(context == NULL || context->IsContext());
     thread_local_top_.context_ = context;
   }
   Context** context_address() { return &thread_local_top_.context_; }
@@ -594,7 +573,7 @@
     return thread_local_top_.scheduled_exception_;
   }
   bool has_scheduled_exception() {
-    return !thread_local_top_.scheduled_exception_->IsTheHole();
+    return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
   }
   void clear_scheduled_exception() {
     thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
@@ -618,7 +597,6 @@
   }
   inline Address* handler_address() { return &thread_local_top_.handler_; }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Bottom JS entry (see StackTracer::Trace in log.cc).
   static Address js_entry_sp(ThreadLocalTop* thread) {
     return thread->js_entry_sp_;
@@ -626,7 +604,6 @@
   inline Address* js_entry_sp_address() {
     return &thread_local_top_.js_entry_sp_;
   }
-#endif
 
   // Generated code scratch locations.
   void* formal_count_address() { return &thread_local_top_.formal_count_; }
@@ -895,14 +872,6 @@
     return &interp_canonicalize_mapping_;
   }
 
-  ZoneObjectList* frame_element_constant_list() {
-    return &frame_element_constant_list_;
-  }
-
-  ZoneObjectList* result_constant_list() {
-    return &result_constant_list_;
-  }
-
   void* PreallocatedStorageNew(size_t size);
   void PreallocatedStorageDelete(void* p);
   void PreallocatedStorageInit(size_t size);
@@ -914,12 +883,6 @@
 
   inline bool DebuggerHasBreakPoints();
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  ProducerHeapProfile* producer_heap_profile() {
-    return producer_heap_profile_;
-  }
-#endif
-
 #ifdef DEBUG
   HistogramInfo* heap_histograms() { return heap_histograms_; }
 
@@ -957,22 +920,21 @@
 
   static const int kJSRegexpStaticOffsetsVectorSize = 50;
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Address external_callback() {
     return thread_local_top_.external_callback_;
   }
   void set_external_callback(Address callback) {
     thread_local_top_.external_callback_ = callback;
   }
-#endif
 
-#ifdef ENABLE_VMSTATE_TRACKING
   StateTag current_vm_state() {
     return thread_local_top_.current_vm_state_;
   }
 
   void SetCurrentVMState(StateTag state) {
     if (RuntimeProfiler::IsEnabled()) {
+      // Make sure thread local top is initialized.
+      ASSERT(thread_local_top_.isolate_ == this);
       StateTag current_state = thread_local_top_.current_vm_state_;
       if (current_state != JS && state == JS) {
         // Non-JS -> JS transition.
@@ -990,9 +952,6 @@
     }
     thread_local_top_.current_vm_state_ = state;
   }
-#endif
-
-  void ResetEagerOptimizingData();
 
   void SetData(void* data) { embedder_data_ = data; }
   void* GetData() { return embedder_data_; }
@@ -1011,6 +970,7 @@
     void Insert(PerIsolateThreadData* data);
     void Remove(Isolate* isolate, ThreadId thread_id);
     void Remove(PerIsolateThreadData* data);
+    void RemoveAllThreads(Isolate* isolate);
 
    private:
     PerIsolateThreadData* list_;
@@ -1157,8 +1117,6 @@
       regexp_macro_assembler_canonicalize_;
   RegExpStack* regexp_stack_;
   unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
-  ZoneObjectList frame_element_constant_list_;
-  ZoneObjectList result_constant_list_;
   void* embedder_data_;
 
 #if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
@@ -1180,10 +1138,6 @@
   Debug* debug_;
 #endif
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  ProducerHeapProfile* producer_heap_profile_;
-#endif
-
 #define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
   type name##_;
   ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
@@ -1373,10 +1327,4 @@
 
 } }  // namespace v8::internal
 
-// TODO(isolates): Get rid of these -inl.h includes and place them only where
-//                 they're needed.
-#include "allocation-inl.h"
-#include "zone-inl.h"
-#include "frames-inl.h"
-
 #endif  // V8_ISOLATE_H_
diff --git a/src/json-parser.cc b/src/json-parser.cc
deleted file mode 100644
index b7f57c2..0000000
--- a/src/json-parser.cc
+++ /dev/null
@@ -1,513 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "v8.h"
-
-#include "char-predicates-inl.h"
-#include "conversions.h"
-#include "json-parser.h"
-#include "messages.h"
-#include "spaces.h"
-
-namespace v8 {
-namespace internal {
-
-
-Handle<Object> JsonParser::ParseJson(Handle<String> source) {
-  isolate_ = source->map()->isolate();
-  source_ = Handle<String>(source->TryFlattenGetString());
-  source_length_ = source_->length() - 1;
-
-  // Optimized fast case where we only have ascii characters.
-  if (source_->IsSeqAsciiString()) {
-      is_sequential_ascii_ = true;
-      seq_source_ = Handle<SeqAsciiString>::cast(source_);
-  } else {
-    is_sequential_ascii_ = false;
-  }
-
-  // Set initial position right before the string.
-  position_ = -1;
-  // Advance to the first character (posibly EOS)
-  Advance();
-  Next();
-  Handle<Object> result = ParseJsonValue();
-  if (result.is_null() || Next() != Token::EOS) {
-    // Parse failed. Scanner's current token is the unexpected token.
-    Token::Value token = current_.token;
-
-    const char* message;
-    const char* name_opt = NULL;
-
-    switch (token) {
-      case Token::EOS:
-        message = "unexpected_eos";
-        break;
-      case Token::NUMBER:
-        message = "unexpected_token_number";
-        break;
-      case Token::STRING:
-        message = "unexpected_token_string";
-        break;
-      case Token::IDENTIFIER:
-      case Token::FUTURE_RESERVED_WORD:
-        message = "unexpected_token_identifier";
-        break;
-      default:
-        message = "unexpected_token";
-        name_opt = Token::String(token);
-        ASSERT(name_opt != NULL);
-        break;
-    }
-
-    Factory* factory = isolate()->factory();
-    MessageLocation location(factory->NewScript(source),
-                             current_.beg_pos,
-                             current_.end_pos);
-    Handle<JSArray> array;
-    if (name_opt == NULL) {
-      array = factory->NewJSArray(0);
-    } else {
-      Handle<String> name = factory->NewStringFromUtf8(CStrVector(name_opt));
-      Handle<FixedArray> element = factory->NewFixedArray(1);
-      element->set(0, *name);
-      array = factory->NewJSArrayWithElements(element);
-    }
-    Handle<Object> result = factory->NewSyntaxError(message, array);
-    isolate()->Throw(*result, &location);
-    return Handle<Object>::null();
-  }
-  return result;
-}
-
-
-// Parse any JSON value.
-Handle<Object> JsonParser::ParseJsonValue() {
-  Token::Value token = Next();
-  switch (token) {
-    case Token::STRING:
-      return GetString(false);
-    case Token::NUMBER:
-      return isolate()->factory()->NewNumber(number_);
-    case Token::FALSE_LITERAL:
-      return isolate()->factory()->false_value();
-    case Token::TRUE_LITERAL:
-      return isolate()->factory()->true_value();
-    case Token::NULL_LITERAL:
-      return isolate()->factory()->null_value();
-    case Token::LBRACE:
-      return ParseJsonObject();
-    case Token::LBRACK:
-      return ParseJsonArray();
-    default:
-      return ReportUnexpectedToken();
-  }
-}
-
-
-// Parse a JSON object. Scanner must be right after '{' token.
-Handle<Object> JsonParser::ParseJsonObject() {
-  Handle<JSFunction> object_constructor(
-      isolate()->global_context()->object_function());
-  Handle<JSObject> json_object =
-      isolate()->factory()->NewJSObject(object_constructor);
-
-  if (Peek() == Token::RBRACE) {
-    Next();
-  } else {
-    do {
-      if (Next() != Token::STRING) {
-        return ReportUnexpectedToken();
-      }
-      Handle<String> key = GetString(true);
-      if (Next() != Token::COLON) {
-        return ReportUnexpectedToken();
-      }
-
-      Handle<Object> value = ParseJsonValue();
-      if (value.is_null()) return Handle<Object>::null();
-
-      uint32_t index;
-      if (key->AsArrayIndex(&index)) {
-        SetOwnElement(json_object, index, value, kNonStrictMode);
-      } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
-        SetPrototype(json_object, value);
-      } else {
-        SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
-      }
-    } while (Next() == Token::COMMA);
-    if (current_.token != Token::RBRACE) {
-      return ReportUnexpectedToken();
-    }
-  }
-  return json_object;
-}
-
-// Parse a JSON array. Scanner must be right after '[' token.
-Handle<Object> JsonParser::ParseJsonArray() {
-  ZoneScope zone_scope(isolate(), DELETE_ON_EXIT);
-  ZoneList<Handle<Object> > elements(4);
-
-  Token::Value token = Peek();
-  if (token == Token::RBRACK) {
-    Next();
-  } else {
-    do {
-      Handle<Object> element = ParseJsonValue();
-      if (element.is_null()) return Handle<Object>::null();
-      elements.Add(element);
-      token = Next();
-    } while (token == Token::COMMA);
-    if (token != Token::RBRACK) {
-      return ReportUnexpectedToken();
-    }
-  }
-
-  // Allocate a fixed array with all the elements.
-  Handle<FixedArray> fast_elements =
-      isolate()->factory()->NewFixedArray(elements.length());
-
-  for (int i = 0, n = elements.length(); i < n; i++) {
-    fast_elements->set(i, *elements[i]);
-  }
-
-  return isolate()->factory()->NewJSArrayWithElements(fast_elements);
-}
-
-
-Token::Value JsonParser::Next() {
-  current_ = next_;
-  ScanJson();
-  return current_.token;
-}
-
-void JsonParser::ScanJson() {
-  if (source_->IsSeqAsciiString()) {
-    is_sequential_ascii_ = true;
-  } else {
-    is_sequential_ascii_ = false;
-  }
-
-  Token::Value token;
-  do {
-    // Remember the position of the next token
-    next_.beg_pos = position_;
-    switch (c0_) {
-      case '\t':
-      case '\r':
-      case '\n':
-      case ' ':
-        Advance();
-        token = Token::WHITESPACE;
-        break;
-      case '{':
-        Advance();
-        token = Token::LBRACE;
-        break;
-      case '}':
-        Advance();
-        token = Token::RBRACE;
-        break;
-      case '[':
-        Advance();
-        token = Token::LBRACK;
-        break;
-      case ']':
-        Advance();
-        token = Token::RBRACK;
-        break;
-      case ':':
-        Advance();
-        token = Token::COLON;
-        break;
-      case ',':
-        Advance();
-        token = Token::COMMA;
-        break;
-      case '"':
-        token = ScanJsonString();
-        break;
-      case '-':
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9':
-        token = ScanJsonNumber();
-        break;
-      case 't':
-        token = ScanJsonIdentifier("true", Token::TRUE_LITERAL);
-        break;
-      case 'f':
-        token = ScanJsonIdentifier("false", Token::FALSE_LITERAL);
-        break;
-      case 'n':
-        token = ScanJsonIdentifier("null", Token::NULL_LITERAL);
-        break;
-      default:
-        if (c0_ < 0) {
-          Advance();
-          token = Token::EOS;
-        } else {
-          Advance();
-          token = Token::ILLEGAL;
-        }
-    }
-  } while (token == Token::WHITESPACE);
-
-  next_.end_pos = position_;
-  next_.token = token;
-}
-
-
-Token::Value JsonParser::ScanJsonIdentifier(const char* text,
-                                            Token::Value token) {
-  while (*text != '\0') {
-    if (c0_ != *text) return Token::ILLEGAL;
-    Advance();
-    text++;
-  }
-  return token;
-}
-
-
-Token::Value JsonParser::ScanJsonNumber() {
-  bool negative = false;
-
-  if (c0_ == '-') {
-    Advance();
-    negative = true;
-  }
-  if (c0_ == '0') {
-    Advance();
-    // Prefix zero is only allowed if it's the only digit before
-    // a decimal point or exponent.
-    if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL;
-  } else {
-    int i = 0;
-    int digits = 0;
-    if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL;
-    do {
-      i = i * 10 + c0_ - '0';
-      digits++;
-      Advance();
-    } while (c0_ >= '0' && c0_ <= '9');
-    if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
-      number_ = (negative ? -i : i);
-      return Token::NUMBER;
-    }
-  }
-  if (c0_ == '.') {
-    Advance();
-    if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL;
-    do {
-      Advance();
-    } while (c0_ >= '0' && c0_ <= '9');
-  }
-  if (AsciiAlphaToLower(c0_) == 'e') {
-    Advance();
-    if (c0_ == '-' || c0_ == '+') Advance();
-    if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL;
-    do {
-      Advance();
-    } while (c0_ >= '0' && c0_ <= '9');
-  }
-  if (is_sequential_ascii_) {
-    Vector<const char> chars(seq_source_->GetChars() +  next_.beg_pos,
-                             position_ - next_.beg_pos);
-    number_ = StringToDouble(isolate()->unicode_cache(),
-                             chars,
-                             NO_FLAGS,  // Hex, octal or trailing junk.
-                             OS::nan_value());
-  } else {
-    Vector<char> buffer = Vector<char>::New(position_ - next_.beg_pos);
-    String::WriteToFlat(*source_, buffer.start(), next_.beg_pos, position_);
-    Vector<const char> result =
-        Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
-        position_ - next_.beg_pos);
-    number_ = StringToDouble(isolate()->unicode_cache(),
-                             result,
-                             NO_FLAGS,  // Hex, octal or trailing junk.
-                             0.0);
-    buffer.Dispose();
-  }
-  return Token::NUMBER;
-}
-
-Token::Value JsonParser::SlowScanJsonString() {
-  // The currently scanned ascii characters.
-  Handle<String> ascii(isolate()->factory()->NewSubString(source_,
-                                                          next_.beg_pos + 1,
-                                                          position_));
-  Handle<String> two_byte =
-      isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize,
-                                                NOT_TENURED);
-  Handle<SeqTwoByteString> seq_two_byte =
-      Handle<SeqTwoByteString>::cast(two_byte);
-
-  int allocation_count = 1;
-  int count = 0;
-
-  while (c0_ != '"') {
-    // Create new seq string
-    if (count >= kInitialSpecialStringSize * allocation_count) {
-      allocation_count = allocation_count * 2;
-      int new_size = allocation_count * kInitialSpecialStringSize;
-      Handle<String> new_two_byte =
-          isolate()->factory()->NewRawTwoByteString(new_size,
-                                                    NOT_TENURED);
-      uc16* char_start =
-          Handle<SeqTwoByteString>::cast(new_two_byte)->GetChars();
-      String::WriteToFlat(*seq_two_byte, char_start, 0, count);
-      seq_two_byte = Handle<SeqTwoByteString>::cast(new_two_byte);
-    }
-
-    // Check for control character (0x00-0x1f) or unterminated string (<0).
-    if (c0_ < 0x20) return Token::ILLEGAL;
-    if (c0_ != '\\') {
-      seq_two_byte->SeqTwoByteStringSet(count++, c0_);
-      Advance();
-    } else {
-      Advance();
-      switch (c0_) {
-        case '"':
-        case '\\':
-        case '/':
-          seq_two_byte->SeqTwoByteStringSet(count++, c0_);
-          break;
-        case 'b':
-          seq_two_byte->SeqTwoByteStringSet(count++, '\x08');
-          break;
-        case 'f':
-          seq_two_byte->SeqTwoByteStringSet(count++, '\x0c');
-          break;
-        case 'n':
-          seq_two_byte->SeqTwoByteStringSet(count++, '\x0a');
-          break;
-        case 'r':
-          seq_two_byte->SeqTwoByteStringSet(count++, '\x0d');
-          break;
-        case 't':
-          seq_two_byte->SeqTwoByteStringSet(count++, '\x09');
-          break;
-        case 'u': {
-          uc32 value = 0;
-          for (int i = 0; i < 4; i++) {
-            Advance();
-            int digit = HexValue(c0_);
-            if (digit < 0) {
-              return Token::ILLEGAL;
-            }
-            value = value * 16 + digit;
-          }
-          seq_two_byte->SeqTwoByteStringSet(count++, value);
-          break;
-        }
-        default:
-          return Token::ILLEGAL;
-      }
-      Advance();
-    }
-  }
-  // Advance past the last '"'.
-  ASSERT_EQ('"', c0_);
-  Advance();
-
-  // Shrink the the string to our length.
-  if (isolate()->heap()->InNewSpace(*seq_two_byte)) {
-    isolate()->heap()->new_space()->
-          ShrinkStringAtAllocationBoundary<SeqTwoByteString>(*seq_two_byte,
-                                                             count);
-  } else {
-    int string_size = SeqTwoByteString::SizeFor(count);
-    int allocated_string_size =
-        SeqTwoByteString::SizeFor(kInitialSpecialStringSize * allocation_count);
-    int delta = allocated_string_size - string_size;
-    Address start_filler_object = seq_two_byte->address() + string_size;
-    seq_two_byte->set_length(count);
-    isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
-  }
-  string_val_ = isolate()->factory()->NewConsString(ascii, seq_two_byte);
-  return Token::STRING;
-}
-
-
-Token::Value JsonParser::ScanJsonString() {
-  ASSERT_EQ('"', c0_);
-  // Set string_val to null. If string_val is not set we assume an
-  // ascii string begining at next_.beg_pos + 1 to next_.end_pos - 1.
-  string_val_ = Handle<String>::null();
-  Advance();
-  // Fast case for ascii only without escape characters.
-  while (c0_ != '"') {
-    // Check for control character (0x00-0x1f) or unterminated string (<0).
-    if (c0_ < 0x20) return Token::ILLEGAL;
-    if (c0_ != '\\' && c0_ < kMaxAsciiCharCode) {
-      Advance();
-    } else {
-      return SlowScanJsonString();
-    }
-  }
-  ASSERT_EQ('"', c0_);
-  // Advance past the last '"'.
-  Advance();
-  return Token::STRING;
-}
-
-Handle<String> JsonParser::GetString() {
-  return GetString(false);
-}
-
-Handle<String> JsonParser::GetSymbol() {
-  Handle<String> result = GetString(true);
-  if (result->IsSymbol()) return result;
-  return isolate()->factory()->LookupSymbol(result);
-}
-
-Handle<String> JsonParser::GetString(bool hint_symbol) {
-  // We have a non ascii string, return that.
-  if (!string_val_.is_null()) return string_val_;
-
-  if (is_sequential_ascii_ && hint_symbol) {
-    Handle<SeqAsciiString> seq = Handle<SeqAsciiString>::cast(source_);
-    // The current token includes the '"' in both ends.
-    int length = current_.end_pos - current_.beg_pos - 2;
-    return isolate()->factory()->LookupAsciiSymbol(seq_source_,
-                                                   current_.beg_pos + 1,
-                                                   length);
-  }
-  // The current token includes the '"' in both ends.
-  return  isolate()->factory()->NewSubString(
-      source_, current_.beg_pos + 1, current_.end_pos - 1);
-}
-
-} }  // namespace v8::internal
diff --git a/src/json-parser.h b/src/json-parser.h
index 5903d21..0c01461 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -28,12 +28,19 @@
 #ifndef V8_JSON_PARSER_H_
 #define V8_JSON_PARSER_H_
 
+#include "v8.h"
+
+#include "char-predicates-inl.h"
+#include "v8conversions.h"
+#include "messages.h"
+#include "spaces-inl.h"
 #include "token.h"
 
 namespace v8 {
 namespace internal {
 
 // A simple json parser.
+template <bool seq_ascii>
 class JsonParser BASE_EMBEDDED {
  public:
   static Handle<Object> Parse(Handle<String> source) {
@@ -47,41 +54,64 @@
   Handle<Object> ParseJson(Handle<String> source);
 
   inline void Advance() {
+    position_++;
     if (position_ >= source_length_) {
-      position_++;
       c0_ = kEndOfString;
-    } else if (is_sequential_ascii_) {
-      position_++;
+    } else if (seq_ascii) {
       c0_ = seq_source_->SeqAsciiStringGet(position_);
     } else {
-      position_++;
       c0_ = source_->Get(position_);
     }
   }
 
-  inline Isolate* isolate() { return isolate_; }
+  // The JSON lexical grammar is specified in the ECMAScript 5 standard,
+  // section 15.12.1.1. The only allowed whitespace characters between tokens
+  // are tab, carriage-return, newline and space.
 
-  // Get the string for the current string token.
-  Handle<String> GetString(bool hint_symbol);
-  Handle<String> GetString();
-  Handle<String> GetSymbol();
+  inline void AdvanceSkipWhitespace() {
+    do {
+      Advance();
+    } while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' ');
+  }
 
-  // Scan a single JSON token. The JSON lexical grammar is specified in the
-  // ECMAScript 5 standard, section 15.12.1.1.
-  // Recognizes all of the single-character tokens directly, or calls a function
-  // to scan a number, string or identifier literal.
-  // The only allowed whitespace characters between tokens are tab,
-  // carriage-return, newline and space.
-  void ScanJson();
+  inline void SkipWhitespace() {
+    while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' ') {
+      Advance();
+    }
+  }
+
+  inline uc32 AdvanceGetChar() {
+    Advance();
+    return c0_;
+  }
+
+  // Checks that current charater is c.
+  // If so, then consume c and skip whitespace.
+  inline bool MatchSkipWhiteSpace(uc32 c) {
+    if (c0_ == c) {
+      AdvanceSkipWhitespace();
+      return true;
+    }
+    return false;
+  }
 
   // A JSON string (production JSONString) is subset of valid JavaScript string
   // literals. The string must only be double-quoted (not single-quoted), and
   // the only allowed backslash-escapes are ", /, \, b, f, n, r, t and
   // four-digit hex escapes (uXXXX). Any other use of backslashes is invalid.
-  Token::Value ScanJsonString();
-  // Slow version for unicode support, uses the first ascii_count characters,
-  // as first part of a ConsString
-  Token::Value SlowScanJsonString();
+  Handle<String> ParseJsonString() {
+    return ScanJsonString<false>();
+  }
+  Handle<String> ParseJsonSymbol() {
+    return ScanJsonString<true>();
+  }
+  template <bool is_symbol>
+  Handle<String> ScanJsonString();
+  // Creates a new string and copies prefix[start..end] into the beginning
+  // of it. Then scans the rest of the string, adding characters after the
+  // prefix. Called by ScanJsonString when reaching a '\' or non-ASCII char.
+  template <typename StringType, typename SinkChar>
+  Handle<String> SlowScanJsonString(Handle<String> prefix, int start, int end);
 
   // A JSON number (production JSONNumber) is a subset of the valid JavaScript
   // decimal number literals.
@@ -89,12 +119,7 @@
   // digit before and after a decimal point, may not have prefixed zeros (unless
   // the integer part is zero), and may include an exponent part (e.g., "e-10").
   // Hexadecimal and octal numbers are not allowed.
-  Token::Value ScanJsonNumber();
-
-  // Used to recognizes one of the literals "true", "false", or "null". These
-  // are the only valid JSON identifiers (productions JSONBooleanLiteral,
-  // JSONNullLiteral).
-  Token::Value ScanJsonIdentifier(const char* text, Token::Value token);
+  Handle<Object> ParseJsonNumber();
 
   // Parse a single JSON value from input (grammar production JSONValue).
   // A JSON value is either a (double-quoted) string literal, a number literal,
@@ -119,23 +144,13 @@
 
   // Mark that a parsing error has happened at the current token, and
   // return a null handle. Primarily for readability.
-  Handle<Object> ReportUnexpectedToken() { return Handle<Object>::null(); }
+  inline Handle<Object> ReportUnexpectedCharacter() {
+    return Handle<Object>::null();
+  }
 
-  // Peek at the next token.
-  Token::Value Peek() { return next_.token; }
-  // Scan the next token and return the token scanned on the last call.
-  Token::Value Next();
+  inline Isolate* isolate() { return isolate_; }
 
-  struct TokenInfo {
-    TokenInfo() : token(Token::ILLEGAL),
-                  beg_pos(0),
-                  end_pos(0) { }
-    Token::Value token;
-    int beg_pos;
-    int end_pos;
-  };
-
-  static const int kInitialSpecialStringSize = 1024;
+  static const int kInitialSpecialStringLength = 1024;
 
 
  private:
@@ -143,19 +158,441 @@
   int source_length_;
   Handle<SeqAsciiString> seq_source_;
 
-  bool is_sequential_ascii_;
-  // Current and next token
-  TokenInfo current_;
-  TokenInfo next_;
   Isolate* isolate_;
   uc32 c0_;
   int position_;
-
-
-  Handle<String> string_val_;
-  double number_;
 };
 
+template <bool seq_ascii>
+Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source) {
+  isolate_ = source->map()->isolate();
+  source_ = Handle<String>(source->TryFlattenGetString());
+  source_length_ = source_->length();
+
+  // Optimized fast case where we only have ASCII characters.
+  if (seq_ascii) {
+    seq_source_ = Handle<SeqAsciiString>::cast(source_);
+  }
+
+  // Set initial position right before the string.
+  position_ = -1;
+  // Advance to the first character (posibly EOS)
+  AdvanceSkipWhitespace();
+  Handle<Object> result = ParseJsonValue();
+  if (result.is_null() || c0_ != kEndOfString) {
+    // Parse failed. Current character is the unexpected token.
+
+    const char* message;
+    Factory* factory = isolate()->factory();
+    Handle<JSArray> array;
+
+    switch (c0_) {
+      case kEndOfString:
+        message = "unexpected_eos";
+        array = factory->NewJSArray(0);
+        break;
+      case '-':
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        message = "unexpected_token_number";
+        array = factory->NewJSArray(0);
+        break;
+      case '"':
+        message = "unexpected_token_string";
+        array = factory->NewJSArray(0);
+        break;
+      default:
+        message = "unexpected_token";
+        Handle<Object> name = LookupSingleCharacterStringFromCode(c0_);
+        Handle<FixedArray> element = factory->NewFixedArray(1);
+        element->set(0, *name);
+        array = factory->NewJSArrayWithElements(element);
+        break;
+    }
+
+    MessageLocation location(factory->NewScript(source),
+                             position_,
+                             position_ + 1);
+    Handle<Object> result = factory->NewSyntaxError(message, array);
+    isolate()->Throw(*result, &location);
+    return Handle<Object>::null();
+  }
+  return result;
+}
+
+
+// Parse any JSON value.
+template <bool seq_ascii>
+Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() {
+  switch (c0_) {
+    case '"':
+      return ParseJsonString();
+    case '-':
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      return ParseJsonNumber();
+    case 'f':
+      if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' &&
+          AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') {
+        AdvanceSkipWhitespace();
+        return isolate()->factory()->false_value();
+      } else {
+        return ReportUnexpectedCharacter();
+      }
+    case 't':
+      if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' &&
+          AdvanceGetChar() == 'e') {
+        AdvanceSkipWhitespace();
+        return isolate()->factory()->true_value();
+      } else {
+        return ReportUnexpectedCharacter();
+      }
+    case 'n':
+      if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' &&
+          AdvanceGetChar() == 'l') {
+        AdvanceSkipWhitespace();
+        return isolate()->factory()->null_value();
+      } else {
+        return ReportUnexpectedCharacter();
+      }
+    case '{':
+      return ParseJsonObject();
+    case '[':
+      return ParseJsonArray();
+    default:
+      return ReportUnexpectedCharacter();
+  }
+}
+
+
+// Parse a JSON object. Position must be right at '{'.
+template <bool seq_ascii>
+Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
+  Handle<JSFunction> object_constructor(
+      isolate()->global_context()->object_function());
+  Handle<JSObject> json_object =
+      isolate()->factory()->NewJSObject(object_constructor);
+  ASSERT_EQ(c0_, '{');
+
+  AdvanceSkipWhitespace();
+  if (c0_ != '}') {
+    do {
+      if (c0_ != '"') return ReportUnexpectedCharacter();
+      Handle<String> key = ParseJsonSymbol();
+      if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
+      AdvanceSkipWhitespace();
+      Handle<Object> value = ParseJsonValue();
+      if (value.is_null()) return ReportUnexpectedCharacter();
+
+      uint32_t index;
+      if (key->AsArrayIndex(&index)) {
+        SetOwnElement(json_object, index, value, kNonStrictMode);
+      } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
+        SetPrototype(json_object, value);
+      } else {
+        SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
+      }
+    } while (MatchSkipWhiteSpace(','));
+    if (c0_ != '}') {
+      return ReportUnexpectedCharacter();
+    }
+  }
+  AdvanceSkipWhitespace();
+  return json_object;
+}
+
+// Parse a JSON array. Position must be right at '['.
+template <bool seq_ascii>
+Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
+  ZoneScope zone_scope(isolate(), DELETE_ON_EXIT);
+  ZoneList<Handle<Object> > elements(4);
+  ASSERT_EQ(c0_, '[');
+
+  AdvanceSkipWhitespace();
+  if (c0_ != ']') {
+    do {
+      Handle<Object> element = ParseJsonValue();
+      if (element.is_null()) return ReportUnexpectedCharacter();
+      elements.Add(element);
+    } while (MatchSkipWhiteSpace(','));
+    if (c0_ != ']') {
+      return ReportUnexpectedCharacter();
+    }
+  }
+  AdvanceSkipWhitespace();
+  // Allocate a fixed array with all the elements.
+  Handle<FixedArray> fast_elements =
+      isolate()->factory()->NewFixedArray(elements.length());
+  for (int i = 0, n = elements.length(); i < n; i++) {
+    fast_elements->set(i, *elements[i]);
+  }
+  return isolate()->factory()->NewJSArrayWithElements(fast_elements);
+}
+
+
+template <bool seq_ascii>
+Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
+  bool negative = false;
+  int beg_pos = position_;
+  if (c0_ == '-') {
+    Advance();
+    negative = true;
+  }
+  if (c0_ == '0') {
+    Advance();
+    // Prefix zero is only allowed if it's the only digit before
+    // a decimal point or exponent.
+    if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter();
+  } else {
+    int i = 0;
+    int digits = 0;
+    if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter();
+    do {
+      i = i * 10 + c0_ - '0';
+      digits++;
+      Advance();
+    } while (c0_ >= '0' && c0_ <= '9');
+    if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
+      SkipWhitespace();
+      return Handle<Smi>(Smi::FromInt((negative ? -i : i)), isolate());
+    }
+  }
+  if (c0_ == '.') {
+    Advance();
+    if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
+    do {
+      Advance();
+    } while (c0_ >= '0' && c0_ <= '9');
+  }
+  if (AsciiAlphaToLower(c0_) == 'e') {
+    Advance();
+    if (c0_ == '-' || c0_ == '+') Advance();
+    if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
+    do {
+      Advance();
+    } while (c0_ >= '0' && c0_ <= '9');
+  }
+  int length = position_ - beg_pos;
+  double number;
+  if (seq_ascii) {
+    Vector<const char> chars(seq_source_->GetChars() +  beg_pos, length);
+    number = StringToDouble(isolate()->unicode_cache(),
+                             chars,
+                             NO_FLAGS,  // Hex, octal or trailing junk.
+                             OS::nan_value());
+  } else {
+    Vector<char> buffer = Vector<char>::New(length);
+    String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
+    Vector<const char> result =
+        Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
+        length);
+    number = StringToDouble(isolate()->unicode_cache(),
+                             result,
+                             NO_FLAGS,  // Hex, octal or trailing junk.
+                             0.0);
+    buffer.Dispose();
+  }
+  SkipWhitespace();
+  return isolate()->factory()->NewNumber(number);
+}
+
+
+template <typename StringType>
+inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c);
+
+template <>
+inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) {
+  seq_str->SeqTwoByteStringSet(i, c);
+}
+
+template <>
+inline void SeqStringSet(Handle<SeqAsciiString> seq_str, int i, uc32 c) {
+  seq_str->SeqAsciiStringSet(i, c);
+}
+
+template <typename StringType>
+inline Handle<StringType> NewRawString(Factory* factory, int length);
+
+template <>
+inline Handle<SeqTwoByteString> NewRawString(Factory* factory, int length) {
+  return factory->NewRawTwoByteString(length, NOT_TENURED);
+}
+
+template <>
+inline Handle<SeqAsciiString> NewRawString(Factory* factory, int length) {
+  return factory->NewRawAsciiString(length, NOT_TENURED);
+}
+
+
+// Scans the rest of a JSON string starting from position_ and writes
+// prefix[start..end] along with the scanned characters into a
+// sequential string of type StringType.
+template <bool seq_ascii>
+template <typename StringType, typename SinkChar>
+Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(
+    Handle<String> prefix, int start, int end) {
+  int count = end - start;
+  int max_length = count + source_length_ - position_;
+  int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
+  Handle<StringType> seq_str = NewRawString<StringType>(isolate()->factory(),
+                                                        length);
+  // Copy prefix into seq_str.
+  SinkChar* dest = seq_str->GetChars();
+  String::WriteToFlat(*prefix, dest, start, end);
+
+  while (c0_ != '"') {
+    // Check for control character (0x00-0x1f) or unterminated string (<0).
+    if (c0_ < 0x20) return Handle<String>::null();
+    if (count >= length) {
+      // We need to create a longer sequential string for the result.
+      return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count);
+    }
+    if (c0_ != '\\') {
+      // If the sink can contain UC16 characters, or source_ contains only
+      // ASCII characters, there's no need to test whether we can store the
+      // character. Otherwise check whether the UC16 source character can fit
+      // in the ASCII sink.
+      if (sizeof(SinkChar) == kUC16Size ||
+          seq_ascii ||
+          c0_ <= kMaxAsciiCharCode) {
+        SeqStringSet(seq_str, count++, c0_);
+        Advance();
+      } else {
+        // StringType is SeqAsciiString and we just read a non-ASCII char.
+        return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count);
+      }
+    } else {
+      Advance();  // Advance past the \.
+      switch (c0_) {
+        case '"':
+        case '\\':
+        case '/':
+          SeqStringSet(seq_str, count++, c0_);
+          break;
+        case 'b':
+          SeqStringSet(seq_str, count++, '\x08');
+          break;
+        case 'f':
+          SeqStringSet(seq_str, count++, '\x0c');
+          break;
+        case 'n':
+          SeqStringSet(seq_str, count++, '\x0a');
+          break;
+        case 'r':
+          SeqStringSet(seq_str, count++, '\x0d');
+          break;
+        case 't':
+          SeqStringSet(seq_str, count++, '\x09');
+          break;
+        case 'u': {
+          uc32 value = 0;
+          for (int i = 0; i < 4; i++) {
+            Advance();
+            int digit = HexValue(c0_);
+            if (digit < 0) {
+              return Handle<String>::null();
+            }
+            value = value * 16 + digit;
+          }
+          if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) {
+            SeqStringSet(seq_str, count++, value);
+            break;
+          } else {
+            // StringType is SeqAsciiString and we just read a non-ASCII char.
+            position_ -= 6;  // Rewind position_ to \ in \uxxxx.
+            Advance();
+            return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str,
+                                                              0,
+                                                              count);
+          }
+        }
+        default:
+          return Handle<String>::null();
+      }
+      Advance();
+    }
+  }
+  // Shrink seq_string length to count.
+  if (isolate()->heap()->InNewSpace(*seq_str)) {
+    isolate()->heap()->new_space()->
+        template ShrinkStringAtAllocationBoundary<StringType>(
+            *seq_str, count);
+  } else {
+    int string_size = StringType::SizeFor(count);
+    int allocated_string_size = StringType::SizeFor(length);
+    int delta = allocated_string_size - string_size;
+    Address start_filler_object = seq_str->address() + string_size;
+    seq_str->set_length(count);
+    isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
+  }
+  ASSERT_EQ('"', c0_);
+  // Advance past the last '"'.
+  AdvanceSkipWhitespace();
+  return seq_str;
+}
+
+
+template <bool seq_ascii>
+template <bool is_symbol>
+Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
+  ASSERT_EQ('"', c0_);
+  Advance();
+  if (c0_ == '"') {
+    AdvanceSkipWhitespace();
+    return Handle<String>(isolate()->heap()->empty_string());
+  }
+  int beg_pos = position_;
+  // Fast case for ASCII only without escape characters.
+  do {
+    // Check for control character (0x00-0x1f) or unterminated string (<0).
+    if (c0_ < 0x20) return Handle<String>::null();
+    if (c0_ != '\\') {
+      if (seq_ascii || c0_ <= kMaxAsciiCharCode) {
+        Advance();
+      } else {
+        return SlowScanJsonString<SeqTwoByteString, uc16>(source_,
+                                                          beg_pos,
+                                                          position_);
+      }
+    } else {
+      return SlowScanJsonString<SeqAsciiString, char>(source_,
+                                                      beg_pos,
+                                                      position_);
+    }
+  } while (c0_ != '"');
+  int length = position_ - beg_pos;
+  Handle<String> result;
+  if (seq_ascii && is_symbol) {
+    result = isolate()->factory()->LookupAsciiSymbol(seq_source_,
+                                                     beg_pos,
+                                                     length);
+  } else {
+    result = isolate()->factory()->NewRawAsciiString(length);
+    char* dest = SeqAsciiString::cast(*result)->GetChars();
+    String::WriteToFlat(*source_, dest, beg_pos, position_);
+  }
+  ASSERT_EQ('"', c0_);
+  // Advance past the last '"'.
+  AdvanceSkipWhitespace();
+  return result;
+}
+
 } }  // namespace v8::internal
 
 #endif  // V8_JSON_PARSER_H_
diff --git a/src/json.js b/src/json.js
index 7a6189c..6c984a1 100644
--- a/src/json.js
+++ b/src/json.js
@@ -153,7 +153,7 @@
   if (IS_STRING(value)) {
     return %QuoteJSONString(value);
   } else if (IS_NUMBER(value)) {
-    return NUMBER_IS_FINITE(value) ? $String(value) : "null";
+    return JSON_NUMBER_TO_STRING(value);
   } else if (IS_BOOLEAN(value)) {
     return value ? "true" : "false";
   } else if (IS_NULL(value)) {
@@ -164,7 +164,7 @@
       return SerializeArray(value, replacer, stack, indent, gap);
     } else if (IS_NUMBER_WRAPPER(value)) {
       value = ToNumber(value);
-      return NUMBER_IS_FINITE(value) ? ToString(value) : "null";
+      return JSON_NUMBER_TO_STRING(value);
     } else if (IS_STRING_WRAPPER(value)) {
       return %QuoteJSONString(ToString(value));
     } else if (IS_BOOLEAN_WRAPPER(value)) {
@@ -191,31 +191,37 @@
   var val = value[0];
   if (IS_STRING(val)) {
     // First entry is a string. Remaining entries are likely to be strings too.
-    builder.push(%QuoteJSONString(val));
-    for (var i = 1; i < len; i++) {
-      val = value[i];
-      if (IS_STRING(val)) {
-        builder.push(%QuoteJSONStringComma(val));
-      } else {
-        builder.push(",");
-        var before = builder.length;
-        BasicJSONSerialize(i, value[i], stack, builder);
-        if (before == builder.length) builder[before - 1] = ",null";
+    var array_string = %QuoteJSONStringArray(value);
+    if (!IS_UNDEFINED(array_string)) {
+      // array_string also includes bracket characters so we are done.
+      builder[builder.length - 1] = array_string;
+      stack.pop();
+      return;
+    } else {
+      builder.push(%QuoteJSONString(val));
+      for (var i = 1; i < len; i++) {
+        val = value[i];
+        if (IS_STRING(val)) {
+          builder.push(%QuoteJSONStringComma(val));
+        } else {
+          builder.push(",");
+          var before = builder.length;
+          BasicJSONSerialize(i, val, stack, builder);
+          if (before == builder.length) builder[before - 1] = ",null";
+        }
       }
     }
   } else if (IS_NUMBER(val)) {
     // First entry is a number. Remaining entries are likely to be numbers too.
-    builder.push(NUMBER_IS_FINITE(val) ? %_NumberToString(val) : "null");
+    builder.push(JSON_NUMBER_TO_STRING(val));
     for (var i = 1; i < len; i++) {
       builder.push(",");
       val = value[i];
       if (IS_NUMBER(val)) {
-        builder.push(NUMBER_IS_FINITE(val) 
-                     ? %_NumberToString(val) 
-                     : "null");
+        builder.push(JSON_NUMBER_TO_STRING(val));
       } else {
         var before = builder.length;
-        BasicJSONSerialize(i, value[i], stack, builder);
+        BasicJSONSerialize(i, val, stack, builder);
         if (before == builder.length) builder[before - 1] = ",null";
       }
     }
@@ -226,8 +232,7 @@
     for (var i = 1; i < len; i++) {
       builder.push(",");
       before = builder.length;
-      val = value[i];
-      BasicJSONSerialize(i, val, stack, builder);
+      BasicJSONSerialize(i, value[i], stack, builder);
       if (before == builder.length) builder[before - 1] = ",null";
     }
   }
@@ -273,9 +278,9 @@
     }
   }
   if (IS_STRING(value)) {
-    builder.push(%QuoteJSONString(value));
+    builder.push(value !== "" ? %QuoteJSONString(value) : '""');
   } else if (IS_NUMBER(value)) {
-    builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null");
+    builder.push(JSON_NUMBER_TO_STRING(value));
   } else if (IS_BOOLEAN(value)) {
     builder.push(value ? "true" : "false");
   } else if (IS_NULL(value)) {
@@ -285,7 +290,7 @@
     // Unwrap value if necessary
     if (IS_NUMBER_WRAPPER(value)) {
       value = ToNumber(value);
-      builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null");
+      builder.push(JSON_NUMBER_TO_STRING(value));
     } else if (IS_STRING_WRAPPER(value)) {
       builder.push(%QuoteJSONString(ToString(value)));
     } else if (IS_BOOLEAN_WRAPPER(value)) {
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index e7aa860..bc47df8 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -127,7 +127,7 @@
     return re;
   }
   pattern = FlattenGetString(pattern);
-  CompilationZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+  ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
   PostponeInterruptsScope postpone(isolate);
   RegExpCompileData parse_result;
   FlatStringReader reader(isolate, pattern);
@@ -327,7 +327,7 @@
 bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
   // Compile the RegExp.
   Isolate* isolate = re->GetIsolate();
-  CompilationZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+  ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
   PostponeInterruptsScope postpone(isolate);
   // If we had a compilation error the last time this is saved at the
   // saved code index.
@@ -848,6 +848,7 @@
   }
 
   static const int kNoRegister = -1;
+
  private:
   EndNode* accept_;
   int next_register_;
@@ -1957,13 +1958,10 @@
   ASSERT(characters_filled_in < details->characters());
   int characters = details->characters();
   int char_mask;
-  int char_shift;
   if (compiler->ascii()) {
     char_mask = String::kMaxAsciiCharCode;
-    char_shift = 8;
   } else {
     char_mask = String::kMaxUC16CharCode;
-    char_shift = 16;
   }
   for (int k = 0; k < elms_->length(); k++) {
     TextElement elm = elms_->at(k);
@@ -2806,6 +2804,7 @@
   AlternativeGeneration* at(int i) {
     return alt_gens_[i];
   }
+
  private:
   static const int kAFew = 10;
   ZoneList<AlternativeGeneration*> alt_gens_;
@@ -3365,6 +3364,7 @@
     }
     stream()->Add("}}");
   }
+
  private:
   bool first_;
   StringStream* stream() { return stream_; }
@@ -4885,7 +4885,6 @@
       cp_offset += elm.data.u_atom->data().length();
     } else {
       cp_offset++;
-      Vector<const uc16> quarks = elm.data.u_atom->data();
     }
   }
 }
@@ -5324,8 +5323,6 @@
     return CompilationResult(error_message);
   }
 
-  NodeInfo info = *node->info();
-
   // Create the correct assembler for the architecture.
 #ifndef V8_INTERPRETED_REGEXP
   // Native regexp implementation.
diff --git a/src/jsregexp.h b/src/jsregexp.h
index 58958d8..13f9e2e 100644
--- a/src/jsregexp.h
+++ b/src/jsregexp.h
@@ -29,7 +29,6 @@
 #define V8_JSREGEXP_H_
 
 #include "allocation.h"
-#include "macro-assembler.h"
 #include "zone-inl.h"
 
 namespace v8 {
diff --git a/src/lithium-allocator-inl.h b/src/lithium-allocator-inl.h
index c0beaaf..8f660ce 100644
--- a/src/lithium-allocator-inl.h
+++ b/src/lithium-allocator-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -62,27 +62,27 @@
     : instr_(instr),
       limit_(instr->TempCount()),
       current_(0) {
-  current_ = AdvanceToNext(0);
+  SkipUninteresting();
 }
 
 
-bool TempIterator::HasNext() { return current_ < limit_; }
+bool TempIterator::Done() { return current_ >= limit_; }
 
 
-LOperand* TempIterator::Next() {
-  ASSERT(HasNext());
+LOperand* TempIterator::Current() {
+  ASSERT(!Done());
   return instr_->TempAt(current_);
 }
 
 
-int TempIterator::AdvanceToNext(int start) {
-  while (start < limit_ && instr_->TempAt(start) == NULL) start++;
-  return start;
+void TempIterator::SkipUninteresting() {
+  while (current_ < limit_ && instr_->TempAt(current_) == NULL) ++current_;
 }
 
 
 void TempIterator::Advance() {
-  current_ = AdvanceToNext(current_ + 1);
+  ++current_;
+  SkipUninteresting();
 }
 
 
@@ -90,27 +90,29 @@
     : instr_(instr),
       limit_(instr->InputCount()),
       current_(0) {
-  current_ = AdvanceToNext(0);
+  SkipUninteresting();
 }
 
 
-bool InputIterator::HasNext() { return current_ < limit_; }
+bool InputIterator::Done() { return current_ >= limit_; }
 
 
-LOperand* InputIterator::Next() {
-  ASSERT(HasNext());
+LOperand* InputIterator::Current() {
+  ASSERT(!Done());
   return instr_->InputAt(current_);
 }
 
 
 void InputIterator::Advance() {
-  current_ = AdvanceToNext(current_ + 1);
+  ++current_;
+  SkipUninteresting();
 }
 
 
-int InputIterator::AdvanceToNext(int start) {
-  while (start < limit_ && instr_->InputAt(start)->IsConstantOperand()) start++;
-  return start;
+void InputIterator::SkipUninteresting() {
+  while (current_ < limit_ && instr_->InputAt(current_)->IsConstantOperand()) {
+    ++current_;
+  }
 }
 
 
@@ -118,23 +120,23 @@
     : input_iterator_(instr), env_iterator_(instr->environment()) { }
 
 
-bool UseIterator::HasNext() {
-  return input_iterator_.HasNext() || env_iterator_.HasNext();
+bool UseIterator::Done() {
+  return input_iterator_.Done() && env_iterator_.Done();
 }
 
 
-LOperand* UseIterator::Next() {
-  ASSERT(HasNext());
-  return input_iterator_.HasNext()
-      ? input_iterator_.Next()
-      : env_iterator_.Next();
+LOperand* UseIterator::Current() {
+  ASSERT(!Done());
+  return input_iterator_.Done()
+      ? env_iterator_.Current()
+      : input_iterator_.Current();
 }
 
 
 void UseIterator::Advance() {
-  input_iterator_.HasNext()
-      ? input_iterator_.Advance()
-      : env_iterator_.Advance();
+  input_iterator_.Done()
+      ? env_iterator_.Advance()
+      : input_iterator_.Advance();
 }
 
 } }  // namespace v8::internal
diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
index 50ed122..4661106 100644
--- a/src/lithium-allocator.cc
+++ b/src/lithium-allocator.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -303,6 +303,11 @@
   // we need to split use positons in a special way.
   bool split_at_start = false;
 
+  if (current->start().Value() == position.Value()) {
+    // When splitting at start we need to locate the previous use interval.
+    current = first_interval_;
+  }
+
   while (current != NULL) {
     if (current->Contains(position)) {
       current->SplitAt(position);
@@ -352,6 +357,11 @@
   }
   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;
+
   // 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_;
@@ -565,10 +575,10 @@
   BitVector* live_out = new BitVector(next_virtual_register_);
 
   // Process all successor blocks.
-  HBasicBlock* successor = block->end()->FirstSuccessor();
-  while (successor != NULL) {
+  for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
     // Add values live on entry to the successor. Note the successor's
     // live_in will not be computed yet for backwards edges.
+    HBasicBlock* successor = it.Current();
     BitVector* live_in = live_in_sets_[successor->block_id()];
     if (live_in != NULL) live_out->Union(*live_in);
 
@@ -582,11 +592,6 @@
         live_out->Add(phi->OperandAt(index)->id());
       }
     }
-
-    // Check if we are done with second successor.
-    if (successor == block->end()->SecondSuccessor()) break;
-
-    successor = block->end()->SecondSuccessor();
   }
 
   return live_out;
@@ -790,8 +795,8 @@
                                         int gap_index) {
   // Handle fixed temporaries.
   if (first != NULL) {
-    for (TempIterator it(first); it.HasNext(); it.Advance()) {
-      LUnallocated* temp = LUnallocated::cast(it.Next());
+    for (TempIterator it(first); !it.Done(); it.Advance()) {
+      LUnallocated* temp = LUnallocated::cast(it.Current());
       if (temp->HasFixedPolicy()) {
         AllocateFixed(temp, gap_index - 1, false);
       }
@@ -832,8 +837,8 @@
 
   // Handle fixed input operands of second instruction.
   if (second != NULL) {
-    for (UseIterator it(second); it.HasNext(); it.Advance()) {
-      LUnallocated* cur_input = LUnallocated::cast(it.Next());
+    for (UseIterator it(second); !it.Done(); it.Advance()) {
+      LUnallocated* cur_input = LUnallocated::cast(it.Current());
       if (cur_input->HasFixedPolicy()) {
         LUnallocated* input_copy = cur_input->CopyUnconstrained();
         bool is_tagged = HasTaggedValue(cur_input->VirtualRegister());
@@ -968,8 +973,8 @@
           }
         }
 
-        for (UseIterator it(instr); it.HasNext(); it.Advance()) {
-          LOperand* input = it.Next();
+        for (UseIterator it(instr); !it.Done(); it.Advance()) {
+          LOperand* input = it.Current();
 
           LifetimePosition use_pos;
           if (input->IsUnallocated() &&
@@ -983,8 +988,8 @@
           if (input->IsUnallocated()) live->Add(input->VirtualRegister());
         }
 
-        for (TempIterator it(instr); it.HasNext(); it.Advance()) {
-          LOperand* temp = it.Next();
+        for (TempIterator it(instr); !it.Done(); it.Advance()) {
+          LOperand* temp = it.Current();
           if (instr->IsMarkedAsCall()) {
             if (temp->IsRegister()) continue;
             if (temp->IsUnallocated()) {
@@ -1019,7 +1024,7 @@
         operand = chunk_->DefineConstantOperand(constant);
       } else {
         ASSERT(!op->EmitAtUses());
-        LUnallocated* unalloc = new LUnallocated(LUnallocated::NONE);
+        LUnallocated* unalloc = new LUnallocated(LUnallocated::ANY);
         unalloc->set_virtual_register(op->id());
         operand = unalloc;
       }
diff --git a/src/lithium-allocator.h b/src/lithium-allocator.h
index d456558..e4e6497 100644
--- a/src/lithium-allocator.h
+++ b/src/lithium-allocator.h
@@ -162,12 +162,12 @@
 class TempIterator BASE_EMBEDDED {
  public:
   inline explicit TempIterator(LInstruction* instr);
-  inline bool HasNext();
-  inline LOperand* Next();
+  inline bool Done();
+  inline LOperand* Current();
   inline void Advance();
 
  private:
-  inline int AdvanceToNext(int start);
+  inline void SkipUninteresting();
   LInstruction* instr_;
   int limit_;
   int current_;
@@ -178,12 +178,12 @@
 class InputIterator BASE_EMBEDDED {
  public:
   inline explicit InputIterator(LInstruction* instr);
-  inline bool HasNext();
-  inline LOperand* Next();
+  inline bool Done();
+  inline LOperand* Current();
   inline void Advance();
 
  private:
-  inline int AdvanceToNext(int start);
+  inline void SkipUninteresting();
   LInstruction* instr_;
   int limit_;
   int current_;
@@ -193,8 +193,8 @@
 class UseIterator BASE_EMBEDDED {
  public:
   inline explicit UseIterator(LInstruction* instr);
-  inline bool HasNext();
-  inline LOperand* Next();
+  inline bool Done();
+  inline LOperand* Current();
   inline void Advance();
 
  private:
diff --git a/src/lithium.cc b/src/lithium.cc
index 62b263b..64ef469 100644
--- a/src/lithium.cc
+++ b/src/lithium.cc
@@ -166,21 +166,26 @@
 }
 
 
-int ExternalArrayTypeToShiftSize(ExternalArrayType type) {
-  switch (type) {
-    case kExternalByteArray:
-    case kExternalUnsignedByteArray:
-    case kExternalPixelArray:
+int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind) {
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       return 0;
-    case kExternalShortArray:
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       return 1;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       return 2;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
       return 3;
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+      return kPointerSizeLog2;
   }
   UNREACHABLE();
   return 0;
diff --git a/src/lithium.h b/src/lithium.h
index ffc236d..6010b77 100644
--- a/src/lithium.h
+++ b/src/lithium.h
@@ -519,34 +519,34 @@
       : env_(env),
         limit_(env != NULL ? env->values()->length() : 0),
         current_(0) {
-    current_ = AdvanceToNext(0);
+    SkipUninteresting();
   }
 
-  inline bool HasNext() {
-    return env_ != NULL && current_ < limit_;
-  }
+  bool Done() { return current_ >= limit_; }
 
-  inline LOperand* Next() {
-    ASSERT(HasNext());
+  LOperand* Current() {
+    ASSERT(!Done());
     return env_->values()->at(current_);
   }
 
-  inline void Advance() {
-    current_ = AdvanceToNext(current_ + 1);
+  void Advance() {
+    ASSERT(!Done());
+    ++current_;
+    SkipUninteresting();
   }
 
-  inline LEnvironment* env() { return env_; }
+  LEnvironment* env() { return env_; }
 
  private:
-  inline bool ShouldSkip(LOperand* op) {
+  bool ShouldSkip(LOperand* op) {
     return op == NULL || op->IsConstantOperand() || op->IsArgument();
   }
 
-  inline int AdvanceToNext(int start) {
-    while (start < limit_ && ShouldSkip(env_->values()->at(start))) {
-      start++;
+  // Skip until something interesting, beginning with and including current_.
+  void SkipUninteresting() {
+    while (current_ < limit_ && ShouldSkip(env_->values()->at(current_))) {
+      ++current_;
     }
-    return start;
   }
 
   LEnvironment* env_;
@@ -559,38 +559,34 @@
 class DeepIterator BASE_EMBEDDED {
  public:
   explicit DeepIterator(LEnvironment* env)
-      : current_iterator_(env) { }
-
-  inline bool HasNext() {
-    if (current_iterator_.HasNext()) return true;
-    if (current_iterator_.env() == NULL) return false;
-    AdvanceToOuter();
-    return current_iterator_.HasNext();
+      : current_iterator_(env) {
+    SkipUninteresting();
   }
 
-  inline LOperand* Next() {
-    ASSERT(current_iterator_.HasNext());
-    return current_iterator_.Next();
+  bool Done() { return current_iterator_.Done(); }
+
+  LOperand* Current() {
+    ASSERT(!current_iterator_.Done());
+    return current_iterator_.Current();
   }
 
-  inline void Advance() {
-    if (current_iterator_.HasNext()) {
-      current_iterator_.Advance();
-    } else {
-      AdvanceToOuter();
-    }
+  void Advance() {
+    current_iterator_.Advance();
+    SkipUninteresting();
   }
 
  private:
-  inline void AdvanceToOuter() {
-    current_iterator_ = ShallowIterator(current_iterator_.env()->outer());
+  void SkipUninteresting() {
+    while (current_iterator_.env() != NULL && current_iterator_.Done()) {
+      current_iterator_ = ShallowIterator(current_iterator_.env()->outer());
+    }
   }
 
   ShallowIterator current_iterator_;
 };
 
 
-int ExternalArrayTypeToShiftSize(ExternalArrayType type);
+int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind);
 
 
 } }  // namespace v8::internal
diff --git a/src/liveedit.cc b/src/liveedit.cc
index e89cae3..0b01e8a 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -66,7 +66,7 @@
 class Differencer {
  public:
   explicit Differencer(Comparator::Input* input)
-      : input_(input), len1_(input->getLength1()), len2_(input->getLength2()) {
+      : input_(input), len1_(input->GetLength1()), len2_(input->GetLength2()) {
     buffer_ = NewArray<int>(len1_ * len2_);
   }
   ~Differencer() {
@@ -151,7 +151,7 @@
         if (cached_res == kEmptyCellValue) {
           Direction dir;
           int res;
-          if (input_->equals(pos1, pos2)) {
+          if (input_->Equals(pos1, pos2)) {
             res = CompareUpToTail(pos1 + 1, pos2 + 1);
             dir = EQ;
           } else {
@@ -279,6 +279,70 @@
 }
 
 
+// Additional to Input interface. Lets switch Input range to subrange.
+// More elegant way would be to wrap one Input as another Input object
+// and translate positions there, but that would cost us additional virtual
+// call per comparison.
+class SubrangableInput : public Comparator::Input {
+ public:
+  virtual void SetSubrange1(int offset, int len) = 0;
+  virtual void SetSubrange2(int offset, int len) = 0;
+};
+
+
+class SubrangableOutput : public Comparator::Output {
+ public:
+  virtual void SetSubrange1(int offset, int len) = 0;
+  virtual void SetSubrange2(int offset, int len) = 0;
+};
+
+
+static int min(int a, int b) {
+  return a < b ? a : b;
+}
+
+
+// Finds common prefix and suffix in input. This parts shouldn't take space in
+// linear programming table. Enable subranging in input and output.
+static void NarrowDownInput(SubrangableInput* input,
+    SubrangableOutput* output) {
+  const int len1 = input->GetLength1();
+  const int len2 = input->GetLength2();
+
+  int common_prefix_len;
+  int common_suffix_len;
+
+  {
+    common_prefix_len = 0;
+    int prefix_limit = min(len1, len2);
+    while (common_prefix_len < prefix_limit &&
+        input->Equals(common_prefix_len, common_prefix_len)) {
+      common_prefix_len++;
+    }
+
+    common_suffix_len = 0;
+    int suffix_limit = min(len1 - common_prefix_len, len2 - common_prefix_len);
+
+    while (common_suffix_len < suffix_limit &&
+        input->Equals(len1 - common_suffix_len - 1,
+        len2 - common_suffix_len - 1)) {
+      common_suffix_len++;
+    }
+  }
+
+  if (common_prefix_len > 0 || common_suffix_len > 0) {
+    int new_len1 = len1 - common_suffix_len - common_prefix_len;
+    int new_len2 = len2 - common_suffix_len - common_prefix_len;
+
+    input->SetSubrange1(common_prefix_len, new_len1);
+    input->SetSubrange2(common_prefix_len, new_len2);
+
+    output->SetSubrange1(common_prefix_len, new_len1);
+    output->SetSubrange2(common_prefix_len, new_len2);
+  }
+}
+
+
 // A helper class that writes chunk numbers into JSArray.
 // Each chunk is stored as 3 array elements: (pos1_begin, pos1_end, pos2_end).
 class CompareOutputArrayWriter {
@@ -319,13 +383,13 @@
       : s1_(s1), offset1_(offset1), len1_(len1),
         s2_(s2), offset2_(offset2), len2_(len2) {
   }
-  virtual int getLength1() {
+  virtual int GetLength1() {
     return len1_;
   }
-  virtual int getLength2() {
+  virtual int GetLength2() {
     return len2_;
   }
-  bool equals(int index1, int index2) {
+  bool Equals(int index1, int index2) {
     return s1_->Get(offset1_ + index1) == s2_->Get(offset2_ + index2);
   }
 
@@ -401,20 +465,26 @@
 
 
 // Represents 2 strings as 2 arrays of lines.
-class LineArrayCompareInput : public Comparator::Input {
+class LineArrayCompareInput : public SubrangableInput {
  public:
   LineArrayCompareInput(Handle<String> s1, Handle<String> s2,
                         LineEndsWrapper line_ends1, LineEndsWrapper line_ends2)
       : s1_(s1), s2_(s2), line_ends1_(line_ends1),
-        line_ends2_(line_ends2) {
+        line_ends2_(line_ends2),
+        subrange_offset1_(0), subrange_offset2_(0),
+        subrange_len1_(line_ends1_.length()),
+        subrange_len2_(line_ends2_.length()) {
   }
-  int getLength1() {
-    return line_ends1_.length();
+  int GetLength1() {
+    return subrange_len1_;
   }
-  int getLength2() {
-    return line_ends2_.length();
+  int GetLength2() {
+    return subrange_len2_;
   }
-  bool equals(int index1, int index2) {
+  bool Equals(int index1, int index2) {
+    index1 += subrange_offset1_;
+    index2 += subrange_offset2_;
+
     int line_start1 = line_ends1_.GetLineStart(index1);
     int line_start2 = line_ends2_.GetLineStart(index2);
     int line_end1 = line_ends1_.GetLineEnd(index1);
@@ -427,26 +497,42 @@
     return CompareSubstrings(s1_, line_start1, s2_, line_start2,
                              len1);
   }
+  void SetSubrange1(int offset, int len) {
+    subrange_offset1_ = offset;
+    subrange_len1_ = len;
+  }
+  void SetSubrange2(int offset, int len) {
+    subrange_offset2_ = offset;
+    subrange_len2_ = len;
+  }
 
  private:
   Handle<String> s1_;
   Handle<String> s2_;
   LineEndsWrapper line_ends1_;
   LineEndsWrapper line_ends2_;
+  int subrange_offset1_;
+  int subrange_offset2_;
+  int subrange_len1_;
+  int subrange_len2_;
 };
 
 
 // Stores compare result in JSArray. For each chunk tries to conduct
 // a fine-grained nested diff token-wise.
-class TokenizingLineArrayCompareOutput : public Comparator::Output {
+class TokenizingLineArrayCompareOutput : public SubrangableOutput {
  public:
   TokenizingLineArrayCompareOutput(LineEndsWrapper line_ends1,
                                    LineEndsWrapper line_ends2,
                                    Handle<String> s1, Handle<String> s2)
-      : line_ends1_(line_ends1), line_ends2_(line_ends2), s1_(s1), s2_(s2) {
+      : line_ends1_(line_ends1), line_ends2_(line_ends2), s1_(s1), s2_(s2),
+        subrange_offset1_(0), subrange_offset2_(0) {
   }
 
   void AddChunk(int line_pos1, int line_pos2, int line_len1, int line_len2) {
+    line_pos1 += subrange_offset1_;
+    line_pos2 += subrange_offset2_;
+
     int char_pos1 = line_ends1_.GetLineStart(line_pos1);
     int char_pos2 = line_ends2_.GetLineStart(line_pos2);
     int char_len1 = line_ends1_.GetLineStart(line_pos1 + line_len1) - char_pos1;
@@ -466,6 +552,12 @@
       array_writer_.WriteChunk(char_pos1, char_pos2, char_len1, char_len2);
     }
   }
+  void SetSubrange1(int offset, int len) {
+    subrange_offset1_ = offset;
+  }
+  void SetSubrange2(int offset, int len) {
+    subrange_offset2_ = offset;
+  }
 
   Handle<JSArray> GetResult() {
     return array_writer_.GetResult();
@@ -479,6 +571,8 @@
   LineEndsWrapper line_ends2_;
   Handle<String> s1_;
   Handle<String> s2_;
+  int subrange_offset1_;
+  int subrange_offset2_;
 };
 
 
@@ -493,6 +587,8 @@
   LineArrayCompareInput input(s1, s2, line_ends1, line_ends2);
   TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2);
 
+  NarrowDownInput(&input, &output);
+
   Comparator::CalculateDifference(&input, &output);
 
   return output.GetResult();
@@ -814,7 +910,7 @@
 JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
                                      Handle<String> source) {
   Isolate* isolate = Isolate::Current();
-  CompilationZoneScope zone_scope(isolate, DELETE_ON_EXIT);
+  ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
 
   FunctionInfoListener listener;
   Handle<Object> original_source = Handle<Object>(script->source());
diff --git a/src/liveedit.h b/src/liveedit.h
index 60e6238..4ee4466 100644
--- a/src/liveedit.h
+++ b/src/liveedit.h
@@ -143,14 +143,13 @@
 // A general-purpose comparator between 2 arrays.
 class Comparator {
  public:
-
   // Holds 2 arrays of some elements allowing to compare any pair of
   // element from the first array and element from the second array.
   class Input {
    public:
-    virtual int getLength1() = 0;
-    virtual int getLength2() = 0;
-    virtual bool equals(int index1, int index2) = 0;
+    virtual int GetLength1() = 0;
+    virtual int GetLength2() = 0;
+    virtual bool Equals(int index1, int index2) = 0;
 
    protected:
     virtual ~Input() {}
diff --git a/src/liveobjectlist.cc b/src/liveobjectlist.cc
index 29a9b01..e382a06 100644
--- a/src/liveobjectlist.cc
+++ b/src/liveobjectlist.cc
@@ -1649,7 +1649,6 @@
 // Helper class for copying HeapObjects.
 class LolVisitor: public ObjectVisitor {
  public:
-
   LolVisitor(HeapObject* target, Handle<HeapObject> handle_to_skip)
       : target_(target), handle_to_skip_(handle_to_skip), found_(false) {}
 
@@ -2586,4 +2585,3 @@
 } }  // namespace v8::internal
 
 #endif  // LIVE_OBJECT_LIST
-
diff --git a/src/log-inl.h b/src/log-inl.h
index 02238fe..8aebbc7 100644
--- a/src/log-inl.h
+++ b/src/log-inl.h
@@ -34,8 +34,6 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 Logger::LogEventsAndTags Logger::ToNativeByScript(Logger::LogEventsAndTags tag,
                                                   Script* script) {
   if ((tag == FUNCTION_TAG || tag == LAZY_COMPILE_TAG || tag == SCRIPT_TAG)
@@ -51,8 +49,6 @@
   }
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 
 } }  // namespace v8::internal
 
diff --git a/src/log-utils.cc b/src/log-utils.cc
index 1bba7cd..2d1ce23 100644
--- a/src/log-utils.cc
+++ b/src/log-utils.cc
@@ -33,101 +33,14 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 
-LogDynamicBuffer::LogDynamicBuffer(
-    int block_size, int max_size, const char* seal, int seal_size)
-    : block_size_(block_size),
-      max_size_(max_size - (max_size % block_size_)),
-      seal_(seal),
-      seal_size_(seal_size),
-      blocks_(max_size_ / block_size_ + 1),
-      write_pos_(0), block_index_(0), block_write_pos_(0), is_sealed_(false) {
-  ASSERT(BlocksCount() > 0);
-  AllocateBlock(0);
-  for (int i = 1; i < BlocksCount(); ++i) {
-    blocks_[i] = NULL;
-  }
-}
+const char* Log::kLogToTemporaryFile = "&";
 
 
-LogDynamicBuffer::~LogDynamicBuffer() {
-  for (int i = 0; i < BlocksCount(); ++i) {
-    DeleteArray(blocks_[i]);
-  }
-}
-
-
-int LogDynamicBuffer::Read(int from_pos, char* dest_buf, int buf_size) {
-  if (buf_size == 0) return 0;
-  int read_pos = from_pos;
-  int block_read_index = BlockIndex(from_pos);
-  int block_read_pos = PosInBlock(from_pos);
-  int dest_buf_pos = 0;
-  // Read until dest_buf is filled, or write_pos_ encountered.
-  while (read_pos < write_pos_ && dest_buf_pos < buf_size) {
-    const int read_size = Min(write_pos_ - read_pos,
-        Min(buf_size - dest_buf_pos, block_size_ - block_read_pos));
-    memcpy(dest_buf + dest_buf_pos,
-           blocks_[block_read_index] + block_read_pos, read_size);
-    block_read_pos += read_size;
-    dest_buf_pos += read_size;
-    read_pos += read_size;
-    if (block_read_pos == block_size_) {
-      block_read_pos = 0;
-      ++block_read_index;
-    }
-  }
-  return dest_buf_pos;
-}
-
-
-int LogDynamicBuffer::Seal() {
-  WriteInternal(seal_, seal_size_);
-  is_sealed_ = true;
-  return 0;
-}
-
-
-int LogDynamicBuffer::Write(const char* data, int data_size) {
-  if (is_sealed_) {
-    return 0;
-  }
-  if ((write_pos_ + data_size) <= (max_size_ - seal_size_)) {
-    return WriteInternal(data, data_size);
-  } else {
-    return Seal();
-  }
-}
-
-
-int LogDynamicBuffer::WriteInternal(const char* data, int data_size) {
-  int data_pos = 0;
-  while (data_pos < data_size) {
-    const int write_size =
-        Min(data_size - data_pos, block_size_ - block_write_pos_);
-    memcpy(blocks_[block_index_] + block_write_pos_, data + data_pos,
-           write_size);
-    block_write_pos_ += write_size;
-    data_pos += write_size;
-    if (block_write_pos_ == block_size_) {
-      block_write_pos_ = 0;
-      AllocateBlock(++block_index_);
-    }
-  }
-  write_pos_ += data_size;
-  return data_size;
-}
-
-// Must be the same message as in Logger::PauseProfiler.
-const char* const Log::kDynamicBufferSeal = "profiler,\"pause\"\n";
-
 Log::Log(Logger* logger)
-  : write_to_file_(false),
-    is_stopped_(false),
+  : is_stopped_(false),
     output_handle_(NULL),
     ll_output_handle_(NULL),
-    output_buffer_(NULL),
     mutex_(NULL),
     message_buffer_(NULL),
     logger_(logger) {
@@ -142,7 +55,6 @@
 
 
 void Log::Initialize() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   mutex_ = OS::CreateMutex();
   message_buffer_ = NewArray<char>(kMessageBufferSize);
 
@@ -166,19 +78,19 @@
     FLAG_prof_auto = false;
   }
 
-  bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
+  bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api
       || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
       || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof;
 
-  bool open_log_file = start_logging || FLAG_prof_lazy;
-
   // If we're logging anything, we need to open the log file.
   if (open_log_file) {
     if (strcmp(FLAG_logfile, "-") == 0) {
       OpenStdout();
     } else if (strcmp(FLAG_logfile, "*") == 0) {
-      OpenMemoryBuffer();
-    } else  {
+      // Does nothing for now. Will be removed.
+    } else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) {
+      OpenTemporaryFile();
+    } else {
       if (strchr(FLAG_logfile, '%') != NULL ||
           !Isolate::Current()->IsDefaultIsolate()) {
         // If there's a '%' in the log file name we have to expand
@@ -222,14 +134,18 @@
       }
     }
   }
-#endif
 }
 
 
 void Log::OpenStdout() {
   ASSERT(!IsEnabled());
   output_handle_ = stdout;
-  write_to_file_ = true;
+}
+
+
+void Log::OpenTemporaryFile() {
+  ASSERT(!IsEnabled());
+  output_handle_ = i::OS::OpenTemporaryFile();
 }
 
 
@@ -244,7 +160,6 @@
 void Log::OpenFile(const char* name) {
   ASSERT(!IsEnabled());
   output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
-  write_to_file_ = true;
   if (FLAG_ll_prof) {
     // Open the low-level log file.
     size_t len = strlen(name);
@@ -257,25 +172,18 @@
 }
 
 
-void Log::OpenMemoryBuffer() {
-  ASSERT(!IsEnabled());
-  output_buffer_ = new LogDynamicBuffer(
-      kDynamicBufferBlockSize, kMaxDynamicBufferSize,
-      kDynamicBufferSeal, StrLength(kDynamicBufferSeal));
-  write_to_file_ = false;
-}
-
-
-void Log::Close() {
-  if (write_to_file_) {
-    if (output_handle_ != NULL) fclose(output_handle_);
-    output_handle_ = NULL;
-    if (ll_output_handle_ != NULL) fclose(ll_output_handle_);
-    ll_output_handle_ = NULL;
-  } else {
-    delete output_buffer_;
-    output_buffer_ = NULL;
+FILE* Log::Close() {
+  FILE* result = NULL;
+  if (output_handle_ != NULL) {
+    if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
+      fclose(output_handle_);
+    } else {
+      result = output_handle_;
+    }
   }
+  output_handle_ = NULL;
+  if (ll_output_handle_ != NULL) fclose(ll_output_handle_);
+  ll_output_handle_ = NULL;
 
   DeleteArray(message_buffer_);
   message_buffer_ = NULL;
@@ -284,27 +192,7 @@
   mutex_ = NULL;
 
   is_stopped_ = false;
-}
-
-
-int Log::GetLogLines(int from_pos, char* dest_buf, int max_size) {
-  if (write_to_file_) return 0;
-  ASSERT(output_buffer_ != NULL);
-  ASSERT(from_pos >= 0);
-  ASSERT(max_size >= 0);
-  int actual_size = output_buffer_->Read(from_pos, dest_buf, max_size);
-  ASSERT(actual_size <= max_size);
-  if (actual_size == 0) return 0;
-
-  // Find previous log line boundary.
-  char* end_pos = dest_buf + actual_size - 1;
-  while (end_pos >= dest_buf && *end_pos != '\n') --end_pos;
-  actual_size = static_cast<int>(end_pos - dest_buf + 1);
-  // If the assertion below is hit, it means that there was no line end
-  // found --- something wrong has happened.
-  ASSERT(actual_size > 0);
-  ASSERT(actual_size <= max_size);
-  return actual_size;
+  return result;
 }
 
 
@@ -413,9 +301,7 @@
 
 void LogMessageBuilder::WriteToLogFile() {
   ASSERT(pos_ <= Log::kMessageBufferSize);
-  const int written = log_->write_to_file_ ?
-      log_->WriteToFile(log_->message_buffer_, pos_) :
-      log_->WriteToMemory(log_->message_buffer_, pos_);
+  const int written = log_->WriteToFile(log_->message_buffer_, pos_);
   if (written != pos_) {
     log_->stop();
     log_->logger_->LogFailure();
@@ -423,6 +309,4 @@
 }
 
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
diff --git a/src/log-utils.h b/src/log-utils.h
index 81bbf77..d336d71 100644
--- a/src/log-utils.h
+++ b/src/log-utils.h
@@ -33,69 +33,11 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 class Logger;
 
-// A memory buffer that increments its size as you write in it.  Size
-// is incremented with 'block_size' steps, never exceeding 'max_size'.
-// During growth, memory contents are never copied.  At the end of the
-// buffer an amount of memory specified in 'seal_size' is reserved.
-// When writing position reaches max_size - seal_size, buffer auto-seals
-// itself with 'seal' and allows no further writes. Data pointed by
-// 'seal' must be available during entire LogDynamicBuffer lifetime.
-//
-// An instance of this class is created dynamically by Log.
-class LogDynamicBuffer {
- public:
-  LogDynamicBuffer(
-      int block_size, int max_size, const char* seal, int seal_size);
-
-  ~LogDynamicBuffer();
-
-  // Reads contents of the buffer starting from 'from_pos'.  Upon
-  // return, 'dest_buf' is filled with the data. Actual amount of data
-  // filled is returned, it is <= 'buf_size'.
-  int Read(int from_pos, char* dest_buf, int buf_size);
-
-  // Writes 'data' to the buffer, making it larger if necessary.  If
-  // data is too big to fit in the buffer, it doesn't get written at
-  // all. In that case, buffer auto-seals itself and stops to accept
-  // any incoming writes. Returns amount of data written (it is either
-  // 'data_size', or 0, if 'data' is too big).
-  int Write(const char* data, int data_size);
-
- private:
-  void AllocateBlock(int index) {
-    blocks_[index] = NewArray<char>(block_size_);
-  }
-
-  int BlockIndex(int pos) const { return pos / block_size_; }
-
-  int BlocksCount() const { return BlockIndex(max_size_) + 1; }
-
-  int PosInBlock(int pos) const { return pos % block_size_; }
-
-  int Seal();
-
-  int WriteInternal(const char* data, int data_size);
-
-  const int block_size_;
-  const int max_size_;
-  const char* seal_;
-  const int seal_size_;
-  ScopedVector<char*> blocks_;
-  int write_pos_;
-  int block_index_;
-  int block_write_pos_;
-  bool is_sealed_;
-};
-
-
 // Functions and data for performing output of log messages.
 class Log {
  public:
-
   // Performs process-wide initialization.
   void Initialize();
 
@@ -103,18 +45,21 @@
   void stop() { is_stopped_ = true; }
 
   // Frees all resources acquired in Initialize and Open... functions.
-  void Close();
-
-  // See description in include/v8.h.
-  int GetLogLines(int from_pos, char* dest_buf, int max_size);
+  // When a temporary file is used for the log, returns its stream descriptor,
+  // leaving the file open.
+  FILE* Close();
 
   // Returns whether logging is enabled.
   bool IsEnabled() {
-    return !is_stopped_ && (output_handle_ != NULL || output_buffer_ != NULL);
+    return !is_stopped_ && output_handle_ != NULL;
   }
 
   // Size of buffer used for formatting log messages.
-  static const int kMessageBufferSize = v8::V8::kMinimumSizeForLogLinesBuffer;
+  static const int kMessageBufferSize = 2048;
+
+  // This mode is only used in tests, as temporary files are automatically
+  // deleted on close and thus can't be accessed afterwards.
+  static const char* kLogToTemporaryFile;
 
  private:
   explicit Log(Logger* logger);
@@ -125,8 +70,8 @@
   // Opens file for logging.
   void OpenFile(const char* name);
 
-  // Opens memory buffer for logging.
-  void OpenMemoryBuffer();
+  // Opens a temporary file for logging.
+  void OpenTemporaryFile();
 
   // Implementation of writing to a log file.
   int WriteToFile(const char* msg, int length) {
@@ -138,38 +83,16 @@
     return length;
   }
 
-  // Implementation of writing to a memory buffer.
-  int WriteToMemory(const char* msg, int length) {
-    ASSERT(output_buffer_ != NULL);
-    return output_buffer_->Write(msg, length);
-  }
-
-  bool write_to_file_;
-
   // Whether logging is stopped (e.g. due to insufficient resources).
   bool is_stopped_;
 
-  // When logging is active, either output_handle_ or output_buffer_ is used
-  // to store a pointer to log destination. If logging was opened via OpenStdout
-  // or OpenFile, then output_handle_ is used. If logging was opened
-  // via OpenMemoryBuffer, then output_buffer_ is used.
-  // mutex_ should be acquired before using output_handle_ or output_buffer_.
+  // When logging is active output_handle_ is used to store a pointer to log
+  // destination.  mutex_ should be acquired before using output_handle_.
   FILE* output_handle_;
 
   // Used when low-level profiling is active.
   FILE* ll_output_handle_;
 
-  LogDynamicBuffer* output_buffer_;
-
-  // Size of dynamic buffer block (and dynamic buffer initial size).
-  static const int kDynamicBufferBlockSize = 65536;
-
-  // Maximum size of dynamic buffer.
-  static const int kMaxDynamicBufferSize = 50 * 1024 * 1024;
-
-  // Message to "seal" dynamic buffer with.
-  static const char* const kDynamicBufferSeal;
-
   // mutex_ is a Mutex used for enforcing exclusive
   // access to the formatting buffer and the log file or log memory buffer.
   Mutex* mutex_;
@@ -224,8 +147,6 @@
   int pos_;
 };
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
 
 #endif  // V8_LOG_UTILS_H_
diff --git a/src/log.cc b/src/log.cc
index 0474ce0..04fd22e 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -43,8 +43,6 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 //
 // Sliding state window.  Updates counters to keep track of the last
 // window of kBufferSize states.  This is useful to track where we
@@ -122,6 +120,7 @@
   // Returns the next index in the cyclic buffer.
   int Succ(int index) { return (index + 1) % kBufferSize; }
 
+  Isolate* isolate_;
   // Cyclic buffer for communicating profiling samples
   // between the signal handler and the worker thread.
   static const int kBufferSize = 128;
@@ -148,10 +147,6 @@
 void StackTracer::Trace(Isolate* isolate, TickSample* sample) {
   ASSERT(isolate->IsInitialized());
 
-  sample->tos = NULL;
-  sample->frames_count = 0;
-  sample->has_external_callback = false;
-
   // Avoid collecting traces while doing GC.
   if (sample->state == GC) return;
 
@@ -271,7 +266,8 @@
 // Profiler implementation.
 //
 Profiler::Profiler(Isolate* isolate)
-    : Thread(isolate, "v8:Profiler"),
+    : Thread("v8:Profiler"),
+      isolate_(isolate),
       head_(0),
       tail_(0),
       overflow_(false),
@@ -326,9 +322,8 @@
 void Profiler::Run() {
   TickSample sample;
   bool overflow = Remove(&sample);
-  i::Isolate* isolate = ISOLATE;
   while (running_) {
-    LOG(isolate, TickEvent(&sample, overflow));
+    LOG(isolate_, TickEvent(&sample, overflow));
     overflow = Remove(&sample);
   }
 }
@@ -399,8 +394,10 @@
 
   void Remove(Address code_address) {
     HashMap::Entry* entry = FindEntry(code_address);
-    if (entry != NULL) DeleteArray(static_cast<const char*>(entry->value));
-    RemoveEntry(entry);
+    if (entry != NULL) {
+      DeleteArray(static_cast<char*>(entry->value));
+      RemoveEntry(entry);
+    }
   }
 
   void Move(Address from, Address to) {
@@ -522,7 +519,6 @@
     log_events_(NULL),
     logging_nesting_(0),
     cpu_profiler_nesting_(0),
-    heap_profiler_nesting_(0),
     log_(new Log(this)),
     name_buffer_(new NameBuffer),
     address_to_name_map_(NULL),
@@ -556,71 +552,54 @@
   msg.WriteToLogFile();
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 
 void Logger::StringEvent(const char* name, const char* value) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log) UncheckedStringEvent(name, value);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::UncheckedStringEvent(const char* name, const char* value) {
   if (!log_->IsEnabled()) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,\"%s\"\n", name, value);
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::IntEvent(const char* name, int value) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log) UncheckedIntEvent(name, value);
-#endif
 }
 
 
 void Logger::IntPtrTEvent(const char* name, intptr_t value) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log) UncheckedIntPtrTEvent(name, value);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::UncheckedIntEvent(const char* name, int value) {
   if (!log_->IsEnabled()) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,%d\n", name, value);
   msg.WriteToLogFile();
 }
-#endif
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
   if (!log_->IsEnabled()) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value);
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::HandleEvent(const char* name, Object** location) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_handles) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,0x%" V8PRIxPTR "\n", name, location);
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 // ApiEvent is private so all the calls come from the Logger class.  It is the
 // caller's responsibility to ensure that log is enabled and that
 // FLAG_log_api is true.
@@ -633,11 +612,9 @@
   va_end(ap);
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::ApiNamedSecurityCheck(Object* key) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   if (key->IsString()) {
     SmartPointer<char> str =
@@ -648,14 +625,12 @@
   } else {
     ApiEvent("api,check-security,['no-name']\n");
   }
-#endif
 }
 
 
 void Logger::SharedLibraryEvent(const char* library_path,
                                 uintptr_t start,
                                 uintptr_t end) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_prof) return;
   LogMessageBuilder msg(this);
   msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
@@ -663,14 +638,12 @@
              start,
              end);
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::SharedLibraryEvent(const wchar_t* library_path,
                                 uintptr_t start,
                                 uintptr_t end) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_prof) return;
   LogMessageBuilder msg(this);
   msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
@@ -678,11 +651,9 @@
              start,
              end);
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
   // Prints "/" + re.source + "/" +
   //      (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
@@ -723,23 +694,19 @@
 
   msg.WriteToLogFile();
 }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 
 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_regexp) return;
   LogMessageBuilder msg(this);
   msg.Append("regexp-compile,");
   LogRegExpSource(regexp);
   msg.Append(in_cache ? ",hit\n" : ",miss\n");
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::LogRuntime(Vector<const char> format, JSArray* args) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_runtime) return;
   HandleScope scope;
   LogMessageBuilder msg(this);
@@ -780,22 +747,18 @@
   }
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::ApiIndexedSecurityCheck(uint32_t index) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   ApiEvent("api,check-security,%u\n", index);
-#endif
 }
 
 
 void Logger::ApiNamedPropertyAccess(const char* tag,
                                     JSObject* holder,
                                     Object* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   ASSERT(name->IsString());
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   String* class_name_obj = holder->class_name();
@@ -804,58 +767,47 @@
   SmartPointer<char> property_name =
       String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
-#endif
 }
 
 void Logger::ApiIndexedPropertyAccess(const char* tag,
                                       JSObject* holder,
                                       uint32_t index) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   String* class_name_obj = holder->class_name();
   SmartPointer<char> class_name =
       class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
-#endif
 }
 
 void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   String* class_name_obj = object->class_name();
   SmartPointer<char> class_name =
       class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
-#endif
 }
 
 
 void Logger::ApiEntryCall(const char* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   ApiEvent("api,%s\n", name);
-#endif
 }
 
 
 void Logger::NewEvent(const char* name, void* object, size_t size) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object,
              static_cast<unsigned int>(size));
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::DeleteEvent(const char* name, void* object) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object);
   msg.WriteToLogFile();
-#endif
 }
 
 
@@ -868,7 +820,6 @@
   LOGGER->DeleteEvent(name, object);
 }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::CallbackEventInternal(const char* prefix, const char* name,
                                    Address entry_point) {
   if (!log_->IsEnabled() || !FLAG_log_code) return;
@@ -881,43 +832,35 @@
   msg.Append('\n');
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::CallbackEvent(String* name, Address entry_point) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   SmartPointer<char> str =
       name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   CallbackEventInternal("", *str, entry_point);
-#endif
 }
 
 
 void Logger::GetterCallbackEvent(String* name, Address entry_point) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   SmartPointer<char> str =
       name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   CallbackEventInternal("get ", *str, entry_point);
-#endif
 }
 
 
 void Logger::SetterCallbackEvent(String* name, Address entry_point) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   SmartPointer<char> str =
       name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   CallbackEventInternal("set ", *str, entry_point);
-#endif
 }
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag,
                              Code* code,
                              const char* comment) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -947,14 +890,12 @@
   msg.Append('"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag,
                              Code* code,
                              String* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -979,11 +920,9 @@
   msg.Append('"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 // ComputeMarker must only be used when SharedFunctionInfo is known.
 static const char* ComputeMarker(Code* code) {
   switch (code->kind()) {
@@ -992,14 +931,12 @@
     default: return "";
   }
 }
-#endif
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag,
                              Code* code,
                              SharedFunctionInfo* shared,
                              String* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1031,7 +968,6 @@
   msg.Append(",%s", ComputeMarker(code));
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
@@ -1042,7 +978,6 @@
                              Code* code,
                              SharedFunctionInfo* shared,
                              String* source, int line) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1080,12 +1015,10 @@
   msg.Append(",%s", ComputeMarker(code));
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1108,21 +1041,17 @@
   msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count);
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeMovingGCEvent() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_ll_prof) return;
   LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag));
   OS::SignalCodeMovingGC();
-#endif
 }
 
 
 void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1147,36 +1076,30 @@
   msg.Append('\"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeMoveEvent(Address from, Address to) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to);
   if (Serializer::enabled() && address_to_name_map_ != NULL) {
     address_to_name_map_->Move(from, to);
   }
   MoveEventInternal(CODE_MOVE_EVENT, from, to);
-#endif
 }
 
 
 void Logger::CodeDeleteEvent(Address from) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from);
   if (Serializer::enabled() && address_to_name_map_ != NULL) {
     address_to_name_map_->Remove(from);
   }
   DeleteEventInternal(CODE_DELETE_EVENT, from);
-#endif
 }
 
 
 void Logger::SnapshotPositionEvent(Address addr, int pos) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos);
   if (Serializer::enabled() && address_to_name_map_ != NULL) {
@@ -1198,18 +1121,14 @@
   msg.Append(",%d", pos);
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::MoveEventInternal(LogEventsAndTags event,
                                Address from,
                                Address to) {
@@ -1222,10 +1141,8 @@
   msg.Append('\n');
   msg.WriteToLogFile();
 }
-#endif
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::DeleteEventInternal(LogEventsAndTags event, Address from) {
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   LogMessageBuilder msg(this);
@@ -1234,11 +1151,9 @@
   msg.Append('\n');
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::ResourceEvent(const char* name, const char* tag) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,%s,", name, tag);
@@ -1251,12 +1166,10 @@
 
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::SuspectReadEvent(String* name, Object* obj) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_suspect) return;
   LogMessageBuilder msg(this);
   String* class_name = obj->IsJSObject()
@@ -1270,12 +1183,10 @@
   msg.Append('"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg(this);
   // Using non-relative system time in order to be able to synchronize with
@@ -1283,121 +1194,34 @@
   msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n",
              space, kind, OS::TimeCurrentMillis());
   msg.WriteToLogFile();
-#endif
-}
-
-
-void Logger::HeapSampleStats(const char* space, const char* kind,
-                             intptr_t capacity, intptr_t used) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!log_->IsEnabled() || !FLAG_log_gc) return;
-  LogMessageBuilder msg(this);
-  msg.Append("heap-sample-stats,\"%s\",\"%s\","
-                 "%" V8_PTR_PREFIX "d,%" V8_PTR_PREFIX "d\n",
-             space, kind, capacity, used);
-  msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg(this);
   msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg(this);
   msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
   msg.WriteToLogFile();
-#endif
-}
-
-
-void Logger::HeapSampleJSConstructorEvent(const char* constructor,
-                                          int number, int bytes) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!log_->IsEnabled() || !FLAG_log_gc) return;
-  LogMessageBuilder msg(this);
-  msg.Append("heap-js-cons-item,%s,%d,%d\n", constructor, number, bytes);
-  msg.WriteToLogFile();
-#endif
-}
-
-// Event starts with comma, so we don't have it in the format string.
-static const char kEventText[] = "heap-js-ret-item,%s";
-// We take placeholder strings into account, but it's OK to be conservative.
-static const int kEventTextLen = sizeof(kEventText)/sizeof(kEventText[0]);
-
-void Logger::HeapSampleJSRetainersEvent(
-    const char* constructor, const char* event) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!log_->IsEnabled() || !FLAG_log_gc) return;
-  const int cons_len = StrLength(constructor);
-  const int event_len = StrLength(event);
-  int pos = 0;
-  // Retainer lists can be long. We may need to split them into multiple events.
-  do {
-    LogMessageBuilder msg(this);
-    msg.Append(kEventText, constructor);
-    int to_write = event_len - pos;
-    if (to_write > Log::kMessageBufferSize - (cons_len + kEventTextLen)) {
-      int cut_pos = pos + Log::kMessageBufferSize - (cons_len + kEventTextLen);
-      ASSERT(cut_pos < event_len);
-      while (cut_pos > pos && event[cut_pos] != ',') --cut_pos;
-      if (event[cut_pos] != ',') {
-        // Crash in debug mode, skip in release mode.
-        ASSERT(false);
-        return;
-      }
-      // Append a piece of event that fits, without trailing comma.
-      msg.AppendStringPart(event + pos, cut_pos - pos);
-      // Start next piece with comma.
-      pos = cut_pos;
-    } else {
-      msg.Append("%s", event + pos);
-      pos += event_len;
-    }
-    msg.Append('\n');
-    msg.WriteToLogFile();
-  } while (pos < event_len);
-#endif
-}
-
-
-void Logger::HeapSampleJSProducerEvent(const char* constructor,
-                                       Address* stack) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!log_->IsEnabled() || !FLAG_log_gc) return;
-  LogMessageBuilder msg(this);
-  msg.Append("heap-js-prod-item,%s", constructor);
-  while (*stack != NULL) {
-    msg.Append(",0x%" V8PRIxPTR, *stack++);
-  }
-  msg.Append("\n");
-  msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::DebugTag(const char* call_site_tag) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("debug-tag,%s\n", call_site_tag);
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   StringBuilder s(parameter.length() + 1);
   for (int i = 0; i < parameter.length(); ++i) {
@@ -1411,11 +1235,9 @@
              parameter_string);
   DeleteArray(parameter_string);
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::TickEvent(TickSample* sample, bool overflow) {
   if (!log_->IsEnabled() || !FLAG_prof) return;
   LogMessageBuilder msg(this);
@@ -1443,21 +1265,14 @@
 }
 
 
-int Logger::GetActiveProfilerModules() {
-  int result = PROFILER_MODULE_NONE;
-  if (profiler_ != NULL && !profiler_->paused()) {
-    result |= PROFILER_MODULE_CPU;
-  }
-  if (FLAG_log_gc) {
-    result |= PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS;
-  }
-  return result;
+bool Logger::IsProfilerPaused() {
+  return profiler_ == NULL || profiler_->paused();
 }
 
 
-void Logger::PauseProfiler(int flags, int tag) {
+void Logger::PauseProfiler() {
   if (!log_->IsEnabled()) return;
-  if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) {
+  if (profiler_ != NULL) {
     // It is OK to have negative nesting.
     if (--cpu_profiler_nesting_ == 0) {
       profiler_->pause();
@@ -1466,31 +1281,17 @@
           ticker_->Stop();
         }
         FLAG_log_code = false;
-        // Must be the same message as Log::kDynamicBufferSeal.
         LOG(ISOLATE, UncheckedStringEvent("profiler", "pause"));
       }
       --logging_nesting_;
     }
   }
-  if (flags &
-      (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) {
-    if (--heap_profiler_nesting_ == 0) {
-      FLAG_log_gc = false;
-      --logging_nesting_;
-    }
-  }
-  if (tag != 0) {
-    UncheckedIntEvent("close-tag", tag);
-  }
 }
 
 
-void Logger::ResumeProfiler(int flags, int tag) {
+void Logger::ResumeProfiler() {
   if (!log_->IsEnabled()) return;
-  if (tag != 0) {
-    UncheckedIntEvent("open-tag", tag);
-  }
-  if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) {
+  if (profiler_ != NULL) {
     if (cpu_profiler_nesting_++ == 0) {
       ++logging_nesting_;
       if (FLAG_prof_lazy) {
@@ -1506,20 +1307,13 @@
       profiler_->resume();
     }
   }
-  if (flags &
-      (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) {
-    if (heap_profiler_nesting_++ == 0) {
-      ++logging_nesting_;
-      FLAG_log_gc = true;
-    }
-  }
 }
 
 
 // This function can be called when Log's mutex is acquired,
 // either from main or Profiler's thread.
 void Logger::LogFailure() {
-  PauseProfiler(PROFILER_MODULE_CPU, 0);
+  PauseProfiler();
 }
 
 
@@ -1528,11 +1322,6 @@
 }
 
 
-int Logger::GetLogLines(int from_pos, char* dest_buf, int max_size) {
-  return log_->GetLogLines(from_pos, dest_buf, max_size);
-}
-
-
 class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor {
  public:
   EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis,
@@ -1544,8 +1333,12 @@
   virtual void LeaveContext(Context* context) {}
 
   virtual void VisitFunction(JSFunction* function) {
+    SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared());
+    Object* maybe_script = sfi->script();
+    if (maybe_script->IsScript()
+        && !Script::cast(maybe_script)->HasValidSource()) return;
     if (sfis_ != NULL) {
-      sfis_[*count_] = Handle<SharedFunctionInfo>(function->shared());
+      sfis_[*count_] = Handle<SharedFunctionInfo>(sfi);
     }
     if (code_objects_ != NULL) {
       ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
@@ -1649,7 +1442,6 @@
 
 
 void Logger::LogCodeInfo() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_ll_prof) return;
 #if V8_TARGET_ARCH_IA32
   const char arch[] = "ia32";
@@ -1661,7 +1453,6 @@
   const char arch[] = "unknown";
 #endif
   LowLevelLogWriteBytes(arch, sizeof(arch));
-#endif  // ENABLE_LOGGING_AND_PROFILING
 }
 
 
@@ -1814,11 +1605,8 @@
   }
 }
 
-#endif
-
 
 bool Logger::Setup() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
   if (is_initialized_) return true;
   is_initialized_ = true;
@@ -1842,9 +1630,9 @@
 
   if (FLAG_ll_prof) LogCodeInfo();
 
-  ticker_ = new Ticker(Isolate::Current(), kSamplingIntervalMs);
-
   Isolate* isolate = Isolate::Current();
+  ticker_ = new Ticker(isolate, kSamplingIntervalMs);
+
   if (FLAG_sliding_state_window && sliding_state_window_ == NULL) {
     sliding_state_window_ = new SlidingStateWindow(isolate);
   }
@@ -1870,10 +1658,6 @@
   }
 
   return true;
-
-#else
-  return false;
-#endif
 }
 
 
@@ -1883,23 +1667,18 @@
 
 
 void Logger::EnsureTickerStarted() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   ASSERT(ticker_ != NULL);
   if (!ticker_->IsActive()) ticker_->Start();
-#endif
 }
 
 
 void Logger::EnsureTickerStopped() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (ticker_ != NULL && ticker_->IsActive()) ticker_->Stop();
-#endif
 }
 
 
-void Logger::TearDown() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!is_initialized_) return;
+FILE* Logger::TearDown() {
+  if (!is_initialized_) return NULL;
   is_initialized_ = false;
 
   // Stop the profiler before closing the file.
@@ -1915,13 +1694,11 @@
   delete ticker_;
   ticker_ = NULL;
 
-  log_->Close();
-#endif
+  return log_->Close();
 }
 
 
 void Logger::EnableSlidingStateWindow() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If the ticker is NULL, Logger::Setup has not been called yet.  In
   // that case, we set the sliding_state_window flag so that the
   // sliding window computation will be started when Logger::Setup is
@@ -1935,7 +1712,6 @@
   if (sliding_state_window_ == NULL) {
     sliding_state_window_ = new SlidingStateWindow(Isolate::Current());
   }
-#endif
 }
 
 
diff --git a/src/log.h b/src/log.h
index 93f3fe7..31d8404 100644
--- a/src/log.h
+++ b/src/log.h
@@ -78,7 +78,6 @@
 class Ticker;
 
 #undef LOG
-#ifdef ENABLE_LOGGING_AND_PROFILING
 #define LOG(isolate, Call)                          \
   do {                                              \
     v8::internal::Logger* logger =                  \
@@ -86,9 +85,6 @@
     if (logger->is_logging())                       \
       logger->Call;                                 \
   } while (false)
-#else
-#define LOG(isolate, Call) ((void) 0)
-#endif
 
 #define LOG_EVENTS_AND_TAGS_LIST(V)                                     \
   V(CODE_CREATION_EVENT,            "code-creation")                    \
@@ -161,7 +157,9 @@
   Sampler* sampler();
 
   // Frees resources acquired in Setup.
-  void TearDown();
+  // When a temporary file is used for the log, returns its stream descriptor,
+  // leaving the file open.
+  FILE* TearDown();
 
   // Enable the computation of a sliding window of states.
   void EnableSlidingStateWindow();
@@ -272,7 +270,6 @@
   // Log an event reported from generated code
   void LogRuntime(Vector<const char> format, JSArray* args);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   bool is_logging() {
     return logging_nesting_ > 0;
   }
@@ -280,13 +277,9 @@
   // Pause/Resume collection of profiling data.
   // When data collection is paused, CPU Tick events are discarded until
   // data collection is Resumed.
-  void PauseProfiler(int flags, int tag);
-  void ResumeProfiler(int flags, int tag);
-  int GetActiveProfilerModules();
-
-  // If logging is performed into a memory buffer, allows to
-  // retrieve previously written messages. See v8.h.
-  int GetLogLines(int from_pos, char* dest_buf, int max_size);
+  void PauseProfiler();
+  void ResumeProfiler();
+  bool IsProfilerPaused();
 
   // Logs all compiled functions found in the heap.
   void LogCompiledFunctions();
@@ -407,7 +400,6 @@
 
   int logging_nesting_;
   int cpu_profiler_nesting_;
-  int heap_profiler_nesting_;
 
   Log* log_;
 
@@ -431,9 +423,6 @@
   Address prev_code_;
 
   friend class CpuProfiler;
-#else
-  bool is_logging() { return false; }
-#endif
 };
 
 
diff --git a/src/macros.py b/src/macros.py
index 28d501f..fc08cb1 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -38,12 +38,13 @@
 const SETTER = 1;
 
 # These definitions must match the index of the properties in objects.h.
-const kApiTagOffset               = 0;
-const kApiPropertyListOffset      = 1;
-const kApiSerialNumberOffset      = 2;
-const kApiConstructorOffset       = 2;
-const kApiPrototypeTemplateOffset = 5;
-const kApiParentTemplateOffset    = 6;
+const kApiTagOffset                 = 0;
+const kApiPropertyListOffset        = 1;
+const kApiSerialNumberOffset        = 2;
+const kApiConstructorOffset         = 2;
+const kApiPrototypeTemplateOffset   = 5;
+const kApiParentTemplateOffset      = 6;
+const kApiPrototypeAttributesOffset = 15;
 
 const NO_HINT     = 0;
 const NUMBER_HINT = 1;
@@ -128,6 +129,7 @@
 macro TO_STRING_INLINE(arg) = (IS_STRING(%IS_VAR(arg)) ? arg : NonStringToString(arg));
 macro TO_NUMBER_INLINE(arg) = (IS_NUMBER(%IS_VAR(arg)) ? arg : NonNumberToNumber(arg));
 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");
 
 # Macros implemented in Python.
 python macro CHAR_CODE(str) = ord(str[1]);
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 9439905..0bf8286 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -396,6 +396,8 @@
                                          FixedArray::BodyDescriptor,
                                          void>::Visit);
 
+    table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit);
+
     table_.Register(kVisitGlobalContext,
                     &FixedBodyVisitor<StaticMarkingVisitor,
                                       Context::MarkCompactBodyDescriptor,
@@ -675,8 +677,9 @@
 
     Map* map = SafeMap(ctx);
     Heap* heap = map->heap();
-    if (!(map == heap->raw_unchecked_context_map() ||
+    if (!(map == heap->raw_unchecked_function_context_map() ||
           map == heap->raw_unchecked_catch_context_map() ||
+          map == heap->raw_unchecked_with_context_map() ||
           map == heap->raw_unchecked_global_context_map())) {
       return false;
     }
@@ -942,18 +945,6 @@
     StaticMarkingVisitor::VisitPointers(heap_, start, end);
   }
 
-  void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
-    StaticMarkingVisitor::VisitCodeTarget(heap, rinfo);
-  }
-
-  void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) {
-    StaticMarkingVisitor::VisitGlobalPropertyCell(heap, rinfo);
-  }
-
-  void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) {
-    StaticMarkingVisitor::VisitDebugTarget(heap, rinfo);
-  }
-
  private:
   Heap* heap_;
 };
@@ -1106,6 +1097,7 @@
   int PointersRemoved() {
     return pointers_removed_;
   }
+
  private:
   Heap* heap_;
   int pointers_removed_;
@@ -1136,9 +1128,12 @@
       map->ClearCodeCache(heap());
     }
     SetMark(map);
-    if (FLAG_collect_maps &&
-        map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
-        map->instance_type() <= JS_FUNCTION_TYPE) {
+
+    // When map collection is enabled we have to mark through map's transitions
+    // in a special way to make transition links weak.
+    // Only maps for subclasses of JSReceiver can have transitions.
+    STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
+    if (FLAG_collect_maps && map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
       MarkMapContents(map);
     } else {
       marking_stack_.Push(map);
@@ -1220,8 +1215,8 @@
        next_object != NULL; next_object = iterator.next()) {
     if (next_object->IsMap()) {  // Could also be ByteArray on free list.
       Map* map = Map::cast(next_object);
-      if (map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
-          map->instance_type() <= JS_FUNCTION_TYPE) {
+      STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+      if (map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
         map->CreateBackPointers();
       } else {
         ASSERT(map->instance_descriptors() == heap()->empty_descriptor_array());
@@ -1505,6 +1500,12 @@
   // reachable from the weak roots.
   ProcessExternalMarking();
 
+  // Object literal map caches reference symbols (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
+  // symbol table.
+  ProcessMapCaches();
+
   // Prune the symbol table removing all symbols only pointed to by the
   // symbol table.  Cannot use symbol_table() here because the symbol
   // table is marked.
@@ -1533,6 +1534,57 @@
 }
 
 
+void MarkCompactCollector::ProcessMapCaches() {
+  Object* raw_context = heap()->global_contexts_list_;
+  while (raw_context != heap()->undefined_value()) {
+    Context* context = reinterpret_cast<Context*>(raw_context);
+    if (context->IsMarked()) {
+      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 (!raw_map_cache->IsMarked() &&
+          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()->null_value()) continue;
+          STATIC_ASSERT(MapCache::kEntrySize == 2);
+          Object* raw_map = map_cache->get(i + 1);
+          if (raw_map->IsHeapObject() &&
+              HeapObject::cast(raw_map)->IsMarked()) {
+            ++used_elements;
+          } else {
+            // Delete useless entries with unmarked maps.
+            ASSERT(raw_map->IsMap());
+            map_cache->set_null_unchecked(heap(), i);
+            map_cache->set_null_unchecked(heap(), 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);
+          MarkObject(map_cache);
+        }
+      }
+    }
+    // Move to next element in the list.
+    raw_context = context->get(Context::NEXT_CONTEXT_LINK);
+  }
+  ProcessMarkingStack();
+}
+
+
 #ifdef DEBUG
 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
   live_bytes_ += obj->Size();
@@ -1597,8 +1649,8 @@
 
     ASSERT(SafeIsMap(map));
     // Only JSObject and subtypes have map transitions and back pointers.
-    if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue;
-    if (map->instance_type() > JS_FUNCTION_TYPE) continue;
+    STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+    if (map->instance_type() < FIRST_JS_RECEIVER_TYPE) continue;
 
     if (map->IsMarked() && map->attached_to_shared_function_info()) {
       // This map is used for inobject slack tracking and has been detached
@@ -1608,38 +1660,48 @@
     }
 
     // Clear dead prototype transitions.
-    FixedArray* prototype_transitions = map->unchecked_prototype_transitions();
-    if (prototype_transitions->length() > 0) {
-      int finger = Smi::cast(prototype_transitions->get(0))->value();
-      int new_finger = 1;
-      for (int i = 1; i < finger; i += 2) {
-        Object* prototype = prototype_transitions->get(i);
-        Object* cached_map = prototype_transitions->get(i + 1);
+    int number_of_transitions = map->NumberOfProtoTransitions();
+    if (number_of_transitions > 0) {
+      FixedArray* prototype_transitions =
+          map->unchecked_prototype_transitions();
+      int new_number_of_transitions = 0;
+      const int header = Map::kProtoTransitionHeaderSize;
+      const int proto_offset =
+          header + Map::kProtoTransitionPrototypeOffset;
+      const int map_offset = header + Map::kProtoTransitionMapOffset;
+      const int step = Map::kProtoTransitionElementsPerEntry;
+      for (int i = 0; i < number_of_transitions; i++) {
+        Object* prototype = prototype_transitions->get(proto_offset + i * step);
+        Object* cached_map = prototype_transitions->get(map_offset + i * step);
         if (HeapObject::cast(prototype)->IsMarked() &&
             HeapObject::cast(cached_map)->IsMarked()) {
-          if (new_finger != i) {
-            prototype_transitions->set_unchecked(heap_,
-                                                 new_finger,
-                                                 prototype,
-                                                 UPDATE_WRITE_BARRIER);
-            prototype_transitions->set_unchecked(heap_,
-                                                 new_finger + 1,
-                                                 cached_map,
-                                                 SKIP_WRITE_BARRIER);
+          if (new_number_of_transitions != i) {
+            prototype_transitions->set_unchecked(
+                heap_,
+                proto_offset + new_number_of_transitions * step,
+                prototype,
+                UPDATE_WRITE_BARRIER);
+            prototype_transitions->set_unchecked(
+                heap_,
+                map_offset + new_number_of_transitions * step,
+                cached_map,
+                SKIP_WRITE_BARRIER);
           }
-          new_finger += 2;
+          new_number_of_transitions++;
         }
       }
 
       // Fill slots that became free with undefined value.
       Object* undefined = heap()->raw_unchecked_undefined_value();
-      for (int i = new_finger; i < finger; i++) {
+      for (int i = new_number_of_transitions * step;
+           i < number_of_transitions * step;
+           i++) {
         prototype_transitions->set_unchecked(heap_,
-                                             i,
+                                             header + i,
                                              undefined,
                                              SKIP_WRITE_BARRIER);
       }
-      prototype_transitions->set_unchecked(0, Smi::FromInt(new_finger));
+      map->SetNumberOfProtoTransitions(new_number_of_transitions);
     }
 
     // Follow the chain of back pointers to find the prototype.
@@ -2001,6 +2063,7 @@
     VisitPointer(&target);
     rinfo->set_call_address(Code::cast(target)->instruction_start());
   }
+
  private:
   Heap* heap_;
 };
@@ -3195,11 +3258,9 @@
     GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj));
   }
 #endif
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (obj->IsCode()) {
     PROFILE(isolate, CodeDeleteEvent(obj->address()));
   }
-#endif
 }
 
 
diff --git a/src/mark-compact.h b/src/mark-compact.h
index 04d0ff6..179edba 100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -306,6 +306,10 @@
   // flag on the marking stack.
   void RefillMarkingStack();
 
+  // 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);
diff --git a/src/messages.js b/src/messages.js
index 75ea99d..0b314a4 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -151,6 +151,7 @@
       unexpected_token_number:      ["Unexpected number"],
       unexpected_token_string:      ["Unexpected string"],
       unexpected_token_identifier:  ["Unexpected identifier"],
+      unexpected_reserved:          ["Unexpected reserved word"],
       unexpected_strict_reserved:   ["Unexpected strict mode reserved word"],
       unexpected_eos:               ["Unexpected end of input"],
       malformed_regexp:             ["Invalid regular expression: /", "%0", "/: ", "%1"],
@@ -193,9 +194,15 @@
       proto_object_or_null:         ["Object prototype may only be an Object or null"],
       property_desc_object:         ["Property description must be an object: ", "%0"],
       redefine_disallowed:          ["Cannot redefine property: ", "%0"],
-      define_disallowed:            ["Cannot define property, object is not extensible: ", "%0"],
+      define_disallowed:            ["Cannot define property:", "%0", ", object is not extensible."],
       non_extensible_proto:         ["%0", " is not extensible"],
+      handler_non_object:           ["Proxy.", "%0", " called with non-object as handler"],
       handler_trap_missing:         ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
+      handler_returned_false:       ["Proxy handler ", "%0", " returned false for '", "%1", "' trap"],
+      handler_returned_undefined:   ["Proxy handler ", "%0", " returned undefined for '", "%1", "' trap"],
+      proxy_prop_not_configurable:  ["Trap ", "%1", " of proxy handler ", "%0", " returned non-configurable descriptor for property ", "%2"],
+      proxy_non_object_prop_names:  ["Trap ", "%1", " returned non-object ", "%0"],
+      proxy_repeated_prop_name:     ["Trap ", "%1", " returned repeated property name ", "%2"],
       // RangeError
       invalid_array_length:         ["Invalid array length"],
       stack_overflow:               ["Maximum call stack size exceeded"],
@@ -242,7 +249,7 @@
       strict_poison_pill:           ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
       strict_caller:                ["Illegal access to a strict mode caller function."],
       cant_prevent_ext_external_array_elements: ["Cannot prevent extension of an object with external array elements"],
-      redef_external_array_element: ["Cannot redefine a property of an object with external array elements"],
+      redef_external_array_element: ["Cannot redefine a property of an object"]
     };
   }
   var message_type = %MessageGetType(message);
@@ -687,18 +694,24 @@
   // can't rely on 'this' being the same as 'obj'.
   var hasBeenSet = false;
   var value;
-  obj.__defineGetter__(name, function () {
+  function getter() {
     if (hasBeenSet) {
       return value;
     }
     hasBeenSet = true;
     value = fun(obj);
     return value;
-  });
-  obj.__defineSetter__(name, function (v) {
+  }
+  function setter(v) {
     hasBeenSet = true;
     value = v;
-  });
+  }
+  var desc = { get: getter,
+               set: setter,
+               enumerable: false,
+               configurable: true };
+  desc = ToPropertyDescriptor(desc);
+  DefineOwnProperty(obj, name, desc, true);
 }
 
 function CallSite(receiver, fun, pos) {
@@ -1014,15 +1027,15 @@
   // overwriting allows leaks of error objects between script blocks
   // in the same context in a browser setting. Therefore we fix the
   // name.
-  %SetProperty(f.prototype, "name", name, READ_ONLY | DONT_DELETE);
+  %SetProperty(f.prototype, "name", name, DONT_ENUM | DONT_DELETE | READ_ONLY);
   %SetCode(f, function(m) {
     if (%_IsConstructCall()) {
       // Define all the expected properties directly on the error
       // object. This avoids going through getters and setters defined
       // on prototype objects.
-      %IgnoreAttributesAndSetProperty(this, 'stack', void 0);
-      %IgnoreAttributesAndSetProperty(this, 'arguments', void 0);
-      %IgnoreAttributesAndSetProperty(this, 'type', void 0);
+      %IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM);
+      %IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM);
+      %IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM);
       if (m === kAddMessageAccessorsMarker) {
         // DefineOneShotAccessor always inserts a message property and
         // ignores setters.
@@ -1030,7 +1043,10 @@
             return FormatMessage(%NewMessageObject(obj.type, obj.arguments));
         });
       } else if (!IS_UNDEFINED(m)) {
-        %IgnoreAttributesAndSetProperty(this, 'message', ToString(m));
+        %IgnoreAttributesAndSetProperty(this,
+                                        'message',
+                                        ToString(m),
+                                        DONT_ENUM);
       }
       captureStackTrace(this, f);
     } else {
@@ -1055,18 +1071,32 @@
 
 $Math.__proto__ = global.Object.prototype;
 
-DefineError(function Error() { });
-DefineError(function TypeError() { });
-DefineError(function RangeError() { });
-DefineError(function SyntaxError() { });
-DefineError(function ReferenceError() { });
-DefineError(function EvalError() { });
-DefineError(function URIError() { });
+// DefineError is a native function. Use explicit receiver. Otherwise
+// the receiver will be 'undefined'.
+this.DefineError(function Error() { });
+this.DefineError(function TypeError() { });
+this.DefineError(function RangeError() { });
+this.DefineError(function SyntaxError() { });
+this.DefineError(function ReferenceError() { });
+this.DefineError(function EvalError() { });
+this.DefineError(function URIError() { });
 
 $Error.captureStackTrace = captureStackTrace;
 
 // Setup extra properties of the Error.prototype object.
-$Error.prototype.message = '';
+function setErrorMessage() {
+  var desc = {value: '',
+              enumerable: false,
+              configurable: true,
+              writable: true };
+  DefineOwnProperty($Error.prototype,
+                    'message',
+                    ToPropertyDescriptor(desc),
+                    true);
+
+}
+
+setErrorMessage();
 
 // Global list of error objects visited during errorToString. This is
 // used to detect cycles in error toString formatting.
diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h
index e787fed..b5ffe73 100644
--- a/src/mips/assembler-mips-inl.h
+++ b/src/mips/assembler-mips-inl.h
@@ -83,8 +83,12 @@
 // RelocInfo.
 
 void RelocInfo::apply(intptr_t delta) {
-  // On MIPS we do not use pc relative addressing, so we don't need to patch the
-  // code here.
+  if (IsInternalReference(rmode_)) {
+    // Absolute code pointer inside code object moves with the code object.
+    byte* p = reinterpret_cast<byte*>(pc_);
+    int count = Assembler::RelocateInternalReference(p, delta);
+    CPU::FlushICache(p, count * sizeof(uint32_t));
+  }
 }
 
 
@@ -300,7 +304,9 @@
 
 
 void Assembler::emit(Instr x) {
-  CheckBuffer();
+  if (!is_buffer_growth_blocked()) {
+    CheckBuffer();
+  }
   *reinterpret_cast<Instr*>(pc_) = x;
   pc_ += kInstrSize;
   CheckTrampolinePoolQuick();
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index 2e10904..51642e0 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -140,7 +140,7 @@
 // -----------------------------------------------------------------------------
 // Implementation of RelocInfo.
 
-const int RelocInfo::kApplyMask = 0;
+const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE;
 
 
 bool RelocInfo::IsCodedSpecially() {
@@ -275,11 +275,17 @@
   last_trampoline_pool_end_ = 0;
   no_trampoline_pool_before_ = 0;
   trampoline_pool_blocked_nesting_ = 0;
-  next_buffer_check_ = kMaxBranchOffset - kTrampolineSize;
+  // We leave space (16 * kTrampolineSlotsSize)
+  // for BlockTrampolinePoolScope buffer.
+  next_buffer_check_ = kMaxBranchOffset - kTrampolineSlotsSize * 16;
   internal_trampoline_exception_ = false;
   last_bound_pos_ = 0;
 
-  ast_id_for_reloc_info_ = kNoASTId;
+  trampoline_emitted_ = false;
+  unbound_labels_count_ = 0;
+  block_buffer_growth_ = false;
+
+  ClearRecordedAstId();
 }
 
 
@@ -386,6 +392,16 @@
 }
 
 
+uint32_t Assembler::GetFunction(Instr instr) {
+  return (instr & kFunctionFieldMask) >> kFunctionShift;
+}
+
+
+uint32_t Assembler::GetFunctionField(Instr instr) {
+  return instr & kFunctionFieldMask;
+}
+
+
 uint32_t Assembler::GetImmediate16(Instr instr) {
   return instr & kImm16Mask;
 }
@@ -444,6 +460,8 @@
 // code is conv to an 18-bit value addressing bytes, hence the -4 value.
 
 const int kEndOfChain = -4;
+// Determines the end of the Jump chain (a subset of the label link chain).
+const int kEndOfJumpChain = 0;
 
 
 bool Assembler::IsBranch(Instr instr) {
@@ -477,6 +495,39 @@
 }
 
 
+bool Assembler::IsJump(Instr instr) {
+  uint32_t opcode   = GetOpcodeField(instr);
+  uint32_t rt_field = GetRtField(instr);
+  uint32_t rd_field = GetRdField(instr);
+  uint32_t function_field = GetFunctionField(instr);
+  // Checks if the instruction is a jump.
+  return opcode == J || opcode == JAL ||
+      (opcode == SPECIAL && rt_field == 0 &&
+      ((function_field == JALR) || (rd_field == 0 && (function_field == JR))));
+}
+
+
+bool Assembler::IsJ(Instr instr) {
+  uint32_t opcode = GetOpcodeField(instr);
+  // Checks if the instruction is a jump.
+  return opcode == J;
+}
+
+
+bool Assembler::IsLui(Instr instr) {
+  uint32_t opcode = GetOpcodeField(instr);
+  // Checks if the instruction is a load upper immediate.
+  return opcode == LUI;
+}
+
+
+bool Assembler::IsOri(Instr instr) {
+  uint32_t opcode = GetOpcodeField(instr);
+  // Checks if the instruction is a load upper immediate.
+  return opcode == ORI;
+}
+
+
 bool Assembler::IsNop(Instr instr, unsigned int type) {
   // See Assembler::nop(type).
   ASSERT(type < 32);
@@ -564,17 +615,47 @@
        return (imm18 + pos);
      }
   }
-  // Check we have a branch instruction.
-  ASSERT(IsBranch(instr));
+  // Check we have a branch or jump instruction.
+  ASSERT(IsBranch(instr) || IsJ(instr) || IsLui(instr));
   // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
   // the compiler uses arithmectic shifts for signed integers.
-  int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
+  if (IsBranch(instr)) {
+    int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
 
-  if (imm18 == kEndOfChain) {
-    // EndOfChain sentinel is returned directly, not relative to pc or pos.
-    return kEndOfChain;
+    if (imm18 == kEndOfChain) {
+      // EndOfChain sentinel is returned directly, not relative to pc or pos.
+      return kEndOfChain;
+    } else {
+      return pos + kBranchPCOffset + imm18;
+    }
+  } else if (IsLui(instr)) {
+    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
+    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
+    ASSERT(IsOri(instr_ori));
+    int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
+    imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
+
+    if (imm == kEndOfJumpChain) {
+      // EndOfChain sentinel is returned directly, not relative to pc or pos.
+      return kEndOfChain;
+    } else {
+      uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
+      int32_t delta = instr_address - imm;
+      ASSERT(pos > delta);
+      return pos - delta;
+    }
   } else {
-    return pos + kBranchPCOffset + imm18;
+    int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
+    if (imm28 == kEndOfJumpChain) {
+      // EndOfChain sentinel is returned directly, not relative to pc or pos.
+      return kEndOfChain;
+    } else {
+      uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
+      instr_address &= kImm28Mask;
+      int32_t delta = instr_address - imm28;
+      ASSERT(pos > delta);
+      return pos - delta;
+    }
   }
 }
 
@@ -589,15 +670,41 @@
     return;
   }
 
-  ASSERT(IsBranch(instr));
-  int32_t imm18 = target_pos - (pos + kBranchPCOffset);
-  ASSERT((imm18 & 3) == 0);
+  ASSERT(IsBranch(instr) || IsJ(instr) || IsLui(instr));
+  if (IsBranch(instr)) {
+    int32_t imm18 = target_pos - (pos + kBranchPCOffset);
+    ASSERT((imm18 & 3) == 0);
 
-  instr &= ~kImm16Mask;
-  int32_t imm16 = imm18 >> 2;
-  ASSERT(is_int16(imm16));
+    instr &= ~kImm16Mask;
+    int32_t imm16 = imm18 >> 2;
+    ASSERT(is_int16(imm16));
 
-  instr_at_put(pos, instr | (imm16 & kImm16Mask));
+    instr_at_put(pos, instr | (imm16 & kImm16Mask));
+  } else if (IsLui(instr)) {
+    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
+    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
+    ASSERT(IsOri(instr_ori));
+    uint32_t imm = (uint32_t)buffer_ + target_pos;
+    ASSERT((imm & 3) == 0);
+
+    instr_lui &= ~kImm16Mask;
+    instr_ori &= ~kImm16Mask;
+
+    instr_at_put(pos + 0 * Assembler::kInstrSize,
+                 instr_lui | ((imm & kHiMask) >> kLuiShift));
+    instr_at_put(pos + 1 * Assembler::kInstrSize,
+                 instr_ori | (imm & kImm16Mask));
+  } else {
+    uint32_t imm28 = (uint32_t)buffer_ + target_pos;
+    imm28 &= kImm28Mask;
+    ASSERT((imm28 & 3) == 0);
+
+    instr &= ~kImm26Mask;
+    uint32_t imm26 = imm28 >> 2;
+    ASSERT(is_uint26(imm26));
+
+    instr_at_put(pos, instr | (imm26 & kImm26Mask));
+  }
 }
 
 
@@ -627,36 +734,33 @@
 
 void Assembler::bind_to(Label* L, int pos) {
   ASSERT(0 <= pos && pos <= pc_offset());  // Must have 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()) {
     int32_t fixup_pos = L->pos();
     int32_t dist = pos - fixup_pos;
     next(L);  // Call next before overwriting link with target at fixup_pos.
-    if (dist > kMaxBranchOffset) {
-      do {
-        int32_t trampoline_pos = get_trampoline_entry(fixup_pos);
-        if (kInvalidSlotPos == trampoline_pos) {
-          // Internal error.
-          return;
+    Instr instr = instr_at(fixup_pos);
+    if (IsBranch(instr)) {
+      if (dist > kMaxBranchOffset) {
+        if (trampoline_pos == kInvalidSlotPos) {
+          trampoline_pos = get_trampoline_entry(fixup_pos);
+          CHECK(trampoline_pos != kInvalidSlotPos);
         }
         ASSERT((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
         target_at_put(fixup_pos, trampoline_pos);
         fixup_pos = trampoline_pos;
         dist = pos - fixup_pos;
-      } while (dist > kMaxBranchOffset);
-    } else if (dist < -kMaxBranchOffset) {
-      do {
-        int32_t trampoline_pos = get_trampoline_entry(fixup_pos, false);
-        if (kInvalidSlotPos == trampoline_pos) {
-          // Internal error.
-          return;
-        }
-        ASSERT((trampoline_pos - fixup_pos) >= -kMaxBranchOffset);
-        target_at_put(fixup_pos, trampoline_pos);
-        fixup_pos = trampoline_pos;
-        dist = pos - fixup_pos;
-      } while (dist < -kMaxBranchOffset);
-    };
-    target_at_put(fixup_pos, pos);
+      }
+      target_at_put(fixup_pos, pos);
+    } else {
+      ASSERT(IsJ(instr) || IsLui(instr));
+      target_at_put(fixup_pos, pos);
+    }
   }
   L->bind_to(pos);
 
@@ -667,27 +771,6 @@
 }
 
 
-void Assembler::link_to(Label* L, Label* appendix) {
-  if (appendix->is_linked()) {
-    if (L->is_linked()) {
-      // Append appendix to L's list.
-      int fixup_pos;
-      int link = L->pos();
-      do {
-        fixup_pos = link;
-        link = target_at(fixup_pos);
-      } while (link > 0);
-      ASSERT(link == kEndOfChain);
-      target_at_put(fixup_pos, appendix->pos());
-    } else {
-      // L is empty, simply use appendix.
-      *L = *appendix;
-    }
-  }
-  appendix->Unuse();  // Appendix should not be used anymore.
-}
-
-
 void Assembler::bind(Label* L) {
   ASSERT(!L->is_bound());  // Label can only be bound once.
   bind_to(L, pc_offset());
@@ -705,6 +788,12 @@
   }
 }
 
+bool Assembler::is_near(Label* L) {
+  if (L->is_bound()) {
+    return ((pc_offset() - L->pos()) < kMaxBranchOffset - 4 * kInstrSize);
+  }
+  return false;
+}
 
 // We have to use a temporary register for things that can be relocated even
 // if they can be encoded in the MIPS's 16 bits of immediate-offset instruction
@@ -817,7 +906,6 @@
 }
 
 
-// Registers are in the order of the instruction encoding, from left to right.
 void Assembler::GenInstrJump(Opcode opcode,
                               uint32_t address) {
   BlockTrampolinePoolScope block_trampoline_pool(this);
@@ -828,53 +916,15 @@
 }
 
 
-// Returns the next free label entry from the next trampoline pool.
-int32_t Assembler::get_label_entry(int32_t pos, bool next_pool) {
-  int trampoline_count = trampolines_.length();
-  int32_t label_entry = 0;
-  ASSERT(trampoline_count > 0);
-
-  if (next_pool) {
-    for (int i = 0; i < trampoline_count; i++) {
-      if (trampolines_[i].start() > pos) {
-       label_entry = trampolines_[i].take_label();
-       break;
-      }
-    }
-  } else {  //  Caller needs a label entry from the previous pool.
-    for (int i = trampoline_count-1; i >= 0; i--) {
-      if (trampolines_[i].end() < pos) {
-       label_entry = trampolines_[i].take_label();
-       break;
-      }
-    }
-  }
-  return label_entry;
-}
-
-
-// Returns the next free trampoline entry from the next trampoline pool.
-int32_t Assembler::get_trampoline_entry(int32_t pos, bool next_pool) {
-  int trampoline_count = trampolines_.length();
+// Returns the next free trampoline entry.
+int32_t Assembler::get_trampoline_entry(int32_t pos) {
   int32_t trampoline_entry = kInvalidSlotPos;
-  ASSERT(trampoline_count > 0);
 
   if (!internal_trampoline_exception_) {
-    if (next_pool) {
-      for (int i = 0; i < trampoline_count; i++) {
-        if (trampolines_[i].start() > pos) {
-         trampoline_entry = trampolines_[i].take_slot();
-         break;
-        }
-      }
-    } else {  //  Caller needs a trampoline entry from the previous pool.
-      for (int i = trampoline_count-1; i >= 0; i--) {
-        if (trampolines_[i].end() < pos) {
-         trampoline_entry = trampolines_[i].take_slot();
-         break;
-        }
-      }
+    if (trampoline_.start() > pos) {
+     trampoline_entry = trampoline_.take_slot();
     }
+
     if (kInvalidSlotPos == trampoline_entry) {
       internal_trampoline_exception_ = true;
     }
@@ -883,64 +933,43 @@
 }
 
 
-int32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
+uint32_t Assembler::jump_address(Label* L) {
   int32_t target_pos;
-  int32_t pc_offset_v = pc_offset();
 
   if (L->is_bound()) {
     target_pos = L->pos();
-    int32_t dist = pc_offset_v - target_pos;
-    if (dist > kMaxBranchOffset) {
-      do {
-        int32_t trampoline_pos = get_trampoline_entry(target_pos);
-        if (kInvalidSlotPos == trampoline_pos) {
-          // Internal error.
-          return 0;
-        }
-        ASSERT((trampoline_pos - target_pos) > 0);
-        ASSERT((trampoline_pos - target_pos) <= kMaxBranchOffset);
-        target_at_put(trampoline_pos, target_pos);
-        target_pos = trampoline_pos;
-        dist = pc_offset_v - target_pos;
-      } while (dist > kMaxBranchOffset);
-    } else if (dist < -kMaxBranchOffset) {
-      do {
-        int32_t trampoline_pos = get_trampoline_entry(target_pos, false);
-        if (kInvalidSlotPos == trampoline_pos) {
-          // Internal error.
-          return 0;
-        }
-        ASSERT((target_pos - trampoline_pos) > 0);
-        ASSERT((target_pos - trampoline_pos) <= kMaxBranchOffset);
-        target_at_put(trampoline_pos, target_pos);
-        target_pos = trampoline_pos;
-        dist = pc_offset_v - target_pos;
-      } while (dist < -kMaxBranchOffset);
-    }
   } else {
     if (L->is_linked()) {
       target_pos = L->pos();  // L's link.
-      int32_t dist = pc_offset_v - target_pos;
-      if (dist > kMaxBranchOffset) {
-        do {
-          int32_t label_pos = get_label_entry(target_pos);
-          ASSERT((label_pos - target_pos) < kMaxBranchOffset);
-          label_at_put(L, label_pos);
-          target_pos = label_pos;
-          dist = pc_offset_v - target_pos;
-        } while (dist > kMaxBranchOffset);
-      } else if (dist < -kMaxBranchOffset) {
-        do {
-          int32_t label_pos = get_label_entry(target_pos, false);
-          ASSERT((label_pos - target_pos) > -kMaxBranchOffset);
-          label_at_put(L, label_pos);
-          target_pos = label_pos;
-          dist = pc_offset_v - target_pos;
-        } while (dist < -kMaxBranchOffset);
-      }
       L->link_to(pc_offset());
     } else {
       L->link_to(pc_offset());
+      return kEndOfJumpChain;
+    }
+  }
+
+  uint32_t imm = (uint32_t)buffer_ + target_pos;
+  ASSERT((imm & 3) == 0);
+
+  return imm;
+}
+
+
+int32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
+  int32_t target_pos;
+
+  if (L->is_bound()) {
+    target_pos = L->pos();
+  } else {
+    if (L->is_linked()) {
+      target_pos = L->pos();
+      L->link_to(pc_offset());
+    } else {
+      L->link_to(pc_offset());
+      if (!trampoline_emitted_) {
+        unbound_labels_count_++;
+        next_buffer_check_ -= kTrampolineSlotsSize;
+      }
       return kEndOfChain;
     }
   }
@@ -969,6 +998,10 @@
     } else {
       target_pos = kEndOfChain;
       instr_at_put(at_offset, 0);
+      if (!trampoline_emitted_) {
+        unbound_labels_count_++;
+        next_buffer_check_ -= kTrampolineSlotsSize;
+      }
     }
     L->link_to(at_offset);
   }
@@ -1336,13 +1369,37 @@
 //-------------Misc-instructions--------------
 
 // Break / Trap instructions.
-void Assembler::break_(uint32_t code) {
+void Assembler::break_(uint32_t code, bool break_as_stop) {
   ASSERT((code & ~0xfffff) == 0);
+  // We need to invalidate breaks that could be stops as well because the
+  // simulator expects a char pointer after the stop instruction.
+  // See constants-mips.h for explanation.
+  ASSERT((break_as_stop &&
+          code <= kMaxStopCode &&
+          code > kMaxWatchpointCode) ||
+         (!break_as_stop &&
+          (code > kMaxStopCode ||
+           code <= kMaxWatchpointCode)));
   Instr break_instr = SPECIAL | BREAK | (code << 6);
   emit(break_instr);
 }
 
 
+void Assembler::stop(const char* msg, uint32_t code) {
+  ASSERT(code > kMaxWatchpointCode);
+  ASSERT(code <= kMaxStopCode);
+#if defined(V8_HOST_ARCH_MIPS)
+  break_(0x54321);
+#else  // V8_HOST_ARCH_MIPS
+  BlockTrampolinePoolFor(2);
+  // The Simulator will handle the stop instruction and get the message address.
+  // On MIPS stop() is just a special kind of break_().
+  break_(code, true);
+  emit(reinterpret_cast<Instr>(msg));
+#endif
+}
+
+
 void Assembler::tge(Register rs, Register rt, uint16_t code) {
   ASSERT(is_uint10(code));
   Instr instr = SPECIAL | TGE | rs.code() << kRsShift
@@ -1767,6 +1824,48 @@
 }
 
 
+int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
+  Instr instr = instr_at(pc);
+  ASSERT(IsJ(instr) || IsLui(instr));
+  if (IsLui(instr)) {
+    Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
+    Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
+    ASSERT(IsOri(instr_ori));
+    int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
+    imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
+    if (imm == kEndOfJumpChain) {
+      return 0;  // Number of instructions patched.
+    }
+    imm += pc_delta;
+    ASSERT((imm & 3) == 0);
+
+    instr_lui &= ~kImm16Mask;
+    instr_ori &= ~kImm16Mask;
+
+    instr_at_put(pc + 0 * Assembler::kInstrSize,
+                 instr_lui | ((imm >> kLuiShift) & kImm16Mask));
+    instr_at_put(pc + 1 * Assembler::kInstrSize,
+                 instr_ori | (imm & kImm16Mask));
+    return 2;  // Number of instructions patched.
+  } else {
+    uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
+    if ((int32_t)imm28 == kEndOfJumpChain) {
+      return 0;  // Number of instructions patched.
+    }
+    imm28 += pc_delta;
+    imm28 &= kImm28Mask;
+    ASSERT((imm28 & 3) == 0);
+
+    instr &= ~kImm26Mask;
+    uint32_t imm26 = imm28 >> 2;
+    ASSERT(is_uint26(imm26));
+
+    instr_at_put(pc, instr | (imm26 & kImm26Mask));
+    return 1;  // Number of instructions patched.
+  }
+}
+
+
 void Assembler::GrowBuffer() {
   if (!own_buffer_) FATAL("external code buffer is too small");
 
@@ -1802,9 +1901,14 @@
   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
                                reloc_info_writer.last_pc() + pc_delta);
 
-  // On ia32 and ARM pc relative addressing is used, and we thus need to apply a
-  // shift by pc_delta. But on MIPS the target address it directly loaded, so
-  // we do not need to relocate here.
+  // Relocate runtime entries.
+  for (RelocIterator it(desc); !it.done(); it.next()) {
+    RelocInfo::Mode rmode = it.rinfo()->rmode();
+    if (rmode == RelocInfo::INTERNAL_REFERENCE) {
+      byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
+      RelocateInternalReference(p, pc_delta);
+    }
+  }
 
   ASSERT(!overflow());
 }
@@ -1843,9 +1947,8 @@
     }
     ASSERT(buffer_space() >= kMaxRelocSize);  // Too late to grow buffer here.
     if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
-      ASSERT(ast_id_for_reloc_info_ != kNoASTId);
-      RelocInfo reloc_info_with_ast_id(pc_, rmode, ast_id_for_reloc_info_);
-      ast_id_for_reloc_info_ = kNoASTId;
+      RelocInfo reloc_info_with_ast_id(pc_, rmode, RecordedAstId());
+      ClearRecordedAstId();
       reloc_info_writer.Write(&reloc_info_with_ast_id);
     } else {
       reloc_info_writer.Write(&rinfo);
@@ -1859,16 +1962,7 @@
 }
 
 
-void Assembler::CheckTrampolinePool(bool force_emit) {
-  // Calculate the offset of the next check.
-  next_buffer_check_ = pc_offset() + kCheckConstInterval;
-
-  int dist = pc_offset() - last_trampoline_pool_end_;
-
-  if (dist <= kMaxDistBetweenPools && !force_emit) {
-    return;
-  }
-
+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_,
@@ -1886,29 +1980,43 @@
     return;
   }
 
-  // First we emit jump (2 instructions), then we emit trampoline pool.
-  { BlockTrampolinePoolScope block_trampoline_pool(this);
-    Label after_pool;
-    b(&after_pool);
-    nop();
-
-    int pool_start = pc_offset();
-    for (int i = 0; i < kSlotsPerTrampoline; i++) {
+  ASSERT(!trampoline_emitted_);
+  ASSERT(unbound_labels_count_ >= 0);
+  if (unbound_labels_count_ > 0) {
+    // First we emit jump (2 instructions), then we emit trampoline pool.
+    { BlockTrampolinePoolScope block_trampoline_pool(this);
+      Label after_pool;
       b(&after_pool);
       nop();
-    }
-    for (int i = 0; i < kLabelsPerTrampoline; i++) {
-      emit(0);
-    }
-    last_trampoline_pool_end_ = pc_offset() - kInstrSize;
-    bind(&after_pool);
-    trampolines_.Add(Trampoline(pool_start,
-                                kSlotsPerTrampoline,
-                                kLabelsPerTrampoline));
 
-    // Since a trampoline pool was just emitted,
-    // move the check offset forward by the standard interval.
-    next_buffer_check_ = last_trampoline_pool_end_ + kMaxDistBetweenPools;
+      int pool_start = pc_offset();
+      for (int i = 0; i < unbound_labels_count_; i++) {
+        uint32_t imm32;
+        imm32 = jump_address(&after_pool);
+        { BlockGrowBufferScope block_buf_growth(this);
+          // Buffer growth (and relocation) must be blocked for internal
+          // references until associated instructions are emitted and available
+          // to be patched.
+          RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+          lui(at, (imm32 & kHiMask) >> kLuiShift);
+          ori(at, at, (imm32 & kImm16Mask));
+        }
+        jr(at);
+        nop();
+      }
+      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() +
+        kMaxBranchOffset - kTrampolineSlotsSize * 16;
   }
   return;
 }
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index a167393..a16cd80 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -328,8 +328,8 @@
 // Class MemOperand represents a memory operand in load and store instructions.
 class MemOperand : public Operand {
  public:
-
   explicit MemOperand(Register rn, int32_t offset = 0);
+  int32_t offset() const { return offset_; }
 
  private:
   int32_t offset_;
@@ -372,6 +372,7 @@
   // Enable a specified feature within a scope.
   class Scope BASE_EMBEDDED {
 #ifdef DEBUG
+
    public:
     explicit Scope(CpuFeature f) {
       unsigned mask = 1u << f;
@@ -391,11 +392,13 @@
         isolate_->set_enabled_cpu_features(old_enabled_);
       }
     }
-   private:
+
+ private:
     Isolate* isolate_;
     unsigned old_enabled_;
 #else
-   public:
+
+ public:
     explicit Scope(CpuFeature f) {}
 #endif
   };
@@ -478,6 +481,9 @@
   // 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 current code position.
+  // Determines if Label is bound and near enough so that branch instruction
+  // can be used to reach it, instead of jump instruction.
+  bool is_near(Label* L);
 
   // 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.
@@ -488,6 +494,7 @@
     ASSERT((o & 3) == 0);   // Assert the offset is aligned.
     return o >> 2;
   }
+  uint32_t jump_address(Label* L);
 
   // Puts a labels target address at the given position.
   // The high 8 bits are set to zero.
@@ -675,7 +682,8 @@
   //-------------Misc-instructions--------------
 
   // Break / Trap instructions.
-  void break_(uint32_t code);
+  void break_(uint32_t code, bool break_as_stop = false);
+  void stop(const char* msg, uint32_t code = kMaxStopCode);
   void tge(Register rs, Register rt, uint16_t code);
   void tgeu(Register rs, Register rt, uint16_t code);
   void tlt(Register rs, Register rt, uint16_t code);
@@ -771,8 +779,13 @@
   void fcmp(FPURegister src1, const double src2, FPUCondition cond);
 
   // Check the code size generated from label to here.
-  int InstructionsGeneratedSince(Label* l) {
-    return (pc_offset() - l->pos()) / kInstrSize;
+  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.
@@ -791,6 +804,25 @@
     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
   };
 
+  // Class for postponing the assembly buffer growth. Typically used for
+  // sequences of instructions that must be emitted as a unit, before
+  // buffer growth (and relocation) can occur.
+  // This blocking scope is not nestable.
+  class BlockGrowBufferScope {
+   public:
+    explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) {
+      assem_->StartBlockGrowBuffer();
+    }
+    ~BlockGrowBufferScope() {
+      assem_->EndBlockGrowBuffer();
+    }
+
+    private:
+     Assembler* assem_;
+
+     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
+  };
+
   // Debugging.
 
   // Mark address of the ExitJSFrame code.
@@ -801,12 +833,24 @@
 
   // Record the AST id of the CallIC being compiled, so that it can be placed
   // in the relocation information.
-  void RecordAstId(unsigned ast_id) { ast_id_for_reloc_info_ = ast_id; }
+  void SetRecordedAstId(unsigned ast_id) {
+    ASSERT(recorded_ast_id_ == kNoASTId);
+    recorded_ast_id_ = ast_id;
+  }
+
+  unsigned RecordedAstId() {
+    ASSERT(recorded_ast_id_ != kNoASTId);
+    return recorded_ast_id_;
+  }
+
+  void ClearRecordedAstId() { recorded_ast_id_ = kNoASTId; }
 
   // Record a comment relocation entry that can be used by a disassembler.
   // Use --code-comments to enable.
   void RecordComment(const char* msg);
 
+  static int RelocateInternalReference(byte* pc, intptr_t pc_delta);
+
   // 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);
@@ -843,6 +887,11 @@
   static bool IsBeq(Instr instr);
   static bool IsBne(Instr instr);
 
+  static bool IsJump(Instr instr);
+  static bool IsJ(Instr instr);
+  static bool IsLui(Instr instr);
+  static bool IsOri(Instr instr);
+
   static bool IsNop(Instr instr, unsigned int type);
   static bool IsPop(Instr instr);
   static bool IsPush(Instr instr);
@@ -864,6 +913,8 @@
   static uint32_t GetSa(Instr instr);
   static uint32_t GetSaField(Instr instr);
   static uint32_t GetOpcodeField(Instr instr);
+  static uint32_t GetFunction(Instr instr);
+  static uint32_t GetFunctionField(Instr instr);
   static uint32_t GetImmediate16(Instr instr);
   static uint32_t GetLabelConst(Instr instr);
 
@@ -879,13 +930,13 @@
 
   static bool IsAndImmediate(Instr instr);
 
-  void CheckTrampolinePool(bool force_emit = false);
+  void CheckTrampolinePool();
 
  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.
-  unsigned ast_id_for_reloc_info_;
+  unsigned recorded_ast_id_;
 
   bool emit_debug_code() const { return emit_debug_code_; }
 
@@ -912,6 +963,7 @@
   void StartBlockTrampolinePool() {
     trampoline_pool_blocked_nesting_++;
   }
+
   void EndBlockTrampolinePool() {
     trampoline_pool_blocked_nesting_--;
   }
@@ -924,6 +976,25 @@
     return internal_trampoline_exception_;
   }
 
+  bool is_trampoline_emitted() const {
+    return trampoline_emitted_;
+  }
+
+  // Temporarily block automatic assembly buffer growth.
+  void StartBlockGrowBuffer() {
+    ASSERT(!block_buffer_growth_);
+    block_buffer_growth_ = true;
+  }
+
+  void EndBlockGrowBuffer() {
+    ASSERT(block_buffer_growth_);
+    block_buffer_growth_ = false;
+  }
+
+  bool is_buffer_growth_blocked() const {
+    return block_buffer_growth_;
+  }
+
  private:
   // Code buffer:
   // The buffer into which code and relocation info are generated.
@@ -960,6 +1031,9 @@
   // Keep track of the last emitted pool to guarantee a maximal distance.
   int last_trampoline_pool_end_;  // pc offset of the end of the last pool.
 
+  // Automatic growth of the assembly buffer may be blocked for some sequences.
+  bool block_buffer_growth_;  // Block growth when true.
+
   // Relocation information generation.
   // Each relocation is encoded as a variable size value.
   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
@@ -1040,7 +1114,6 @@
   // Labels.
   void print(Label* L);
   void bind_to(Label* L, int pos);
-  void link_to(Label* L, Label* appendix);
   void next(Label* L);
 
   // One trampoline consists of:
@@ -1053,13 +1126,17 @@
   // label_count *  kInstrSize.
   class Trampoline {
    public:
-    Trampoline(int start, int slot_count, int label_count) {
+    Trampoline() {
+      start_ = 0;
+      next_slot_ = 0;
+      free_slot_count_ = 0;
+      end_ = 0;
+    }
+    Trampoline(int start, int slot_count) {
       start_ = start;
       next_slot_ = start;
       free_slot_count_ = slot_count;
-      next_label_ = start + slot_count * 2 * kInstrSize;
-      free_label_count_ = label_count;
-      end_ = next_label_ + (label_count - 1) * kInstrSize;
+      end_ = start + slot_count * kTrampolineSlotsSize;
     }
     int start() {
       return start_;
@@ -1078,40 +1155,30 @@
       } else {
         trampoline_slot = next_slot_;
         free_slot_count_--;
-        next_slot_ += 2*kInstrSize;
+        next_slot_ += kTrampolineSlotsSize;
       }
       return trampoline_slot;
     }
-    int take_label() {
-      int label_pos = next_label_;
-      ASSERT(free_label_count_ > 0);
-      free_label_count_--;
-      next_label_ += kInstrSize;
-      return label_pos;
-    }
    private:
     int start_;
     int end_;
     int next_slot_;
     int free_slot_count_;
-    int next_label_;
-    int free_label_count_;
   };
 
-  int32_t get_label_entry(int32_t pos, bool next_pool = true);
-  int32_t get_trampoline_entry(int32_t pos, bool next_pool = true);
-
-  static const int kSlotsPerTrampoline = 2304;
-  static const int kLabelsPerTrampoline = 8;
-  static const int kTrampolineInst =
-      2 * kSlotsPerTrampoline + kLabelsPerTrampoline;
-  static const int kTrampolineSize = kTrampolineInst * kInstrSize;
+  int32_t get_trampoline_entry(int32_t pos);
+  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 use jump instructions rather
+  // than regular branch instructions.
+  bool trampoline_emitted_;
+  static const int kTrampolineSlotsSize = 4 * kInstrSize;
   static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
-  static const int kMaxDistBetweenPools =
-      kMaxBranchOffset - 2 * kTrampolineSize;
   static const int kInvalidSlotPos = -1;
 
-  List<Trampoline> trampolines_;
+  Trampoline trampoline_;
   bool internal_trampoline_exception_;
 
   friend class RegExpMacroAssemblerMIPS;
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index e22259d..1555653 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -344,7 +344,7 @@
   // Handle construction of an empty array of a certain size. Bail out if size
   // is too large to actually allocate an elements array.
   ASSERT(kSmiTag == 0);
-  __ Branch(call_generic_code, ge, a2,
+  __ Branch(call_generic_code, Ugreater_equal, a2,
             Operand(JSObject::kInitialMaxFastElementArray << kSmiTagSize));
 
   // a0: argc
@@ -634,7 +634,7 @@
   __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
   __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kConstructStubOffset));
   __ Addu(t9, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ Jump(Operand(t9));
+  __ Jump(t9);
 
   // a0: number of arguments
   // a1: called object
@@ -942,10 +942,11 @@
         masm->isolate()->builtins()->HandleApiCallConstruct();
     ParameterCount expected(0);
     __ InvokeCode(code, expected, expected,
-                  RelocInfo::CODE_TARGET, CALL_FUNCTION);
+                  RelocInfo::CODE_TARGET, CALL_FUNCTION, CALL_AS_METHOD);
   } else {
     ParameterCount actual(a0);
-    __ InvokeFunction(a1, actual, CALL_FUNCTION);
+    __ InvokeFunction(a1, actual, CALL_FUNCTION,
+                      NullCallWrapper(), CALL_AS_METHOD);
   }
 
   // Pop the function from the stack.
@@ -973,9 +974,9 @@
   __ Branch(&use_receiver, eq, t0, Operand(zero_reg));
 
   // If the type of the result (stored in its map) is less than
-  // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
+  // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
   __ GetObjectType(v0, a3, a3);
-  __ Branch(&exit, greater_equal, a3, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
 
   // Throw away the result of the constructor invocation and use the
   // on-stack receiver as the result.
@@ -1074,11 +1075,11 @@
   // Invoke the code and pass argc as a0.
   __ mov(a0, a3);
   if (is_construct) {
-    __ Call(masm->isolate()->builtins()->JSConstructCall(),
-            RelocInfo::CODE_TARGET);
+    __ Call(masm->isolate()->builtins()->JSConstructCall());
   } else {
     ParameterCount actual(a0);
-    __ InvokeFunction(a1, actual, CALL_FUNCTION);
+    __ InvokeFunction(a1, actual, CALL_FUNCTION,
+                      NullCallWrapper(), CALL_AS_METHOD);
   }
 
   __ LeaveInternalFrame();
@@ -1214,8 +1215,7 @@
     __ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
 
     // Do not transform the receiver for native (Compilerhints already in a3).
-    __ And(t0, a3, Operand(1 << (SharedFunctionInfo::kES5Native +
-                                 kSmiTagSize)));
+    __ And(t0, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
     __ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
 
     // Compute the receiver in non-strict mode.
@@ -1233,10 +1233,9 @@
     __ LoadRoot(a3, Heap::kNullValueRootIndex);
     __ Branch(&use_global_receiver, eq, a2, Operand(a3));
 
-    STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-    STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
     __ GetObjectType(a2, a3, a3);
-    __ Branch(&shift_arguments, ge, a3, Operand(FIRST_JS_OBJECT_TYPE));
+    __ Branch(&shift_arguments, ge, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
 
     __ bind(&convert_to_object);
     __ EnterInternalFrame();  // In order to preserve argument count.
@@ -1339,7 +1338,8 @@
           RelocInfo::CODE_TARGET, ne, a2, Operand(a0));
 
   ParameterCount expected(0);
-  __ InvokeCode(a3, expected, expected, JUMP_FUNCTION);
+  __ InvokeCode(a3, expected, expected, JUMP_FUNCTION,
+                NullCallWrapper(), CALL_AS_METHOD);
 }
 
 
@@ -1401,8 +1401,7 @@
   __ Branch(&push_receiver, ne, t0, Operand(zero_reg));
 
   // Do not transform the receiver for native (Compilerhints already in a2).
-  __ And(t0, a2, Operand(1 << (SharedFunctionInfo::kES5Native +
-                               kSmiTagSize)));
+  __ And(t0, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
   __ Branch(&push_receiver, ne, t0, Operand(zero_reg));
 
   // Compute the receiver in non-strict mode.
@@ -1415,10 +1414,9 @@
 
   // Check if the receiver is already a JavaScript object.
   // a0: receiver
-  STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-  STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+  STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
   __ GetObjectType(a0, a1, a1);
-  __ Branch(&push_receiver, ge, a1, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
 
   // Convert the receiver to a regular object.
   // a0: receiver
@@ -1473,7 +1471,8 @@
   ParameterCount actual(a0);
   __ sra(a0, a0, kSmiTagSize);
   __ lw(a1, MemOperand(fp, kFunctionOffset));
-  __ InvokeFunction(a1, actual, CALL_FUNCTION);
+  __ InvokeFunction(a1, actual, CALL_FUNCTION,
+                    NullCallWrapper(), CALL_AS_METHOD);
 
   // Tear down the internal frame and remove function, receiver and args.
   __ LeaveInternalFrame();
@@ -1573,20 +1572,20 @@
     // Adjust for return address and receiver.
     __ Addu(a0, a0, Operand(2 * kPointerSize));
     // Compute copy end address. Also adjust for return address.
-    __ Addu(t1, fp, kPointerSize);
+    __ Addu(t3, fp, kPointerSize);
 
     // Copy the arguments (including the receiver) to the new stack frame.
     // a0: copy start address
     // a1: function
     // a2: expected number of arguments
     // a3: code entry to call
-    // t1: copy end address
+    // t3: copy end address
     Label copy;
     __ bind(&copy);
     __ lw(t0, MemOperand(a0));  // Adjusted above for return addr and receiver.
     __ push(t0);
     __ Subu(a0, a0, kPointerSize);
-    __ Branch(&copy, ne, a0, Operand(t1));
+    __ Branch(&copy, ne, a0, Operand(t3));
 
     // Fill the remaining expected arguments with undefined.
     // a1: function
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index c999994..d89d3e5 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -158,7 +158,7 @@
   __ lw(a3, MemOperand(sp, 0));
 
   // Setup the object header.
-  __ LoadRoot(a2, Heap::kContextMapRootIndex);
+  __ LoadRoot(a2, Heap::kFunctionContextMapRootIndex);
   __ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
   __ li(a2, Operand(Smi::FromInt(length)));
   __ sw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset));
@@ -166,11 +166,10 @@
   // Setup the fixed slots.
   __ li(a1, Operand(Smi::FromInt(0)));
   __ sw(a3, MemOperand(v0, Context::SlotOffset(Context::CLOSURE_INDEX)));
-  __ sw(v0, MemOperand(v0, Context::SlotOffset(Context::FCONTEXT_INDEX)));
-  __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
+  __ sw(cp, MemOperand(v0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
   __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::EXTENSION_INDEX)));
 
-  // Copy the global object from the surrounding context.
+  // Copy the global object from the previous context.
   __ lw(a1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_INDEX)));
 
@@ -187,7 +186,7 @@
 
   // Need to collect. Call into runtime system.
   __ bind(&gc);
-  __ TailCallRuntime(Runtime::kNewContext, 1, 1);
+  __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1);
 }
 
 
@@ -306,12 +305,6 @@
   }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "ConvertToDoubleStub"; }
-
-#ifdef DEBUG
-  void Print() { PrintF("ConvertToDoubleStub\n"); }
-#endif
 };
 
 
@@ -397,11 +390,11 @@
     __ mov(scratch1, a0);
     ConvertToDoubleStub stub1(a3, a2, scratch1, scratch2);
     __ push(ra);
-    __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub1.GetCode());
     // Write Smi from a1 to a1 and a0 in double format.
     __ mov(scratch1, a1);
     ConvertToDoubleStub stub2(a1, a0, scratch1, scratch2);
-    __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub2.GetCode());
     __ pop(ra);
   }
 }
@@ -483,7 +476,7 @@
     __ mov(scratch1, object);
     ConvertToDoubleStub stub(dst2, dst1, scratch1, scratch2);
     __ push(ra);
-    __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub.GetCode());
     __ pop(ra);
   }
 
@@ -672,9 +665,8 @@
     // Restore FCSR.
     __ ctc1(scratch1, FCSR);
 
-    // Check for inexact conversion.
-    __ srl(scratch2, scratch2, kFCSRFlagShift);
-    __ And(scratch2, scratch2, (kFCSRFlagMask | kFCSRInexactFlagBit));
+    // Check for inexact conversion or exception.
+    __ And(scratch2, scratch2, kFCSRFlagMask);
 
     // Jump to not_int32 if the operation did not succeed.
     __ Branch(not_int32, ne, scratch2, Operand(zero_reg));
@@ -757,9 +749,8 @@
     // Restore FCSR.
     __ ctc1(scratch1, FCSR);
 
-    // Check for inexact conversion.
-    __ srl(scratch2, scratch2, kFCSRFlagShift);
-    __ And(scratch2, scratch2, (kFCSRFlagMask | kFCSRInexactFlagBit));
+    // Check for inexact conversion or exception.
+    __ And(scratch2, scratch2, kFCSRFlagMask);
 
     // Jump to not_int32 if the operation did not succeed.
     __ Branch(not_int32, ne, scratch2, Operand(zero_reg));
@@ -985,13 +976,13 @@
     // Smis. If it's not a heap number, then return equal.
     if (cc == less || cc == greater) {
       __ GetObjectType(a0, t4, t4);
-      __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE));
+      __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
     } else {
       __ GetObjectType(a0, t4, t4);
       __ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE));
       // Comparing JS objects with <=, >= is complicated.
       if (cc != eq) {
-      __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE));
+      __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
         // Normally here we fall through to return_equal, but undefined is
         // special: (undefined == undefined) == true, but
         // (undefined <= undefined) == false!  See ECMAScript 11.8.5.
@@ -1110,7 +1101,7 @@
     __ mov(t6, rhs);
     ConvertToDoubleStub stub1(a1, a0, t6, t5);
     __ push(ra);
-    __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub1.GetCode());
 
     __ pop(ra);
   }
@@ -1145,7 +1136,7 @@
     __ mov(t6, lhs);
     ConvertToDoubleStub stub2(a3, a2, t6, t5);
     __ push(ra);
-    __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
+    __ Call(stub2.GetCode());
     __ pop(ra);
     // Load rhs to a double in a1, a0.
     if (rhs.is(a0)) {
@@ -1309,15 +1300,15 @@
 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
                                            Register lhs,
                                            Register rhs) {
-    // If either operand is a JSObject or an oddball value, then they are
+    // 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 == JS_FUNCTION_TYPE);
+    STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
     Label first_non_object;
     // Get the type of the first operand into a2 and compare it with
-    // FIRST_JS_OBJECT_TYPE.
+    // FIRST_SPEC_OBJECT_TYPE.
     __ GetObjectType(lhs, a2, a2);
-    __ Branch(&first_non_object, less, a2, Operand(FIRST_JS_OBJECT_TYPE));
+    __ Branch(&first_non_object, less, a2, Operand(FIRST_SPEC_OBJECT_TYPE));
 
     // Return non-zero.
     Label return_not_equal;
@@ -1330,7 +1321,7 @@
     __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE));
 
     __ GetObjectType(rhs, a3, a3);
-    __ Branch(&return_not_equal, greater, a3, Operand(FIRST_JS_OBJECT_TYPE));
+    __ Branch(&return_not_equal, greater, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
 
     // Check for oddballs: true, false, null, undefined.
     __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE));
@@ -1406,9 +1397,9 @@
   __ Ret();
 
   __ bind(&object_test);
-  __ Branch(not_both_strings, lt, a2, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE));
   __ GetObjectType(rhs, a2, a3);
-  __ Branch(not_both_strings, lt, a3, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
 
   // If both objects are undetectable, they are equal.  Otherwise, they
   // are not equal, since they are different objects and an object is not
@@ -1720,7 +1711,6 @@
 }
 
 
-// This stub does not handle the inlined cases (Smis, Booleans, undefined).
 // The stub returns zero for false, and a non-zero value for true.
 void ToBooleanStub::Generate(MacroAssembler* masm) {
   // This stub uses FPU instructions.
@@ -1784,7 +1774,7 @@
   // "tos_" is a register and contains a non-zero value.
   // Hence we implicitly return true if the greater than
   // condition is satisfied.
-  __ Ret(gt, scratch0, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Ret(ge, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
 
   // Check for string.
   __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset));
@@ -1792,7 +1782,7 @@
   // "tos_" is a register and contains a non-zero value.
   // Hence we implicitly return true if the greater than
   // condition is satisfied.
-  __ Ret(gt, scratch0, Operand(FIRST_NONSTRING_TYPE));
+  __ Ret(ge, scratch0, Operand(FIRST_NONSTRING_TYPE));
 
   // String value => false iff empty, i.e., length is zero.
   __ lw(tos_, FieldMemOperand(tos_, String::kLengthOffset));
@@ -1807,31 +1797,17 @@
 }
 
 
-Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
-  UnaryOpStub stub(key, type_info);
-  return stub.GetCode();
-}
-
-
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -1856,19 +1832,13 @@
 
 void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
   // Argument is in a0 and v0 at this point, so we can overwrite a0.
-  // Push this stub's key. Although the operation and the type info are
-  // encoded into the key, the encoding is opaque, so push them too.
-  __ li(a2, Operand(Smi::FromInt(MinorKey())));
-  __ li(a1, Operand(Smi::FromInt(op_)));
+  __ li(a2, Operand(Smi::FromInt(op_)));
+  __ li(a1, Operand(Smi::FromInt(mode_)));
   __ li(a0, Operand(Smi::FromInt(operand_type_)));
-
   __ Push(v0, a2, a1, a0);
 
   __ TailCallExternalReference(
-      ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
-                        masm->isolate()),
-      4,
-      1);
+      ExternalReference(IC_Utility(IC::kUnaryOp_Patch), masm->isolate()), 4, 1);
 }
 
 
@@ -1966,6 +1936,7 @@
   GenerateTypeTransition(masm);
 }
 
+
 void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
                                             Label* slow) {
   EmitCheckForHeapNumber(masm, a0, a1, t2, slow);
@@ -2002,6 +1973,8 @@
 void UnaryOpStub::GenerateHeapNumberCodeBitNot(
     MacroAssembler* masm,
     Label* slow) {
+  Label impossible;
+
   EmitCheckForHeapNumber(masm, a0, a1, t2, slow);
   // Convert the heap number in a0 to an untagged integer in a1.
   __ ConvertToInt32(a0, a1, a2, a3, f0, slow);
@@ -2020,17 +1993,28 @@
   __ bind(&try_float);
   if (mode_ == UNARY_NO_OVERWRITE) {
     Label slow_allocate_heapnumber, heapnumber_allocated;
-    __ AllocateHeapNumber(v0, a2, a3, t2, &slow_allocate_heapnumber);
+    // Allocate a new heap number without zapping v0, which we need if it fails.
+    __ AllocateHeapNumber(a2, a3, t0, t2, &slow_allocate_heapnumber);
     __ jmp(&heapnumber_allocated);
 
     __ bind(&slow_allocate_heapnumber);
     __ EnterInternalFrame();
-    __ push(a1);
+    __ push(v0);  // Push the heap number, not the untagged int32.
     __ CallRuntime(Runtime::kNumberAlloc, 0);
-    __ pop(a1);
+    __ mov(a2, v0);  // Move the new heap number into a2.
+    // Get the heap number into v0, now that the new heap number is in a2.
+    __ pop(v0);
     __ LeaveInternalFrame();
 
+    // Convert the heap number in v0 to an untagged integer in a1.
+    // This can't go slow-case because it's the same number we already
+    // converted once again.
+    __ ConvertToInt32(v0, a1, a3, t0, f0, &impossible);
+    // Negate the result.
+    __ Xor(a1, a1, -1);
+
     __ bind(&heapnumber_allocated);
+    __ mov(v0, a2);  // Move newly allocated heap number to v0.
   }
 
   if (CpuFeatures::IsSupported(FPU)) {
@@ -2046,6 +2030,11 @@
     WriteInt32ToHeapNumberStub stub(a1, v0, a2, a3);
     __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
   }
+
+  __ bind(&impossible);
+  if (FLAG_debug_code) {
+    __ stop("Incorrect assumption in bit-not stub");
+  }
 }
 
 
@@ -2101,14 +2090,6 @@
 }
 
 
-Handle<Code> GetBinaryOpStub(int key,
-                             BinaryOpIC::TypeInfo type_info,
-                             BinaryOpIC::TypeInfo result_type_info) {
-  BinaryOpStub stub(key, type_info, result_type_info);
-  return stub.GetCode();
-}
-
-
 void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
   Label get_result;
 
@@ -2165,12 +2146,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -2179,13 +2155,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -2687,37 +2660,36 @@
     case Token::MUL:
     case Token::DIV:
     case Token::MOD: {
-    // Load both operands and check that they are 32-bit integer.
-    // Jump to type transition if they are not. The registers a0 and a1 (right
-    // and left) are preserved for the runtime call.
-    FloatingPointHelper::Destination destination =
-        CpuFeatures::IsSupported(FPU) &&
-        op_ != Token::MOD ?
-        FloatingPointHelper::kFPURegisters :
-        FloatingPointHelper::kCoreRegisters;
+      // Load both operands and check that they are 32-bit integer.
+      // Jump to type transition if they are not. The registers a0 and a1 (right
+      // and left) are preserved for the runtime call.
+      FloatingPointHelper::Destination destination =
+          (CpuFeatures::IsSupported(FPU) && op_ != Token::MOD)
+              ? FloatingPointHelper::kFPURegisters
+              : FloatingPointHelper::kCoreRegisters;
 
-    FloatingPointHelper::LoadNumberAsInt32Double(masm,
-                                                 right,
-                                                 destination,
-                                                 f14,
-                                                 a2,
-                                                 a3,
-                                                 heap_number_map,
-                                                 scratch1,
-                                                 scratch2,
-                                                 f2,
-                                                 &transition);
-    FloatingPointHelper::LoadNumberAsInt32Double(masm,
-                                                 left,
-                                                 destination,
-                                                 f12,
-                                                 t0,
-                                                 t1,
-                                                 heap_number_map,
-                                                 scratch1,
-                                                 scratch2,
-                                                 f2,
-                                                 &transition);
+      FloatingPointHelper::LoadNumberAsInt32Double(masm,
+                                                   right,
+                                                   destination,
+                                                   f14,
+                                                   a2,
+                                                   a3,
+                                                   heap_number_map,
+                                                   scratch1,
+                                                   scratch2,
+                                                   f2,
+                                                   &transition);
+      FloatingPointHelper::LoadNumberAsInt32Double(masm,
+                                                   left,
+                                                   destination,
+                                                   f12,
+                                                   t0,
+                                                   t1,
+                                                   heap_number_map,
+                                                   scratch1,
+                                                   scratch2,
+                                                   f2,
+                                                   &transition);
 
       if (destination == FloatingPointHelper::kFPURegisters) {
         CpuFeatures::Scope scope(FPU);
@@ -2759,8 +2731,7 @@
           // Restore FCSR.
           __ ctc1(scratch1, FCSR);
 
-          // Check for inexact conversion.
-          __ srl(scratch2, scratch2, kFCSRFlagShift);
+          // Check for inexact conversion or exception.
           __ And(scratch2, scratch2, kFCSRFlagMask);
 
           if (result_type_ <= BinaryOpIC::INT32) {
@@ -2788,9 +2759,11 @@
           // DIV just falls through to allocating a heap number.
         }
 
-        if (result_type_ >= (op_ == Token::DIV) ? BinaryOpIC::HEAP_NUMBER
-                                                : BinaryOpIC::INT32) {
-          __ bind(&return_heap_number);
+        __ bind(&return_heap_number);
+        // Return a heap number, or fall through to type transition or runtime
+        // call if we can't.
+        if (result_type_ >= ((op_ == Token::DIV) ? BinaryOpIC::HEAP_NUMBER
+                                                 : BinaryOpIC::INT32)) {
           // We are using FPU registers so s0 is available.
           heap_number_result = s0;
           GenerateHeapResultAllocation(masm,
@@ -2969,7 +2942,11 @@
       UNREACHABLE();
   }
 
-  if (transition.is_linked()) {
+  // We never expect DIV to yield an integer result, so we always generate
+  // type transition code for DIV operations expecting an integer result: the
+  // code will fall through to this type transition.
+  if (transition.is_linked() ||
+      ((op_ == Token::DIV) && (result_type_ <= BinaryOpIC::INT32))) {
     __ bind(&transition);
     GenerateTypeTransition(masm);
   }
@@ -3541,15 +3518,10 @@
 
   __ li(a2, Operand(ExternalReference::isolate_address()));
 
-  // From arm version of this function:
-  // TODO(1242173): To let the GC traverse the return address of the exit
-  // frames, we need to know where the return address is. Right now,
-  // we push it on the stack to be able to find it again, but we never
-  // restore from it in case of changes, which makes it impossible to
-  // support moving the C entry code stub. This should be fixed, but currently
-  // this is OK because the CEntryStub gets generated so early in the V8 boot
-  // sequence that it is not moving ever.
-
+  // 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.
   { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
     // This branch-and-link sequence is needed to find the current PC on mips,
     // saved to the ra register.
@@ -3755,24 +3727,22 @@
   // 4 args slots
   // args
 
-  #ifdef ENABLE_LOGGING_AND_PROFILING
-    // If this is the outermost JS call, set js_entry_sp value.
-    Label non_outermost_js;
-    ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
-                                  masm->isolate());
-    __ li(t1, Operand(ExternalReference(js_entry_sp)));
-    __ lw(t2, MemOperand(t1));
-    __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg));
-    __ sw(fp, MemOperand(t1));
-    __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
-    Label cont;
-    __ b(&cont);
-    __ nop();   // Branch delay slot nop.
-    __ bind(&non_outermost_js);
-    __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
-    __ bind(&cont);
-    __ push(t0);
-  #endif
+  // If this is the outermost JS call, set js_entry_sp value.
+  Label non_outermost_js;
+  ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
+                                masm->isolate());
+  __ li(t1, Operand(ExternalReference(js_entry_sp)));
+  __ lw(t2, MemOperand(t1));
+  __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg));
+  __ sw(fp, MemOperand(t1));
+  __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
+  Label cont;
+  __ b(&cont);
+  __ nop();   // Branch delay slot nop.
+  __ bind(&non_outermost_js);
+  __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
+  __ bind(&cont);
+  __ push(t0);
 
   // Call a faked try-block that does the invoke.
   __ bal(&invoke);  // bal exposes branch delay slot.
@@ -3841,16 +3811,14 @@
   __ PopTryHandler();
 
   __ bind(&exit);  // v0 holds result
-  #ifdef ENABLE_LOGGING_AND_PROFILING
-    // Check if the current stack frame is marked as the outermost JS frame.
-    Label non_outermost_js_2;
-    __ pop(t1);
-    __ Branch(&non_outermost_js_2, ne, t1,
-              Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
-    __ li(t1, Operand(ExternalReference(js_entry_sp)));
-    __ sw(zero_reg, MemOperand(t1));
-    __ bind(&non_outermost_js_2);
-  #endif
+  // Check if the current stack frame is marked as the outermost JS frame.
+  Label non_outermost_js_2;
+  __ pop(t1);
+  __ Branch(&non_outermost_js_2, ne, t1,
+            Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
+  __ li(t1, Operand(ExternalReference(js_entry_sp)));
+  __ sw(zero_reg, MemOperand(t1));
+  __ bind(&non_outermost_js_2);
 
   // Restore the top frame descriptors from the stack.
   __ pop(t1);
@@ -4074,11 +4042,252 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewNonStrictSlow(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 runtime;
+  __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ lw(a2, MemOperand(a3, StandardFrameConstants::kContextOffset));
+  __ Branch(&runtime, ne,
+            a2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
 
+  // Patch the arguments.length and the parameters pointer in the current frame.
+  __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ sw(a2, MemOperand(sp, 0 * kPointerSize));
+  __ sll(t3, a2, 1);
+  __ Addu(a3, a3, Operand(t3));
+  __ addiu(a3, a3, StandardFrameConstants::kCallerSPOffset);
+  __ sw(a3, MemOperand(sp, 1 * kPointerSize));
+
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+  // Stack layout:
+  //  sp[0] : number of parameters (tagged)
+  //  sp[4] : address of receiver argument
+  //  sp[8] : function
+  // Registers used over whole function:
+  //  t2 : allocated object (tagged)
+  //  t5 : mapped parameter count (tagged)
+
+  __ lw(a1, MemOperand(sp, 0 * kPointerSize));
+  // a1 = parameter count (tagged)
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label runtime;
+  Label adaptor_frame, try_allocate;
+  __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ lw(a2, MemOperand(a3, StandardFrameConstants::kContextOffset));
+  __ Branch(&adaptor_frame, eq, a2,
+            Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+
+  // No adaptor, parameter count = argument count.
+  __ mov(a2, a1);
+  __ b(&try_allocate);
+  __ nop();   // Branch delay slot nop.
+
+  // We have an adaptor frame. Patch the parameters pointer.
+  __ bind(&adaptor_frame);
+  __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ sll(t6, a2, 1);
+  __ Addu(a3, a3, Operand(t6));
+  __ Addu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset));
+  __ sw(a3, MemOperand(sp, 1 * kPointerSize));
+
+  // a1 = parameter count (tagged)
+  // a2 = argument count (tagged)
+  // Compute the mapped parameter count = min(a1, a2) in a1.
+  Label skip_min;
+  __ Branch(&skip_min, lt, a1, Operand(a2));
+  __ mov(a1, a2);
+  __ bind(&skip_min);
+
+  __ 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 param_map_size;
+  ASSERT_EQ(0, Smi::FromInt(0));
+  __ Branch(USE_DELAY_SLOT, &param_map_size, eq, a1, Operand(zero_reg));
+  __ mov(t5, zero_reg);  // In delay slot: param map size = 0 when a1 == 0.
+  __ sll(t5, a1, 1);
+  __ addiu(t5, t5, kParameterMapHeaderSize);
+  __ bind(&param_map_size);
+
+  // 2. Backing store.
+  __ sll(t6, a2, 1);
+  __ Addu(t5, t5, Operand(t6));
+  __ Addu(t5, t5, Operand(FixedArray::kHeaderSize));
+
+  // 3. Arguments object.
+  __ Addu(t5, t5, Operand(Heap::kArgumentsObjectSize));
+
+  // Do the allocation of all three objects in one go.
+  __ AllocateInNewSpace(t5, v0, a3, t0, &runtime, TAG_OBJECT);
+
+  // v0 = address of new object(s) (tagged)
+  // a2 = argument count (tagged)
+  // Get the arguments boilerplate from the current (global) context into t0.
+  const int kNormalOffset =
+      Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
+  const int kAliasedOffset =
+      Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
+
+  __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ lw(t0, FieldMemOperand(t0, GlobalObject::kGlobalContextOffset));
+  Label skip2_ne, skip2_eq;
+  __ Branch(&skip2_ne, ne, a1, Operand(zero_reg));
+  __ lw(t0, MemOperand(t0, kNormalOffset));
+  __ bind(&skip2_ne);
+
+  __ Branch(&skip2_eq, eq, a1, Operand(zero_reg));
+  __ lw(t0, MemOperand(t0, kAliasedOffset));
+  __ bind(&skip2_eq);
+
+  // v0 = address of new object (tagged)
+  // a1 = mapped parameter count (tagged)
+  // a2 = argument count (tagged)
+  // t0 = address of boilerplate object (tagged)
+  // Copy the JS object part.
+  for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
+    __ lw(a3, FieldMemOperand(t0, i));
+    __ sw(a3, FieldMemOperand(v0, i));
+  }
+
+  // Setup the callee in-object property.
+  STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
+  __ lw(a3, MemOperand(sp, 2 * kPointerSize));
+  const int kCalleeOffset = JSObject::kHeaderSize +
+      Heap::kArgumentsCalleeIndex * kPointerSize;
+  __ sw(a3, FieldMemOperand(v0, kCalleeOffset));
+
+  // Use the length (smi tagged) and set that as an in-object property too.
+  STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
+  const int kLengthOffset = JSObject::kHeaderSize +
+      Heap::kArgumentsLengthIndex * kPointerSize;
+  __ sw(a2, FieldMemOperand(v0, kLengthOffset));
+
+  // Setup the elements pointer in the allocated arguments object.
+  // If we allocated a parameter map, t0 will point there, otherwise
+  // it will point to the backing store.
+  __ Addu(t0, v0, Operand(Heap::kArgumentsObjectSize));
+  __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
+
+  // v0 = address of new object (tagged)
+  // a1 = mapped parameter count (tagged)
+  // a2 = argument count (tagged)
+  // t0 = address of parameter map or backing store (tagged)
+  // Initialize parameter map. If there are no mapped arguments, we're done.
+  Label skip_parameter_map;
+  Label skip3;
+  __ Branch(&skip3, ne, a1, Operand(Smi::FromInt(0)));
+  // Move backing store address to a3, because it is
+  // expected there when filling in the unmapped arguments.
+  __ mov(a3, t0);
+  __ bind(&skip3);
+
+  __ Branch(&skip_parameter_map, eq, a1, Operand(Smi::FromInt(0)));
+
+  __ LoadRoot(t2, Heap::kNonStrictArgumentsElementsMapRootIndex);
+  __ sw(t2, FieldMemOperand(t0, FixedArray::kMapOffset));
+  __ Addu(t2, a1, Operand(Smi::FromInt(2)));
+  __ sw(t2, FieldMemOperand(t0, FixedArray::kLengthOffset));
+  __ sw(cp, FieldMemOperand(t0, FixedArray::kHeaderSize + 0 * kPointerSize));
+  __ sll(t6, a1, 1);
+  __ Addu(t2, t0, Operand(t6));
+  __ Addu(t2, t2, Operand(kParameterMapHeaderSize));
+  __ sw(t2, FieldMemOperand(t0, FixedArray::kHeaderSize + 1 * kPointerSize));
+
+  // 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;
+  __ mov(t2, a1);
+  __ lw(t5, MemOperand(sp, 0 * kPointerSize));
+  __ Addu(t5, t5, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
+  __ Subu(t5, t5, Operand(a1));
+  __ LoadRoot(t3, Heap::kTheHoleValueRootIndex);
+  __ sll(t6, t2, 1);
+  __ Addu(a3, t0, Operand(t6));
+  __ Addu(a3, a3, Operand(kParameterMapHeaderSize));
+
+  // t2 = loop variable (tagged)
+  // a1 = mapping index (tagged)
+  // a3 = address of backing store (tagged)
+  // t0 = address of parameter map (tagged)
+  // t1 = temporary scratch (a.o., for address calculation)
+  // t3 = the hole value
+  __ jmp(&parameters_test);
+
+  __ bind(&parameters_loop);
+  __ Subu(t2, t2, Operand(Smi::FromInt(1)));
+  __ sll(t1, t2, 1);
+  __ Addu(t1, t1, Operand(kParameterMapHeaderSize - kHeapObjectTag));
+  __ Addu(t6, t0, t1);
+  __ sw(t5, MemOperand(t6));
+  __ Subu(t1, t1, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
+  __ Addu(t6, a3, t1);
+  __ sw(t3, MemOperand(t6));
+  __ Addu(t5, t5, Operand(Smi::FromInt(1)));
+  __ bind(&parameters_test);
+  __ Branch(&parameters_loop, ne, t2, Operand(Smi::FromInt(0)));
+
+  __ bind(&skip_parameter_map);
+  // a2 = argument count (tagged)
+  // a3 = address of backing store (tagged)
+  // t1 = scratch
+  // Copy arguments header and remaining slots (if there are any).
+  __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex);
+  __ sw(t1, FieldMemOperand(a3, FixedArray::kMapOffset));
+  __ sw(a2, FieldMemOperand(a3, FixedArray::kLengthOffset));
+
+  Label arguments_loop, arguments_test;
+  __ mov(t5, a1);
+  __ lw(t0, MemOperand(sp, 1 * kPointerSize));
+  __ sll(t6, t5, 1);
+  __ Subu(t0, t0, Operand(t6));
+  __ jmp(&arguments_test);
+
+  __ bind(&arguments_loop);
+  __ Subu(t0, t0, Operand(kPointerSize));
+  __ lw(t2, MemOperand(t0, 0));
+  __ sll(t6, t5, 1);
+  __ Addu(t1, a3, Operand(t6));
+  __ sw(t2, FieldMemOperand(t1, FixedArray::kHeaderSize));
+  __ Addu(t5, t5, Operand(Smi::FromInt(1)));
+
+  __ bind(&arguments_test);
+  __ Branch(&arguments_loop, lt, t5, Operand(a2));
+
+  // Return and remove the on-stack parameters.
+  __ Addu(sp, sp, Operand(3 * kPointerSize));
+  __ Ret();
+
+  // Do the runtime call to allocate the arguments object.
+  // a2 = argument count (taggged)
+  __ bind(&runtime);
+  __ sw(a2, MemOperand(sp, 0 * kPointerSize));  // Patch argument count.
+  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+}
+
+
+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;
   __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
@@ -4111,40 +4320,31 @@
 
   __ Addu(a1, a1, Operand(FixedArray::kHeaderSize / kPointerSize));
   __ bind(&add_arguments_object);
-  __ Addu(a1, a1, Operand(GetArgumentsObjectSize() / kPointerSize));
+  __ Addu(a1, a1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
 
   // Do the allocation of both objects in one go.
-  __ AllocateInNewSpace(
-      a1,
-      v0,
-      a2,
-      a3,
-      &runtime,
-      static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
+  __ AllocateInNewSpace(a1,
+                        v0,
+                        a2,
+                        a3,
+                        &runtime,
+                        static_cast<AllocationFlags>(TAG_OBJECT |
+                                                     SIZE_IN_WORDS));
 
   // Get the arguments boilerplate from the current (global) context.
   __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ lw(t0, FieldMemOperand(t0, GlobalObject::kGlobalContextOffset));
-  __ lw(t0, MemOperand(t0,
-                       Context::SlotOffset(GetArgumentsBoilerplateIndex())));
+  __ lw(t0, MemOperand(t0, Context::SlotOffset(
+      Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
 
   // Copy the JS object part.
   __ CopyFields(v0, t0, a3.bit(), JSObject::kHeaderSize / kPointerSize);
 
-  if (type_ == NEW_NON_STRICT) {
-    // Setup the callee in-object property.
-    STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
-    __ lw(a3, MemOperand(sp, 2 * kPointerSize));
-    const int kCalleeOffset = JSObject::kHeaderSize +
-                              Heap::kArgumentsCalleeIndex * kPointerSize;
-    __ sw(a3, FieldMemOperand(v0, kCalleeOffset));
-  }
-
   // Get the length (smi tagged) and set that as an in-object property too.
   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
   __ lw(a1, MemOperand(sp, 0 * kPointerSize));
   __ sw(a1, FieldMemOperand(v0, JSObject::kHeaderSize +
-                                Heap::kArgumentsLengthIndex * kPointerSize));
+      Heap::kArgumentsLengthIndex * kPointerSize));
 
   Label done;
   __ Branch(&done, eq, a1, Operand(zero_reg));
@@ -4154,12 +4354,13 @@
 
   // Setup the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ Addu(t0, v0, Operand(GetArgumentsObjectSize()));
+  __ Addu(t0, v0, Operand(Heap::kArgumentsObjectSizeStrict));
   __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
   __ LoadRoot(a3, Heap::kFixedArrayMapRootIndex);
   __ sw(a3, FieldMemOperand(t0, FixedArray::kMapOffset));
   __ sw(a1, FieldMemOperand(t0, FixedArray::kLengthOffset));
-  __ srl(a1, a1, kSmiTagSize);  // Untag the length for the loop.
+  // Untag the length for the loop.
+  __ srl(a1, a1, kSmiTagSize);
 
   // Copy the fixed array slots.
   Label loop;
@@ -4183,7 +4384,7 @@
 
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+  __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
 }
 
 
@@ -4365,10 +4566,9 @@
   __ movz(t9, t0, a0);  // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset.
 
   // 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 the hole.
-  __ GetObjectType(t9, a0, a0);
-  __ Branch(&runtime, ne, a0, Operand(CODE_TYPE));
+  // encoding. If it has, the field contains a code object otherwise it contains
+  // a smi (code flushing support).
+  __ JumpIfSmi(t9, &runtime);
 
   // a3: encoding of subject string (1 if ASCII, 0 if two_byte);
   // t9: code
@@ -4692,7 +4892,11 @@
     Label call_as_function;
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
     __ Branch(&call_as_function, eq, t0, Operand(at));
-    __ InvokeFunction(a1, actual, JUMP_FUNCTION);
+    __ InvokeFunction(a1,
+                      actual,
+                      JUMP_FUNCTION,
+                      NullCallWrapper(),
+                      CALL_AS_METHOD);
     __ bind(&call_as_function);
   }
   __ InvokeFunction(a1,
@@ -4709,6 +4913,7 @@
   __ li(a0, Operand(argc_));  // Setup the number of arguments.
   __ mov(a2, zero_reg);
   __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION);
+  __ SetCallKind(t1, CALL_AS_METHOD);
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
 }
@@ -4716,16 +4921,9 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT((lhs_.is(a0) && rhs_.is(a1)) ||
          (lhs_.is(a1) && rhs_.is(a0)));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case lt: cc_name = "LT"; break;
@@ -4736,40 +4934,14 @@
     case ne: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* lhs_name = lhs_.is(a0) ? "_a0" : "_a1";
-  const char* rhs_name = rhs_.is(a0) ? "_a0" : "_a1";
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == eq || cc_ == ne)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s%s%s",
-               cc_name,
-               lhs_name,
-               rhs_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == eq || cc_ == ne;
+  stream->Add("CompareStub_%s", cc_name);
+  stream->Add(lhs_.is(a0) ? "_a0" : "_a1");
+  stream->Add(rhs_.is(a0) ? "_a0" : "_a1");
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
@@ -6352,6 +6524,7 @@
   __ Jump(a2);
 }
 
+
 void DirectCEntryStub::Generate(MacroAssembler* masm) {
   // No need to pop or drop anything, LeaveExitFrame will restore the old
   // stack, thus dropping the allocated space for the return value.
@@ -6376,6 +6549,7 @@
   this->GenerateCall(masm, t9);
 }
 
+
 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
                                     Register target) {
   __ Move(t9, target);
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index 356aa97..aa224bc 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -59,35 +59,14 @@
 };
 
 
-class ToBooleanStub: public CodeStub {
- public:
-  explicit ToBooleanStub(Register tos) : tos_(tos) { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  Register tos_;
-  Major MajorKey() { return ToBoolean; }
-  int MinorKey() { return tos_.code(); }
-};
-
-
 class UnaryOpStub: public CodeStub {
  public:
-  UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
+  UnaryOpStub(Token::Value op,
+              UnaryOverwriteMode mode,
+              UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(UnaryOpIC::UNINITIALIZED),
-        name_(NULL) {
-  }
-
-  UnaryOpStub(
-      int key,
-      UnaryOpIC::TypeInfo operand_type)
-      : op_(OpBits::decode(key)),
-        mode_(ModeBits::decode(key)),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -97,20 +76,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("UnaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -164,8 +130,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     use_fpu_ = CpuFeatures::IsSupported(FPU);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -178,8 +143,7 @@
         mode_(ModeBits::decode(key)),
         use_fpu_(FPUBits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -195,20 +159,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
@@ -395,12 +346,6 @@
   }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "WriteInt32ToHeapNumberStub"; }
-
-#ifdef DEBUG
-  void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); }
-#endif
 };
 
 
@@ -427,14 +372,6 @@
   int MinorKey() { return 0; }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "NumberToStringStub"; }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("NumberToStringStub\n");
-  }
-#endif
 };
 
 
@@ -452,8 +389,6 @@
   int MinorKey() { return 0; }
 
   bool NeedsImmovableCode() { return true; }
-
-  const char* GetName() { return "RegExpCEntryStub"; }
 };
 
 // Trampoline stub to call into native code. To call safely into native code
@@ -474,13 +409,10 @@
   int MinorKey() { return 0; }
 
   bool NeedsImmovableCode() { return true; }
-
-  const char* GetName() { return "DirectCEntryStub"; }
 };
 
 class FloatingPointHelper : public AllStatic {
  public:
-
   enum Destination {
     kFPURegisters,
     kCoreRegisters
@@ -658,13 +590,6 @@
       StringDictionary::kHeaderSize +
       StringDictionary::kElementsStartIndex * kPointerSize;
 
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("StringDictionaryLookupStub\n");
-  }
-#endif
-
   Major MajorKey() { return StringDictionaryNegativeLookup; }
 
   int MinorKey() {
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index fecd321..a8de9c8 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -60,9 +60,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static void SetFunctionInfo(Handle<JSFunction> fun,
                               FunctionLiteral* lit,
diff --git a/src/mips/constants-mips.h b/src/mips/constants-mips.h
index 2567330..6bf2570 100644
--- a/src/mips/constants-mips.h
+++ b/src/mips/constants-mips.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -93,13 +93,27 @@
 static const uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1;
 
 // FCSR constants.
-static const uint32_t kFCSRFlagMask = (1 << 6) - 1;
-static const uint32_t kFCSRFlagShift = 2;
-static const uint32_t kFCSRInexactFlagBit = 1 << 0;
-static const uint32_t kFCSRUnderflowFlagBit = 1 << 1;
-static const uint32_t kFCSROverflowFlagBit = 1 << 2;
-static const uint32_t kFCSRDivideByZeroFlagBit = 1 << 3;
-static const uint32_t kFCSRInvalidOpFlagBit = 1 << 4;
+static const uint32_t kFCSRInexactFlagBit = 2;
+static const uint32_t kFCSRUnderflowFlagBit = 3;
+static const uint32_t kFCSROverflowFlagBit = 4;
+static const uint32_t kFCSRDivideByZeroFlagBit = 5;
+static const uint32_t kFCSRInvalidOpFlagBit = 6;
+
+static const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
+static const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
+static const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
+static const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
+static const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
+
+static const uint32_t kFCSRFlagMask =
+    kFCSRInexactFlagMask |
+    kFCSRUnderflowFlagMask |
+    kFCSROverflowFlagMask |
+    kFCSRDivideByZeroFlagMask |
+    kFCSRInvalidOpFlagMask;
+
+static const uint32_t kFCSRExceptionFlagMask =
+    kFCSRFlagMask ^ kFCSRInexactFlagMask;
 
 // Helper functions for converting between register numbers and names.
 class Registers {
@@ -119,7 +133,6 @@
   static const int32_t kMinValue = 0x80000000;
 
  private:
-
   static const char* names_[kNumSimuRegisters];
   static const RegisterAlias aliases_[];
 };
@@ -139,7 +152,6 @@
   };
 
  private:
-
   static const char* names_[kNumFPURegisters];
   static const RegisterAlias aliases_[];
 };
@@ -158,6 +170,18 @@
   call_rt_redirected = 0xfffff
 };
 
+// On MIPS Simulator breakpoints can have different codes:
+// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
+//   the simulator will run through them and print the registers.
+// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
+//   instructions (see Assembler::stop()).
+// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
+//   debugger.
+static const uint32_t kMaxWatchpointCode = 31;
+static const uint32_t kMaxStopCode = 127;
+STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
+
+
 // ----- Fields offset and length.
 static const int kOpcodeShift   = 26;
 static const int kOpcodeBits    = 6;
@@ -177,6 +201,8 @@
 static const int kImm16Bits  = 16;
 static const int kImm26Shift = 0;
 static const int kImm26Bits  = 26;
+static const int kImm28Shift = 0;
+static const int kImm28Bits  = 28;
 
 static const int kFsShift       = 11;
 static const int kFsBits        = 5;
@@ -196,6 +222,7 @@
 static const int  kOpcodeMask   = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
 static const int  kImm16Mask    = ((1 << kImm16Bits) - 1) << kImm16Shift;
 static const int  kImm26Mask    = ((1 << kImm26Bits) - 1) << kImm26Shift;
+static const int  kImm28Mask    = ((1 << kImm28Bits) - 1) << kImm28Shift;
 static const int  kRsFieldMask  = ((1 << kRsBits) - 1) << kRsShift;
 static const int  kRtFieldMask  = ((1 << kRtBits) - 1) << kRtShift;
 static const int  kRdFieldMask  = ((1 << kRdBits) - 1) << kRdShift;
@@ -736,4 +763,3 @@
 } }   // namespace v8::internal
 
 #endif    // #ifndef V8_MIPS_CONSTANTS_H_
-
diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc
index 4b69859..9a19aba 100644
--- a/src/mips/deoptimizer-mips.cc
+++ b/src/mips/deoptimizer-mips.cc
@@ -78,6 +78,11 @@
 }
 
 
+void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
+  UNIMPLEMENTED();
+}
+
+
 void Deoptimizer::EntryGenerator::Generate() {
   UNIMPLEMENTED();
 }
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 9c93c63..7834273 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -101,16 +101,18 @@
   }
 
   void EmitPatchInfo() {
-    int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
-    Register reg = Register::from_code(delta_to_patch_site / kImm16Mask);
-    __ andi(at, reg, delta_to_patch_site % kImm16Mask);
+    if (patch_site_.is_bound()) {
+      int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
+      Register reg = Register::from_code(delta_to_patch_site / kImm16Mask);
+      __ andi(at, reg, delta_to_patch_site % kImm16Mask);
 #ifdef DEBUG
-    info_emitted_ = true;
+      info_emitted_ = true;
 #endif
+    } else {
+      __ nop();  // Signals no inlined code.
+    }
   }
 
-  bool is_bound() const { return patch_site_.is_bound(); }
-
  private:
   MacroAssembler* masm_;
   Label patch_site_;
@@ -137,6 +139,7 @@
 void FullCodeGenerator::Generate(CompilationInfo* info) {
   ASSERT(info_ == NULL);
   info_ = info;
+  scope_ = info->scope();
   SetFunctionPosition(function());
   Comment cmnt(masm_, "[ function compiled by full code generator");
 
@@ -147,20 +150,20 @@
   }
 #endif
 
-  // Strict mode functions need to replace the receiver with undefined
-  // when called as functions (without an explicit receiver
-  // object). t1 is zero for method calls and non-zero for function
-  // calls.
-  if (info->is_strict_mode()) {
+  // Strict mode functions and builtins need to replace the receiver
+  // with undefined when called as functions (without an explicit
+  // receiver object). t1 is zero for method calls and non-zero for
+  // function calls.
+  if (info->is_strict_mode() || info->is_native()) {
     Label ok;
     __ Branch(&ok, eq, t1, Operand(zero_reg));
-    int receiver_offset = scope()->num_parameters() * kPointerSize;
+    int receiver_offset = info->scope()->num_parameters() * kPointerSize;
     __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
     __ sw(a2, MemOperand(sp, receiver_offset));
     __ bind(&ok);
   }
 
-  int locals_count = scope()->num_stack_slots();
+  int locals_count = info->scope()->num_stack_slots();
 
   __ Push(ra, fp, cp, a1);
   if (locals_count > 0) {
@@ -180,7 +183,7 @@
   bool function_in_register = true;
 
   // Possibly allocate a local context.
-  int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   if (heap_slots > 0) {
     Comment cmnt(masm_, "[ Allocate local context");
     // Argument to NewContext is the function, which is in a1.
@@ -189,14 +192,14 @@
       FastNewContextStub stub(heap_slots);
       __ CallStub(&stub);
     } else {
-      __ CallRuntime(Runtime::kNewContext, 1);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
     }
     function_in_register = false;
     // Context is returned in both v0 and cp.  It replaces the context
     // passed to us.  It's saved in the stack and kept live in cp.
     __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
     // Copy any necessary parameters into the context.
-    int num_parameters = scope()->num_parameters();
+    int num_parameters = info->scope()->num_parameters();
     for (int i = 0; i < num_parameters; i++) {
       Slot* slot = scope()->parameter(i)->AsSlot();
       if (slot != NULL && slot->type() == Slot::CONTEXT) {
@@ -228,27 +231,28 @@
       __ mov(a3, a1);
     }
     // Receiver is just before the parameters on the caller's stack.
-    int offset = scope()->num_parameters() * kPointerSize;
+    int num_parameters = info->scope()->num_parameters();
+    int offset = num_parameters * kPointerSize;
     __ Addu(a2, fp,
            Operand(StandardFrameConstants::kCallerSPOffset + offset));
-    __ li(a1, Operand(Smi::FromInt(scope()->num_parameters())));
+    __ li(a1, Operand(Smi::FromInt(num_parameters)));
     __ Push(a3, a2, a1);
 
     // 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 stub(
-        is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT
-                         : ArgumentsAccessStub::NEW_NON_STRICT);
+    ArgumentsAccessStub::Type type;
+    if (is_strict_mode()) {
+      type = ArgumentsAccessStub::NEW_STRICT;
+    } else if (function()->has_duplicate_parameters()) {
+      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+    } else {
+      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+    }
+    ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
 
-    Variable* arguments_shadow = scope()->arguments_shadow();
-    if (arguments_shadow != NULL) {
-      // Duplicate the value; move-to-slot operation might clobber registers.
-      __ mov(a3, v0);
-      Move(arguments_shadow->AsSlot(), a3, a1, a2);
-    }
     Move(arguments->AsSlot(), v0, a1, a2);
   }
 
@@ -348,7 +352,7 @@
     { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
       // Here we use masm_-> instead of the __ macro to avoid the code coverage
       // tool from instrumenting as we rely on the code size here.
-      int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
+      int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
       CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
       __ RecordJSReturn();
       masm_->mov(sp, fp);
@@ -386,7 +390,7 @@
   // For simplicity we always test the accumulator register.
   codegen()->Move(result_register(), slot);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -420,7 +424,7 @@
     if (true_label_ != fall_through_) __ Branch(true_label_);
   } else {
     __ LoadRoot(result_register(), index);
-    codegen()->DoTest(true_label_, false_label_, fall_through_);
+    codegen()->DoTest(this);
   }
 }
 
@@ -467,7 +471,7 @@
   } else {
     // For simplicity we always test the accumulator register.
     __ li(result_register(), Operand(lit));
-    codegen()->DoTest(true_label_, false_label_, fall_through_);
+    codegen()->DoTest(this);
   }
 }
 
@@ -503,7 +507,7 @@
   __ Drop(count);
   __ Move(result_register(), reg);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -581,7 +585,8 @@
 }
 
 
-void FullCodeGenerator::DoTest(Label* if_true,
+void FullCodeGenerator::DoTest(Expression* condition,
+                               Label* if_true,
                                Label* if_false,
                                Label* fall_through) {
   if (CpuFeatures::IsSupported(FPU)) {
@@ -715,10 +720,14 @@
         // context.
         ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
         if (FLAG_debug_code) {
-          // Check that we're not inside a 'with'.
-          __ lw(a1, ContextOperand(cp, Context::FCONTEXT_INDEX));
-          __ Check(eq, "Unexpected declaration in current context.",
-                   a1, Operand(cp));
+          // Check that we're not inside a with or catch context.
+          __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset));
+          __ LoadRoot(t0, Heap::kWithContextMapRootIndex);
+          __ Check(ne, "Declaration in with context.",
+                   a1, Operand(t0));
+          __ LoadRoot(t0, Heap::kCatchContextMapRootIndex);
+          __ Check(ne, "Declaration in catch context.",
+                   a1, Operand(t0));
         }
         if (mode == Variable::CONST) {
           __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
@@ -774,7 +783,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
 
       __ push(result_register());
@@ -789,7 +798,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ Call(ic);
       // Value in v0 is ignored (declarations are statements).
     }
   }
@@ -864,7 +873,8 @@
     // Record position before stub call for type feedback.
     SetSourcePosition(clause->position());
     Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
-    EmitCallIC(ic, &patch_site, clause->CompareId());
+    __ Call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
+    patch_site.EmitPatchInfo();
 
     __ Branch(&next_test, ne, v0, Operand(zero_reg));
     __ Drop(1);  // Switch value is no longer needed.
@@ -918,7 +928,7 @@
   Label convert, done_convert;
   __ JumpIfSmi(a0, &convert);
   __ GetObjectType(a0, a1, a1);
-  __ Branch(&done_convert, hs, a1, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(&done_convert, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
   __ bind(&convert);
   __ push(a0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
@@ -1107,7 +1117,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1128,8 +1138,7 @@
         __ Branch(slow, ne, temp, Operand(zero_reg));
       }
       // Load next context in chain.
-      __ lw(next, ContextOperand(current, Context::CLOSURE_INDEX));
-      __ lw(next, FieldMemOperand(next, JSFunction::kContextOffset));
+      __ lw(next, ContextOperand(current, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering cp.
       current = next;
     }
@@ -1153,8 +1162,7 @@
     __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX));
     __ Branch(slow, ne, temp, Operand(zero_reg));
     // Load next context in chain.
-    __ lw(next, ContextOperand(next, Context::CLOSURE_INDEX));
-    __ lw(next, FieldMemOperand(next, JSFunction::kContextOffset));
+    __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX));
     __ Branch(&loop);
     __ bind(&fast);
   }
@@ -1165,7 +1173,7 @@
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  EmitCallIC(ic, mode, AstNode::kNoNumber);
+  __ Call(ic, mode);
 }
 
 
@@ -1184,8 +1192,7 @@
         __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX));
         __ Branch(slow, ne, temp, Operand(zero_reg));
       }
-      __ lw(next, ContextOperand(context, Context::CLOSURE_INDEX));
-      __ lw(next, FieldMemOperand(next, JSFunction::kContextOffset));
+      __ lw(next, ContextOperand(context, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering cp.
       context = next;
     }
@@ -1246,7 +1253,7 @@
           __ li(a0, Operand(key_literal->handle()));
           Handle<Code> ic =
               isolate()->builtins()->KeyedLoadIC_Initialize();
-          EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
+          __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
           __ Branch(done);
         }
       }
@@ -1255,24 +1262,27 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
-  // Four cases: non-this global variables, lookup slots, all other
-  // types of slots, and parameters that rewrite to explicit property
-  // accesses on the arguments object.
-  Slot* slot = var->AsSlot();
-  Property* property = var->AsProperty();
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
 
-  if (var->is_global() && !var->is_this()) {
+  // Three cases: non-this global variables, lookup slots, and all other
+  // types of slots.
+  Slot* slot = var->AsSlot();
+  ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
+
+  if (slot == NULL) {
     Comment cmnt(masm_, "Global variable");
     // Use inline caching. Variable name is passed in a2 and the global
     // object (receiver) in a0.
     __ lw(a0, GlobalObjectOperand());
     __ li(a2, Operand(var->name()));
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
     context()->Plug(v0);
 
-  } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
+  } else if (slot->type() == Slot::LOOKUP) {
     Label done, slow;
 
     // Generate code for loading from variables potentially shadowed
@@ -1288,7 +1298,7 @@
 
     context()->Plug(v0);
 
-  } else if (slot != NULL) {
+  } else {
     Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
                             ? "Context slot"
                             : "Stack slot");
@@ -1305,31 +1315,6 @@
      } else {
        context()->Plug(slot);
      }
-  } else {
-    Comment cmnt(masm_, "Rewritten parameter");
-    ASSERT_NOT_NULL(property);
-    // Rewritten parameter accesses are of the form "slot[literal]".
-    // Assert that the object is in a slot.
-    Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
-    ASSERT_NOT_NULL(object_var);
-    Slot* object_slot = object_var->AsSlot();
-    ASSERT_NOT_NULL(object_slot);
-
-    // Load the object.
-    Move(a1, object_slot);
-
-    // Assert that the key is a smi.
-    Literal* key_literal = property->key()->AsLiteral();
-    ASSERT_NOT_NULL(key_literal);
-    ASSERT(key_literal->handle()->IsSmi());
-
-    // Load the key.
-    __ li(a0, Operand(key_literal->handle()));
-
-    // Call keyed load IC. It has arguments key and receiver in a0 and a1.
-    Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
-    context()->Plug(v0);
   }
 }
 
@@ -1440,7 +1425,7 @@
             Handle<Code> ic = is_strict_mode()
                 ? isolate()->builtins()->StoreIC_Initialize_Strict()
                 : isolate()->builtins()->StoreIC_Initialize();
-            EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id());
+            __ Call(ic, RelocInfo::CODE_TARGET, key->id());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           } else {
             VisitForEffect(value);
@@ -1573,7 +1558,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
@@ -1600,27 +1585,13 @@
     case KEYED_PROPERTY:
       // We need the key and receiver on both the stack and in v0 and a1.
       if (expr->is_compound()) {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          __ lw(v0, EmitSlotSearch(obj_proxy->var()->AsSlot(), v0));
-          __ push(v0);
-          __ li(v0, Operand(property->key()->AsLiteral()->handle()));
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForAccumulatorValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForAccumulatorValue(property->key());
         __ lw(a1, MemOperand(sp, 0));
         __ push(v0);
       } else {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          __ lw(a1, EmitSlotSearch(obj_proxy->var()->AsSlot(), v0));
-          __ li(v0, Operand(property->key()->AsLiteral()->handle()));
-          __ Push(a1, v0);
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForStackValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForStackValue(property->key());
       }
       break;
   }
@@ -1631,7 +1602,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -1698,7 +1669,7 @@
   __ li(a2, Operand(key->handle()));
   // Call load IC. It has arguments receiver and property name a0 and a2.
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
@@ -1707,7 +1678,7 @@
   __ mov(a0, result_register());
   // Call keyed load IC. It has arguments key and receiver in a0 and a1.
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
@@ -1735,7 +1706,8 @@
 
   __ bind(&stub_call);
   BinaryOpStub stub(op, mode);
-  EmitCallIC(stub.GetCode(), &patch_site, expr->id());
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   __ jmp(&done);
 
   __ bind(&smi_case);
@@ -1816,7 +1788,9 @@
   __ mov(a0, result_register());
   __ pop(a1);
   BinaryOpStub stub(op, mode);
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code.
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   context()->Plug(v0);
 }
 
@@ -1830,7 +1804,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
@@ -1856,30 +1830,20 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ Call(ic);
       break;
     }
     case KEYED_PROPERTY: {
       __ push(result_register());  // Preserve value.
-      if (prop->is_synthetic()) {
-        ASSERT(prop->obj()->AsVariableProxy() != NULL);
-        ASSERT(prop->key()->AsLiteral() != NULL);
-        { AccumulatorValueContext for_object(this);
-          EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
-        }
-        __ mov(a2, result_register());
-        __ li(a1, Operand(prop->key()->AsLiteral()->handle()));
-      } else {
-        VisitForStackValue(prop->obj());
-        VisitForAccumulatorValue(prop->key());
-        __ mov(a1, result_register());
-        __ pop(a2);
-      }
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
+      __ mov(a1, result_register());
+      __ pop(a2);
       __ pop(a0);  // Restore value.
       Handle<Code> ic = is_strict_mode()
         ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
         : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ Call(ic);
       break;
     }
   }
@@ -1890,8 +1854,6 @@
 
 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
                                                Token::Value op) {
-  // Left-hand sides that rewrite to explicit property accesses do not reach
-  // here.
   ASSERT(var != NULL);
   ASSERT(var->is_global() || var->AsSlot() != NULL);
 
@@ -1906,7 +1868,7 @@
     Handle<Code> ic = is_strict_mode()
         ? isolate()->builtins()->StoreIC_Initialize_Strict()
         : isolate()->builtins()->StoreIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
 
   } else if (op == Token::INIT_CONST) {
     // Like var declarations, const declarations are hoisted to function
@@ -1927,17 +1889,7 @@
         __ Branch(&skip, ne, a1, Operand(t0));
         __ sw(result_register(), MemOperand(fp, SlotOffset(slot)));
         break;
-      case Slot::CONTEXT: {
-        __ lw(a1, ContextOperand(cp, Context::FCONTEXT_INDEX));
-        __ lw(a2, ContextOperand(a1, slot->index()));
-        __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
-        __ Branch(&skip, ne, a2, Operand(t0));
-        __ sw(result_register(), ContextOperand(a1, slot->index()));
-        int offset = Context::SlotOffset(slot->index());
-        __ mov(a3, result_register());  // Preserve the stored value in v0.
-        __ RecordWrite(a1, Operand(offset), a3, a2);
-        break;
-      }
+      case Slot::CONTEXT:
       case Slot::LOOKUP:
         __ push(result_register());
         __ li(a0, Operand(slot->var()->name()));
@@ -2014,7 +1966,7 @@
   Handle<Code> ic = is_strict_mode()
         ? isolate()->builtins()->StoreIC_Initialize_Strict()
         : isolate()->builtins()->StoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2066,7 +2018,7 @@
   Handle<Code> ic = is_strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2119,7 +2071,7 @@
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
-  EmitCallIC(ic, mode, expr->id());
+  __ Call(ic, mode, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2153,7 +2105,7 @@
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
   __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize));  // Key.
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2193,7 +2145,8 @@
   __ push(a1);
 
   // Push the receiver of the enclosing function and do runtime call.
-  __ lw(a1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize));
+  int receiver_offset = 2 + info_->scope()->num_parameters();
+  __ lw(a1, MemOperand(fp, receiver_offset * kPointerSize));
   __ push(a1);
   // Push the strict mode flag.
   __ li(a1, Operand(Smi::FromInt(strict_mode_flag())));
@@ -2310,9 +2263,9 @@
       __ bind(&done);
       // Push function.
       __ push(v0);
-      // Push global receiver.
-      __ lw(a1, GlobalObjectOperand());
-      __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset));
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
       __ push(a1);
       __ bind(&call);
     }
@@ -2334,7 +2287,7 @@
     } else {
       // Call to a keyed property.
       // For a synthetic property use keyed load IC followed by function call,
-      // for a regular property use keyed EmitCallIC.
+      // for a regular property use EmitKeyedCallWithIC.
       if (prop->is_synthetic()) {
         // Do not visit the object and key subexpressions (they are shared
         // by all occurrences of the same rewritten parameter).
@@ -2352,7 +2305,7 @@
         SetSourcePosition(prop->position());
 
         Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-        EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+        __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
         __ lw(a1, GlobalObjectOperand());
         __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset));
         __ Push(v0, a1);  // Function, receiver.
@@ -2477,9 +2430,10 @@
   __ And(at, a1, Operand(1 << Map::kIsUndetectable));
   __ Branch(if_false, ne, at, Operand(zero_reg));
   __ lbu(a1, FieldMemOperand(a2, Map::kInstanceTypeOffset));
-  __ Branch(if_false, lt, a1, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
-  Split(le, a1, Operand(LAST_JS_OBJECT_TYPE), if_true, if_false, fall_through);
+  Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE),
+        if_true, if_false, fall_through);
 
   context()->Plug(if_true, if_false);
 }
@@ -2500,7 +2454,7 @@
   __ JumpIfSmi(v0, if_false);
   __ GetObjectType(v0, a1, a1);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
-  Split(ge, a1, Operand(FIRST_JS_OBJECT_TYPE),
+  Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE),
         if_true, if_false, fall_through);
 
   context()->Plug(if_true, if_false);
@@ -2738,7 +2692,7 @@
   // parameter count in a0.
   VisitForAccumulatorValue(args->at(0));
   __ mov(a1, v0);
-  __ li(a0, Operand(Smi::FromInt(scope()->num_parameters())));
+  __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
   __ CallStub(&stub);
   context()->Plug(v0);
@@ -2750,7 +2704,7 @@
 
   Label exit;
   // Get the number of formal parameters.
-  __ li(v0, Operand(Smi::FromInt(scope()->num_parameters())));
+  __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
 
   // Check if the calling frame is an arguments adaptor frame.
   __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
@@ -2779,14 +2733,15 @@
   // Check that the object is a JS object but take special care of JS
   // functions to make sure they have 'Function' as their class.
   __ GetObjectType(v0, v0, a1);  // Map is now in v0.
-  __ Branch(&null, lt, a1, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(&null, lt, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
 
-  // As long as JS_FUNCTION_TYPE is the last instance type and it is
-  // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
-  // LAST_JS_OBJECT_TYPE.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
-  __ Branch(&function, eq, a1, Operand(JS_FUNCTION_TYPE));
+  // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
+  // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
+  STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+  STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+                LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
+  __ Branch(&function, ge, a1, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE));
 
   // Check if the constructor in the map is a function.
   __ lw(v0, FieldMemOperand(v0, Map::kConstructorOffset));
@@ -2829,13 +2784,12 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
+
   // Finally, we're expected to leave a value on the top of the stack.
   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
   context()->Plug(v0);
@@ -3184,7 +3138,8 @@
   // InvokeFunction requires the function in a1. Move it in there.
   __ mov(a1, result_register());
   ParameterCount count(arg_count);
-  __ InvokeFunction(a1, count, CALL_FUNCTION);
+  __ InvokeFunction(a1, count, CALL_FUNCTION,
+                    NullCallWrapper(), CALL_AS_METHOD);
   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
   context()->Plug(v0);
 }
@@ -3443,9 +3398,7 @@
   __ Branch(&bailout, ne, scratch2, Operand(JS_ARRAY_TYPE));
 
   // Check that the array has fast elements.
-  __ lbu(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset));
-  __ And(scratch3, scratch2, Operand(1 << Map::kHasFastElements));
-  __ Branch(&bailout, eq, scratch3, Operand(zero_reg));
+  __ CheckFastElements(scratch1, scratch2, &bailout);
 
   // If the array has length zero, return the empty string.
   __ lw(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
@@ -3649,6 +3602,39 @@
 }
 
 
+void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 1);
+
+  // Load the function into v0.
+  VisitForAccumulatorValue(args->at(0));
+
+  // Prepare for the test.
+  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);
+
+  // Test for strict mode function.
+  __ lw(a1, FieldMemOperand(v0, JSFunction::kSharedFunctionInfoOffset));
+  __ lw(a1, FieldMemOperand(a1, SharedFunctionInfo::kCompilerHintsOffset));
+  __ And(at, a1, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
+                               kSmiTagSize)));
+  __ Branch(if_true, ne, at, Operand(zero_reg));
+
+  // Test for native function.
+  __ And(at, a1, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
+  __ Branch(if_true, ne, at, Operand(zero_reg));
+
+  // Not native or strict-mode function.
+  __ Branch(if_false);
+
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+  context()->Plug(if_true, if_false);
+}
+
+
 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   Handle<String> name = expr->name();
   if (name->length() > 0 && name->Get(0) == '_') {
@@ -3681,7 +3667,7 @@
         isolate()->stub_cache()->ComputeCallInitialize(arg_count,
                                                        NOT_IN_LOOP,
                                                        mode);
-    EmitCallIC(ic, mode, expr->id());
+    __ Call(ic, mode, expr->id());
     // Restore context register.
     __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
   } else {
@@ -3824,7 +3810,7 @@
   VisitForAccumulatorValue(expr->expression());
   SetSourcePosition(expr->position());
   __ mov(a0, result_register());
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
   context()->Plug(v0);
 }
 
@@ -3841,7 +3827,7 @@
   }
 
   // Expression can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
@@ -3856,7 +3842,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
@@ -3869,15 +3855,8 @@
       __ push(v0);
       EmitNamedPropertyLoad(prop);
     } else {
-      if (prop->is_arguments_access()) {
-        VariableProxy* obj_proxy = prop->obj()->AsVariableProxy();
-        __ lw(v0, EmitSlotSearch(obj_proxy->var()->AsSlot(), v0));
-        __ push(v0);
-        __ li(v0, Operand(prop->key()->AsLiteral()->handle()));
-      } else {
-        VisitForStackValue(prop->obj());
-        VisitForAccumulatorValue(prop->key());
-      }
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
       __ lw(a1, MemOperand(sp, 0));
       __ push(v0);
       EmitKeyedPropertyLoad(prop);
@@ -3942,7 +3921,8 @@
   SetSourcePosition(expr->position());
 
   BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
-  EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
+  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+  patch_site.EmitPatchInfo();
   __ bind(&done);
 
   // Store the value returned in v0.
@@ -3974,7 +3954,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -3992,7 +3972,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -4016,7 +3996,7 @@
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+    __ Call(ic);
     PrepareForBailout(expr, TOS_REG);
     context()->Plug(v0);
   } else if (proxy != NULL &&
@@ -4039,30 +4019,17 @@
     context()->Plug(v0);
   } else {
     // This expression cannot throw a reference error at the top level.
-    context()->HandleExpression(expr);
+    VisitInCurrentContext(expr);
   }
 }
 
-
-bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
-                                          Expression* left,
-                                          Expression* right,
-                                          Label* if_true,
-                                          Label* if_false,
-                                          Label* fall_through) {
-  if (op != Token::EQ && op != Token::EQ_STRICT) return false;
-
-  // Check for the pattern: typeof <expression> == <string literal>.
-  Literal* right_literal = right->AsLiteral();
-  if (right_literal == NULL) return false;
-  Handle<Object> right_literal_value = right_literal->handle();
-  if (!right_literal_value->IsString()) return false;
-  UnaryOperation* left_unary = left->AsUnaryOperation();
-  if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
-  Handle<String> check = Handle<String>::cast(right_literal_value);
-
+void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
+                                                 Handle<String> check,
+                                                 Label* if_true,
+                                                 Label* if_false,
+                                                 Label* fall_through) {
   { AccumulatorValueContext context(this);
-    VisitForTypeofValue(left_unary->expression());
+    VisitForTypeofValue(expr);
   }
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
 
@@ -4097,7 +4064,7 @@
   } else if (check->Equals(isolate()->heap()->function_symbol())) {
     __ JumpIfSmi(v0, if_false);
     __ GetObjectType(v0, a1, v0);  // Leave map in a1.
-    Split(ge, v0, Operand(FIRST_FUNCTION_CLASS_TYPE),
+    Split(ge, v0, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE),
         if_true, if_false, fall_through);
 
   } else if (check->Equals(isolate()->heap()->object_symbol())) {
@@ -4106,9 +4073,9 @@
     __ Branch(if_true, eq, v0, Operand(at));
     // Check for JS objects => true.
     __ GetObjectType(v0, v0, a1);
-    __ Branch(if_false, lo, a1, Operand(FIRST_JS_OBJECT_TYPE));
+    __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
     __ lbu(a1, FieldMemOperand(v0, Map::kInstanceTypeOffset));
-    __ Branch(if_false, hs, a1, Operand(FIRST_FUNCTION_CLASS_TYPE));
+    __ Branch(if_false, gt, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
     // Check for undetectable objects => false.
     __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset));
     __ And(a1, a1, Operand(1 << Map::kIsUndetectable));
@@ -4116,8 +4083,18 @@
   } else {
     if (if_false != fall_through) __ jmp(if_false);
   }
+}
 
-  return true;
+
+void FullCodeGenerator::EmitLiteralCompareUndefined(Expression* expr,
+                                                    Label* if_true,
+                                                    Label* if_false,
+                                                    Label* fall_through) {
+  VisitForAccumulatorValue(expr);
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+
+  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
+  Split(eq, v0, Operand(at), if_true, if_false, fall_through);
 }
 
 
@@ -4137,14 +4114,12 @@
 
   // First we try a fast inlined version of the compare when one of
   // the operands is a literal.
-  Token::Value op = expr->op();
-  Expression* left = expr->left();
-  Expression* right = expr->right();
-  if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) {
+  if (TryLiteralCompare(expr, if_true, if_false, fall_through)) {
     context()->Plug(if_true, if_false);
     return;
   }
 
+  Token::Value op = expr->op();
   VisitForStackValue(expr->left());
   switch (op) {
     case Token::IN:
@@ -4168,11 +4143,8 @@
     default: {
       VisitForAccumulatorValue(expr->right());
       Condition cc = eq;
-      bool strict = false;
       switch (op) {
         case Token::EQ_STRICT:
-          strict = true;
-          // Fall through.
         case Token::EQ:
           cc = eq;
           __ mov(a0, result_register());
@@ -4218,7 +4190,8 @@
       // Record position and call the compare IC.
       SetSourcePosition(expr->position());
       Handle<Code> ic = CompareIC::GetUninitialized(op);
-      EmitCallIC(ic, &patch_site, expr->id());
+      __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
+      patch_site.EmitPatchInfo();
       PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
       Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through);
     }
@@ -4277,70 +4250,6 @@
 }
 
 
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   RelocInfo::Mode mode,
-                                   unsigned ast_id) {
-  ASSERT(mode == RelocInfo::CODE_TARGET ||
-         mode == RelocInfo::CODE_TARGET_CONTEXT);
-  Counters* counters = isolate()->counters();
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(counters->named_load_full(), 1, a1, a2);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(counters->named_store_full(), 1, a1, a2);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2);
-    default:
-      break;
-  }
-  if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) {
-    __ Call(ic, mode);
-  } else {
-    ASSERT(mode == RelocInfo::CODE_TARGET);
-    mode = RelocInfo::CODE_TARGET_WITH_ID;
-    __ CallWithAstId(ic, mode, ast_id);
-  }
-}
-
-
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   JumpPatchSite* patch_site,
-                                   unsigned ast_id) {
-  Counters* counters = isolate()->counters();
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(counters->named_load_full(), 1, a1, a2);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(counters->named_store_full(), 1, a1, a2);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2);
-    default:
-      break;
-  }
-
-  if (ast_id == kNoASTId) {
-    __ Call(ic, RelocInfo::CODE_TARGET);
-  } else {
-    __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
-  }
-  if (patch_site != NULL && patch_site->is_bound()) {
-    patch_site->EmitPatchInfo();
-  } else {
-    __ nop();  // Signals no inlined code.
-  }
-}
-
-
 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
   ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
   __ sw(value, MemOperand(fp, frame_offset));
@@ -4352,6 +4261,27 @@
 }
 
 
+void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
+  Scope* declaration_scope = scope()->DeclarationScope();
+  if (declaration_scope->is_global_scope()) {
+    // Contexts nested in the global context have a canonical empty function
+    // as their closure, not the anonymous closure containing the global
+    // code.  Pass a smi sentinel and let the runtime look up the empty
+    // function.
+    __ li(at, Operand(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.
+    __ lw(at, ContextOperand(cp, Context::CLOSURE_INDEX));
+  } else {
+    ASSERT(declaration_scope->is_function_scope());
+    __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  }
+  __ push(at);
+}
+
+
 // ----------------------------------------------------------------------------
 // Non-local control flow support.
 
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index 12c81c2..da39962 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -80,10 +80,10 @@
 
   // Check that the receiver is a valid JS object.
   __ GetObjectType(receiver, scratch0, scratch1);
-  __ Branch(miss, lt, scratch1, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(miss, lt, scratch1, Operand(FIRST_SPEC_OBJECT_TYPE));
 
   // If this assert fails, we have to check upper bound too.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
 
   GenerateGlobalInstanceTypeCheck(masm, scratch1, miss);
 
@@ -214,115 +214,6 @@
 }
 
 
-static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
-                                         Label* miss,
-                                         Register elements,
-                                         Register key,
-                                         Register result,
-                                         Register reg0,
-                                         Register reg1,
-                                         Register reg2) {
-  // 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:
-  //
-  // reg0 - holds the untagged key on entry and holds the hash once computed.
-  //
-  // reg1 - Used to hold the capacity mask of the dictionary.
-  //
-  // reg2 - Used for the index into the dictionary.
-  // at   - Temporary (avoid MacroAssembler instructions also using 'at').
-  Label done;
-
-  // Compute the hash code from the untagged key.  This must be kept in sync
-  // with ComputeIntegerHash in utils.h.
-  //
-  // hash = ~hash + (hash << 15);
-  __ nor(reg1, reg0, zero_reg);
-  __ sll(at, reg0, 15);
-  __ addu(reg0, reg1, at);
-
-  // hash = hash ^ (hash >> 12);
-  __ srl(at, reg0, 12);
-  __ xor_(reg0, reg0, at);
-
-  // hash = hash + (hash << 2);
-  __ sll(at, reg0, 2);
-  __ addu(reg0, reg0, at);
-
-  // hash = hash ^ (hash >> 4);
-  __ srl(at, reg0, 4);
-  __ xor_(reg0, reg0, at);
-
-  // hash = hash * 2057;
-  __ li(reg1, Operand(2057));
-  __ mul(reg0, reg0, reg1);
-
-  // hash = hash ^ (hash >> 16);
-  __ srl(at, reg0, 16);
-  __ xor_(reg0, reg0, at);
-
-  // Compute the capacity mask.
-  __ lw(reg1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
-  __ sra(reg1, reg1, kSmiTagSize);
-  __ Subu(reg1, reg1, Operand(1));
-
-  // Generate an unrolled loop that performs a few probes before giving up.
-  static const int kProbes = 4;
-  for (int i = 0; i < kProbes; i++) {
-    // Use reg2 for index calculations and keep the hash intact in reg0.
-    __ mov(reg2, reg0);
-    // Compute the masked index: (hash + i + i * i) & mask.
-    if (i > 0) {
-      __ Addu(reg2, reg2, Operand(NumberDictionary::GetProbeOffset(i)));
-    }
-    __ and_(reg2, reg2, reg1);
-
-    // Scale the index by multiplying by the element size.
-    ASSERT(NumberDictionary::kEntrySize == 3);
-    __ sll(at, reg2, 1);  // 2x.
-    __ addu(reg2, reg2, at);  // reg2 = reg2 * 3.
-
-    // Check if the key is identical to the name.
-    __ sll(at, reg2, kPointerSizeLog2);
-    __ addu(reg2, elements, at);
-
-    __ lw(at, FieldMemOperand(reg2, NumberDictionary::kElementsStartOffset));
-    if (i != kProbes - 1) {
-      __ Branch(&done, eq, key, Operand(at));
-    } else {
-      __ Branch(miss, ne, key, Operand(at));
-    }
-  }
-
-  __ bind(&done);
-  // Check that the value is a normal property.
-  // reg2: elements + (index * kPointerSize).
-  const int kDetailsOffset =
-      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
-  __ lw(reg1, FieldMemOperand(reg2, kDetailsOffset));
-  __ And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
-  __ Branch(miss, ne, at, Operand(zero_reg));
-
-  // Get the value at the masked, scaled index and return.
-  const int kValueOffset =
-      NumberDictionary::kElementsStartOffset + kPointerSize;
-  __ lw(result, FieldMemOperand(reg2, kValueOffset));
-}
-
-
 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- a2    : name
@@ -567,7 +458,8 @@
 
   // Invoke the function.
   ParameterCount actual(argc);
-  __ InvokeFunction(a1, actual, JUMP_FUNCTION);
+  __ InvokeFunction(a1, actual, JUMP_FUNCTION,
+                    NullCallWrapper(), CALL_AS_METHOD);
 }
 
 
@@ -750,7 +642,7 @@
   __ Branch(&slow_load, ne, a3, Operand(at));
   __ sra(a0, a2, kSmiTagSize);
   // a0: untagged index
-  GenerateNumberDictionaryLoad(masm, &slow_load, t0, a2, a1, a0, a3, t1);
+  __ LoadFromNumberDictionary(&slow_load, t0, a2, a1, a0, a3, t1);
   __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, a0, a3);
   __ jmp(&do_call);
 
@@ -892,6 +784,175 @@
 }
 
 
+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.
+  __ GetObjectType(object, scratch1, scratch2);
+  __ Branch(slow_case, lt, scratch2, Operand(FIRST_JS_RECEIVER_TYPE));
+
+  // Check that the key is a positive smi.
+  __ And(scratch1, key, Operand(0x8000001));
+  __ Branch(slow_case, ne, scratch1, Operand(zero_reg));
+
+  // Load the elements into scratch1 and check its map.
+  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  __ lw(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.
+  __ lw(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset));
+  __ Subu(scratch2, scratch2, Operand(Smi::FromInt(2)));
+  __ Branch(unmapped_case, Ugreater_equal, key, Operand(scratch2));
+
+  // Load element index and check whether it is the hole.
+  const int kOffset =
+      FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag;
+
+  __ li(scratch3, Operand(kPointerSize >> 1));
+  __ mul(scratch3, key, scratch3);
+  __ Addu(scratch3, scratch3, Operand(kOffset));
+
+  __ Addu(scratch2, scratch1, scratch3);
+  __ lw(scratch2, MemOperand(scratch2));
+  __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex);
+  __ Branch(unmapped_case, eq, scratch2, Operand(scratch3));
+
+  // 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).
+  __ lw(scratch1, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
+  __ li(scratch3, Operand(kPointerSize >> 1));
+  __ mul(scratch3, scratch2, scratch3);
+  __ Addu(scratch3, scratch3, Operand(Context::kHeaderSize - kHeapObjectTag));
+  __ Addu(scratch2, scratch1, scratch3);
+  return MemOperand(scratch2);
+}
+
+
+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;
+  __ lw(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);
+  __ lw(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
+  __ Branch(slow_case, Ugreater_equal, key, Operand(scratch));
+  __ li(scratch, Operand(kPointerSize >> 1));
+  __ mul(scratch, key, scratch);
+  __ Addu(scratch,
+          scratch,
+          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ Addu(scratch, backing_store, scratch);
+  return MemOperand(scratch);
+}
+
+
+void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- lr     : return address
+  //  -- a0     : key
+  //  -- a1     : receiver
+  // -----------------------------------
+  Label slow, notin;
+  MemOperand mapped_location =
+      GenerateMappedArgumentsLookup(masm, a1, a0, a2, a3, t0, &notin, &slow);
+  __ lw(v0, mapped_location);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in a2.
+  MemOperand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, a0, a2, a3, &slow);
+  __ lw(a2, unmapped_location);
+  __ Branch(&slow, eq, a2, Operand(a3));
+  __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
+  __ mov(v0, a2);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
+void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- a0     : value
+  //  -- a1     : key
+  //  -- a2     : receiver
+  //  -- lr     : return address
+  // -----------------------------------
+  Label slow, notin;
+  MemOperand mapped_location =
+      GenerateMappedArgumentsLookup(masm, a2, a1, a3, t0, t1, &notin, &slow);
+  __ sw(a0, mapped_location);
+  // Verify mapped_location MemOperand is register, with no offset.
+  ASSERT_EQ(mapped_location.offset(), 0);
+  __ RecordWrite(a3, mapped_location.rm(), t5);
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);  // (In delay slot) return the value stored in v0.
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in a3.
+  MemOperand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, a1, a3, t0, &slow);
+  __ sw(a0, unmapped_location);
+  ASSERT_EQ(unmapped_location.offset(), 0);
+  __ RecordWrite(a3, unmapped_location.rm(), t5);
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);  // (In delay slot) return the value stored in v0.
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
+void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
+                                             int argc) {
+  // ----------- S t a t e -------------
+  //  -- a2    : name
+  //  -- lr    : return address
+  // -----------------------------------
+  Label slow, notin;
+  // Load receiver.
+  __ lw(a1, MemOperand(sp, argc * kPointerSize));
+  MemOperand mapped_location =
+      GenerateMappedArgumentsLookup(masm, a1, a2, a3, t0, t1, &notin, &slow);
+  __ lw(a1, mapped_location);
+  GenerateFunctionTailCall(masm, argc, &slow, a3);
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in a3.
+  MemOperand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, a2, a3, t0, &slow);
+  __ lw(a1, unmapped_location);
+  __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
+  __ Branch(&slow, eq, a1, Operand(a3));
+  GenerateFunctionTailCall(masm, argc, &slow, a3);
+  __ bind(&slow);
+  GenerateMiss(masm, argc);
+}
+
+
+Object* KeyedLoadIC_Miss(Arguments args);
+
+
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
   // ---------- S t a t e --------------
   //  -- ra     : return address
@@ -949,11 +1010,8 @@
   GenerateKeyedLoadReceiverCheck(
       masm, receiver, a2, a3, Map::kHasIndexedInterceptor, &slow);
 
-  // Check the "has fast elements" bit in the receiver's map which is
-  // now in a2.
-  __ lbu(a3, FieldMemOperand(a2, Map::kBitField2Offset));
-  __ And(at, a3, Operand(1 << Map::kHasFastElements));
-  __ Branch(&check_number_dictionary, eq, at, Operand(zero_reg));
+  // Check the receiver's map to see if it has fast elements.
+  __ CheckFastElements(a2, a3, &check_number_dictionary);
 
   GenerateFastArrayLoad(
       masm, receiver, key, t0, a3, a2, v0, NULL, &slow);
@@ -972,7 +1030,7 @@
   __ LoadRoot(at, Heap::kHashTableMapRootIndex);
   __ Branch(&slow, ne, a3, Operand(at));
   __ sra(a2, a0, kSmiTagSize);
-  GenerateNumberDictionaryLoad(masm, &slow, t0, a0, v0, a2, a3, t1);
+  __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
   __ Ret();
 
   // Slow case, key and receiver still in a0 and a1.
@@ -1173,8 +1231,10 @@
   __ lbu(t3, FieldMemOperand(t3, Map::kInstanceTypeOffset));
 
   __ Branch(&array, eq, t3, Operand(JS_ARRAY_TYPE));
-  // Check that the object is some kind of JS object.
-  __ Branch(&slow, lt, t3, Operand(FIRST_JS_OBJECT_TYPE));
+  // Check that the object is some kind of JSObject.
+  __ Branch(&slow, lt, t3, Operand(FIRST_JS_RECEIVER_TYPE));
+  __ Branch(&slow, eq, t3, Operand(JS_PROXY_TYPE));
+  __ Branch(&slow, eq, t3, Operand(JS_FUNCTION_PROXY_TYPE));
 
   // Object case: Check key against length in the elements array.
   __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 8b342a2..5e8d676 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -50,87 +50,6 @@
 }
 
 
-// Arguments macros.
-#define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2
-#define COND_ARGS cond, r1, r2
-
-#define REGISTER_TARGET_BODY(Name) \
-void MacroAssembler::Name(Register target, \
-                          BranchDelaySlot bd) { \
-  Name(Operand(target), bd); \
-} \
-void MacroAssembler::Name(Register target, COND_TYPED_ARGS, \
-                          BranchDelaySlot bd) { \
-  Name(Operand(target), COND_ARGS, bd); \
-}
-
-
-#define INT_PTR_TARGET_BODY(Name) \
-void MacroAssembler::Name(intptr_t target, RelocInfo::Mode rmode, \
-                          BranchDelaySlot bd) { \
-  Name(Operand(target, rmode), bd); \
-} \
-void MacroAssembler::Name(intptr_t target, \
-                          RelocInfo::Mode rmode, \
-                          COND_TYPED_ARGS, \
-                          BranchDelaySlot bd) { \
-  Name(Operand(target, rmode), COND_ARGS, bd); \
-}
-
-
-#define BYTE_PTR_TARGET_BODY(Name) \
-void MacroAssembler::Name(byte* target, RelocInfo::Mode rmode, \
-                          BranchDelaySlot bd) { \
-  Name(reinterpret_cast<intptr_t>(target), rmode, bd); \
-} \
-void MacroAssembler::Name(byte* target, \
-                          RelocInfo::Mode rmode, \
-                          COND_TYPED_ARGS, \
-                          BranchDelaySlot bd) { \
-  Name(reinterpret_cast<intptr_t>(target), rmode, COND_ARGS, bd); \
-}
-
-
-#define CODE_TARGET_BODY(Name) \
-void MacroAssembler::Name(Handle<Code> target, RelocInfo::Mode rmode, \
-                          BranchDelaySlot bd) { \
-  Name(reinterpret_cast<intptr_t>(target.location()), rmode, bd); \
-} \
-void MacroAssembler::Name(Handle<Code> target, \
-                          RelocInfo::Mode rmode, \
-                          COND_TYPED_ARGS, \
-                          BranchDelaySlot bd) { \
-  Name(reinterpret_cast<intptr_t>(target.location()), rmode, COND_ARGS, bd); \
-}
-
-
-REGISTER_TARGET_BODY(Jump)
-REGISTER_TARGET_BODY(Call)
-INT_PTR_TARGET_BODY(Jump)
-INT_PTR_TARGET_BODY(Call)
-BYTE_PTR_TARGET_BODY(Jump)
-BYTE_PTR_TARGET_BODY(Call)
-CODE_TARGET_BODY(Jump)
-CODE_TARGET_BODY(Call)
-
-#undef COND_TYPED_ARGS
-#undef COND_ARGS
-#undef REGISTER_TARGET_BODY
-#undef BYTE_PTR_TARGET_BODY
-#undef CODE_TARGET_BODY
-
-
-void MacroAssembler::Ret(BranchDelaySlot bd) {
-  Jump(Operand(ra), bd);
-}
-
-
-void MacroAssembler::Ret(Condition cond, Register r1, const Operand& r2,
-    BranchDelaySlot bd) {
-  Jump(Operand(ra), cond, r1, r2, bd);
-}
-
-
 void MacroAssembler::LoadRoot(Register destination,
                               Heap::RootListIndex index) {
   lw(destination, MemOperand(s6, index << kPointerSizeLog2));
@@ -193,6 +112,7 @@
   sw(scratch, MemOperand(object, Page::kDirtyFlagOffset));
 }
 
+
 // Push and pop all registers that can hold pointers.
 void MacroAssembler::PushSafepointRegisters() {
   // Safepoints expect a block of kNumSafepointRegisters values on the
@@ -203,12 +123,14 @@
   MultiPush(kSafepointSavedRegisters);
 }
 
+
 void MacroAssembler::PopSafepointRegisters() {
   const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
   MultiPop(kSafepointSavedRegisters);
   Addu(sp, sp, Operand(num_unsaved * kPointerSize));
 }
 
+
 void MacroAssembler::PushSafepointRegistersAndDoubles() {
   PushSafepointRegisters();
   Subu(sp, sp, Operand(FPURegister::kNumAllocatableRegisters * kDoubleSize));
@@ -218,6 +140,7 @@
   }
 }
 
+
 void MacroAssembler::PopSafepointRegistersAndDoubles() {
   for (int i = 0; i < FPURegister::kNumAllocatableRegisters; i+=2) {
     FPURegister reg = FPURegister::FromAllocationIndex(i);
@@ -227,6 +150,7 @@
   PopSafepointRegisters();
 }
 
+
 void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src,
                                                              Register dst) {
   sw(src, SafepointRegistersAndDoublesSlot(dst));
@@ -419,6 +343,114 @@
 }
 
 
+void MacroAssembler::LoadFromNumberDictionary(Label* miss,
+                                              Register elements,
+                                              Register key,
+                                              Register result,
+                                              Register reg0,
+                                              Register reg1,
+                                              Register reg2) {
+  // 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:
+  //
+  // reg0 - holds the untagged key on entry and holds the hash once computed.
+  //
+  // reg1 - Used to hold the capacity mask of the dictionary.
+  //
+  // reg2 - Used for the index into the dictionary.
+  // at   - Temporary (avoid MacroAssembler instructions also using 'at').
+  Label done;
+
+  // Compute the hash code from the untagged key.  This must be kept in sync
+  // with ComputeIntegerHash in utils.h.
+  //
+  // hash = ~hash + (hash << 15);
+  nor(reg1, reg0, zero_reg);
+  sll(at, reg0, 15);
+  addu(reg0, reg1, at);
+
+  // hash = hash ^ (hash >> 12);
+  srl(at, reg0, 12);
+  xor_(reg0, reg0, at);
+
+  // hash = hash + (hash << 2);
+  sll(at, reg0, 2);
+  addu(reg0, reg0, at);
+
+  // hash = hash ^ (hash >> 4);
+  srl(at, reg0, 4);
+  xor_(reg0, reg0, at);
+
+  // hash = hash * 2057;
+  li(reg1, Operand(2057));
+  mul(reg0, reg0, reg1);
+
+  // hash = hash ^ (hash >> 16);
+  srl(at, reg0, 16);
+  xor_(reg0, reg0, at);
+
+  // Compute the capacity mask.
+  lw(reg1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
+  sra(reg1, reg1, kSmiTagSize);
+  Subu(reg1, reg1, Operand(1));
+
+  // Generate an unrolled loop that performs a few probes before giving up.
+  static const int kProbes = 4;
+  for (int i = 0; i < kProbes; i++) {
+    // Use reg2 for index calculations and keep the hash intact in reg0.
+    mov(reg2, reg0);
+    // Compute the masked index: (hash + i + i * i) & mask.
+    if (i > 0) {
+      Addu(reg2, reg2, Operand(NumberDictionary::GetProbeOffset(i)));
+    }
+    and_(reg2, reg2, reg1);
+
+    // Scale the index by multiplying by the element size.
+    ASSERT(NumberDictionary::kEntrySize == 3);
+    sll(at, reg2, 1);  // 2x.
+    addu(reg2, reg2, at);  // reg2 = reg2 * 3.
+
+    // Check if the key is identical to the name.
+    sll(at, reg2, kPointerSizeLog2);
+    addu(reg2, elements, at);
+
+    lw(at, FieldMemOperand(reg2, NumberDictionary::kElementsStartOffset));
+    if (i != kProbes - 1) {
+      Branch(&done, eq, key, Operand(at));
+    } else {
+      Branch(miss, ne, key, Operand(at));
+    }
+  }
+
+  bind(&done);
+  // Check that the value is a normal property.
+  // reg2: elements + (index * kPointerSize).
+  const int kDetailsOffset =
+      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+  lw(reg1, FieldMemOperand(reg2, kDetailsOffset));
+  And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
+  Branch(miss, ne, at, Operand(zero_reg));
+
+  // Get the value at the masked, scaled index and return.
+  const int kValueOffset =
+      NumberDictionary::kElementsStartOffset + kPointerSize;
+  lw(result, FieldMemOperand(reg2, kValueOffset));
+}
+
+
 // ---------------------------------------------------------------------------
 // Instruction macros.
 
@@ -670,14 +702,6 @@
 }
 
 
-// Exception-generating instructions and debugging support.
-void MacroAssembler::stop(const char* msg) {
-  // TO_UPGRADE: Just a break for now. Maybe we could upgrade it.
-  // We use the 0x54321 value to be able to find it easily when reading memory.
-  break_(0x54321);
-}
-
-
 void MacroAssembler::MultiPush(RegList regs) {
   int16_t NumSaved = 0;
   int16_t NumToPush = NumberOfBitsSet(regs);
@@ -840,11 +864,11 @@
 
 void MacroAssembler::Trunc_uw_d(FPURegister fd, Register rs) {
   ASSERT(!fd.is(f22));
-  ASSERT(!rs.is(t6));
+  ASSERT(!rs.is(t8));
 
   // Load 2^31 into f22.
-  Or(t6, zero_reg, 0x80000000);
-  Cvt_d_uw(f22, t6);
+  Or(t8, zero_reg, 0x80000000);
+  Cvt_d_uw(f22, t8);
 
   // Test if f22 > fd.
   c(OLT, D, fd, f22);
@@ -859,7 +883,7 @@
   sub_d(f22, fd, f22);
   trunc_w_d(f22, f22);
   mfc1(rs, f22);
-  or_(rs, rs, t6);
+  or_(rs, rs, t8);
 
   Label done;
   Branch(&done);
@@ -1052,6 +1076,51 @@
 }
 
 
+void MacroAssembler::EmitECMATruncate(Register result,
+                                      FPURegister double_input,
+                                      FPURegister single_scratch,
+                                      Register scratch,
+                                      Register input_high,
+                                      Register input_low) {
+  CpuFeatures::Scope scope(FPU);
+  ASSERT(!input_high.is(result));
+  ASSERT(!input_low.is(result));
+  ASSERT(!input_low.is(input_high));
+  ASSERT(!scratch.is(result) &&
+         !scratch.is(input_high) &&
+         !scratch.is(input_low));
+  ASSERT(!single_scratch.is(double_input));
+
+  Label done;
+  Label manual;
+
+  // Clear cumulative exception flags and save the FCSR.
+  Register scratch2 = input_high;
+  cfc1(scratch2, FCSR);
+  ctc1(zero_reg, FCSR);
+  // Try a conversion to a signed integer.
+  trunc_w_d(single_scratch, double_input);
+  mfc1(result, single_scratch);
+  // Retrieve and restore the FCSR.
+  cfc1(scratch, FCSR);
+  ctc1(scratch2, FCSR);
+  // Check for overflow and NaNs.
+  And(scratch,
+      scratch,
+      kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | kFCSRInvalidOpFlagMask);
+  // If we had no exceptions we are done.
+  Branch(&done, eq, scratch, Operand(zero_reg));
+
+  // Load the double value and perform a manual truncation.
+  Move(input_low, input_high, double_input);
+  EmitOutOfInt32RangeTruncate(result,
+                              input_high,
+                              input_low,
+                              scratch);
+  bind(&done);
+}
+
+
 void MacroAssembler::GetLeastBitsFromSmi(Register dst,
                                          Register src,
                                          int num_least_bits) {
@@ -1074,7 +1143,54 @@
     (cond != cc_always && (!rs.is(zero_reg) || !rt.rm().is(zero_reg))))
 
 
+bool MacroAssembler::UseAbsoluteCodePointers() {
+  if (is_trampoline_emitted()) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
 void MacroAssembler::Branch(int16_t offset, BranchDelaySlot bdslot) {
+  BranchShort(offset, bdslot);
+}
+
+
+void MacroAssembler::Branch(int16_t offset, Condition cond, Register rs,
+                            const Operand& rt,
+                            BranchDelaySlot bdslot) {
+  BranchShort(offset, cond, rs, rt, bdslot);
+}
+
+
+void MacroAssembler::Branch(Label* L, BranchDelaySlot bdslot) {
+  bool is_label_near = is_near(L);
+  if (UseAbsoluteCodePointers() && !is_label_near) {
+    Jr(L, bdslot);
+  } else {
+    BranchShort(L, bdslot);
+  }
+}
+
+
+void MacroAssembler::Branch(Label* L, Condition cond, Register rs,
+                            const Operand& rt,
+                            BranchDelaySlot bdslot) {
+  bool is_label_near = is_near(L);
+  if (UseAbsoluteCodePointers() && !is_label_near) {
+    Label skip;
+    Condition neg_cond = NegateCondition(cond);
+    BranchShort(&skip, neg_cond, rs, rt);
+    Jr(L, bdslot);
+    bind(&skip);
+  } else {
+    BranchShort(L, cond, rs, rt, bdslot);
+  }
+}
+
+
+void MacroAssembler::BranchShort(int16_t offset, BranchDelaySlot bdslot) {
   b(offset);
 
   // Emit a nop in the branch delay slot if required.
@@ -1083,9 +1199,9 @@
 }
 
 
-void MacroAssembler::Branch(int16_t offset, Condition cond, Register rs,
-                            const Operand& rt,
-                            BranchDelaySlot bdslot) {
+void MacroAssembler::BranchShort(int16_t offset, Condition cond, Register rs,
+                                 const Operand& rt,
+                                 BranchDelaySlot bdslot) {
   BRANCH_ARGS_CHECK(cond, rs, rt);
   ASSERT(!rs.is(zero_reg));
   Register r2 = no_reg;
@@ -1157,7 +1273,8 @@
         break;
       case Uless:
         if (r2.is(zero_reg)) {
-          b(offset);
+          // No code needs to be emitted.
+          return;
         } else {
           sltu(scratch, rs, r2);
           bne(scratch, zero_reg, offset);
@@ -1216,7 +1333,7 @@
         } else {
           r2 = scratch;
           li(r2, rt);
-          sltu(scratch, rs, r2);
+          slt(scratch, rs, r2);
           beq(scratch, zero_reg, offset);
         }
         break;
@@ -1269,7 +1386,8 @@
         break;
       case Uless:
         if (rt.imm32_ == 0) {
-          b(offset);
+          // No code needs to be emitted.
+          return;
         } else if (is_int16(rt.imm32_)) {
           sltiu(scratch, rs, rt.imm32_);
           bne(scratch, zero_reg, offset);
@@ -1300,7 +1418,7 @@
 }
 
 
-void MacroAssembler::Branch(Label* L, BranchDelaySlot bdslot) {
+void MacroAssembler::BranchShort(Label* L, BranchDelaySlot bdslot) {
   // We use branch_offset as an argument for the branch instructions to be sure
   // it is called just before generating the branch instruction, as needed.
 
@@ -1312,9 +1430,9 @@
 }
 
 
-void MacroAssembler::Branch(Label* L, Condition cond, Register rs,
-                            const Operand& rt,
-                            BranchDelaySlot bdslot) {
+void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs,
+                                 const Operand& rt,
+                                 BranchDelaySlot bdslot) {
   BRANCH_ARGS_CHECK(cond, rs, rt);
 
   int32_t offset;
@@ -1402,8 +1520,8 @@
         break;
       case Uless:
         if (r2.is(zero_reg)) {
-          offset = shifted_branch_offset(L, false);
-          b(offset);
+          // No code needs to be emitted.
+          return;
         } else {
           sltu(scratch, rs, r2);
           offset = shifted_branch_offset(L, false);
@@ -1468,7 +1586,7 @@
         } else {
           r2 = scratch;
           li(r2, rt);
-          sltu(scratch, rs, r2);
+          slt(scratch, rs, r2);
           offset = shifted_branch_offset(L, false);
           beq(scratch, zero_reg, offset);
         }
@@ -1532,8 +1650,8 @@
         break;
      case Uless:
         if (rt.imm32_ == 0) {
-          offset = shifted_branch_offset(L, false);
-          b(offset);
+          // No code needs to be emitted.
+          return;
         } else if (is_int16(rt.imm32_)) {
           sltiu(scratch, rs, rt.imm32_);
           offset = shifted_branch_offset(L, false);
@@ -1570,11 +1688,49 @@
 }
 
 
+void MacroAssembler::BranchAndLink(int16_t offset, BranchDelaySlot bdslot) {
+  BranchAndLinkShort(offset, bdslot);
+}
+
+
+void MacroAssembler::BranchAndLink(int16_t offset, Condition cond, Register rs,
+                                   const Operand& rt,
+                                   BranchDelaySlot bdslot) {
+  BranchAndLinkShort(offset, cond, rs, rt, bdslot);
+}
+
+
+void MacroAssembler::BranchAndLink(Label* L, BranchDelaySlot bdslot) {
+  bool is_label_near = is_near(L);
+  if (UseAbsoluteCodePointers() && !is_label_near) {
+    Jalr(L, bdslot);
+  } else {
+    BranchAndLinkShort(L, bdslot);
+  }
+}
+
+
+void MacroAssembler::BranchAndLink(Label* L, Condition cond, Register rs,
+                                   const Operand& rt,
+                                   BranchDelaySlot bdslot) {
+  bool is_label_near = is_near(L);
+  if (UseAbsoluteCodePointers() && !is_label_near) {
+    Label skip;
+    Condition neg_cond = NegateCondition(cond);
+    BranchShort(&skip, neg_cond, rs, rt);
+    Jalr(L, bdslot);
+    bind(&skip);
+  } else {
+    BranchAndLinkShort(L, cond, rs, rt, bdslot);
+  }
+}
+
+
 // We need to use a bgezal or bltzal, but they can't be used directly with the
 // slt instructions. We could use sub or add instead but we would miss overflow
 // cases, so we keep slt and add an intermediate third instruction.
-void MacroAssembler::BranchAndLink(int16_t offset,
-                                   BranchDelaySlot bdslot) {
+void MacroAssembler::BranchAndLinkShort(int16_t offset,
+                                        BranchDelaySlot bdslot) {
   bal(offset);
 
   // Emit a nop in the branch delay slot if required.
@@ -1583,9 +1739,9 @@
 }
 
 
-void MacroAssembler::BranchAndLink(int16_t offset, Condition cond, Register rs,
-                                   const Operand& rt,
-                                   BranchDelaySlot bdslot) {
+void MacroAssembler::BranchAndLinkShort(int16_t offset, Condition cond,
+                                        Register rs, const Operand& rt,
+                                        BranchDelaySlot bdslot) {
   BRANCH_ARGS_CHECK(cond, rs, rt);
   Register r2 = no_reg;
   Register scratch = at;
@@ -1665,7 +1821,7 @@
 }
 
 
-void MacroAssembler::BranchAndLink(Label* L, BranchDelaySlot bdslot) {
+void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) {
   bal(shifted_branch_offset(L, false));
 
   // Emit a nop in the branch delay slot if required.
@@ -1674,9 +1830,9 @@
 }
 
 
-void MacroAssembler::BranchAndLink(Label* L, Condition cond, Register rs,
-                                   const Operand& rt,
-                                   BranchDelaySlot bdslot) {
+void MacroAssembler::BranchAndLinkShort(Label* L, Condition cond, Register rs,
+                                        const Operand& rt,
+                                        BranchDelaySlot bdslot) {
   BRANCH_ARGS_CHECK(cond, rs, rt);
 
   int32_t offset;
@@ -1772,164 +1928,230 @@
 }
 
 
-void MacroAssembler::Jump(const Operand& target, BranchDelaySlot bdslot) {
-  BlockTrampolinePoolScope block_trampoline_pool(this);
-  if (target.is_reg()) {
-      jr(target.rm());
-  } else {
-    if (!MustUseReg(target.rmode_)) {
-        j(target.imm32_);
-    } else {
-      li(t9, target);
-      jr(t9);
-    }
-  }
-  // Emit a nop in the branch delay slot if required.
-  if (bdslot == PROTECT)
-    nop();
-}
-
-
-void MacroAssembler::Jump(const Operand& target,
-                          Condition cond, Register rs, const Operand& rt,
-                          BranchDelaySlot bdslot) {
-  BlockTrampolinePoolScope block_trampoline_pool(this);
-  BRANCH_ARGS_CHECK(cond, rs, rt);
-  if (target.is_reg()) {
-    if (cond == cc_always) {
-      jr(target.rm());
-    } else {
-      Branch(2, NegateCondition(cond), rs, rt);
-      jr(target.rm());
-    }
-  } else {  // Not register target.
-    if (!MustUseReg(target.rmode_)) {
-      if (cond == cc_always) {
-        j(target.imm32_);
-      } else {
-        Branch(2, NegateCondition(cond), rs, rt);
-        j(target.imm32_);  // Will generate only one instruction.
-      }
-    } else {  // MustUseReg(target).
-      li(t9, target);
-      if (cond == cc_always) {
-        jr(t9);
-      } else {
-        Branch(2, NegateCondition(cond), rs, rt);
-        jr(t9);  // Will generate only one instruction.
-      }
-    }
-  }
-  // Emit a nop in the branch delay slot if required.
-  if (bdslot == PROTECT)
-    nop();
-}
-
-
-int MacroAssembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
-  return 4 * kInstrSize;
-}
-
-
-int MacroAssembler::CallSize(Register reg) {
-  return 2 * kInstrSize;
-}
-
-
-// Note: To call gcc-compiled C code on mips, you must call thru t9.
-void MacroAssembler::Call(const Operand& target, BranchDelaySlot bdslot) {
-  BlockTrampolinePoolScope block_trampoline_pool(this);
-  if (target.is_reg()) {
-      jalr(target.rm());
-  } else {  // !target.is_reg().
-    if (!MustUseReg(target.rmode_)) {
-      jal(target.imm32_);
-    } else {  // MustUseReg(target).
-      // Must record previous source positions before the
-      // li() generates a new code target.
-      positions_recorder()->WriteRecordedPositions();
-      li(t9, target);
-      jalr(t9);
-    }
-  }
-  // Emit a nop in the branch delay slot if required.
-  if (bdslot == PROTECT)
-    nop();
-}
-
-
-// Note: To call gcc-compiled C code on mips, you must call thru t9.
-void MacroAssembler::Call(const Operand& target,
-                          Condition cond, Register rs, const Operand& rt,
-                          BranchDelaySlot bdslot) {
-  BlockTrampolinePoolScope block_trampoline_pool(this);
-  BRANCH_ARGS_CHECK(cond, rs, rt);
-  if (target.is_reg()) {
-    if (cond == cc_always) {
-      jalr(target.rm());
-    } else {
-      Branch(2, NegateCondition(cond), rs, rt);
-      jalr(target.rm());
-    }
-  } else {  // !target.is_reg().
-    if (!MustUseReg(target.rmode_)) {
-      if (cond == cc_always) {
-        jal(target.imm32_);
-      } else {
-        Branch(2, NegateCondition(cond), rs, rt);
-        jal(target.imm32_);  // Will generate only one instruction.
-      }
-    } else {  // MustUseReg(target)
-      li(t9, target);
-      if (cond == cc_always) {
-        jalr(t9);
-      } else {
-        Branch(2, NegateCondition(cond), rs, rt);
-        jalr(t9);  // Will generate only one instruction.
-      }
-    }
-  }
-  // Emit a nop in the branch delay slot if required.
-  if (bdslot == PROTECT)
-    nop();
-}
-
-
-void MacroAssembler::CallWithAstId(Handle<Code> code,
-                                   RelocInfo::Mode rmode,
-                                   unsigned ast_id,
-                                   Condition cond,
-                                   Register r1,
-                                   const Operand& r2) {
-  ASSERT(rmode == RelocInfo::CODE_TARGET_WITH_ID);
-  ASSERT(ast_id != kNoASTId);
-  ASSERT(ast_id_for_reloc_info_ == kNoASTId);
-  ast_id_for_reloc_info_ = ast_id;
-  Call(reinterpret_cast<intptr_t>(code.location()), rmode, cond, r1, r2);
-}
-
-
-void MacroAssembler::Drop(int count,
+void MacroAssembler::Jump(Register target,
                           Condition cond,
-                          Register reg,
-                          const Operand& op) {
-  if (count <= 0) {
-    return;
+                          Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bd) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+  if (cond == cc_always) {
+    jr(target);
+  } else {
+    BRANCH_ARGS_CHECK(cond, rs, rt);
+    Branch(2, NegateCondition(cond), rs, rt);
+    jr(target);
+  }
+  // Emit a nop in the branch delay slot if required.
+  if (bd == PROTECT)
+    nop();
+}
+
+
+void MacroAssembler::Jump(intptr_t target,
+                          RelocInfo::Mode rmode,
+                          Condition cond,
+                          Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bd) {
+  li(t9, Operand(target, rmode));
+  Jump(t9, cond, rs, rt, bd);
+}
+
+
+void MacroAssembler::Jump(Address target,
+                          RelocInfo::Mode rmode,
+                          Condition cond,
+                          Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bd) {
+  ASSERT(!RelocInfo::IsCodeTarget(rmode));
+  Jump(reinterpret_cast<intptr_t>(target), rmode, cond, rs, rt, bd);
+}
+
+
+void MacroAssembler::Jump(Handle<Code> code,
+                          RelocInfo::Mode rmode,
+                          Condition cond,
+                          Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bd) {
+  ASSERT(RelocInfo::IsCodeTarget(rmode));
+  Jump(reinterpret_cast<intptr_t>(code.location()), rmode, cond, rs, rt, bd);
+}
+
+
+int MacroAssembler::CallSize(Register target,
+                             Condition cond,
+                             Register rs,
+                             const Operand& rt,
+                             BranchDelaySlot bd) {
+  int size = 0;
+
+  if (cond == cc_always) {
+    size += 1;
+  } else {
+    size += 3;
   }
 
-  Label skip;
+  if (bd == PROTECT)
+    size += 1;
 
-  if (cond != al) {
-    Branch(&skip, NegateCondition(cond), reg, op);
-  }
+  return size * kInstrSize;
+}
 
-  if (count > 0) {
-    addiu(sp, sp, count * kPointerSize);
-  }
 
-  if (cond != al) {
-    bind(&skip);
+// Note: To call gcc-compiled C code on mips, you must call thru t9.
+void MacroAssembler::Call(Register target,
+                          Condition cond,
+                          Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bd) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+  Label start;
+  bind(&start);
+  if (cond == cc_always) {
+    jalr(target);
+  } else {
+    BRANCH_ARGS_CHECK(cond, rs, rt);
+    Branch(2, NegateCondition(cond), rs, rt);
+    jalr(target);
   }
+  // Emit a nop in the branch delay slot if required.
+  if (bd == PROTECT)
+    nop();
+
+  ASSERT_EQ(CallSize(target, cond, rs, rt, bd),
+            SizeOfCodeGeneratedSince(&start));
+}
+
+
+int MacroAssembler::CallSize(Address target,
+                             RelocInfo::Mode rmode,
+                             Condition cond,
+                             Register rs,
+                             const Operand& rt,
+                             BranchDelaySlot bd) {
+  int size = CallSize(t9, cond, rs, rt, bd);
+  return size + 2 * kInstrSize;
+}
+
+
+void MacroAssembler::Call(Address target,
+                          RelocInfo::Mode rmode,
+                          Condition cond,
+                          Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bd) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+  Label start;
+  bind(&start);
+  int32_t target_int = reinterpret_cast<int32_t>(target);
+  // Must record previous source positions before the
+  // li() generates a new code target.
+  positions_recorder()->WriteRecordedPositions();
+  li(t9, Operand(target_int, rmode), true);
+  Call(t9, cond, rs, rt, bd);
+  ASSERT_EQ(CallSize(target, rmode, cond, rs, rt, bd),
+            SizeOfCodeGeneratedSince(&start));
+}
+
+
+int MacroAssembler::CallSize(Handle<Code> code,
+                             RelocInfo::Mode rmode,
+                             unsigned ast_id,
+                             Condition cond,
+                             Register rs,
+                             const Operand& rt,
+                             BranchDelaySlot bd) {
+  return CallSize(reinterpret_cast<Address>(code.location()),
+      rmode, cond, rs, rt, bd);
+}
+
+
+void MacroAssembler::Call(Handle<Code> code,
+                          RelocInfo::Mode rmode,
+                          unsigned ast_id,
+                          Condition cond,
+                          Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bd) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+  Label start;
+  bind(&start);
+  ASSERT(RelocInfo::IsCodeTarget(rmode));
+  if (rmode == RelocInfo::CODE_TARGET && ast_id != kNoASTId) {
+    SetRecordedAstId(ast_id);
+    rmode = RelocInfo::CODE_TARGET_WITH_ID;
+  }
+  Call(reinterpret_cast<Address>(code.location()), rmode, cond, rs, rt, bd);
+  ASSERT_EQ(CallSize(code, rmode, ast_id, cond, rs, rt),
+            SizeOfCodeGeneratedSince(&start));
+}
+
+
+void MacroAssembler::Ret(Condition cond,
+                         Register rs,
+                         const Operand& rt,
+                         BranchDelaySlot bd) {
+  Jump(ra, cond, rs, rt, bd);
+}
+
+
+void MacroAssembler::J(Label* L, BranchDelaySlot bdslot) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+
+  uint32_t imm28;
+  imm28 = jump_address(L);
+  imm28 &= kImm28Mask;
+  { BlockGrowBufferScope block_buf_growth(this);
+    // Buffer growth (and relocation) must be blocked for internal references
+    // until associated instructions are emitted and available to be patched.
+    RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+    j(imm28);
+  }
+  // Emit a nop in the branch delay slot if required.
+  if (bdslot == PROTECT)
+    nop();
+}
+
+
+void MacroAssembler::Jr(Label* L, BranchDelaySlot bdslot) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+
+  uint32_t imm32;
+  imm32 = jump_address(L);
+  { BlockGrowBufferScope block_buf_growth(this);
+    // Buffer growth (and relocation) must be blocked for internal references
+    // until associated instructions are emitted and available to be patched.
+    RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+    lui(at, (imm32 & kHiMask) >> kLuiShift);
+    ori(at, at, (imm32 & kImm16Mask));
+  }
+  jr(at);
+
+  // Emit a nop in the branch delay slot if required.
+  if (bdslot == PROTECT)
+    nop();
+}
+
+
+void MacroAssembler::Jalr(Label* L, BranchDelaySlot bdslot) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+
+  uint32_t imm32;
+  imm32 = jump_address(L);
+  { BlockGrowBufferScope block_buf_growth(this);
+    // Buffer growth (and relocation) must be blocked for internal references
+    // until associated instructions are emitted and available to be patched.
+    RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+    lui(at, (imm32 & kHiMask) >> kLuiShift);
+    ori(at, at, (imm32 & kImm16Mask));
+  }
+  jalr(at);
+
+  // Emit a nop in the branch delay slot if required.
+  if (bdslot == PROTECT)
+    nop();
 }
 
 
@@ -1954,6 +2176,29 @@
 }
 
 
+void MacroAssembler::Drop(int count,
+                          Condition cond,
+                          Register reg,
+                          const Operand& op) {
+  if (count <= 0) {
+    return;
+  }
+
+  Label skip;
+
+  if (cond != al) {
+     Branch(&skip, NegateCondition(cond), reg, op);
+  }
+
+  addiu(sp, sp, count * kPointerSize);
+
+  if (cond != al) {
+    bind(&skip);
+  }
+}
+
+
+
 void MacroAssembler::Swap(Register reg1,
                           Register reg2,
                           Register scratch) {
@@ -1974,6 +2219,12 @@
 }
 
 
+void MacroAssembler::Push(Handle<Object> handle) {
+  li(at, Operand(handle));
+  push(at);
+}
+
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
 
 void MacroAssembler::DebugBreak() {
@@ -2515,8 +2766,8 @@
                                                  Register scratch1,
                                                  Register scratch2,
                                                  Label* gc_required) {
-  LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
-  AllocateHeapNumber(result, scratch1, scratch2, t6, gc_required);
+  LoadRoot(t8, Heap::kHeapNumberMapRootIndex);
+  AllocateHeapNumber(result, scratch1, scratch2, t8, gc_required);
   sdc1(value, FieldMemOperand(result, HeapNumber::kValueOffset));
 }
 
@@ -2605,6 +2856,15 @@
 }
 
 
+void MacroAssembler::CheckFastElements(Register map,
+                                       Register scratch,
+                                       Label* fail) {
+  STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0);
+  lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
+  Branch(fail, hi, scratch, Operand(Map::kMaximumBitField2FastElementValue));
+}
+
+
 void MacroAssembler::CheckMap(Register obj,
                               Register scratch,
                               Handle<Map> map,
@@ -2775,9 +3035,9 @@
     Handle<Code> adaptor =
         isolate()->builtins()->ArgumentsAdaptorTrampoline();
     if (flag == CALL_FUNCTION) {
-      call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
+      call_wrapper.BeforeCall(CallSize(adaptor));
       SetCallKind(t1, call_kind);
-      Call(adaptor, RelocInfo::CODE_TARGET);
+      Call(adaptor);
       call_wrapper.AfterCall();
       jmp(done);
     } else {
@@ -2861,7 +3121,8 @@
 
 void MacroAssembler::InvokeFunction(JSFunction* function,
                                     const ParameterCount& actual,
-                                    InvokeFlag flag) {
+                                    InvokeFlag flag,
+                                    CallKind call_kind) {
   ASSERT(function->is_compiled());
 
   // Get the function and setup the context.
@@ -2874,7 +3135,7 @@
   if (V8::UseCrankshaft()) {
     UNIMPLEMENTED_MIPS();
   } else {
-    InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+    InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag, call_kind);
   }
 }
 
@@ -2892,8 +3153,8 @@
                                             Register scratch,
                                             Label* fail) {
   lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
-  Branch(fail, lt, scratch, Operand(FIRST_JS_OBJECT_TYPE));
-  Branch(fail, gt, scratch, Operand(LAST_JS_OBJECT_TYPE));
+  Branch(fail, lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  Branch(fail, gt, scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
 }
 
 
@@ -2973,7 +3234,7 @@
 void MacroAssembler::CallStub(CodeStub* stub, Condition cond,
                               Register r1, const Operand& r2) {
   ASSERT(allow_stub_calls());  // Stub calls are not allowed in some stubs.
-  Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2);
+  Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond, r1, r2);
 }
 
 
@@ -2984,17 +3245,18 @@
   { MaybeObject* maybe_result = stub->TryGetCode();
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-  Call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, cond, r1, r2);
+  Call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET,
+      kNoASTId, cond, r1, r2);
   return result;
 }
 
 
-
 void MacroAssembler::TailCallStub(CodeStub* stub) {
   ASSERT(allow_stub_calls());  // Stub calls are not allowed in some stubs.
   Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
 }
 
+
 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub,
                                              Condition cond,
                                              Register r1,
@@ -3190,23 +3452,18 @@
   ASSERT(!overflow_dst.is(right));
   ASSERT(!left.is(right));
 
-  // TODO(kalmard) There must be a way to optimize dst == left and dst == right
-  // cases.
-
   if (dst.is(left)) {
-    addu(overflow_dst, left, right);
-    xor_(dst, overflow_dst, left);
-    xor_(scratch, overflow_dst, right);
-    and_(scratch, scratch, dst);
-    mov(dst, overflow_dst);
-    mov(overflow_dst, scratch);
+    mov(scratch, left);  // Preserve left.
+    addu(dst, left, right);  // Left is overwritten.
+    xor_(scratch, dst, scratch);  // Original left.
+    xor_(overflow_dst, dst, right);
+    and_(overflow_dst, overflow_dst, scratch);
   } else if (dst.is(right)) {
-    addu(overflow_dst, left, right);
-    xor_(dst, overflow_dst, right);
-    xor_(scratch, overflow_dst, left);
-    and_(scratch, scratch, dst);
-    mov(dst, overflow_dst);
-    mov(overflow_dst, scratch);
+    mov(scratch, right);  // Preserve right.
+    addu(dst, left, right);  // Right is overwritten.
+    xor_(scratch, dst, scratch);  // Original right.
+    xor_(overflow_dst, dst, left);
+    and_(overflow_dst, overflow_dst, scratch);
   } else {
     addu(dst, left, right);
     xor_(overflow_dst, dst, left);
@@ -3230,23 +3487,18 @@
   ASSERT(!scratch.is(left));
   ASSERT(!scratch.is(right));
 
-  // TODO(kalmard) There must be a way to optimize dst == left and dst == right
-  // cases.
-
   if (dst.is(left)) {
-    subu(overflow_dst, left, right);
-    xor_(scratch, overflow_dst, left);
-    xor_(dst, left, right);
-    and_(scratch, scratch, dst);
-    mov(dst, overflow_dst);
-    mov(overflow_dst, scratch);
+    mov(scratch, left);  // Preserve left.
+    subu(dst, left, right);  // Left is overwritten.
+    xor_(overflow_dst, dst, scratch);  // scratch is original left.
+    xor_(scratch, scratch, right);  // scratch is original left.
+    and_(overflow_dst, scratch, overflow_dst);
   } else if (dst.is(right)) {
-    subu(overflow_dst, left, right);
-    xor_(dst, left, right);
-    xor_(scratch, overflow_dst, left);
-    and_(scratch, scratch, dst);
-    mov(dst, overflow_dst);
-    mov(overflow_dst, scratch);
+    mov(scratch, right);  // Preserve right.
+    subu(dst, left, right);  // Right is overwritten.
+    xor_(overflow_dst, dst, left);
+    xor_(scratch, left, scratch);  // Original right.
+    and_(overflow_dst, scratch, overflow_dst);
   } else {
     subu(dst, left, right);
     xor_(overflow_dst, dst, left);
@@ -3315,6 +3567,7 @@
   JumpToExternalReference(ext);
 }
 
+
 MaybeObject* MacroAssembler::TryTailCallExternalReference(
     const ExternalReference& ext, int num_arguments, int result_size) {
   // TODO(1236192): Most runtime routines don't need the number of
@@ -3356,10 +3609,12 @@
   GetBuiltinEntry(t9, id);
   if (flag == CALL_FUNCTION) {
     call_wrapper.BeforeCall(CallSize(t9));
+    SetCallKind(t1, CALL_AS_METHOD);
     Call(t9);
     call_wrapper.AfterCall();
   } else {
     ASSERT(flag == JUMP_FUNCTION);
+    SetCallKind(t1, CALL_AS_METHOD);
     Jump(t9);
   }
 }
@@ -3445,6 +3700,8 @@
     lw(elements, FieldMemOperand(elements, HeapObject::kMapOffset));
     LoadRoot(at, Heap::kFixedArrayMapRootIndex);
     Branch(&ok, eq, elements, Operand(at));
+    LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex);
+    Branch(&ok, eq, elements, Operand(at));
     LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex);
     Branch(&ok, eq, elements, Operand(at));
     Abort("JSObject with fast elements map has slow elements");
@@ -3509,12 +3766,9 @@
 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.
-    lw(dst, MemOperand(cp, Context::SlotOffset(Context::CLOSURE_INDEX)));
-    // Load the function context (which is the incoming, outer context).
-    lw(dst, FieldMemOperand(dst, JSFunction::kContextOffset));
+    lw(dst, MemOperand(cp, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     for (int i = 1; i < context_chain_length; i++) {
-      lw(dst, MemOperand(dst, Context::SlotOffset(Context::CLOSURE_INDEX)));
-      lw(dst, FieldMemOperand(dst, JSFunction::kContextOffset));
+      lw(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     }
   } else {
     // Slot is in the current function context.  Move it into the
@@ -3522,17 +3776,6 @@
     // cannot be allowed to destroy the context in esi).
     Move(dst, cp);
   }
-
-  // We should not have found a 'with' context by walking the context chain
-  // (i.e., the static scope chain and runtime context chain do not agree).
-  // A variable occurring in such a scope should have slot type LOOKUP and
-  // not CONTEXT.
-  if (emit_debug_code()) {
-    lw(t9, MemOperand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
-    Check(eq, "Yo dawg, I heard you liked function contexts "
-              "so I put function contexts in all your contexts",
-               dst, Operand(t9));
-  }
 }
 
 
@@ -3718,6 +3961,7 @@
 #endif  // defined(V8_HOST_ARCH_MIPS)
 }
 
+
 void MacroAssembler::AssertStackIsAligned() {
   if (emit_debug_code()) {
       const int frame_alignment = ActivationFrameAlignment();
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index bcb459e..4994516 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -99,44 +99,11 @@
   // macro assembler.
   MacroAssembler(Isolate* isolate, void* buffer, int size);
 
-// Arguments macros.
+  // Arguments macros.
 #define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2
 #define COND_ARGS cond, r1, r2
 
-// Prototypes.
-
-// Prototypes for functions with no target (eg Ret()).
-#define DECLARE_NOTARGET_PROTOTYPE(Name) \
-  void Name(BranchDelaySlot bd = PROTECT); \
-  void Name(COND_TYPED_ARGS, BranchDelaySlot bd = PROTECT); \
-  inline void Name(BranchDelaySlot bd, COND_TYPED_ARGS) { \
-    Name(COND_ARGS, bd); \
-  }
-
-// Prototypes for functions with a target.
-
-// Cases when relocation may be needed.
-#define DECLARE_RELOC_PROTOTYPE(Name, target_type) \
-  void Name(target_type target, \
-            RelocInfo::Mode rmode, \
-            BranchDelaySlot bd = PROTECT); \
-  inline void Name(BranchDelaySlot bd, \
-                   target_type target, \
-                   RelocInfo::Mode rmode) { \
-    Name(target, rmode, bd); \
-  } \
-  void Name(target_type target, \
-            RelocInfo::Mode rmode, \
-            COND_TYPED_ARGS, \
-            BranchDelaySlot bd = PROTECT); \
-  inline void Name(BranchDelaySlot bd, \
-                   target_type target, \
-                   RelocInfo::Mode rmode, \
-                   COND_TYPED_ARGS) { \
-    Name(target, rmode, COND_ARGS, bd); \
-  }
-
-// Cases when relocation is not needed.
+  // Cases when relocation is not needed.
 #define DECLARE_NORELOC_PROTOTYPE(Name, target_type) \
   void Name(target_type target, BranchDelaySlot bd = PROTECT); \
   inline void Name(BranchDelaySlot bd, target_type target) { \
@@ -151,44 +118,44 @@
     Name(target, COND_ARGS, bd); \
   }
 
-// Target prototypes.
-
-#define DECLARE_JUMP_CALL_PROTOTYPES(Name) \
-  DECLARE_NORELOC_PROTOTYPE(Name, Register) \
-  DECLARE_NORELOC_PROTOTYPE(Name, const Operand&) \
-  DECLARE_RELOC_PROTOTYPE(Name, byte*) \
-  DECLARE_RELOC_PROTOTYPE(Name, Handle<Code>)
-
 #define DECLARE_BRANCH_PROTOTYPES(Name) \
   DECLARE_NORELOC_PROTOTYPE(Name, Label*) \
   DECLARE_NORELOC_PROTOTYPE(Name, int16_t)
 
+  DECLARE_BRANCH_PROTOTYPES(Branch)
+  DECLARE_BRANCH_PROTOTYPES(BranchAndLink)
 
-DECLARE_JUMP_CALL_PROTOTYPES(Jump)
-DECLARE_JUMP_CALL_PROTOTYPES(Call)
-
-DECLARE_BRANCH_PROTOTYPES(Branch)
-DECLARE_BRANCH_PROTOTYPES(BranchAndLink)
-
-DECLARE_NOTARGET_PROTOTYPE(Ret)
-
+#undef DECLARE_BRANCH_PROTOTYPES
 #undef COND_TYPED_ARGS
 #undef COND_ARGS
-#undef DECLARE_NOTARGET_PROTOTYPE
-#undef DECLARE_NORELOC_PROTOTYPE
-#undef DECLARE_RELOC_PROTOTYPE
-#undef DECLARE_JUMP_CALL_PROTOTYPES
-#undef DECLARE_BRANCH_PROTOTYPES
 
-  void CallWithAstId(Handle<Code> code,
-                     RelocInfo::Mode rmode,
-                     unsigned ast_id,
-                     Condition cond = al,
-                     Register r1 = zero_reg,
-                     const Operand& r2 = Operand(zero_reg));
 
-  int CallSize(Register reg);
-  int CallSize(Handle<Code> code, RelocInfo::Mode rmode);
+  // Jump, Call, and Ret pseudo instructions implementing inter-working.
+#define COND_ARGS Condition cond = al, Register rs = zero_reg, \
+  const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
+
+  void Jump(Register target, COND_ARGS);
+  void Jump(intptr_t target, RelocInfo::Mode rmode, COND_ARGS);
+  void Jump(Address target, RelocInfo::Mode rmode, COND_ARGS);
+  void Jump(Handle<Code> code, RelocInfo::Mode rmode, COND_ARGS);
+  int CallSize(Register target, COND_ARGS);
+  void Call(Register target, COND_ARGS);
+  int CallSize(Address target, RelocInfo::Mode rmode, COND_ARGS);
+  void Call(Address target, RelocInfo::Mode rmode, COND_ARGS);
+  int CallSize(Handle<Code> code,
+               RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+               unsigned ast_id = kNoASTId,
+               COND_ARGS);
+  void Call(Handle<Code> code,
+            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+            unsigned ast_id = kNoASTId,
+            COND_ARGS);
+  void Ret(COND_ARGS);
+  inline void Ret(BranchDelaySlot bd) {
+    Ret(al, zero_reg, Operand(zero_reg), bd);
+  }
+
+#undef COND_ARGS
 
   // Emit code to discard a non-negative number of pointer-sized elements
   // from the stack, clobbering only the sp register.
@@ -299,6 +266,16 @@
                               Register scratch,
                               Label* miss);
 
+
+  void LoadFromNumberDictionary(Label* miss,
+                                Register elements,
+                                Register key,
+                                Register result,
+                                Register reg0,
+                                Register reg1,
+                                Register reg2);
+
+
   inline void MarkCode(NopMarkerTypes type) {
     nop(type);
   }
@@ -459,9 +436,6 @@
     li(dst, Operand(value), gen2instr);
   }
 
-  // Exception-generating instructions and debugging support.
-  void stop(const char* msg);
-
   // Push multiple registers on the stack.
   // Registers are saved in numerical order, with higher numbered registers
   // saved in higher memory addresses.
@@ -474,6 +448,9 @@
     sw(src, MemOperand(sp, 0));
   }
 
+  // Push a handle.
+  void Push(Handle<Object> handle);
+
   // Push two registers. Pushes leftmost register first (to highest address).
   void Push(Register src1, Register src2) {
     Subu(sp, sp, Operand(2 * kPointerSize));
@@ -576,6 +553,16 @@
                                    Register input_low,
                                    Register scratch);
 
+  // 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 and all other registers clobbered.
+  void EmitECMATruncate(Register result,
+                        FPURegister double_input,
+                        FPURegister single_scratch,
+                        Register scratch,
+                        Register scratch2,
+                        Register scratch3);
+
   // -------------------------------------------------------------------------
   // Activation frames.
 
@@ -624,27 +611,28 @@
                   const ParameterCount& expected,
                   const ParameterCount& actual,
                   InvokeFlag flag,
-                  const CallWrapper& call_wrapper = NullCallWrapper(),
-                  CallKind call_kind = CALL_AS_METHOD);
+                  const CallWrapper& call_wrapper,
+                  CallKind call_kind);
 
   void InvokeCode(Handle<Code> code,
                   const ParameterCount& expected,
                   const ParameterCount& actual,
                   RelocInfo::Mode rmode,
                   InvokeFlag flag,
-                  CallKind call_kind = CALL_AS_METHOD);
+                  CallKind call_kind);
 
   // 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 = NullCallWrapper(),
-                      CallKind call_kind = CALL_AS_METHOD);
+                      const CallWrapper& call_wrapper,
+                      CallKind call_kind);
 
   void InvokeFunction(JSFunction* function,
                       const ParameterCount& actual,
-                      InvokeFlag flag);
+                      InvokeFlag flag,
+                      CallKind call_kind);
 
 
   void IsObjectJSObjectType(Register heap_object,
@@ -715,6 +703,12 @@
                      Register map,
                      Register type_reg);
 
+  // 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 the map of an object is equal to a specified map (either
   // given directly or as an index into the root list) and branch to
   // label if not. Skip the smi check if not required (object is known
@@ -1088,16 +1082,25 @@
                            Register scratch,
                            int num_arguments);
 
-  void Jump(intptr_t target, RelocInfo::Mode rmode,
-            BranchDelaySlot bd = PROTECT);
-  void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = cc_always,
-            Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg),
-            BranchDelaySlot bd = PROTECT);
-  void Call(intptr_t target, RelocInfo::Mode rmode,
-            BranchDelaySlot bd = PROTECT);
-  void Call(intptr_t target, RelocInfo::Mode rmode, Condition cond = cc_always,
-            Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg),
-            BranchDelaySlot bd = PROTECT);
+  void BranchShort(int16_t offset, BranchDelaySlot bdslot = PROTECT);
+  void BranchShort(int16_t offset, Condition cond, Register rs,
+                   const Operand& rt,
+                   BranchDelaySlot bdslot = PROTECT);
+  void BranchShort(Label* L, BranchDelaySlot bdslot = PROTECT);
+  void BranchShort(Label* L, Condition cond, Register rs,
+                   const Operand& rt,
+                   BranchDelaySlot bdslot = PROTECT);
+  void BranchAndLinkShort(int16_t offset, BranchDelaySlot bdslot = PROTECT);
+  void BranchAndLinkShort(int16_t offset, Condition cond, Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bdslot = PROTECT);
+  void BranchAndLinkShort(Label* L, BranchDelaySlot bdslot = PROTECT);
+  void BranchAndLinkShort(Label* L, Condition cond, Register rs,
+                          const Operand& rt,
+                          BranchDelaySlot bdslot = PROTECT);
+  void J(Label* L, BranchDelaySlot bdslot);
+  void Jr(Label* L, BranchDelaySlot bdslot);
+  void Jalr(Label* L, BranchDelaySlot bdslot);
 
   // Helper functions for generating invokes.
   void InvokePrologue(const ParameterCount& expected,
@@ -1106,8 +1109,8 @@
                       Register code_reg,
                       Label* done,
                       InvokeFlag flag,
-                      const CallWrapper& call_wrapper = NullCallWrapper(),
-                      CallKind call_kind = CALL_AS_METHOD);
+                      const CallWrapper& call_wrapper,
+                      CallKind call_kind);
 
   // Get the code for the given builtin. Returns if able to resolve
   // the function in the 'resolved' flag.
@@ -1128,6 +1131,8 @@
   MemOperand SafepointRegisterSlot(Register reg);
   MemOperand SafepointRegistersAndDoublesSlot(Register reg);
 
+  bool UseAbsoluteCodePointers();
+
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index cfc8f65..9935ef9 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -179,7 +179,7 @@
   // Pop Code* offset from backtrack stack, add Code* and jump to location.
   Pop(a0);
   __ Addu(a0, a0, code_pointer());
-  __ Jump(Operand(a0));
+  __ Jump(a0);
 }
 
 
@@ -1238,7 +1238,7 @@
   __ Call(t9);
   __ lw(ra, MemOperand(sp, 0));
   __ Addu(sp, sp, Operand(stack_alignment));
-  __ Jump(Operand(ra));
+  __ Jump(ra);
 }
 
 
diff --git a/src/mips/regexp-macro-assembler-mips.h b/src/mips/regexp-macro-assembler-mips.h
index ad7ada5..7fe0c88 100644
--- a/src/mips/regexp-macro-assembler-mips.h
+++ b/src/mips/regexp-macro-assembler-mips.h
@@ -29,6 +29,12 @@
 #ifndef V8_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
 #define V8_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
 
+#include "mips/assembler-mips.h"
+#include "mips/assembler-mips-inl.h"
+#include "macro-assembler.h"
+#include "code.h"
+#include "mips/macro-assembler-mips.h"
+
 namespace v8 {
 namespace internal {
 
@@ -249,4 +255,3 @@
 }}  // namespace v8::internal
 
 #endif  // V8_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
-
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 68fb7ce..30e12e7 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -126,16 +126,29 @@
 
 
 void MipsDebugger::Stop(Instruction* instr) {
-  UNIMPLEMENTED_MIPS();
-  char* str = reinterpret_cast<char*>(instr->InstructionBits());
-  if (strlen(str) > 0) {
+  // Get the stop code.
+  uint32_t code = instr->Bits(25, 6);
+  // Retrieve the encoded address, which comes just after this stop.
+  char** msg_address =
+    reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
+  char* msg = *msg_address;
+  ASSERT(msg != NULL);
+
+  // Update this stop description.
+  if (!watched_stops[code].desc) {
+    watched_stops[code].desc = msg;
+  }
+
+  if (strlen(msg) > 0) {
     if (coverage_log != NULL) {
       fprintf(coverage_log, "%s\n", str);
       fflush(coverage_log);
     }
-    instr->SetInstructionBits(0x0);  // Overwrite with nop.
+    // Overwrite the instruction and address with nops.
+    instr->SetInstructionBits(kNopInstr);
+    reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
   }
-  sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
+  sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize);
 }
 
 
@@ -147,9 +160,17 @@
 
 
 void MipsDebugger::Stop(Instruction* instr) {
-  const char* str = reinterpret_cast<char*>(instr->InstructionBits());
-  PrintF("Simulator hit %s\n", str);
-  sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
+  // Get the stop code.
+  uint32_t code = instr->Bits(25, 6);
+  // 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_->watched_stops[code].desc) {
+    sim_->watched_stops[code].desc = msg;
+  }
+  PrintF("Simulator hit %s (%u)\n", msg, code);
+  sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
   Debug();
 }
 #endif  // GENERATED_CODE_COVERAGE
@@ -585,8 +606,67 @@
         }
       } else if (strcmp(cmd, "flags") == 0) {
         PrintF("No flags on MIPS !\n");
-      } else if (strcmp(cmd, "unstop") == 0) {
-          PrintF("Unstop command not implemented on MIPS.");
+      } else if (strcmp(cmd, "stop") == 0) {
+        int32_t value;
+        intptr_t stop_pc = sim_->get_pc() -
+            2 * Instruction::kInstrSize;
+        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 = kMaxWatchpointCode + 1;
+                   i <= kMaxStopCode;
+                   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 = kMaxWatchpointCode + 1;
+                   i <= kMaxStopCode;
+                   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 = kMaxWatchpointCode + 1;
+                   i <= kMaxStopCode;
+                   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, "stat") == 0) || (strcmp(cmd, "st") == 0)) {
         // Print registers and disassemble.
         PrintAllRegs();
@@ -652,9 +732,26 @@
         PrintF("  set a break point on the address\n");
         PrintF("del\n");
         PrintF("  delete the breakpoint\n");
-        PrintF("unstop\n");
-        PrintF("  ignore the stop instruction at the current location");
-        PrintF(" from now on\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 Debugger.\n");
+        PrintF("    All stop codes are watched:\n");
+        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);
       }
@@ -1062,15 +1159,30 @@
 // Sets the rounding error codes in FCSR based on the result of the rounding.
 // Returns true if the operation was invalid.
 bool Simulator::set_fcsr_round_error(double original, double rounded) {
-  if (!isfinite(original) ||
-      rounded > LONG_MAX ||
-      rounded < LONG_MIN) {
-    set_fcsr_bit(6, true);  // Invalid operation.
-    return true;
-  } else if (original != static_cast<double>(rounded)) {
-    set_fcsr_bit(2, true);  // Inexact.
+  bool ret = false;
+
+  if (!isfinite(original) || !isfinite(rounded)) {
+    set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
+    ret = true;
   }
-  return false;
+
+  if (original != rounded) {
+    set_fcsr_bit(kFCSRInexactFlagBit, true);
+  }
+
+  if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
+    set_fcsr_bit(kFCSRUnderflowFlagBit, true);
+    ret = true;
+  }
+
+  if (rounded > INT_MAX || rounded < INT_MIN) {
+    set_fcsr_bit(kFCSROverflowFlagBit, true);
+    // The reference is not really clear but it seems this is required:
+    set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
+    ret = true;
+  }
+
+  return ret;
 }
 
 
@@ -1288,7 +1400,7 @@
   // the break_ instruction, or several variants of traps. All
   // Are "SPECIAL" class opcode, and are distinuished by function.
   int32_t func = instr->FunctionFieldRaw();
-  int32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1;
+  uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1;
 
   // We first check if we met a call_rt_redirected.
   if (instr->InstructionBits() == rtCallRedirInstr) {
@@ -1372,7 +1484,7 @@
           case ExternalReference::BUILTIN_FP_CALL:
             GetFpArgs(&dval0);
             PrintF("Call to host function at %p with arg %f",
-                FUNCTION_ADDR(target), dval1);
+                FUNCTION_ADDR(target), dval0);
             break;
           case ExternalReference::BUILTIN_FP_INT_CALL:
             GetFpArgs(&dval0, &ival);
@@ -1440,14 +1552,13 @@
     set_register(ra, saved_ra);
     set_pc(get_register(ra));
 
-  } else if (func == BREAK && code >= 0 && code < 32) {
-    // First 32 break_ codes interpreted as debug-markers/watchpoints.
-    MipsDebugger dbg(this);
-    ++break_count_;
-    PrintF("\n---- break %d marker: %3d  (instr count: %8d) ----------"
-           "----------------------------------",
-           code, break_count_, icount_);
-    dbg.PrintAllRegs();  // Print registers and continue running.
+  } else if (func == BREAK && code <= kMaxStopCode) {
+    if (IsWatchpoint(code)) {
+      PrintWatchpoint(code);
+    } else {
+      IncreaseStopCounter(code);
+      HandleStop(code, instr);
+    }
   } else {
     // All remaining break_ codes, and all traps are handled here.
     MipsDebugger dbg(this);
@@ -1456,6 +1567,99 @@
 }
 
 
+// Stop helper functions.
+bool Simulator::IsWatchpoint(uint32_t code) {
+  return (code <= kMaxWatchpointCode);
+}
+
+
+void Simulator::PrintWatchpoint(uint32_t code) {
+  MipsDebugger dbg(this);
+  ++break_count_;
+  PrintF("\n---- break %d marker: %3d  (instr count: %8d) ----------"
+         "----------------------------------",
+         code, break_count_, icount_);
+  dbg.PrintAllRegs();  // Print registers and continue running.
+}
+
+
+void Simulator::HandleStop(uint32_t code, Instruction* instr) {
+  // Stop if it is enabled, otherwise go on jumping over the stop
+  // and the message address.
+  if (IsEnabledStop(code)) {
+    MipsDebugger dbg(this);
+    dbg.Stop(instr);
+  } else {
+    set_pc(get_pc() + 2 * Instruction::kInstrSize);
+  }
+}
+
+
+bool Simulator::IsStopInstruction(Instruction* instr) {
+  int32_t func = instr->FunctionFieldRaw();
+  uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6));
+  return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode;
+}
+
+
+bool Simulator::IsEnabledStop(uint32_t code) {
+  ASSERT(code <= kMaxStopCode);
+  ASSERT(code > kMaxWatchpointCode);
+  return !(watched_stops[code].count & kStopDisabledBit);
+}
+
+
+void Simulator::EnableStop(uint32_t code) {
+  if (!IsEnabledStop(code)) {
+    watched_stops[code].count &= ~kStopDisabledBit;
+  }
+}
+
+
+void Simulator::DisableStop(uint32_t code) {
+  if (IsEnabledStop(code)) {
+    watched_stops[code].count |= kStopDisabledBit;
+  }
+}
+
+
+void Simulator::IncreaseStopCounter(uint32_t code) {
+  ASSERT(code <= kMaxStopCode);
+  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) {
+  if (code <= kMaxWatchpointCode) {
+    PrintF("That is a watchpoint, not a stop.\n");
+    return;
+  } else if (code > kMaxStopCode) {
+    PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1);
+    return;
+  }
+  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::SignalExceptions() {
   for (int i = 1; i < kNumExceptions; i++) {
     if (exceptions[i] != 0) {
@@ -1865,9 +2069,10 @@
               break;
             case TRUNC_W_D:  // Truncate double to word (round towards 0).
               {
-                int32_t result = static_cast<int32_t>(fs);
+                double rounded = trunc(fs);
+                int32_t result = static_cast<int32_t>(rounded);
                 set_fpu_register(fd_reg, result);
-                if (set_fcsr_round_error(fs, static_cast<double>(result))) {
+                if (set_fcsr_round_error(fs, rounded)) {
                   set_fpu_register(fd_reg, kFPUInvalidResult);
                 }
               }
@@ -1895,16 +2100,20 @@
             case CVT_S_D:  // Convert double to float (single).
               set_fpu_register_float(fd_reg, static_cast<float>(fs));
               break;
-            case CVT_L_D:  // Mips32r2: Truncate double to 64-bit long-word.
-              i64 = static_cast<int64_t>(fs);
+            case CVT_L_D: {  // Mips32r2: Truncate double to 64-bit long-word.
+              double rounded = trunc(fs);
+              i64 = static_cast<int64_t>(rounded);
               set_fpu_register(fd_reg, i64 & 0xffffffff);
               set_fpu_register(fd_reg + 1, i64 >> 32);
               break;
-            case TRUNC_L_D:  // Mips32r2 instruction.
-              i64 = static_cast<int64_t>(fs);
+            }
+            case TRUNC_L_D: {  // Mips32r2 instruction.
+              double rounded = trunc(fs);
+              i64 = static_cast<int64_t>(rounded);
               set_fpu_register(fd_reg, i64 & 0xffffffff);
               set_fpu_register(fd_reg + 1, i64 >> 32);
               break;
+            }
             case ROUND_L_D: {  // Mips32r2 instruction.
               double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
               i64 = static_cast<int64_t>(rounded);
diff --git a/src/mips/simulator-mips.h b/src/mips/simulator-mips.h
index 21476dc..69dddfa 100644
--- a/src/mips/simulator-mips.h
+++ b/src/mips/simulator-mips.h
@@ -289,6 +289,18 @@
   // Used for breakpoints and traps.
   void SoftwareInterrupt(Instruction* instr);
 
+  // Stop helper functions.
+  bool IsWatchpoint(uint32_t code);
+  void PrintWatchpoint(uint32_t code);
+  void HandleStop(uint32_t code, Instruction* instr);
+  bool IsStopInstruction(Instruction* instr);
+  bool IsEnabledStop(uint32_t code);
+  void EnableStop(uint32_t code);
+  void DisableStop(uint32_t code);
+  void IncreaseStopCounter(uint32_t code);
+  void PrintStopInfo(uint32_t code);
+
+
   // Executes one instruction.
   void InstructionDecode(Instruction* instr);
   // Execute one instruction placed in a branch delay slot.
@@ -354,6 +366,19 @@
   // Registered breakpoints.
   Instruction* break_pc_;
   Instr break_instr_;
+
+  // Stop 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[kMaxStopCode + 1];
 };
 
 
@@ -398,4 +423,3 @@
 
 #endif  // !defined(USE_SIMULATOR)
 #endif  // V8_MIPS_SIMULATOR_MIPS_H_
-
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 47428a8..f1ffe9b 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -126,7 +126,7 @@
 
   // Check that receiver is a JSObject.
   __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
-  __ Branch(miss_label, lt, scratch0, Operand(FIRST_JS_OBJECT_TYPE));
+  __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
 
   // Load properties array.
   Register properties = scratch0;
@@ -472,7 +472,8 @@
 static void GenerateCallFunction(MacroAssembler* masm,
                                  Object* object,
                                  const ParameterCount& arguments,
-                                 Label* miss) {
+                                 Label* miss,
+                                 Code::ExtraICState extra_ic_state) {
   // ----------- S t a t e -------------
   //  -- a0: receiver
   //  -- a1: function to call
@@ -490,7 +491,10 @@
   }
 
   // Invoke the function.
-  __ InvokeFunction(a1, arguments, JUMP_FUNCTION);
+  CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
+      ? CALL_AS_FUNCTION
+      : CALL_AS_METHOD;
+  __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
 }
 
 
@@ -629,10 +633,12 @@
  public:
   CallInterceptorCompiler(StubCompiler* stub_compiler,
                           const ParameterCount& arguments,
-                          Register name)
+                          Register name,
+                          Code::ExtraICState extra_ic_state)
       : stub_compiler_(stub_compiler),
         arguments_(arguments),
-        name_(name) {}
+        name_(name),
+        extra_ic_state_(extra_ic_state) {}
 
   MaybeObject* Compile(MacroAssembler* masm,
                        JSObject* object,
@@ -760,8 +766,11 @@
                                                       arguments_.immediate());
       if (result->IsFailure()) return result;
     } else {
+      CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+          ? CALL_AS_FUNCTION
+          : CALL_AS_METHOD;
       __ InvokeFunction(optimization.constant_function(), arguments_,
-                        JUMP_FUNCTION);
+                        JUMP_FUNCTION, call_kind);
     }
 
     // Deferred code for fast API call case---clean preallocated space.
@@ -844,6 +853,7 @@
   StubCompiler* stub_compiler_;
   const ParameterCount& arguments_;
   Register name_;
+  Code::ExtraICState extra_ic_state_;
 };
 
 
@@ -1503,7 +1513,7 @@
   Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss);
   GenerateFastPropertyLoad(masm(), a1, reg, holder, index);
 
-  GenerateCallFunction(masm(), object, arguments(), &miss);
+  GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -2001,7 +2011,7 @@
   // Tail call the full function. We do not have to patch the receiver
   // because the function makes no use of it.
   __ bind(&slow);
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
 
   __ bind(&miss);
   // a2: function name.
@@ -2086,9 +2096,7 @@
 
   // Retrieve FCSR and check for fpu errors.
   __ cfc1(t5, FCSR);
-  __ srl(t5, t5, kFCSRFlagShift);
-  // Flag 1 marks an inaccurate but still good result so we ignore it.
-  __ And(t5, t5, Operand(kFCSRFlagMask ^ 1));
+  __ And(t5, t5, Operand(kFCSRExceptionFlagMask));
   __ Branch(&no_fpu_error, eq, t5, Operand(zero_reg));
 
   // Check for NaN, Infinity, and -Infinity.
@@ -2137,7 +2145,7 @@
   __ bind(&slow);
   // Tail call the full function. We do not have to patch the receiver
   // because the function makes no use of it.
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
 
   __ bind(&miss);
   // a2: function name.
@@ -2239,7 +2247,7 @@
   // Tail call the full function. We do not have to patch the receiver
   // because the function makes no use of it.
   __ bind(&slow);
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
 
   __ bind(&miss);
   // a2: function name.
@@ -2425,7 +2433,10 @@
       UNREACHABLE();
   }
 
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+  CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+      ? CALL_AS_FUNCTION
+      : CALL_AS_METHOD;
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -2459,7 +2470,7 @@
   // Get the receiver from the stack.
   __ lw(a1, MemOperand(sp, argc * kPointerSize));
 
-  CallInterceptorCompiler compiler(this, arguments(), a2);
+  CallInterceptorCompiler compiler(this, arguments(), a2, extra_ic_state_);
   MaybeObject* result = compiler.Compile(masm(),
                                          object,
                                          holder,
@@ -2479,7 +2490,7 @@
   // Restore receiver.
   __ lw(a0, MemOperand(sp, argc * kPointerSize));
 
-  GenerateCallFunction(masm(), object, arguments(), &miss);
+  GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -2491,13 +2502,11 @@
 }
 
 
-MaybeObject* CallStubCompiler::CompileCallGlobal(
-    JSObject* object,
-    GlobalObject* holder,
-    JSGlobalPropertyCell* cell,
-    JSFunction* function,
-    String* name,
-    Code::ExtraICState extra_ic_state) {
+MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
+                                                 GlobalObject* holder,
+                                                 JSGlobalPropertyCell* cell,
+                                                 JSFunction* function,
+                                                 String* name) {
   // ----------- S t a t e -------------
   //  -- a2    : name
   //  -- ra    : return address
@@ -2538,7 +2547,7 @@
   ASSERT(function->is_compiled());
   Handle<Code> code(function->code());
   ParameterCount expected(function->shared()->formal_parameter_count());
-  CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
+  CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
       ? CALL_AS_FUNCTION
       : CALL_AS_METHOD;
   if (V8::UseCrankshaft()) {
@@ -3083,14 +3092,15 @@
 }
 
 
-MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) {
+MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- ra    : return address
   //  -- a0    : key
   //  -- a1    : receiver
   // -----------------------------------
-  MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode();
   Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
+  MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(a1,
                  a2,
@@ -3172,8 +3182,7 @@
 }
 
 
-MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement(
-    Map* receiver_map) {
+MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- a0    : value
   //  -- a1    : key
@@ -3181,10 +3190,11 @@
   //  -- ra    : return address
   //  -- a3    : scratch
   // -----------------------------------
+  Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
   bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
   MaybeObject* maybe_stub =
-      KeyedStoreFastElementStub(is_js_array).TryGetCode();
-  Code* stub;
+      KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(a2,
                  a3,
@@ -3380,82 +3390,87 @@
 }
 
 
-MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
-    JSObject*receiver, ExternalArrayType array_type) {
-  // ----------- S t a t e -------------
-  //  -- ra    : return address
-  //  -- a0    : key
-  //  -- a1    : receiver
-  // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedLoadExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(a1,
-                 a2,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
-
-  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode();
-}
-
-
-MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
-    JSObject* receiver, ExternalArrayType array_type) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : name
-  //  -- a2    : receiver
-  //  -- ra    : return address
-  // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedStoreExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(a2,
-                 a3,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
-
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  return GetCode();
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm)
 
 
-static bool IsElementTypeSigned(ExternalArrayType array_type) {
-  switch (array_type) {
-    case kExternalByteArray:
-    case kExternalShortArray:
-    case kExternalIntArray:
+void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- ra     : return address
+  //  -- a0     : key
+  //  -- a1     : receiver
+  // -----------------------------------
+  Label slow, miss_force_generic;
+
+  Register key = a0;
+  Register receiver = a1;
+
+  __ JumpIfNotSmi(key, &miss_force_generic);
+  __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ sra(a2, a0, kSmiTagSize);
+  __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
+  __ Ret();
+
+  // Slow case, key and receiver still in a0 and a1.
+  __ bind(&slow);
+  __ IncrementCounter(
+      masm->isolate()->counters()->keyed_load_external_array_slow(),
+      1, a2, a3);
+  // Entry registers are intact.
+  // ---------- S t a t e --------------
+  //  -- ra     : return address
+  //  -- a0     : key
+  //  -- a1     : receiver
+  // -----------------------------------
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+
+  // Miss case, call the runtime.
+  __ bind(&miss_force_generic);
+
+  // ---------- S t a t e --------------
+  //  -- ra     : return address
+  //  -- a0     : key
+  //  -- a1     : receiver
+  // -----------------------------------
+
+  Handle<Code> miss_ic =
+     masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+}
+
+
+static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) {
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
       return true;
 
-    case kExternalUnsignedByteArray:
-    case kExternalUnsignedShortArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       return false;
 
-    default:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       return false;
   }
+  return false;
 }
 
 
 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ---------- S t a t e --------------
   //  -- ra     : return address
   //  -- a0     : key
@@ -3489,33 +3504,33 @@
   ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
 
   Register value = a2;
-  switch (array_type) {
-    case kExternalByteArray:
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
       __ srl(t2, key, 1);
       __ addu(t3, a3, t2);
       __ lb(value, MemOperand(t3, 0));
       break;
-    case kExternalPixelArray:
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       __ srl(t2, key, 1);
       __ addu(t3, a3, t2);
       __ lbu(value, MemOperand(t3, 0));
       break;
-    case kExternalShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
       __ addu(t3, a3, key);
       __ lh(value, MemOperand(t3, 0));
       break;
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ addu(t3, a3, key);
       __ lhu(value, MemOperand(t3, 0));
       break;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       __ sll(t2, key, 1);
       __ addu(t3, a3, t2);
       __ lw(value, MemOperand(t3, 0));
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       __ sll(t3, t2, 2);
       __ addu(t3, a3, t3);
       if (CpuFeatures::IsSupported(FPU)) {
@@ -3525,7 +3540,7 @@
         __ lw(value, MemOperand(t3, 0));
       }
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       __ sll(t2, key, 2);
       __ addu(t3, a3, t2);
       if (CpuFeatures::IsSupported(FPU)) {
@@ -3537,7 +3552,10 @@
         __ lw(a3, MemOperand(t3, Register::kSizeInBytes));
       }
       break;
-    default:
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       break;
   }
@@ -3551,7 +3569,7 @@
   // f0: value (if FPU is supported)
   // a2/a3: value (if FPU is not supported)
 
-  if (array_type == kExternalIntArray) {
+  if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
     // For the Int and UnsignedInt array types, we need to see whether
     // the value can be represented in a Smi. If not, we need to convert
     // it to a HeapNumber.
@@ -3593,7 +3611,7 @@
       __ sw(dst2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
       __ Ret();
     }
-  } else if (array_type == kExternalUnsignedIntArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
     // The test is different for unsigned int values. Since we need
     // the value to be in the range of a positive smi, we can't
     // handle either of the top two bits being set in the value.
@@ -3664,7 +3682,7 @@
       __ mov(v0, t2);
       __ Ret();
     }
-  } else if (array_type == kExternalFloatArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
     // For the floating-point array type, we need to always allocate a
     // HeapNumber.
     if (CpuFeatures::IsSupported(FPU)) {
@@ -3731,7 +3749,7 @@
       __ Ret();
     }
 
-  } else if (array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     if (CpuFeatures::IsSupported(FPU)) {
       CpuFeatures::Scope scope(FPU);
       // Allocate a HeapNumber for the result. Don't use a0 and a1 as
@@ -3785,7 +3803,7 @@
 
 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ---------- S t a t e --------------
   //  -- a0     : value
   //  -- a1     : key
@@ -3820,7 +3838,7 @@
   // a3: external array.
   // t0: key (integer).
 
-  if (array_type == kExternalPixelArray) {
+  if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     // Double to pixel conversion is only implemented in the runtime for now.
     __ JumpIfNotSmi(value, &slow);
   } else {
@@ -3833,8 +3851,8 @@
   // t0: key (integer).
   // t1: value (integer).
 
-  switch (array_type) {
-    case kExternalPixelArray: {
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS: {
       // Clamp the value to [0..255].
       // v0 is used as a scratch register here.
       Label done;
@@ -3851,28 +3869,28 @@
       __ sb(t1, MemOperand(t8, 0));
       }
       break;
-    case kExternalByteArray:
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       __ addu(t8, a3, t0);
       __ sb(t1, MemOperand(t8, 0));
       break;
-    case kExternalShortArray:
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ sll(t8, t0, 1);
       __ addu(t8, a3, t8);
       __ sh(t1, MemOperand(t8, 0));
       break;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       __ sll(t8, t0, 2);
       __ addu(t8, a3, t8);
       __ sw(t1, MemOperand(t8, 0));
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       // Perform int-to-float conversion and store to memory.
       StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4);
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       __ sll(t8, t0, 3);
       __ addu(a3, a3, t8);
       // a3: effective address of the double element
@@ -3894,7 +3912,10 @@
         __ sw(t3, MemOperand(a3, Register::kSizeInBytes));
       }
       break;
-    default:
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       break;
   }
@@ -3903,7 +3924,7 @@
   __ mov(v0, value);
   __ Ret();
 
-  if (array_type != kExternalPixelArray) {
+  if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     // a3: external array.
     // t0: index (integer).
     __ bind(&check_heap_number);
@@ -3924,56 +3945,43 @@
 
       __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset));
 
-      if (array_type == kExternalFloatArray) {
+      if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
         __ cvt_s_d(f0, f0);
         __ sll(t8, t0, 2);
         __ addu(t8, a3, t8);
         __ swc1(f0, MemOperand(t8, 0));
-      } else if (array_type == kExternalDoubleArray) {
+      } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
         __ sll(t8, t0, 3);
         __ addu(t8, a3, t8);
         __ sdc1(f0, MemOperand(t8, 0));
       } else {
-        Label done;
+        __ EmitECMATruncate(t3, f0, f2, t2, t1, t5);
 
-        // Need to perform float-to-int conversion.
-        // Test whether exponent equal to 0x7FF (infinity or NaN).
-
-        __ mfc1(t3, f1);  // Move exponent word of double to t3 (as raw bits).
-        __ li(t1, Operand(0x7FF00000));
-        __ And(t3, t3, Operand(t1));
-        __ Branch(USE_DELAY_SLOT, &done, eq, t3, Operand(t1));
-        __ mov(t3, zero_reg);  // In delay slot.
-
-        // Not infinity or NaN simply convert to int.
-        if (IsElementTypeSigned(array_type)) {
-          __ trunc_w_d(f0, f0);
-          __ mfc1(t3, f0);
-        } else {
-          __ Trunc_uw_d(f0, t3);
-        }
-
-        // t3: HeapNumber converted to integer
-        __ bind(&done);
-        switch (array_type) {
-          case kExternalByteArray:
-          case kExternalUnsignedByteArray:
+        switch (elements_kind) {
+          case JSObject::EXTERNAL_BYTE_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
             __ addu(t8, a3, t0);
             __ sb(t3, MemOperand(t8, 0));
             break;
-          case kExternalShortArray:
-          case kExternalUnsignedShortArray:
+          case JSObject::EXTERNAL_SHORT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
             __ sll(t8, t0, 1);
             __ addu(t8, a3, t8);
             __ sh(t3, MemOperand(t8, 0));
             break;
-          case kExternalIntArray:
-          case kExternalUnsignedIntArray:
+          case JSObject::EXTERNAL_INT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
             __ sll(t8, t0, 2);
             __ addu(t8, a3, t8);
             __ sw(t3, MemOperand(t8, 0));
             break;
-          default:
+          case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+          case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+          case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+          case JSObject::FAST_ELEMENTS:
+          case JSObject::FAST_DOUBLE_ELEMENTS:
+          case JSObject::DICTIONARY_ELEMENTS:
+          case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
             UNREACHABLE();
             break;
         }
@@ -3989,7 +3997,7 @@
       __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset));
       __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset));
 
-      if (array_type == kExternalFloatArray) {
+      if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
         Label done, nan_or_infinity_or_zero;
         static const int kMantissaInHiWordShift =
             kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
@@ -4054,7 +4062,7 @@
         __ srl(t4, t4, kMantissaInLoWordShift);
         __ or_(t3, t6, t4);
         __ Branch(&done);
-      } else if (array_type == kExternalDoubleArray) {
+      } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
         __ sll(t8, t0, 3);
         __ addu(t8, a3, t8);
         // t8: effective address of destination element.
@@ -4062,7 +4070,7 @@
         __ sw(t3, MemOperand(t8, Register::kSizeInBytes));
         __ Ret();
       } else {
-        bool is_signed_type  = IsElementTypeSigned(array_type);
+        bool is_signed_type = IsElementTypeSigned(elements_kind);
         int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
         int32_t min_value    = is_signed_type ? 0x80000000 : 0x00000000;
 
@@ -4119,25 +4127,31 @@
 
         // Result is in t3.
         // This switch block should be exactly the same as above (FPU mode).
-        switch (array_type) {
-          case kExternalByteArray:
-          case kExternalUnsignedByteArray:
+        switch (elements_kind) {
+          case JSObject::EXTERNAL_BYTE_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
             __ addu(t8, a3, t0);
             __ sb(t3, MemOperand(t8, 0));
             break;
-          case kExternalShortArray:
-          case kExternalUnsignedShortArray:
+          case JSObject::EXTERNAL_SHORT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
             __ sll(t8, t0, 1);
             __ addu(t8, a3, t8);
             __ sh(t3, MemOperand(t8, 0));
             break;
-          case kExternalIntArray:
-          case kExternalUnsignedIntArray:
+          case JSObject::EXTERNAL_INT_ELEMENTS:
+          case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
             __ sll(t8, t0, 2);
             __ addu(t8, a3, t8);
             __ sw(t3, MemOperand(t8, 0));
             break;
-          default:
+          case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+          case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+          case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+          case JSObject::FAST_ELEMENTS:
+          case JSObject::FAST_DOUBLE_ELEMENTS:
+          case JSObject::DICTIONARY_ELEMENTS:
+          case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
             UNREACHABLE();
             break;
         }
@@ -4215,6 +4229,75 @@
 }
 
 
+void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
+    MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- ra    : return address
+  //  -- a0    : key
+  //  -- a1    : receiver
+  // -----------------------------------
+  Label miss_force_generic, slow_allocate_heapnumber;
+
+  Register key_reg = a0;
+  Register receiver_reg = a1;
+  Register elements_reg = a2;
+  Register heap_number_reg = a2;
+  Register indexed_double_offset = a3;
+  Register scratch = t0;
+  Register scratch2 = t1;
+  Register scratch3 = t2;
+  Register heap_number_map = t3;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+  // Get the elements array.
+  __ lw(elements_reg,
+        FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
+
+  // Check that the key is within bounds.
+  __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
+  __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch));
+
+  // Load the upper word of the double in the fixed array and test for NaN.
+  __ sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize);
+  __ Addu(indexed_double_offset, elements_reg, Operand(scratch2));
+  uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32);
+  __ lw(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset));
+  __ Branch(&miss_force_generic, eq, scratch, Operand(kHoleNanUpper32));
+
+  // Non-NaN. Allocate a new heap number and copy the double value into it.
+  __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
+  __ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
+                        heap_number_map, &slow_allocate_heapnumber);
+
+  // Don't need to reload the upper 32 bits of the double, it's already in
+  // scratch.
+  __ sw(scratch, FieldMemOperand(heap_number_reg,
+                                 HeapNumber::kExponentOffset));
+  __ lw(scratch, FieldMemOperand(indexed_double_offset,
+                                 FixedArray::kHeaderSize));
+  __ sw(scratch, FieldMemOperand(heap_number_reg,
+                                 HeapNumber::kMantissaOffset));
+
+  __ mov(v0, heap_number_reg);
+  __ Ret();
+
+  __ bind(&slow_allocate_heapnumber);
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+
+  __ bind(&miss_force_generic);
+  Handle<Code> miss_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+}
+
+
 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
                                                       bool is_js_array) {
   // ----------- S t a t e -------------
@@ -4239,7 +4322,7 @@
   // have been verified by the caller to not be a smi.
 
   // Check that the key is a smi.
-  __ JumpIfNotSmi(a0, &miss_force_generic);
+  __ JumpIfNotSmi(key_reg, &miss_force_generic);
 
   // Get the elements array and make sure it is a fast element array, not 'cow'.
   __ lw(elements_reg,
@@ -4278,6 +4361,126 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
+    MacroAssembler* masm,
+    bool is_js_array) {
+  // ----------- S t a t e -------------
+  //  -- a0    : value
+  //  -- a1    : key
+  //  -- a2    : receiver
+  //  -- ra    : return address
+  //  -- a3    : scratch
+  //  -- t0    : scratch (elements_reg)
+  //  -- t1    : scratch (mantissa_reg)
+  //  -- t2    : scratch (exponent_reg)
+  //  -- t3    : scratch4
+  // -----------------------------------
+  Label miss_force_generic, smi_value, is_nan, maybe_nan, have_double_value;
+
+  Register value_reg = a0;
+  Register key_reg = a1;
+  Register receiver_reg = a2;
+  Register scratch = a3;
+  Register elements_reg = t0;
+  Register mantissa_reg = t1;
+  Register exponent_reg = t2;
+  Register scratch4 = t3;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+  __ lw(elements_reg,
+         FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
+
+  // Check that the key is within bounds.
+  if (is_js_array) {
+    __ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+  } else {
+    __ lw(scratch,
+          FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
+  }
+  // Compare smis, unsigned compare catches both negative and out-of-bound
+  // indexes.
+  __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch));
+
+  // Handle smi values specially.
+  __ JumpIfSmi(value_reg, &smi_value);
+
+  // Ensure that the object is a heap number
+  __ CheckMap(value_reg,
+              scratch,
+              masm->isolate()->factory()->heap_number_map(),
+              &miss_force_generic,
+              DONT_DO_SMI_CHECK);
+
+  // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000
+  // in the exponent.
+  __ li(scratch, Operand(kNaNOrInfinityLowerBoundUpper32));
+  __ lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset));
+  __ Branch(&maybe_nan, ge, exponent_reg, Operand(scratch));
+
+  __ lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
+
+  __ bind(&have_double_value);
+  __ sll(scratch4, key_reg, kDoubleSizeLog2 - kSmiTagSize);
+  __ Addu(scratch, elements_reg, Operand(scratch4));
+  __ sw(mantissa_reg, FieldMemOperand(scratch, FixedDoubleArray::kHeaderSize));
+  uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
+  __ sw(exponent_reg, FieldMemOperand(scratch, offset));
+  __ Ret();
+
+  __ bind(&maybe_nan);
+  // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
+  // it's an Infinity, and the non-NaN code path applies.
+  __ li(scratch, Operand(kNaNOrInfinityLowerBoundUpper32));
+  __ Branch(&is_nan, gt, exponent_reg, Operand(scratch));
+  __ lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
+  __ Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg));
+
+  __ bind(&is_nan);
+  // Load canonical NaN for storing into the double array.
+  uint64_t nan_int64 = BitCast<uint64_t>(
+      FixedDoubleArray::canonical_not_the_hole_nan_as_double());
+  __ li(mantissa_reg, Operand(static_cast<uint32_t>(nan_int64)));
+  __ li(exponent_reg, Operand(static_cast<uint32_t>(nan_int64 >> 32)));
+  __ jmp(&have_double_value);
+
+  __ bind(&smi_value);
+  __ Addu(scratch, elements_reg,
+          Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+  __ sll(scratch4, key_reg, kDoubleSizeLog2 - kSmiTagSize);
+  __ Addu(scratch, scratch, scratch4);
+  // scratch is now effective address of the double element
+
+  FloatingPointHelper::Destination destination;
+  if (CpuFeatures::IsSupported(FPU)) {
+    destination = FloatingPointHelper::kFPURegisters;
+  } else {
+    destination = FloatingPointHelper::kCoreRegisters;
+  }
+  __ SmiUntag(value_reg, value_reg);
+  FloatingPointHelper::ConvertIntToDouble(
+      masm, value_reg, destination,
+      f0, mantissa_reg, exponent_reg,  // These are: double_dst, dst1, dst2.
+      scratch4, f2);  // These are: scratch2, single_scratch.
+  if (destination == FloatingPointHelper::kFPURegisters) {
+    CpuFeatures::Scope scope(FPU);
+    __ sdc1(f0, MemOperand(scratch, 0));
+  } else {
+    __ sw(mantissa_reg, MemOperand(scratch, 0));
+    __ sw(exponent_reg, MemOperand(scratch, Register::kSizeInBytes));
+  }
+  __ Ret();
+
+  // Handle store cache miss, replacing the ic with the generic stub.
+  __ bind(&miss_force_generic);
+  Handle<Code> ic =
+      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
+  __ Jump(ic, RelocInfo::CODE_TARGET);
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 3a03535..bad0800 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -1243,13 +1243,17 @@
 const kFrameDetailsSourcePositionIndex = 5;
 const kFrameDetailsConstructCallIndex = 6;
 const kFrameDetailsAtReturnIndex = 7;
-const kFrameDetailsDebuggerFrameIndex = 8;
+const kFrameDetailsFlagsIndex = 8;
 const kFrameDetailsFirstDynamicIndex = 9;
 
 const kFrameDetailsNameIndex = 0;
 const kFrameDetailsValueIndex = 1;
 const kFrameDetailsNameValueSize = 2;
 
+const kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
+const kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
+const kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
+
 /**
  * Wrapper for the frame details information retreived from the VM. The frame
  * details from the VM is an array with the following content. See runtime.cc
@@ -1262,7 +1266,7 @@
  *     5: Source position
  *     6: Construct call
  *     7: Is at return
- *     8: Debugger frame
+ *     8: Flags (debugger frame, optimized frame, inlined frame index)
  *     Arguments name, value
  *     Locals name, value
  *     Return value if any
@@ -1308,7 +1312,27 @@
 
 FrameDetails.prototype.isDebuggerFrame = function() {
   %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsDebuggerFrameIndex];
+  var f = kFrameDetailsFlagDebuggerFrameMask;
+  return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
+}
+
+
+FrameDetails.prototype.isOptimizedFrame = function() {
+  %CheckExecutionState(this.break_id_);
+  var f = kFrameDetailsFlagOptimizedFrameMask;
+  return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
+}
+
+
+FrameDetails.prototype.isInlinedFrame = function() {
+  return this.inlinedFrameIndex() > 0;
+}
+
+
+FrameDetails.prototype.inlinedFrameIndex = function() {
+  %CheckExecutionState(this.break_id_);
+  var f = kFrameDetailsFlagInlinedFrameIndexMask;
+  return (this.details_[kFrameDetailsFlagsIndex] & f) >> 2
 }
 
 
@@ -1447,6 +1471,21 @@
 };
 
 
+FrameMirror.prototype.isOptimizedFrame = function() {
+  return this.details_.isOptimizedFrame();
+};
+
+
+FrameMirror.prototype.isInlinedFrame = function() {
+  return this.details_.isInlinedFrame();
+};
+
+
+FrameMirror.prototype.inlinedFrameIndex = function() {
+  return this.details_.inlinedFrameIndex();
+};
+
+
 FrameMirror.prototype.argumentCount = function() {
   return this.details_.argumentCount();
 };
@@ -1536,8 +1575,12 @@
 
 
 FrameMirror.prototype.evaluate = function(source, disable_break, opt_context_object) {
-  var result = %DebugEvaluate(this.break_id_, this.details_.frameId(),
-                              source, Boolean(disable_break), opt_context_object);
+  var result = %DebugEvaluate(this.break_id_,
+                              this.details_.frameId(),
+                              this.details_.inlinedFrameIndex(),
+                              source,
+                              Boolean(disable_break),
+                              opt_context_object);
   return MakeMirror(result);
 };
 
@@ -1562,8 +1605,10 @@
     // Try to find the function as a property in the receiver. Include the
     // prototype chain in the lookup.
     var property = GetUndefinedMirror();
-    if (!receiver.isUndefined()) {
-      for (var r = receiver; !r.isNull() && property.isUndefined(); r = r.protoObject()) {
+    if (receiver.isObject()) {
+      for (var r = receiver;
+           !r.isNull() && property.isUndefined();
+           r = r.protoObject()) {
         property = r.lookupProperty(func);
       }
     }
@@ -1690,6 +1735,7 @@
   this.break_id_ = frame.break_id_;
   this.details_ = %GetScopeDetails(frame.break_id_,
                                    frame.details_.frameId(),
+                                   frame.details_.inlinedFrameIndex(),
                                    index);
 }
 
diff --git a/src/misc-intrinsics.h b/src/misc-intrinsics.h
new file mode 100644
index 0000000..5393de2
--- /dev/null
+++ b/src/misc-intrinsics.h
@@ -0,0 +1,89 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_MISC_INTRINSICS_H_
+#define V8_MISC_INTRINSICS_H_
+
+#include "../include/v8.h"
+#include "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 dd49116..c5ce12f 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -136,6 +136,7 @@
     return true;
   }
   int raw_size() { return raw_size_; }
+
  private:
   i::List<char> data_;
   int raw_size_;
@@ -265,14 +266,39 @@
  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) {
+    ASSERT_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
 
 
 int main(int argc, char** argv) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // By default, log code create information in the snapshot.
   i::FLAG_log_code = true;
-#endif
+
   // 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);
@@ -281,6 +307,14 @@
     i::FlagList::PrintHelp();
     return !i::FLAG_help;
   }
+#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::Serializer::Enable();
   Persistent<Context> context = v8::Context::New();
   ASSERT(!context.IsEmpty());
diff --git a/src/natives.h b/src/natives.h
index 92f0d90..5f34420 100644
--- a/src/natives.h
+++ b/src/natives.h
@@ -36,7 +36,7 @@
                                      int index);
 
 enum NativeType {
-  CORE, EXPERIMENTAL, D8, I18N
+  CORE, EXPERIMENTAL, D8, TEST
 };
 
 template <NativeType type>
@@ -52,8 +52,11 @@
   // non-debugger scripts have an index in the interval [GetDebuggerCount(),
   // GetNativesCount()).
   static int GetIndex(const char* name);
-  static Vector<const char> GetScriptSource(int index);
+  static int GetRawScriptsSize();
+  static Vector<const char> GetRawScriptSource(int index);
   static Vector<const char> GetScriptName(int index);
+  static Vector<const byte> GetScriptsSource();
+  static void SetRawScriptsSource(Vector<const char> raw_source);
 };
 
 typedef NativesCollection<CORE> Natives;
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 76c520e..2963231 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -88,6 +88,9 @@
     case FIXED_ARRAY_TYPE:
       FixedArray::cast(this)->FixedArrayVerify();
       break;
+    case FIXED_DOUBLE_ARRAY_TYPE:
+      FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
+      break;
     case BYTE_ARRAY_TYPE:
       ByteArray::cast(this)->ByteArrayVerify();
       break;
@@ -289,6 +292,12 @@
 }
 
 
+void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
+  VerifyHeapPointer(cache());
+  ASSERT(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
+}
+
+
 void FixedArray::FixedArrayVerify() {
   for (int i = 0; i < length(); i++) {
     Object* e = get(i);
@@ -301,6 +310,18 @@
 }
 
 
+void FixedDoubleArray::FixedDoubleArrayVerify() {
+  for (int i = 0; i < length(); i++) {
+    if (!is_the_hole(i)) {
+      double value = get(i);
+      ASSERT(!isnan(value) ||
+             (BitCast<uint64_t>(value) ==
+              BitCast<uint64_t>(canonical_not_the_hole_nan_as_double())));
+    }
+  }
+}
+
+
 void JSValue::JSValueVerify() {
   Object* v = value();
   if (v->IsHeapObject()) {
@@ -426,7 +447,9 @@
 void JSArray::JSArrayVerify() {
   JSObjectVerify();
   ASSERT(length()->IsNumber() || length()->IsUndefined());
-  ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
+  ASSERT(elements()->IsUndefined() ||
+         elements()->IsFixedArray() ||
+         elements()->IsFixedDoubleArray());
 }
 
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index aa5fc86..70f6267 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -217,6 +217,10 @@
          String::cast(this)->IsTwoByteRepresentation();
 }
 
+bool Object::HasValidElements() {
+  // Dictionary is covered under FixedArray.
+  return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
+}
 
 StringShape::StringShape(String* str)
   : type_(str->map()->instance_type()) {
@@ -446,9 +450,27 @@
 }
 
 
+bool Object::IsJSReceiver() {
+  return IsHeapObject() &&
+      HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
+}
+
+
 bool Object::IsJSObject() {
-  return IsHeapObject()
-      && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
+  return IsJSReceiver() && !IsJSProxy();
+}
+
+
+bool Object::IsJSProxy() {
+  return Object::IsHeapObject() &&
+     (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
+      HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
+}
+
+
+bool Object::IsJSFunctionProxy() {
+  return Object::IsHeapObject() &&
+      HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
 }
 
 
@@ -471,6 +493,13 @@
 }
 
 
+bool Object::IsFixedDoubleArray() {
+  return Object::IsHeapObject()
+      && HeapObject::cast(this)->map()->instance_type() ==
+          FIXED_DOUBLE_ARRAY_TYPE;
+}
+
+
 bool Object::IsDescriptorArray() {
   return IsFixedArray();
 }
@@ -505,22 +534,17 @@
 
 bool Object::IsContext() {
   if (Object::IsHeapObject()) {
-    Heap* heap = HeapObject::cast(this)->GetHeap();
-    return (HeapObject::cast(this)->map() == heap->context_map() ||
-            HeapObject::cast(this)->map() == heap->catch_context_map() ||
-            HeapObject::cast(this)->map() == heap->global_context_map());
+    Map* map = HeapObject::cast(this)->map();
+    Heap* heap = map->GetHeap();
+    return (map == heap->function_context_map() ||
+            map == heap->catch_context_map() ||
+            map == heap->with_context_map() ||
+            map == heap->global_context_map());
   }
   return false;
 }
 
 
-bool Object::IsCatchContext() {
-  return Object::IsHeapObject() &&
-      HeapObject::cast(this)->map() ==
-      HeapObject::cast(this)->GetHeap()->catch_context_map();
-}
-
-
 bool Object::IsGlobalContext() {
   return Object::IsHeapObject() &&
       HeapObject::cast(this)->map() ==
@@ -584,12 +608,6 @@
 }
 
 
-bool Object::IsJSProxy() {
-  return Object::IsHeapObject()
-      && HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE;
-}
-
-
 bool Object::IsForeign() {
   return Object::IsHeapObject()
       && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
@@ -627,8 +645,8 @@
 
 
 bool Object::IsDictionary() {
-  return IsHashTable() && this !=
-         HeapObject::cast(this)->GetHeap()->symbol_table();
+  return IsHashTable() &&
+      this != HeapObject::cast(this)->GetHeap()->symbol_table();
 }
 
 
@@ -676,6 +694,11 @@
 }
 
 
+bool Object::IsPolymorphicCodeCacheHashTable() {
+  return IsHashTable();
+}
+
+
 bool Object::IsMapCache() {
   return IsHashTable();
 }
@@ -867,7 +890,7 @@
 #else  // V8_TARGET_ARCH_MIPS
   // Prevent gcc from using load-double (mips ldc1) on (possibly)
   // non-64-bit aligned HeapNumber::value.
-  static inline double read_double_field(HeapNumber* p, int offset) {
+  static inline double read_double_field(void* p, int offset) {
     union conversion {
       double d;
       uint32_t u[2];
@@ -886,7 +909,7 @@
 #else  // V8_TARGET_ARCH_MIPS
   // Prevent gcc from using store-double (mips sdc1) on (possibly)
   // non-64-bit aligned HeapNumber::value.
-  static inline void write_double_field(HeapNumber* p, int offset,
+  static inline void write_double_field(void* p, int offset,
                                         double value) {
     union conversion {
       double d;
@@ -1301,8 +1324,7 @@
 
 HeapObject* JSObject::elements() {
   Object* array = READ_FIELD(this, kElementsOffset);
-  // In the assert below Dictionary is covered under FixedArray.
-  ASSERT(array->IsFixedArray() || array->IsExternalArray());
+  ASSERT(array->HasValidElements());
   return reinterpret_cast<HeapObject*>(array);
 }
 
@@ -1311,8 +1333,7 @@
   ASSERT(map()->has_fast_elements() ==
          (value->map() == GetHeap()->fixed_array_map() ||
           value->map() == GetHeap()->fixed_cow_array_map()));
-  // In the assert below Dictionary is covered under FixedArray.
-  ASSERT(value->IsFixedArray() || value->IsExternalArray());
+  ASSERT(value->HasValidElements());
   WRITE_FIELD(this, kElementsOffset, value);
   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
 }
@@ -1560,6 +1581,12 @@
 }
 
 
+FixedArrayBase* FixedArrayBase::cast(Object* object) {
+  ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
+  return reinterpret_cast<FixedArrayBase*>(object);
+}
+
+
 Object* FixedArray::get(int index) {
   ASSERT(index >= 0 && index < this->length());
   return READ_FIELD(this, kHeaderSize + index * kPointerSize);
@@ -1583,6 +1610,105 @@
 }
 
 
+inline bool FixedDoubleArray::is_the_hole_nan(double value) {
+  return BitCast<uint64_t, double>(value) == kHoleNanInt64;
+}
+
+
+inline double FixedDoubleArray::hole_nan_as_double() {
+  return BitCast<double, uint64_t>(kHoleNanInt64);
+}
+
+
+inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
+  ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
+  ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
+  return OS::nan_value();
+}
+
+
+double FixedDoubleArray::get(int index) {
+  ASSERT(map() != HEAP->fixed_cow_array_map() &&
+         map() != HEAP->fixed_array_map());
+  ASSERT(index >= 0 && index < this->length());
+  double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
+  ASSERT(!is_the_hole_nan(result));
+  return result;
+}
+
+
+void FixedDoubleArray::set(int index, double value) {
+  ASSERT(map() != HEAP->fixed_cow_array_map() &&
+         map() != HEAP->fixed_array_map());
+  int offset = kHeaderSize + index * kDoubleSize;
+  if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
+  WRITE_DOUBLE_FIELD(this, offset, value);
+}
+
+
+void FixedDoubleArray::set_the_hole(int index) {
+  ASSERT(map() != HEAP->fixed_cow_array_map() &&
+         map() != HEAP->fixed_array_map());
+  int offset = kHeaderSize + index * kDoubleSize;
+  WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
+}
+
+
+bool FixedDoubleArray::is_the_hole(int index) {
+  int offset = kHeaderSize + index * kDoubleSize;
+  return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
+}
+
+
+void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
+  int old_length = from->length();
+  ASSERT(old_length < length());
+  OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
+              FIELD_ADDR(from, kHeaderSize),
+              old_length * kDoubleSize);
+  int offset = kHeaderSize + old_length * kDoubleSize;
+  for (int current = from->length(); current < length(); ++current) {
+    WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
+    offset += kDoubleSize;
+  }
+}
+
+
+void FixedDoubleArray::Initialize(FixedArray* from) {
+  int old_length = from->length();
+  ASSERT(old_length < length());
+  for (int i = 0; i < old_length; i++) {
+    Object* hole_or_object = from->get(i);
+    if (hole_or_object->IsTheHole()) {
+      set_the_hole(i);
+    } else {
+      set(i, hole_or_object->Number());
+    }
+  }
+  int offset = kHeaderSize + old_length * kDoubleSize;
+  for (int current = from->length(); current < length(); ++current) {
+    WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
+    offset += kDoubleSize;
+  }
+}
+
+
+void FixedDoubleArray::Initialize(NumberDictionary* from) {
+  int offset = kHeaderSize;
+  for (int current = 0; current < length(); ++current) {
+    WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
+    offset += kDoubleSize;
+  }
+  for (int i = 0; i < from->Capacity(); i++) {
+    Object* key = from->KeyAt(i);
+    if (key->IsNumber()) {
+      uint32_t entry = static_cast<uint32_t>(key->Number());
+      set(entry, from->ValueAt(i)->Number());
+    }
+  }
+}
+
+
 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
   if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
   return UPDATE_WRITE_BARRIER;
@@ -1883,6 +2009,7 @@
 
 
 CAST_ACCESSOR(FixedArray)
+CAST_ACCESSOR(FixedDoubleArray)
 CAST_ACCESSOR(DescriptorArray)
 CAST_ACCESSOR(DeoptimizationInputData)
 CAST_ACCESSOR(DeoptimizationOutputData)
@@ -1891,6 +2018,7 @@
 CAST_ACCESSOR(NormalizedMapCache)
 CAST_ACCESSOR(CompilationCacheTable)
 CAST_ACCESSOR(CodeCacheHashTable)
+CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
 CAST_ACCESSOR(MapCache)
 CAST_ACCESSOR(String)
 CAST_ACCESSOR(SeqString)
@@ -1900,6 +2028,7 @@
 CAST_ACCESSOR(ExternalString)
 CAST_ACCESSOR(ExternalAsciiString)
 CAST_ACCESSOR(ExternalTwoByteString)
+CAST_ACCESSOR(JSReceiver)
 CAST_ACCESSOR(JSObject)
 CAST_ACCESSOR(Smi)
 CAST_ACCESSOR(HeapObject)
@@ -1917,6 +2046,7 @@
 CAST_ACCESSOR(JSArray)
 CAST_ACCESSOR(JSRegExp)
 CAST_ACCESSOR(JSProxy)
+CAST_ACCESSOR(JSFunctionProxy)
 CAST_ACCESSOR(Foreign)
 CAST_ACCESSOR(ByteArray)
 CAST_ACCESSOR(ExternalArray)
@@ -1944,9 +2074,11 @@
 }
 
 
-SMI_ACCESSORS(FixedArray, length, kLengthOffset)
+SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
 SMI_ACCESSORS(ByteArray, length, kLengthOffset)
 
+// TODO(1493): Investigate if it's possible to s/INT/SMI/ here (and
+// subsequently unify H{Fixed,External}ArrayLength).
 INT_ACCESSORS(ExternalArray, length, kLengthOffset)
 
 
@@ -2403,6 +2535,10 @@
     return SeqTwoByteString::SizeFor(
         reinterpret_cast<SeqTwoByteString*>(this)->length());
   }
+  if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
+    return FixedDoubleArray::SizeFor(
+        reinterpret_cast<FixedDoubleArray*>(this)->length());
+  }
   ASSERT(instance_type == CODE_TYPE);
   return reinterpret_cast<Code*>(this)->CodeSize();
 }
@@ -2724,19 +2860,6 @@
 }
 
 
-ExternalArrayType Code::external_array_type() {
-  ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
-  byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
-  return static_cast<ExternalArrayType>(type);
-}
-
-
-void Code::set_external_array_type(ExternalArrayType value) {
-  ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
-  WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
-}
-
-
 byte Code::unary_op_type() {
   ASSERT(is_unary_op_stub());
   return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
@@ -2947,7 +3070,7 @@
 
 
 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
-  ASSERT(value->IsNull() || value->IsJSObject());
+  ASSERT(value->IsNull() || value->IsJSReceiver());
   WRITE_FIELD(this, kPrototypeOffset, value);
   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
 }
@@ -2960,21 +3083,34 @@
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
   Map* new_map = Map::cast(obj);
-  new_map->set_has_fast_elements(true);
-  isolate()->counters()->map_slow_to_fast_elements()->Increment();
+  new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
+  isolate()->counters()->map_to_fast_elements()->Increment();
   return new_map;
 }
 
 
-MaybeObject* Map::GetSlowElementsMap() {
-  if (!has_fast_elements()) return this;
+MaybeObject* Map::GetFastDoubleElementsMap() {
+  if (has_fast_double_elements()) return this;
   Object* obj;
   { MaybeObject* maybe_obj = CopyDropTransitions();
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
   Map* new_map = Map::cast(obj);
-  new_map->set_has_fast_elements(false);
-  isolate()->counters()->map_fast_to_slow_elements()->Increment();
+  new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
+  isolate()->counters()->map_to_fast_double_elements()->Increment();
+  return new_map;
+}
+
+
+MaybeObject* Map::GetSlowElementsMap() {
+  if (!has_fast_elements() && !has_fast_double_elements()) return this;
+  Object* obj;
+  { MaybeObject* maybe_obj = CopyDropTransitions();
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  }
+  Map* new_map = Map::cast(obj);
+  new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
+  isolate()->counters()->map_to_slow_elements()->Increment();
   return new_map;
 }
 
@@ -3113,6 +3249,8 @@
 ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
           kAccessCheckInfoOffset)
 ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
+ACCESSORS(FunctionTemplateInfo, prototype_attributes, Smi,
+          kPrototypeAttributesOffset)
 
 ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
 ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
@@ -3171,13 +3309,22 @@
                kIsExpressionBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
                kIsTopLevelBit)
-BOOL_GETTER(SharedFunctionInfo, compiler_hints,
+BOOL_GETTER(SharedFunctionInfo,
+            compiler_hints,
             has_only_simple_this_property_assignments,
             kHasOnlySimpleThisPropertyAssignments)
 BOOL_ACCESSORS(SharedFunctionInfo,
                compiler_hints,
                allows_lazy_compilation,
                kAllowLazyCompilation)
+BOOL_ACCESSORS(SharedFunctionInfo,
+               compiler_hints,
+               uses_arguments,
+               kUsesArguments)
+BOOL_ACCESSORS(SharedFunctionInfo,
+               compiler_hints,
+               has_duplicate_parameters,
+               kHasDuplicateParameters)
 
 
 #if V8_HOST_ARCH_32_BIT
@@ -3261,18 +3408,10 @@
 }
 
 
-bool SharedFunctionInfo::live_objects_may_exist() {
-  return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
-}
-
-
-void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
-  if (value) {
-    set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
-  } else {
-    set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
-  }
-}
+BOOL_ACCESSORS(SharedFunctionInfo,
+               compiler_hints,
+               live_objects_may_exist,
+               kLiveObjectsMayExist)
 
 
 bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
@@ -3280,9 +3419,10 @@
 }
 
 
-bool SharedFunctionInfo::optimization_disabled() {
-  return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
-}
+BOOL_GETTER(SharedFunctionInfo,
+            compiler_hints,
+            optimization_disabled,
+            kOptimizationDisabled)
 
 
 void SharedFunctionInfo::set_optimization_disabled(bool disable) {
@@ -3297,33 +3437,20 @@
 }
 
 
-bool SharedFunctionInfo::strict_mode() {
-  return BooleanBit::get(compiler_hints(), kStrictModeFunction);
-}
-
-
-void SharedFunctionInfo::set_strict_mode(bool value) {
-  set_compiler_hints(BooleanBit::set(compiler_hints(),
-                                     kStrictModeFunction,
-                                     value));
-}
-
-
-bool SharedFunctionInfo::es5_native() {
-  return BooleanBit::get(compiler_hints(), kES5Native);
-}
-
-
-void SharedFunctionInfo::set_es5_native(bool value) {
-  set_compiler_hints(BooleanBit::set(compiler_hints(),
-                                     kES5Native,
-                                     value));
-}
-
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
+               kStrictModeFunction)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
+               name_should_print_as_anonymous,
+               kNameShouldPrintAsAnonymous)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
 
 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
 
+ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
+
 bool Script::HasValidSource() {
   Object* src = this->source();
   if (!src->IsString()) return true;
@@ -3613,6 +3740,7 @@
 
 
 ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
+ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
 
 
 Address Foreign::address() {
@@ -3786,45 +3914,17 @@
 
 
 JSObject::ElementsKind JSObject::GetElementsKind() {
-  if (map()->has_fast_elements()) {
-    ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
-           elements()->map() == GetHeap()->fixed_cow_array_map());
-    return FAST_ELEMENTS;
-  }
-  HeapObject* array = elements();
-  if (array->IsFixedArray()) {
-    // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
-    // FixedArray, but FAST_ELEMENTS is already handled above.
-    ASSERT(array->IsDictionary());
-    return DICTIONARY_ELEMENTS;
-  }
-  ASSERT(!map()->has_fast_elements());
-  if (array->IsExternalArray()) {
-    switch (array->map()->instance_type()) {
-      case EXTERNAL_BYTE_ARRAY_TYPE:
-        return EXTERNAL_BYTE_ELEMENTS;
-      case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
-        return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
-      case EXTERNAL_SHORT_ARRAY_TYPE:
-        return EXTERNAL_SHORT_ELEMENTS;
-      case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
-        return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
-      case EXTERNAL_INT_ARRAY_TYPE:
-        return EXTERNAL_INT_ELEMENTS;
-      case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
-        return EXTERNAL_UNSIGNED_INT_ELEMENTS;
-      case EXTERNAL_FLOAT_ARRAY_TYPE:
-        return EXTERNAL_FLOAT_ELEMENTS;
-      case EXTERNAL_DOUBLE_ARRAY_TYPE:
-        return EXTERNAL_DOUBLE_ELEMENTS;
-      case EXTERNAL_PIXEL_ARRAY_TYPE:
-        return EXTERNAL_PIXEL_ELEMENTS;
-      default:
-        break;
-    }
-  }
-  UNREACHABLE();
-  return DICTIONARY_ELEMENTS;
+  ElementsKind kind = map()->elements_kind();
+  ASSERT((kind == FAST_ELEMENTS &&
+          (elements()->map() == GetHeap()->fixed_array_map() ||
+           elements()->map() == GetHeap()->fixed_cow_array_map())) ||
+         (kind == FAST_DOUBLE_ELEMENTS &&
+          elements()->IsFixedDoubleArray()) ||
+         (kind == DICTIONARY_ELEMENTS &&
+          elements()->IsFixedArray() &&
+          elements()->IsDictionary()) ||
+         (kind > DICTIONARY_ELEMENTS));
+  return kind;
 }
 
 
@@ -3833,6 +3933,11 @@
 }
 
 
+bool JSObject::HasFastDoubleElements() {
+  return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
+}
+
+
 bool JSObject::HasDictionaryElements() {
   return GetElementsKind() == DICTIONARY_ELEMENTS;
 }
@@ -3881,7 +3986,8 @@
 
 
 bool JSObject::AllowsSetElementsLength() {
-  bool result = elements()->IsFixedArray();
+  bool result = elements()->IsFixedArray() ||
+      elements()->IsFixedDoubleArray();
   ASSERT(result == !HasExternalArrayElements());
   return result;
 }
@@ -4026,12 +4132,28 @@
 }
 
 
-Object* JSObject::GetPrototype() {
-  return JSObject::cast(this)->map()->prototype();
+Object* JSReceiver::GetPrototype() {
+  return HeapObject::cast(this)->map()->prototype();
 }
 
 
-PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
+bool JSReceiver::HasProperty(String* name) {
+  if (IsJSProxy()) {
+    return JSProxy::cast(this)->HasPropertyWithHandler(name);
+  }
+  return GetPropertyAttribute(name) != ABSENT;
+}
+
+
+bool JSReceiver::HasLocalProperty(String* name) {
+  if (IsJSProxy()) {
+    return JSProxy::cast(this)->HasPropertyWithHandler(name);
+  }
+  return GetLocalPropertyAttribute(name) != ABSENT;
+}
+
+
+PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
   return GetPropertyAttributeWithReceiver(this, key);
 }
 
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 60028c0..158789e 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -351,6 +351,15 @@
     case DICTIONARY_ELEMENTS:
       elements()->Print(out);
       break;
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      FixedArray* p = FixedArray::cast(elements());
+      for (int i = 2; i < p->length(); i++) {
+        PrintF(out, "   %d: ", i);
+        p->get(i)->ShortPrint(out);
+        PrintF(out, "\n");
+      }
+      break;
+    }
     default:
       UNREACHABLE();
       break;
@@ -472,6 +481,13 @@
 }
 
 
+void PolymorphicCodeCache::PolymorphicCodeCachePrint(FILE* out) {
+  HeapObject::PrintHeader(out, "PolymorphicCodeCache");
+  PrintF(out, "\n - cache: ");
+  cache()->ShortPrint(out);
+}
+
+
 void FixedArray::FixedArrayPrint(FILE* out) {
   HeapObject::PrintHeader(out, "FixedArray");
   PrintF(out, " - length: %d", length());
diff --git a/src/objects-visiting.cc b/src/objects-visiting.cc
index 685e8ad..4cd795e 100644
--- a/src/objects-visiting.cc
+++ b/src/objects-visiting.cc
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -73,6 +73,9 @@
     case FIXED_ARRAY_TYPE:
       return kVisitFixedArray;
 
+    case FIXED_DOUBLE_ARRAY_TYPE:
+      return kVisitFixedDoubleArray;
+
     case ODDBALL_TYPE:
       return kVisitOddball;
 
diff --git a/src/objects-visiting.h b/src/objects-visiting.h
index dcbf2f8..cc64763 100644
--- a/src/objects-visiting.h
+++ b/src/objects-visiting.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -30,6 +30,22 @@
 
 #include "allocation.h"
 
+#if V8_TARGET_ARCH_IA32
+#include "ia32/assembler-ia32.h"
+#include "ia32/assembler-ia32-inl.h"
+#elif V8_TARGET_ARCH_X64
+#include "x64/assembler-x64.h"
+#include "x64/assembler-x64-inl.h"
+#elif V8_TARGET_ARCH_ARM
+#include "arm/assembler-arm.h"
+#include "arm/assembler-arm-inl.h"
+#elif V8_TARGET_ARCH_MIPS
+#include "mips/assembler-mips.h"
+#include "mips/assembler-mips-inl.h"
+#else
+#error Unsupported target architecture.
+#endif
+
 // This file provides base classes and auxiliary methods for defining
 // static object visitors used during GC.
 // Visiting HeapObject body with a normal ObjectVisitor requires performing
@@ -52,6 +68,7 @@
     kVisitShortcutCandidate,
     kVisitByteArray,
     kVisitFixedArray,
+    kVisitFixedDoubleArray,
     kVisitGlobalContext,
 
     // For data objects, JS objects and structs along with generic visitor which
@@ -286,6 +303,8 @@
                                          FixedArray::BodyDescriptor,
                                          int>::Visit);
 
+    table_.Register(kVisitFixedDoubleArray, &VisitFixedDoubleArray);
+
     table_.Register(kVisitGlobalContext,
                     &FixedBodyVisitor<StaticVisitor,
                                       Context::ScavengeBodyDescriptor,
@@ -332,6 +351,11 @@
     return reinterpret_cast<ByteArray*>(object)->ByteArraySize();
   }
 
+  static inline int VisitFixedDoubleArray(Map* map, HeapObject* object) {
+    int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
+    return FixedDoubleArray::SizeFor(length);
+  }
+
   static inline int VisitSeqAsciiString(Map* map, HeapObject* object) {
     return SeqAsciiString::cast(object)->
         SeqAsciiStringSize(map->instance_type());
diff --git a/src/objects.cc b/src/objects.cc
index b407c01..1ab5dd2 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -58,7 +58,6 @@
 const int kGetterIndex = 0;
 const int kSetterIndex = 1;
 
-
 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
                                                   Object* value) {
   Object* result;
@@ -140,6 +139,8 @@
     HeapObject* heap_object = HeapObject::cast(this);
     if (heap_object->IsJSObject()) {
       return JSObject::cast(this)->Lookup(name, result);
+    } else if (heap_object->IsJSProxy()) {
+      return result->HandlerResult();
     }
     Context* global_context = Isolate::Current()->context()->global_context();
     if (heap_object->IsString()) {
@@ -148,8 +149,6 @@
       holder = global_context->number_function()->instance_prototype();
     } else if (heap_object->IsBoolean()) {
       holder = global_context->boolean_function()->instance_prototype();
-    } else if (heap_object->IsJSProxy()) {
-      return result->HandlerResult();
     }
   }
   ASSERT(holder != NULL);  // Cannot handle null or undefined.
@@ -190,7 +189,7 @@
     AccessorInfo* data = AccessorInfo::cast(structure);
     Object* fun_obj = data->getter();
     v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
-    HandleScope scope;
+    HandleScope scope(isolate);
     JSObject* self = JSObject::cast(receiver);
     JSObject* holder_handle = JSObject::cast(holder);
     Handle<String> key(name);
@@ -230,15 +229,15 @@
                                             String* name_raw,
                                             Object* handler_raw) {
   Isolate* isolate = name_raw->GetIsolate();
-  HandleScope scope;
+  HandleScope scope(isolate);
   Handle<Object> receiver(receiver_raw);
   Handle<Object> name(name_raw);
   Handle<Object> handler(handler_raw);
 
   // Extract trap function.
-  LookupResult lookup;
-  Handle<Object> trap(v8::internal::GetProperty(handler, "get", &lookup));
-  if (!lookup.IsFound()) {
+  Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("get");
+  Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+  if (trap->IsUndefined()) {
     // Get the derived `get' property.
     trap = isolate->derived_get_trap();
   }
@@ -489,7 +488,16 @@
       cell->set_value(cell->heap()->the_hole_value());
       dictionary->DetailsAtPut(entry, details.AsDeleted());
     } else {
-      return dictionary->DeleteProperty(entry, mode);
+      Object* deleted = dictionary->DeleteProperty(entry, mode);
+      if (deleted == GetHeap()->true_value()) {
+        FixedArray* new_properties = NULL;
+        MaybeObject* maybe_properties = dictionary->Shrink(name);
+        if (!maybe_properties->To(&new_properties)) {
+          return maybe_properties;
+        }
+        set_properties(new_properties);
+      }
+      return deleted;
     }
   }
   return GetHeap()->true_value();
@@ -638,7 +646,7 @@
 
   // The object is either a number, a string, a boolean,
   // a real JS object, or a Harmony proxy.
-  if (heap_object->IsJSObject() || heap_object->IsJSProxy()) {
+  if (heap_object->IsJSReceiver()) {
     return heap_object->map()->prototype();
   }
   Heap* heap = heap_object->GetHeap();
@@ -1001,7 +1009,6 @@
                        global_object ? "Global Object: " : "",
                        vowel ? "n" : "");
                 accumulator->Put(str);
-                accumulator->Put('>');
                 printed = true;
               }
             }
@@ -1178,6 +1185,8 @@
     case FIXED_ARRAY_TYPE:
       FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
       break;
+    case FIXED_DOUBLE_ARRAY_TYPE:
+      break;
     case JS_OBJECT_TYPE:
     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
     case JS_VALUE_TYPE:
@@ -1281,8 +1290,8 @@
 }
 
 
-String* JSObject::class_name() {
-  if (IsJSFunction()) {
+String* JSReceiver::class_name() {
+  if (IsJSFunction() && IsJSFunctionProxy()) {
     return GetHeap()->function_class_symbol();
   }
   if (map()->constructor()->IsJSFunction()) {
@@ -1294,7 +1303,7 @@
 }
 
 
-String* JSObject::constructor_name() {
+String* JSReceiver::constructor_name() {
   if (map()->constructor()->IsJSFunction()) {
     JSFunction* constructor = JSFunction::cast(map()->constructor());
     String* name = String::cast(constructor->shared()->name());
@@ -1304,6 +1313,7 @@
     Object* proto = GetPrototype();
     if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
   }
+  // TODO(rossberg): what about proxies?
   // If the constructor is not present, return "Object".
   return GetHeap()->Object_symbol();
 }
@@ -1758,10 +1768,10 @@
 }
 
 
-MaybeObject* JSObject::SetProperty(String* name,
-                                   Object* value,
-                                   PropertyAttributes attributes,
-                                   StrictModeFlag strict_mode) {
+MaybeObject* JSReceiver::SetProperty(String* name,
+                                     Object* value,
+                                     PropertyAttributes attributes,
+                                     StrictModeFlag strict_mode) {
   LookupResult result;
   LocalLookup(name, &result);
   return SetProperty(&result, name, value, attributes, strict_mode);
@@ -1771,7 +1781,8 @@
 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
                                                String* name,
                                                Object* value,
-                                               JSObject* holder) {
+                                               JSObject* holder,
+                                               StrictModeFlag strict_mode) {
   Isolate* isolate = GetIsolate();
   HandleScope scope(isolate);
 
@@ -1819,6 +1830,9 @@
     if (setter->IsJSFunction()) {
      return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value);
     } else {
+      if (strict_mode == kNonStrictMode) {
+        return value;
+      }
       Handle<String> key(name);
       Handle<Object> holder_handle(holder, isolate);
       Handle<Object> args[2] = { key, holder_handle };
@@ -1872,15 +1886,17 @@
 }
 
 
-MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index,
-                                                                Object* value,
-                                                                bool* found) {
+MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
+    uint32_t index,
+    Object* value,
+    bool* found,
+    StrictModeFlag strict_mode) {
   Heap* heap = GetHeap();
   for (Object* pt = GetPrototype();
        pt != heap->null_value();
        pt = pt->GetPrototype()) {
     if (!JSObject::cast(pt)->HasDictionaryElements()) {
-        continue;
+      continue;
     }
     NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
     int entry = dictionary->FindEntry(index);
@@ -1888,8 +1904,11 @@
       PropertyDetails details = dictionary->DetailsAt(entry);
       if (details.type() == CALLBACKS) {
         *found = true;
-        return SetElementWithCallback(
-            dictionary->ValueAt(entry), index, value, JSObject::cast(pt));
+        return SetElementWithCallback(dictionary->ValueAt(entry),
+                                      index,
+                                      value,
+                                      JSObject::cast(pt),
+                                      strict_mode);
       }
     }
   }
@@ -1927,6 +1946,42 @@
 }
 
 
+static JSObject::ElementsKind GetElementsKindFromExternalArrayType(
+    ExternalArrayType array_type) {
+  switch (array_type) {
+    case kExternalByteArray:
+      return JSObject::EXTERNAL_BYTE_ELEMENTS;
+      break;
+    case kExternalUnsignedByteArray:
+      return JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
+      break;
+    case kExternalShortArray:
+      return JSObject::EXTERNAL_SHORT_ELEMENTS;
+      break;
+    case kExternalUnsignedShortArray:
+      return JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
+      break;
+    case kExternalIntArray:
+      return JSObject::EXTERNAL_INT_ELEMENTS;
+      break;
+    case kExternalUnsignedIntArray:
+      return JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS;
+      break;
+    case kExternalFloatArray:
+      return JSObject::EXTERNAL_FLOAT_ELEMENTS;
+      break;
+    case kExternalDoubleArray:
+      return JSObject::EXTERNAL_DOUBLE_ELEMENTS;
+      break;
+    case kExternalPixelArray:
+      return JSObject::EXTERNAL_PIXEL_ELEMENTS;
+      break;
+  }
+  UNREACHABLE();
+  return JSObject::DICTIONARY_ELEMENTS;
+}
+
+
 MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type,
                                               bool safe_to_add_transition) {
   Heap* current_heap = heap();
@@ -1969,8 +2024,7 @@
   }
   Map* new_map = Map::cast(obj);
 
-  new_map->set_has_fast_elements(false);
-  new_map->set_has_external_array_elements(true);
+  new_map->set_elements_kind(GetElementsKindFromExternalArrayType(array_type));
   GetIsolate()->counters()->map_to_external_array_elements()->Increment();
 
   // Only remember the map transition if the object's map is NOT equal to the
@@ -2070,10 +2124,12 @@
 
 
 // We only need to deal with CALLBACKS and INTERCEPTORS
-MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
-                                                        String* name,
-                                                        Object* value,
-                                                        bool check_prototype) {
+MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(
+    LookupResult* result,
+    String* name,
+    Object* value,
+    bool check_prototype,
+    StrictModeFlag strict_mode) {
   if (check_prototype && !result->IsProperty()) {
     LookupCallbackSetterInPrototypes(name, result);
   }
@@ -2089,7 +2145,8 @@
               return SetPropertyWithCallback(result->GetCallbackObject(),
                                              name,
                                              value,
-                                             result->holder());
+                                             result->holder(),
+                                             strict_mode);
             }
           }
           break;
@@ -2100,8 +2157,11 @@
           LookupResult r;
           LookupRealNamedProperty(name, &r);
           if (r.IsProperty()) {
-            return SetPropertyWithFailedAccessCheck(&r, name, value,
-                                                    check_prototype);
+            return SetPropertyWithFailedAccessCheck(&r,
+                                                    name,
+                                                    value,
+                                                    check_prototype,
+                                                    strict_mode);
           }
           break;
         }
@@ -2112,19 +2172,175 @@
     }
   }
 
-  HandleScope scope;
-  Handle<Object> value_handle(value);
   Heap* heap = GetHeap();
+  HandleScope scope(heap->isolate());
+  Handle<Object> value_handle(value);
   heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
   return *value_handle;
 }
 
 
-MaybeObject* JSObject::SetProperty(LookupResult* result,
-                                   String* name,
-                                   Object* value,
-                                   PropertyAttributes attributes,
-                                   StrictModeFlag strict_mode) {
+MaybeObject* JSReceiver::SetProperty(LookupResult* result,
+                                     String* key,
+                                     Object* value,
+                                     PropertyAttributes attributes,
+                                     StrictModeFlag strict_mode) {
+  if (result->IsFound() && result->type() == HANDLER) {
+    return JSProxy::cast(this)->SetPropertyWithHandler(
+        key, value, attributes, strict_mode);
+  } else {
+    return JSObject::cast(this)->SetPropertyForResult(
+        result, key, value, attributes, strict_mode);
+  }
+}
+
+
+bool JSProxy::HasPropertyWithHandler(String* name_raw) {
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<Object> receiver(this);
+  Handle<Object> name(name_raw);
+  Handle<Object> handler(this->handler());
+
+  // Extract trap function.
+  Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("has");
+  Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+  if (trap->IsUndefined()) {
+    trap = isolate->derived_has_trap();
+  }
+
+  // Call trap function.
+  Object** args[] = { name.location() };
+  bool has_exception;
+  Handle<Object> result =
+      Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
+  if (has_exception) return Failure::Exception();
+
+  return result->ToBoolean()->IsTrue();
+}
+
+
+MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
+    String* name_raw,
+    Object* value_raw,
+    PropertyAttributes attributes,
+    StrictModeFlag strict_mode) {
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<Object> receiver(this);
+  Handle<Object> name(name_raw);
+  Handle<Object> value(value_raw);
+  Handle<Object> handler(this->handler());
+
+  // Extract trap function.
+  Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set");
+  Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+  if (trap->IsUndefined()) {
+    trap = isolate->derived_set_trap();
+  }
+
+  // Call trap function.
+  Object** args[] = {
+      receiver.location(), name.location(), value.location()
+  };
+  bool has_exception;
+  Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
+  if (has_exception) return Failure::Exception();
+
+  return *value;
+}
+
+
+MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
+    String* name_raw, DeleteMode mode) {
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<Object> receiver(this);
+  Handle<Object> name(name_raw);
+  Handle<Object> handler(this->handler());
+
+  // Extract trap function.
+  Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("delete");
+  Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+  if (trap->IsUndefined()) {
+    Handle<Object> args[] = { handler, trap_name };
+    Handle<Object> error = isolate->factory()->NewTypeError(
+        "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
+    isolate->Throw(*error);
+    return Failure::Exception();
+  }
+
+  // Call trap function.
+  Object** args[] = { name.location() };
+  bool has_exception;
+  Handle<Object> result =
+      Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
+  if (has_exception) return Failure::Exception();
+
+  Object* bool_result = result->ToBoolean();
+  if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) {
+    Handle<Object> args[] = { handler, trap_name };
+    Handle<Object> error = isolate->factory()->NewTypeError(
+        "handler_failed", HandleVector(args, ARRAY_SIZE(args)));
+    isolate->Throw(*error);
+    return Failure::Exception();
+  }
+  return bool_result;
+}
+
+
+MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
+    JSReceiver* receiver_raw,
+    String* name_raw,
+    bool* has_exception) {
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<JSReceiver> receiver(receiver_raw);
+  Handle<Object> name(name_raw);
+  Handle<Object> handler(this->handler());
+
+  // Extract trap function.
+  Handle<String> trap_name =
+      isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
+  Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+  if (trap->IsUndefined()) {
+    Handle<Object> args[] = { handler, trap_name };
+    Handle<Object> error = isolate->factory()->NewTypeError(
+        "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
+    isolate->Throw(*error);
+    *has_exception = true;
+    return NONE;
+  }
+
+  // Call trap function.
+  Object** args[] = { name.location() };
+  Handle<Object> result =
+      Execution::Call(trap, handler, ARRAY_SIZE(args), args, has_exception);
+  if (has_exception) return NONE;
+
+  // TODO(rossberg): convert result to PropertyAttributes
+  USE(result);
+  return NONE;
+}
+
+
+void JSProxy::Fix() {
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<JSProxy> self(this);
+
+  isolate->factory()->BecomeJSObject(self);
+  ASSERT(IsJSObject());
+  // TODO(rossberg): recognize function proxies.
+}
+
+
+
+MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
+                                            String* name,
+                                            Object* value,
+                                            PropertyAttributes attributes,
+                                            StrictModeFlag strict_mode) {
   Heap* heap = GetHeap();
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
@@ -2145,7 +2361,11 @@
   // Check access rights if needed.
   if (IsAccessCheckNeeded()
       && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
-    return SetPropertyWithFailedAccessCheck(result, name, value, true);
+    return SetPropertyWithFailedAccessCheck(result,
+                                            name,
+                                            value,
+                                            true,
+                                            strict_mode);
   }
 
   if (IsJSGlobalProxy()) {
@@ -2165,7 +2385,8 @@
       return SetPropertyWithCallback(accessor_result.GetCallbackObject(),
                                      name,
                                      value,
-                                     accessor_result.holder());
+                                     accessor_result.holder(),
+                                     strict_mode);
     }
   }
   if (!result->IsFound()) {
@@ -2174,7 +2395,7 @@
   }
   if (result->IsReadOnly() && result->IsProperty()) {
     if (strict_mode == kStrictMode) {
-      HandleScope scope;
+      HandleScope scope(heap->isolate());
       Handle<String> key(name);
       Handle<Object> holder(this);
       Handle<Object> args[2] = { key, holder };
@@ -2209,7 +2430,8 @@
       return SetPropertyWithCallback(result->GetCallbackObject(),
                                      name,
                                      value,
-                                     result->holder());
+                                     result->holder(),
+                                     strict_mode);
     case INTERCEPTOR:
       return SetPropertyWithInterceptor(name, value, attributes, strict_mode);
     case CONSTANT_TRANSITION: {
@@ -2262,7 +2484,11 @@
   if (IsAccessCheckNeeded()) {
     Heap* heap = GetHeap();
     if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
-      return SetPropertyWithFailedAccessCheck(&result, name, value, false);
+      return SetPropertyWithFailedAccessCheck(&result,
+                                              name,
+                                              value,
+                                              false,
+                                              kNonStrictMode);
     }
   }
 
@@ -2395,12 +2621,13 @@
 }
 
 
-PropertyAttributes JSObject::GetPropertyAttributeWithReceiver(
-      JSObject* receiver,
+PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
+      JSReceiver* receiver,
       String* key) {
   uint32_t index = 0;
-  if (key->AsArrayIndex(&index)) {
-    if (HasElementWithReceiver(receiver, index)) return NONE;
+  if (IsJSObject() && key->AsArrayIndex(&index)) {
+    if (JSObject::cast(this)->HasElementWithReceiver(receiver, index))
+      return NONE;
     return ABSENT;
   }
   // Named property.
@@ -2410,18 +2637,17 @@
 }
 
 
-PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver,
-                                                  LookupResult* result,
-                                                  String* name,
-                                                  bool continue_search) {
+PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver,
+                                                    LookupResult* result,
+                                                    String* name,
+                                                    bool continue_search) {
   // Check access rights if needed.
   if (IsAccessCheckNeeded()) {
+    JSObject* this_obj = JSObject::cast(this);
     Heap* heap = GetHeap();
-    if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) {
-      return GetPropertyAttributeWithFailedAccessCheck(receiver,
-                                                       result,
-                                                       name,
-                                                       continue_search);
+    if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) {
+      return this_obj->GetPropertyAttributeWithFailedAccessCheck(
+          receiver, result, name, continue_search);
     }
   }
   if (result->IsProperty()) {
@@ -2431,9 +2657,15 @@
       case CONSTANT_FUNCTION:
       case CALLBACKS:
         return result->GetAttributes();
+      case HANDLER: {
+        // TODO(rossberg): propagate exceptions properly.
+        bool has_exception = false;
+        return JSProxy::cast(this)->GetPropertyAttributeWithHandler(
+            receiver, name, &has_exception);
+      }
       case INTERCEPTOR:
-        return result->holder()->
-          GetPropertyAttributeWithInterceptor(receiver, name, continue_search);
+        return result->holder()->GetPropertyAttributeWithInterceptor(
+            JSObject::cast(receiver), name, continue_search);
       default:
         UNREACHABLE();
     }
@@ -2442,11 +2674,11 @@
 }
 
 
-PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) {
+PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) {
   // Check whether the name is an array index.
   uint32_t index = 0;
-  if (name->AsArrayIndex(&index)) {
-    if (HasLocalElement(index)) return NONE;
+  if (IsJSObject() && name->AsArrayIndex(&index)) {
+    if (JSObject::cast(this)->HasLocalElement(index)) return NONE;
     return ABSENT;
   }
   // Named property.
@@ -2460,10 +2692,12 @@
                                      PropertyNormalizationMode mode) {
   Isolate* isolate = obj->GetIsolate();
   Map* fast = obj->map();
-  int index = Hash(fast) % kEntries;
+  int index = fast->Hash() % kEntries;
   Object* result = get(index);
-  if (result->IsMap() && CheckHit(Map::cast(result), fast, mode)) {
+  if (result->IsMap() &&
+      Map::cast(result)->EquivalentToForNormalization(fast, mode)) {
 #ifdef DEBUG
+    Map::cast(result)->SharedMapVerify();
     if (FLAG_enable_slow_asserts) {
       // The cached map should match newly created normalized map bit-by-bit.
       Object* fresh;
@@ -2499,43 +2733,6 @@
 }
 
 
-int NormalizedMapCache::Hash(Map* fast) {
-  // For performance reasons we only hash the 3 most variable fields of a map:
-  // constructor, prototype and bit_field2.
-
-  // Shift away the tag.
-  int hash = (static_cast<uint32_t>(
-        reinterpret_cast<uintptr_t>(fast->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>(fast->prototype())) << 2);
-
-  return hash ^ (hash >> 16) ^ fast->bit_field2();
-}
-
-
-bool NormalizedMapCache::CheckHit(Map* slow,
-                                  Map* fast,
-                                  PropertyNormalizationMode mode) {
-#ifdef DEBUG
-  slow->SharedMapVerify();
-#endif
-  return
-    slow->constructor() == fast->constructor() &&
-    slow->prototype() == fast->prototype() &&
-    slow->inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ?
-                                    0 :
-                                    fast->inobject_properties()) &&
-    slow->instance_type() == fast->instance_type() &&
-    slow->bit_field() == fast->bit_field() &&
-    slow->bit_field2() == fast->bit_field2() &&
-    (slow->bit_field3() & ~(1<<Map::kIsShared)) == fast->bit_field3();
-}
-
-
 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) {
   if (map()->is_shared()) {
     // Fast case maps are never marked as shared.
@@ -2680,48 +2877,76 @@
 
 MaybeObject* JSObject::NormalizeElements() {
   ASSERT(!HasExternalArrayElements());
-  if (HasDictionaryElements()) return this;
-  Map* old_map = map();
-  ASSERT(old_map->has_fast_elements());
 
-  Object* obj;
-  { MaybeObject* maybe_obj = old_map->GetSlowElementsMap();
-    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  // Find the backing store.
+  FixedArrayBase* array = FixedArrayBase::cast(elements());
+  Map* old_map = array->map();
+  bool is_arguments =
+      (old_map == old_map->heap()->non_strict_arguments_elements_map());
+  if (is_arguments) {
+    array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
   }
-  Map* new_map = Map::cast(obj);
+  if (array->IsDictionary()) return array;
 
-  // Get number of entries.
-  FixedArray* array = FixedArray::cast(elements());
-
-  // Compute the effective length.
-  int length = IsJSArray() ?
-               Smi::cast(JSArray::cast(this)->length())->value() :
-               array->length();
-  { MaybeObject* maybe_obj = NumberDictionary::Allocate(length);
-    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  ASSERT(HasFastElements() ||
+         HasFastDoubleElements() ||
+         HasFastArgumentsElements());
+  // Compute the effective length and allocate a new backing store.
+  int length = IsJSArray()
+      ? Smi::cast(JSArray::cast(this)->length())->value()
+      : array->length();
+  NumberDictionary* dictionary = NULL;
+  { Object* object;
+    MaybeObject* maybe = NumberDictionary::Allocate(length);
+    if (!maybe->ToObject(&object)) return maybe;
+    dictionary = NumberDictionary::cast(object);
   }
-  NumberDictionary* dictionary = NumberDictionary::cast(obj);
-  // Copy entries.
+
+  // Copy the elements to the new backing store.
+  bool has_double_elements = array->IsFixedDoubleArray();
   for (int i = 0; i < length; i++) {
-    Object* value = array->get(i);
-    if (!value->IsTheHole()) {
-      PropertyDetails details = PropertyDetails(NONE, NORMAL);
-      Object* result;
-      { MaybeObject* maybe_result =
-            dictionary->AddNumberEntry(i, array->get(i), details);
-        if (!maybe_result->ToObject(&result)) return maybe_result;
+    Object* value = NULL;
+    if (has_double_elements) {
+      FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
+      if (double_array->is_the_hole(i)) {
+        value = GetIsolate()->heap()->the_hole_value();
+      } else {
+        // Objects must be allocated in the old object space, since the
+        // overall number of HeapNumbers needed for the conversion might
+        // exceed the capacity of new space, and we would fail repeatedly
+        // trying to convert the FixedDoubleArray.
+        MaybeObject* maybe_value_object =
+            GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED);
+        if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
       }
+    } else {
+      ASSERT(old_map->has_fast_elements());
+      value = FixedArray::cast(array)->get(i);
+    }
+    PropertyDetails details = PropertyDetails(NONE, NORMAL);
+    if (!value->IsTheHole()) {
+      Object* result;
+      MaybeObject* maybe_result =
+          dictionary->AddNumberEntry(i, value, details);
+      if (!maybe_result->ToObject(&result)) return maybe_result;
       dictionary = NumberDictionary::cast(result);
     }
   }
-  // Switch to using the dictionary as the backing storage for
-  // elements. Set the new map first to satify the elements type
-  // assert in set_elements().
-  set_map(new_map);
-  set_elements(dictionary);
 
-  new_map->heap()->isolate()->counters()->elements_to_dictionary()->
-      Increment();
+  // Switch to using the dictionary as the backing storage for elements.
+  if (is_arguments) {
+    FixedArray::cast(elements())->set(1, dictionary);
+  } else {
+    // Set the new map first to satify the elements type assert in
+    // set_elements().
+    Object* new_map;
+    MaybeObject* maybe = map()->GetSlowElementsMap();
+    if (!maybe->ToObject(&new_map)) return maybe;
+    set_map(Map::cast(new_map));
+    set_elements(dictionary);
+  }
+
+  old_map->isolate()->counters()->elements_to_dictionary()->Increment();
 
 #ifdef DEBUG
   if (FLAG_trace_normalization) {
@@ -2730,7 +2955,8 @@
   }
 #endif
 
-  return this;
+  ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
+  return dictionary;
 }
 
 
@@ -2804,7 +3030,16 @@
       NumberDictionary* dictionary = element_dictionary();
       int entry = dictionary->FindEntry(index);
       if (entry != NumberDictionary::kNotFound) {
-        return dictionary->DeleteProperty(entry, mode);
+        Object* deleted = dictionary->DeleteProperty(entry, mode);
+        if (deleted == GetHeap()->true_value()) {
+          MaybeObject* maybe_elements = dictionary->Shrink(index);
+          FixedArray* new_elements = NULL;
+          if (!maybe_elements->To(&new_elements)) {
+            return maybe_elements;
+          }
+          set_elements(new_elements);
+        }
+        return deleted;
       }
       break;
     }
@@ -2850,6 +3085,93 @@
 }
 
 
+MaybeObject* JSObject::DeleteFastElement(uint32_t index) {
+  ASSERT(HasFastElements() || HasFastArgumentsElements());
+  Heap* heap = GetHeap();
+  FixedArray* backing_store = FixedArray::cast(elements());
+  if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
+    backing_store = FixedArray::cast(backing_store->get(1));
+  } else {
+    Object* writable;
+    MaybeObject* maybe = EnsureWritableFastElements();
+    if (!maybe->ToObject(&writable)) return maybe;
+    backing_store = FixedArray::cast(writable);
+  }
+  uint32_t length = static_cast<uint32_t>(
+      IsJSArray()
+      ? Smi::cast(JSArray::cast(this)->length())->value()
+      : backing_store->length());
+  if (index < length) {
+    backing_store->set_the_hole(index);
+    // If an old space backing store is larger than a certain size and
+    // has too few used values, normalize it.
+    // To avoid doing the check on every delete we require at least
+    // one adjacent hole to the value being deleted.
+    Object* hole = heap->the_hole_value();
+    const int kMinLengthForSparsenessCheck = 64;
+    if (backing_store->length() >= kMinLengthForSparsenessCheck &&
+        !heap->InNewSpace(backing_store) &&
+        ((index > 0 && backing_store->get(index - 1) == hole) ||
+         (index + 1 < length && backing_store->get(index + 1) == hole))) {
+      int num_used = 0;
+      for (int i = 0; i < backing_store->length(); ++i) {
+        if (backing_store->get(i) != hole) ++num_used;
+        // Bail out early if more than 1/4 is used.
+        if (4 * num_used > backing_store->length()) break;
+      }
+      if (4 * num_used <= backing_store->length()) {
+        MaybeObject* result = NormalizeElements();
+        if (result->IsFailure()) return result;
+      }
+    }
+  }
+  return heap->true_value();
+}
+
+
+MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index,
+                                               DeleteMode mode) {
+  Isolate* isolate = GetIsolate();
+  Heap* heap = isolate->heap();
+  FixedArray* backing_store = FixedArray::cast(elements());
+  bool is_arguments =
+      (GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
+  if (is_arguments) {
+    backing_store = FixedArray::cast(backing_store->get(1));
+  }
+  NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
+  int entry = dictionary->FindEntry(index);
+  if (entry != NumberDictionary::kNotFound) {
+    Object* result = dictionary->DeleteProperty(entry, mode);
+    if (result == heap->true_value()) {
+      MaybeObject* maybe_elements = dictionary->Shrink(index);
+      FixedArray* new_elements = NULL;
+      if (!maybe_elements->To(&new_elements)) {
+        return maybe_elements;
+      }
+      if (is_arguments) {
+        FixedArray::cast(elements())->set(1, new_elements);
+      } else {
+        set_elements(new_elements);
+      }
+    }
+    if (mode == STRICT_DELETION && result == heap->false_value()) {
+      // In strict mode, attempting to delete a non-configurable property
+      // throws an exception.
+      HandleScope scope(isolate);
+      Handle<Object> holder(this);
+      Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
+      Handle<Object> args[2] = { name, holder };
+      Handle<Object> error =
+          isolate->factory()->NewTypeError("strict_delete_property",
+                                           HandleVector(args, 2));
+      return isolate->Throw(*error);
+    }
+  }
+  return heap->true_value();
+}
+
+
 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
   Isolate* isolate = GetIsolate();
   // Check access rights if needed.
@@ -2868,23 +3190,24 @@
 
   if (HasIndexedInterceptor()) {
     // Skip interceptor if forcing deletion.
-    if (mode == FORCE_DELETION) {
-      return DeleteElementPostInterceptor(index, mode);
-    }
-    return DeleteElementWithInterceptor(index);
+    return (mode == FORCE_DELETION)
+        ? DeleteElementPostInterceptor(index, FORCE_DELETION)
+        : DeleteElementWithInterceptor(index);
   }
 
   switch (GetElementsKind()) {
-    case FAST_ELEMENTS: {
-      Object* obj;
-      { MaybeObject* maybe_obj = EnsureWritableFastElements();
-        if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-      }
-      uint32_t length = IsJSArray() ?
-      static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
-      static_cast<uint32_t>(FixedArray::cast(elements())->length());
-      if (index < length) {
-        FixedArray::cast(elements())->set_the_hole(index);
+    case FAST_ELEMENTS:
+      return DeleteFastElement(index);
+
+    case DICTIONARY_ELEMENTS:
+      return DeleteDictionaryElement(index, mode);
+
+    case FAST_DOUBLE_ELEMENTS: {
+      int length = IsJSArray()
+          ? Smi::cast(JSArray::cast(this)->length())->value()
+          : FixedDoubleArray::cast(elements())->length();
+      if (index < static_cast<uint32_t>(length)) {
+        FixedDoubleArray::cast(elements())->set_the_hole(index);
       }
       break;
     }
@@ -2900,34 +3223,41 @@
       // Pixel and external array elements cannot be deleted. Just
       // silently ignore here.
       break;
-    case DICTIONARY_ELEMENTS: {
-      NumberDictionary* dictionary = element_dictionary();
-      int entry = dictionary->FindEntry(index);
-      if (entry != NumberDictionary::kNotFound) {
-        Object* result = dictionary->DeleteProperty(entry, mode);
-        if (mode == STRICT_DELETION && result ==
-            isolate->heap()->false_value()) {
-          // In strict mode, deleting a non-configurable property throws
-          // exception. dictionary->DeleteProperty will return false_value()
-          // if a non-configurable property is being deleted.
-          HandleScope scope;
-          Handle<Object> self(this);
-          Handle<Object> i = isolate->factory()->NewNumberFromUint(index);
-          Handle<Object> args[2] = { i, self };
-          return isolate->Throw(*isolate->factory()->NewTypeError(
-              "strict_delete_property", HandleVector(args, 2)));
+
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      uint32_t length = parameter_map->length();
+      Object* probe =
+          index < (length - 2) ? parameter_map->get(index + 2) : NULL;
+      if (probe != NULL && !probe->IsTheHole()) {
+        // TODO(kmillikin): We could check if this was the last aliased
+        // parameter, and revert to normal elements in that case.  That
+        // would enable GC of the context.
+        parameter_map->set_the_hole(index + 2);
+      } else {
+        FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+        if (arguments->IsDictionary()) {
+          return DeleteDictionaryElement(index, mode);
+        } else {
+          return DeleteFastElement(index);
         }
       }
       break;
     }
-    default:
-      UNREACHABLE();
-      break;
   }
   return isolate->heap()->true_value();
 }
 
 
+MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
+  if (IsJSProxy()) {
+    return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
+  } else {
+    return JSObject::cast(this)->DeleteProperty(name, mode);
+  }
+}
+
+
 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
   Isolate* isolate = GetIsolate();
   // ECMA-262, 3rd, 8.6.2.5
@@ -2985,6 +3315,26 @@
 }
 
 
+bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
+                                            ElementsKind kind,
+                                            Object* object) {
+  ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
+  if (kind == FAST_ELEMENTS) {
+    int length = IsJSArray()
+        ? Smi::cast(JSArray::cast(this)->length())->value()
+        : elements->length();
+    for (int i = 0; i < length; ++i) {
+      Object* element = elements->get(i);
+      if (!element->IsTheHole() && element == object) return true;
+    }
+  } else {
+    Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
+    if (!key->IsUndefined()) return true;
+  }
+  return false;
+}
+
+
 // Check whether this object references another object.
 bool JSObject::ReferencesObject(Object* obj) {
   Map* map_of_this = map();
@@ -3008,7 +3358,8 @@
   }
 
   // Check if the object is among the indexed properties.
-  switch (GetElementsKind()) {
+  ElementsKind kind = GetElementsKind();
+  switch (kind) {
     case EXTERNAL_PIXEL_ELEMENTS:
     case EXTERNAL_BYTE_ELEMENTS:
     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
@@ -3018,31 +3369,30 @@
     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
     case EXTERNAL_FLOAT_ELEMENTS:
     case EXTERNAL_DOUBLE_ELEMENTS:
+    case FAST_DOUBLE_ELEMENTS:
       // Raw pixels and external arrays do not reference other
       // objects.
       break;
-    case FAST_ELEMENTS: {
-      int length = IsJSArray() ?
-          Smi::cast(JSArray::cast(this)->length())->value() :
-          FixedArray::cast(elements())->length();
-      for (int i = 0; i < length; i++) {
-        Object* element = FixedArray::cast(elements())->get(i);
-        if (!element->IsTheHole() && element == obj) {
-          return true;
-        }
-      }
-      break;
-    }
+    case FAST_ELEMENTS:
     case DICTIONARY_ELEMENTS: {
-      key = element_dictionary()->SlowReverseLookup(obj);
-      if (!key->IsUndefined()) {
-        return true;
-      }
+      FixedArray* elements = FixedArray::cast(this->elements());
+      if (ReferencesObjectFromElements(elements, kind, obj)) return true;
       break;
     }
-    default:
-      UNREACHABLE();
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      // Check the mapped parameters.
+      int length = parameter_map->length();
+      for (int i = 2; i < length; ++i) {
+        Object* value = parameter_map->get(i);
+        if (!value->IsTheHole() && value == obj) return true;
+      }
+      // Check the arguments.
+      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+      kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
+      if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
       break;
+    }
   }
 
   // For functions check the context.
@@ -3077,9 +3427,9 @@
       }
     }
 
-    // Check the context extension if any.
-    if (context->has_extension()) {
-      return context->extension()->ReferencesObject(obj);
+    // Check the context extension (if any) if it can have references.
+    if (context->has_extension() && !context->IsCatchContext()) {
+      return JSObject::cast(context->extension())->ReferencesObject(obj);
     }
   }
 
@@ -3117,23 +3467,22 @@
   }
 
   // If there are fast elements we normalize.
-  if (HasFastElements()) {
-    Object* ok;
-    { MaybeObject* maybe_ok = NormalizeElements();
-      if (!maybe_ok->ToObject(&ok)) return maybe_ok;
-    }
+  NumberDictionary* dictionary = NULL;
+  { MaybeObject* maybe = NormalizeElements();
+    if (!maybe->To<NumberDictionary>(&dictionary)) return maybe;
   }
+  ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
   // Make sure that we never go back to fast case.
-  element_dictionary()->set_requires_slow_elements();
+  dictionary->set_requires_slow_elements();
 
   // Do a map transition, other objects with this map may still
   // be extensible.
-  Object* new_map;
-  { MaybeObject* maybe_new_map = map()->CopyDropTransitions();
-    if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
+  Map* new_map;
+  { MaybeObject* maybe = map()->CopyDropTransitions();
+    if (!maybe->To<Map>(&new_map)) return maybe;
   }
-  Map::cast(new_map)->set_is_extensible(false);
-  set_map(Map::cast(new_map));
+  new_map->set_is_extensible(false);
+  set_map(new_map);
   ASSERT(!map()->is_extensible());
   return new_map;
 }
@@ -3210,6 +3559,15 @@
 }
 
 
+void JSReceiver::LocalLookup(String* name, LookupResult* result) {
+  if (IsJSProxy()) {
+    result->HandlerResult();
+  } else {
+    JSObject::cast(this)->LocalLookup(name, result);
+  }
+}
+
+
 void JSObject::LocalLookup(String* name, LookupResult* result) {
   ASSERT(name->IsString());
 
@@ -3229,8 +3587,7 @@
   }
 
   // Check __proto__ before interceptor.
-  if (name->Equals(heap->Proto_symbol()) &&
-      !IsJSContextExtensionObject()) {
+  if (name->Equals(heap->Proto_symbol()) && !IsJSContextExtensionObject()) {
     result->ConstantResult(this);
     return;
   }
@@ -3245,7 +3602,7 @@
 }
 
 
-void JSObject::Lookup(String* name, LookupResult* result) {
+void JSReceiver::Lookup(String* name, LookupResult* result) {
   // Ecma-262 3rd 8.6.2.4
   Heap* heap = GetHeap();
   for (Object* current = this;
@@ -3271,6 +3628,24 @@
 }
 
 
+// Search for a getter or setter in an elements dictionary.  Returns either
+// undefined if the element is read-only, or the getter/setter pair (fixed
+// array) if there is an existing one, or the hole value if the element does
+// not exist or is a normal non-getter/setter data element.
+static Object* FindGetterSetterInDictionary(NumberDictionary* dictionary,
+                                            uint32_t index,
+                                            Heap* heap) {
+  int entry = dictionary->FindEntry(index);
+  if (entry != NumberDictionary::kNotFound) {
+    Object* result = dictionary->ValueAt(entry);
+    PropertyDetails details = dictionary->DetailsAt(entry);
+    if (details.IsReadOnly()) return heap->undefined_value();
+    if (details.type() == CALLBACKS && result->IsFixedArray()) return result;
+  }
+  return heap->the_hole_value();
+}
+
+
 MaybeObject* JSObject::DefineGetterSetter(String* name,
                                           PropertyAttributes attributes) {
   Heap* heap = GetHeap();
@@ -3301,29 +3676,35 @@
       case EXTERNAL_UNSIGNED_INT_ELEMENTS:
       case EXTERNAL_FLOAT_ELEMENTS:
       case EXTERNAL_DOUBLE_ELEMENTS:
+      case FAST_DOUBLE_ELEMENTS:
         // Ignore getters and setters on pixel and external array
         // elements.
         return heap->undefined_value();
       case DICTIONARY_ELEMENTS: {
-        // Lookup the index.
-        NumberDictionary* dictionary = element_dictionary();
-        int entry = dictionary->FindEntry(index);
-        if (entry != NumberDictionary::kNotFound) {
-          Object* result = dictionary->ValueAt(entry);
-          PropertyDetails details = dictionary->DetailsAt(entry);
-          if (details.IsReadOnly()) return heap->undefined_value();
-          if (details.type() == CALLBACKS) {
-            if (result->IsFixedArray()) {
-              return result;
-            }
-            // Otherwise allow to override it.
+        Object* probe =
+            FindGetterSetterInDictionary(element_dictionary(), index, heap);
+        if (!probe->IsTheHole()) return probe;
+        // Otherwise allow to override it.
+        break;
+      }
+      case NON_STRICT_ARGUMENTS_ELEMENTS: {
+        // Ascertain whether we have read-only properties or an existing
+        // getter/setter pair in an arguments elements dictionary backing
+        // store.
+        FixedArray* parameter_map = FixedArray::cast(elements());
+        uint32_t length = parameter_map->length();
+        Object* probe =
+            index < (length - 2) ? parameter_map->get(index + 2) : NULL;
+        if (probe == NULL || probe->IsTheHole()) {
+          FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+          if (arguments->IsDictionary()) {
+            NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+            probe = FindGetterSetterInDictionary(dictionary, index, heap);
+            if (!probe->IsTheHole()) return probe;
           }
         }
         break;
       }
-      default:
-        UNREACHABLE();
-        break;
     }
   } else {
     // Lookup the name.
@@ -3386,22 +3767,38 @@
   PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
 
   // Normalize elements to make this operation simple.
-  Object* ok;
-  { MaybeObject* maybe_ok = NormalizeElements();
-    if (!maybe_ok->ToObject(&ok)) return maybe_ok;
+  NumberDictionary* dictionary = NULL;
+  { Object* result;
+    MaybeObject* maybe = NormalizeElements();
+    if (!maybe->ToObject(&result)) return maybe;
+    dictionary = NumberDictionary::cast(result);
   }
+  ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
 
   // Update the dictionary with the new CALLBACKS property.
-  Object* dict;
-  { MaybeObject* maybe_dict =
-        element_dictionary()->Set(index, structure, details);
-    if (!maybe_dict->ToObject(&dict)) return maybe_dict;
+  { Object* result;
+    MaybeObject* maybe = dictionary->Set(index, structure, details);
+    if (!maybe->ToObject(&result)) return maybe;
+    dictionary = NumberDictionary::cast(result);
   }
 
-  NumberDictionary* elements = NumberDictionary::cast(dict);
-  elements->set_requires_slow_elements();
-  // Set the potential new dictionary on the object.
-  set_elements(elements);
+  dictionary->set_requires_slow_elements();
+  // Update the dictionary backing store on the object.
+  if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) {
+    // Also delete any parameter alias.
+    //
+    // TODO(kmillikin): when deleting the last parameter alias we could
+    // switch to a direct backing store without the parameter map.  This
+    // would allow GC of the context.
+    FixedArray* parameter_map = FixedArray::cast(elements());
+    uint32_t length = parameter_map->length();
+    if (index < length - 2) {
+      parameter_map->set(index + 2, GetHeap()->the_hole_value());
+    }
+    parameter_map->set(1, dictionary);
+  } else {
+    set_elements(dictionary);
+  }
 
   return structure;
 }
@@ -3528,13 +3925,14 @@
       case EXTERNAL_UNSIGNED_INT_ELEMENTS:
       case EXTERNAL_FLOAT_ELEMENTS:
       case EXTERNAL_DOUBLE_ELEMENTS:
+      case FAST_DOUBLE_ELEMENTS:
         // Ignore getters and setters on pixel and external array
         // elements.
         return isolate->heap()->undefined_value();
       case DICTIONARY_ELEMENTS:
         break;
-      default:
-        UNREACHABLE();
+      case NON_STRICT_ARGUMENTS_ELEMENTS:
+        UNIMPLEMENTED();
         break;
     }
 
@@ -3819,7 +4217,7 @@
     Object** proto_map_or_index_field =
         RawField(prototype_transitions, HeapObject::kMapOffset);
     Object* map_or_index = *proto_map_or_index_field;
-    const int start = 2;
+    const int start = kProtoTransitionHeaderSize + kProtoTransitionMapOffset;
     int i = map_or_index->IsSmi() ? Smi::cast(map_or_index)->value() : start;
     if (i < prototype_transitions->length()) {
       // Found a map in the prototype transition array.  Record progress in
@@ -3829,7 +4227,7 @@
         Map* next = Map::cast(perhaps_map);
         next->set_map(current);
         *proto_map_or_index_field =
-            Smi::FromInt(i + 2);
+            Smi::FromInt(i + kProtoTransitionElementsPerEntry);
         current = next;
         continue;
       }
@@ -4071,6 +4469,7 @@
  private:
   String* name_;
   Code::Flags flags_;
+  // TODO(jkummerow): We should be able to get by without this.
   Code* code_;
 };
 
@@ -4090,7 +4489,7 @@
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
 
-  // Don't use this, as the table might have grown.
+  // Don't use |this|, as the table might have grown.
   CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj);
 
   int entry = cache->FindInsertionEntry(key.Hash());
@@ -4136,6 +4535,164 @@
 }
 
 
+MaybeObject* PolymorphicCodeCache::Update(MapList* maps,
+                                          Code::Flags flags,
+                                          Code* code) {
+  // Initialize cache if necessary.
+  if (cache()->IsUndefined()) {
+    Object* result;
+    { MaybeObject* maybe_result =
+          PolymorphicCodeCacheHashTable::Allocate(
+              PolymorphicCodeCacheHashTable::kInitialSize);
+      if (!maybe_result->ToObject(&result)) return maybe_result;
+    }
+    set_cache(result);
+  } else {
+    // This entry shouldn't be contained in the cache yet.
+    ASSERT(PolymorphicCodeCacheHashTable::cast(cache())
+               ->Lookup(maps, flags)->IsUndefined());
+  }
+  PolymorphicCodeCacheHashTable* hash_table =
+      PolymorphicCodeCacheHashTable::cast(cache());
+  Object* new_cache;
+  { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code);
+    if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache;
+  }
+  set_cache(new_cache);
+  return this;
+}
+
+
+Object* PolymorphicCodeCache::Lookup(MapList* maps, Code::Flags flags) {
+  if (!cache()->IsUndefined()) {
+    PolymorphicCodeCacheHashTable* hash_table =
+        PolymorphicCodeCacheHashTable::cast(cache());
+    return hash_table->Lookup(maps, flags);
+  } else {
+    return GetHeap()->undefined_value();
+  }
+}
+
+
+// Despite their name, object of this class are not stored in the actual
+// hash table; instead they're temporarily used for lookups. It is therefore
+// safe to have a weak (non-owning) pointer to a MapList as a member field.
+class PolymorphicCodeCacheHashTableKey : public HashTableKey {
+ public:
+  // Callers must ensure that |maps| outlives the newly constructed object.
+  PolymorphicCodeCacheHashTableKey(MapList* maps, int code_flags)
+      : maps_(maps),
+        code_flags_(code_flags) {}
+
+  bool IsMatch(Object* other) {
+    MapList other_maps(kDefaultListAllocationSize);
+    int other_flags;
+    FromObject(other, &other_flags, &other_maps);
+    if (code_flags_ != other_flags) return false;
+    if (maps_->length() != other_maps.length()) return false;
+    // Compare just the hashes first because it's faster.
+    int this_hash = MapsHashHelper(maps_, code_flags_);
+    int other_hash = MapsHashHelper(&other_maps, other_flags);
+    if (this_hash != other_hash) return false;
+
+    // Full comparison: for each map in maps_, look for an equivalent map in
+    // other_maps. This implementation is slow, but probably good enough for
+    // now because the lists are short (<= 4 elements currently).
+    for (int i = 0; i < maps_->length(); ++i) {
+      bool match_found = false;
+      for (int j = 0; j < other_maps.length(); ++j) {
+        if (maps_->at(i)->EquivalentTo(other_maps.at(j))) {
+          match_found = true;
+          break;
+        }
+      }
+      if (!match_found) return false;
+    }
+    return true;
+  }
+
+  static uint32_t MapsHashHelper(MapList* maps, int code_flags) {
+    uint32_t hash = code_flags;
+    for (int i = 0; i < maps->length(); ++i) {
+      hash ^= maps->at(i)->Hash();
+    }
+    return hash;
+  }
+
+  uint32_t Hash() {
+    return MapsHashHelper(maps_, code_flags_);
+  }
+
+  uint32_t HashForObject(Object* obj) {
+    MapList other_maps(kDefaultListAllocationSize);
+    int other_flags;
+    FromObject(obj, &other_flags, &other_maps);
+    return MapsHashHelper(&other_maps, other_flags);
+  }
+
+  MUST_USE_RESULT MaybeObject* AsObject() {
+    Object* obj;
+    // The maps in |maps_| must be copied to a newly allocated FixedArray,
+    // both because the referenced MapList is short-lived, and because C++
+    // objects can't be stored in the heap anyway.
+    { MaybeObject* maybe_obj =
+        HEAP->AllocateUninitializedFixedArray(maps_->length() + 1);
+      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+    }
+    FixedArray* list = FixedArray::cast(obj);
+    list->set(0, Smi::FromInt(code_flags_));
+    for (int i = 0; i < maps_->length(); ++i) {
+      list->set(i + 1, maps_->at(i));
+    }
+    return list;
+  }
+
+ private:
+  static MapList* FromObject(Object* obj, int* code_flags, MapList* maps) {
+    FixedArray* list = FixedArray::cast(obj);
+    maps->Rewind(0);
+    *code_flags = Smi::cast(list->get(0))->value();
+    for (int i = 1; i < list->length(); ++i) {
+      maps->Add(Map::cast(list->get(i)));
+    }
+    return maps;
+  }
+
+  MapList* maps_;  // weak.
+  int code_flags_;
+  static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1;
+};
+
+
+Object* PolymorphicCodeCacheHashTable::Lookup(MapList* maps, int code_flags) {
+  PolymorphicCodeCacheHashTableKey key(maps, code_flags);
+  int entry = FindEntry(&key);
+  if (entry == kNotFound) return GetHeap()->undefined_value();
+  return get(EntryToIndex(entry) + 1);
+}
+
+
+MaybeObject* PolymorphicCodeCacheHashTable::Put(MapList* maps,
+                                                int code_flags,
+                                                Code* code) {
+  PolymorphicCodeCacheHashTableKey key(maps, code_flags);
+  Object* obj;
+  { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  }
+  PolymorphicCodeCacheHashTable* cache =
+      reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj);
+  int entry = cache->FindInsertionEntry(key.Hash());
+  { MaybeObject* maybe_obj = key.AsObject();
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  }
+  cache->set(EntryToIndex(entry), obj);
+  cache->set(EntryToIndex(entry) + 1, code);
+  cache->ElementAdded();
+  return cache;
+}
+
+
 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
   ASSERT(!array->HasExternalArrayElements());
   switch (array->GetElementsKind()) {
@@ -4163,8 +4720,20 @@
       // Compute the union of this and the temporary fixed array.
       return UnionOfKeys(key_array);
     }
-    default:
-      UNREACHABLE();
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNIMPLEMENTED();
+      break;
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+      break;
   }
   UNREACHABLE();
   return GetHeap()->null_value();  // Failure case needs to "return" a value.
@@ -5547,16 +6116,11 @@
 bool String::IsAsciiEqualTo(Vector<const char> str) {
   int slen = length();
   if (str.length() != slen) return false;
-  if (this->IsSeqAsciiString()) {
-    SeqAsciiString* seq = SeqAsciiString::cast(this);
-    char* ch = seq->GetChars();
-    for (int i = 0; i < slen; i++, ch++) {
-      if (*ch != str[i]) return false;
-    }
-  } else {
-    for (int i = 0; i < slen; i++) {
-      if (Get(i) != static_cast<uint16_t>(str[i])) return false;
-    }
+  if (IsFlat() && IsAsciiRepresentation()) {
+    return CompareChars(ToAsciiVector().start(), str.start(), slen) == 0;
+  }
+  for (int i = 0; i < slen; i++) {
+    if (Get(i) != static_cast<uint16_t>(str[i])) return false;
   }
   return true;
 }
@@ -5565,6 +6129,9 @@
 bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
   int slen = length();
   if (str.length() != slen) return false;
+  if (IsFlat() && IsTwoByteRepresentation()) {
+    return CompareChars(ToUC16Vector().start(), str.start(), slen) == 0;
+  }
   for (int i = 0; i < slen; i++) {
     if (Get(i) != str[i]) return false;
   }
@@ -5783,6 +6350,40 @@
 }
 
 
+int Map::Hash() {
+  // For performance reasons we only hash the 3 most variable fields of a map:
+  // constructor, prototype and bit_field2.
+
+  // Shift away the tag.
+  int hash = (static_cast<uint32_t>(
+        reinterpret_cast<uintptr_t>(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);
+
+  return hash ^ (hash >> 16) ^ bit_field2();
+}
+
+
+bool Map::EquivalentToForNormalization(Map* other,
+                                       PropertyNormalizationMode mode) {
+  return
+    constructor() == other->constructor() &&
+    prototype() == other->prototype() &&
+    inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ?
+                              0 :
+                              other->inobject_properties()) &&
+    instance_type() == other->instance_type() &&
+    bit_field() == other->bit_field() &&
+    bit_field2() == other->bit_field2() &&
+    (bit_field3() & ~(1<<Map::kIsShared)) ==
+        (other->bit_field3() & ~(1<<Map::kIsShared));
+}
+
+
 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
   // Iterate over all fields in the body but take care in dealing with
   // the code entry.
@@ -5801,19 +6402,6 @@
 }
 
 
-uint32_t JSFunction::SourceHash() {
-  uint32_t hash = 0;
-  Object* script = shared()->script();
-  if (!script->IsUndefined()) {
-    Object* source = Script::cast(script)->source();
-    if (source->IsUndefined()) hash = String::cast(source)->Hash();
-  }
-  hash ^= ComputeIntegerHash(shared()->start_position_and_type());
-  hash += ComputeIntegerHash(shared()->end_position());
-  return hash;
-}
-
-
 bool JSFunction::IsInlineable() {
   if (IsBuiltin()) return false;
   SharedFunctionInfo* shared_info = shared();
@@ -6281,6 +6869,7 @@
   if (slack != 0) {
     // Resize the initial map and all maps in its transition tree.
     map->TraverseTransitionTree(&ShrinkInstanceSize, &slack);
+
     // Give the correct expected_nof_properties to initial maps created later.
     ASSERT(expected_nof_properties() >= slack);
     set_expected_nof_properties(expected_nof_properties() - slack);
@@ -6465,8 +7054,6 @@
 
 #ifdef ENABLE_DISASSEMBLER
 
-#ifdef OBJECT_PRINT
-
 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
   disasm::NameConverter converter;
   int deopt_count = DeoptCount();
@@ -6613,8 +7200,6 @@
   }
 }
 
-#endif
-
 
 // Identify kind of code.
 const char* Code::Kind2String(Kind kind) {
@@ -6691,7 +7276,7 @@
   if (name != NULL) {
     PrintF(out, "extra_ic_state = %s\n", name);
   } else {
-    PrintF(out, "etra_ic_state = %d\n", extra);
+    PrintF(out, "extra_ic_state = %d\n", extra);
   }
 }
 
@@ -6705,6 +7290,9 @@
     if (ic_state() == MONOMORPHIC) {
       PrintF(out, "type = %s\n", PropertyType2String(type()));
     }
+    if (is_call_stub() || is_keyed_call_stub()) {
+      PrintF(out, "argc = %d\n", arguments_count());
+    }
   }
   if ((name != NULL) && (name[0] != '\0')) {
     PrintF(out, "name = %s\n", name);
@@ -6717,7 +7305,6 @@
   Disassembler::Decode(out, this);
   PrintF(out, "\n");
 
-#ifdef DEBUG
   if (kind() == FUNCTION) {
     DeoptimizationOutputData* data =
         DeoptimizationOutputData::cast(this->deoptimization_data());
@@ -6728,7 +7315,6 @@
     data->DeoptimizationInputDataPrint(out);
   }
   PrintF("\n");
-#endif
 
   if (kind() == OPTIMIZED_FUNCTION) {
     SafepointTable table(this);
@@ -6775,44 +7361,166 @@
 #endif  // ENABLE_DISASSEMBLER
 
 
+static void CopyFastElementsToFast(FixedArray* source,
+                                   FixedArray* destination,
+                                   WriteBarrierMode mode) {
+  uint32_t count = static_cast<uint32_t>(source->length());
+  for (uint32_t i = 0; i < count; ++i) {
+    destination->set(i, source->get(i), mode);
+  }
+}
+
+
+static void CopySlowElementsToFast(NumberDictionary* source,
+                                   FixedArray* destination,
+                                   WriteBarrierMode mode) {
+  for (int i = 0; i < source->Capacity(); ++i) {
+    Object* key = source->KeyAt(i);
+    if (key->IsNumber()) {
+      uint32_t entry = static_cast<uint32_t>(key->Number());
+      destination->set(entry, source->ValueAt(i), mode);
+    }
+  }
+}
+
+
 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity,
                                                         int length) {
   Heap* heap = GetHeap();
   // We should never end in here with a pixel or external array.
   ASSERT(!HasExternalArrayElements());
 
+  // Allocate a new fast elements backing store.
+  FixedArray* new_elements = NULL;
+  { Object* object;
+    MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity);
+    if (!maybe->ToObject(&object)) return maybe;
+    new_elements = FixedArray::cast(object);
+  }
+
+  // Find the new map to use for this object if there is a map change.
+  Map* new_map = NULL;
+  if (elements()->map() != heap->non_strict_arguments_elements_map()) {
+    Object* object;
+    MaybeObject* maybe = map()->GetFastElementsMap();
+    if (!maybe->ToObject(&object)) return maybe;
+    new_map = Map::cast(object);
+  }
+
+  switch (GetElementsKind()) {
+    case FAST_ELEMENTS: {
+      AssertNoAllocation no_gc;
+      WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
+      CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode);
+      set_map(new_map);
+      set_elements(new_elements);
+      break;
+    }
+    case DICTIONARY_ELEMENTS: {
+      AssertNoAllocation no_gc;
+      WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
+      CopySlowElementsToFast(NumberDictionary::cast(elements()),
+                             new_elements,
+                             mode);
+      set_map(new_map);
+      set_elements(new_elements);
+      break;
+    }
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      AssertNoAllocation no_gc;
+      WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
+      // The object's map and the parameter map are unchanged, the unaliased
+      // arguments are copied to the new backing store.
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+      if (arguments->IsDictionary()) {
+        CopySlowElementsToFast(NumberDictionary::cast(arguments),
+                               new_elements,
+                               mode);
+      } else {
+        CopyFastElementsToFast(arguments, new_elements, mode);
+      }
+      parameter_map->set(1, new_elements);
+      break;
+    }
+    case FAST_DOUBLE_ELEMENTS: {
+      FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements());
+      uint32_t old_length = static_cast<uint32_t>(old_elements->length());
+      // Fill out the new array with this content and array holes.
+      for (uint32_t i = 0; i < old_length; i++) {
+        if (!old_elements->is_the_hole(i)) {
+          Object* obj;
+          // Objects must be allocated in the old object space, since the
+          // overall number of HeapNumbers needed for the conversion might
+          // exceed the capacity of new space, and we would fail repeatedly
+          // trying to convert the FixedDoubleArray.
+          MaybeObject* maybe_value_object =
+              GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED);
+          if (!maybe_value_object->ToObject(&obj)) return maybe_value_object;
+          // Force write barrier. It's not worth trying to exploit
+          // elems->GetWriteBarrierMode(), since it requires an
+          // AssertNoAllocation stack object that would have to be positioned
+          // after the HeapNumber allocation anyway.
+          new_elements->set(i, obj, UPDATE_WRITE_BARRIER);
+        }
+      }
+      set_map(new_map);
+      set_elements(new_elements);
+      break;
+    }
+    case EXTERNAL_BYTE_ELEMENTS:
+    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case EXTERNAL_SHORT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case EXTERNAL_INT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case EXTERNAL_FLOAT_ELEMENTS:
+    case EXTERNAL_DOUBLE_ELEMENTS:
+    case EXTERNAL_PIXEL_ELEMENTS:
+      UNREACHABLE();
+      break;
+  }
+
+  // Update the length if necessary.
+  if (IsJSArray()) {
+    JSArray::cast(this)->set_length(Smi::FromInt(length));
+  }
+
+  return new_elements;
+}
+
+
+MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
+    int capacity,
+    int length) {
+  Heap* heap = GetHeap();
+  // We should never end in here with a pixel or external array.
+  ASSERT(!HasExternalArrayElements());
+
   Object* obj;
-  { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity);
+  { MaybeObject* maybe_obj =
+        heap->AllocateUninitializedFixedDoubleArray(capacity);
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
-  FixedArray* elems = FixedArray::cast(obj);
+  FixedDoubleArray* elems = FixedDoubleArray::cast(obj);
 
-  { MaybeObject* maybe_obj = map()->GetFastElementsMap();
+  { MaybeObject* maybe_obj = map()->GetFastDoubleElementsMap();
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
   Map* new_map = Map::cast(obj);
 
   AssertNoAllocation no_gc;
-  WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc);
   switch (GetElementsKind()) {
     case FAST_ELEMENTS: {
-      FixedArray* old_elements = FixedArray::cast(elements());
-      uint32_t old_length = static_cast<uint32_t>(old_elements->length());
-      // Fill out the new array with this content and array holes.
-      for (uint32_t i = 0; i < old_length; i++) {
-        elems->set(i, old_elements->get(i), mode);
-      }
+      elems->Initialize(FixedArray::cast(elements()));
+      break;
+    }
+    case FAST_DOUBLE_ELEMENTS: {
+      elems->Initialize(FixedDoubleArray::cast(elements()));
       break;
     }
     case DICTIONARY_ELEMENTS: {
-      NumberDictionary* dictionary = NumberDictionary::cast(elements());
-      for (int i = 0; i < dictionary->Capacity(); i++) {
-        Object* key = dictionary->KeyAt(i);
-        if (key->IsNumber()) {
-          uint32_t entry = static_cast<uint32_t>(key->Number());
-          elems->set(entry, dictionary->ValueAt(i), mode);
-        }
-      }
+      elems->Initialize(NumberDictionary::cast(elements()));
       break;
     }
     default:
@@ -6820,7 +7528,9 @@
       break;
   }
 
+  ASSERT(new_map->has_fast_double_elements());
   set_map(new_map);
+  ASSERT(elems->IsFixedDoubleArray());
   set_elements(elems);
 
   if (IsJSArray()) {
@@ -6842,10 +7552,8 @@
       // Make sure we never try to shrink dense arrays into sparse arrays.
       ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <=
                                    new_length);
-      Object* obj;
-      { MaybeObject* maybe_obj = NormalizeElements();
-        if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-      }
+      MaybeObject* result = NormalizeElements();
+      if (result->IsFailure()) return result;
 
       // Update length for JSArrays.
       if (IsJSArray()) JSArray::cast(this)->set_length(len);
@@ -6860,7 +7568,19 @@
       }
       break;
     }
-    default:
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNIMPLEMENTED();
+      break;
+    case EXTERNAL_BYTE_ELEMENTS:
+    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+    case EXTERNAL_SHORT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+    case EXTERNAL_INT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case EXTERNAL_FLOAT_ELEMENTS:
+    case EXTERNAL_DOUBLE_ELEMENTS:
+    case EXTERNAL_PIXEL_ELEMENTS:
+    case FAST_DOUBLE_ELEMENTS:
       UNREACHABLE();
       break;
   }
@@ -6900,7 +7620,7 @@
 
 
 static Failure* ArrayLengthRangeError(Heap* heap) {
-  HandleScope scope;
+  HandleScope scope(heap->isolate());
   return heap->isolate()->Throw(
       *FACTORY->NewRangeError("invalid_array_length",
           HandleVector<Object>(NULL, 0)));
@@ -6916,21 +7636,58 @@
   if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
     const int value = Smi::cast(smi_length)->value();
     if (value < 0) return ArrayLengthRangeError(GetHeap());
-    switch (GetElementsKind()) {
-      case FAST_ELEMENTS: {
-        int old_capacity = FixedArray::cast(elements())->length();
+    JSObject::ElementsKind elements_kind = GetElementsKind();
+    switch (elements_kind) {
+      case FAST_ELEMENTS:
+      case FAST_DOUBLE_ELEMENTS: {
+        int old_capacity = FixedArrayBase::cast(elements())->length();
         if (value <= old_capacity) {
           if (IsJSArray()) {
             Object* obj;
-            { MaybeObject* maybe_obj = EnsureWritableFastElements();
+            if (elements_kind == FAST_ELEMENTS) {
+              MaybeObject* maybe_obj = EnsureWritableFastElements();
               if (!maybe_obj->ToObject(&obj)) return maybe_obj;
             }
-            int old_length = FastD2I(JSArray::cast(this)->length()->Number());
-            // NOTE: We may be able to optimize this by removing the
-            // last part of the elements backing storage array and
-            // setting the capacity to the new size.
-            for (int i = value; i < old_length; i++) {
-              FixedArray::cast(elements())->set_the_hole(i);
+            if (2 * value <= old_capacity) {
+              // If more than half the elements won't be used, trim the array.
+              if (value == 0) {
+                initialize_elements();
+              } else {
+                Address filler_start;
+                int filler_size;
+                if (GetElementsKind() == FAST_ELEMENTS) {
+                  FixedArray* fast_elements = FixedArray::cast(elements());
+                  fast_elements->set_length(value);
+                  filler_start = fast_elements->address() +
+                      FixedArray::OffsetOfElementAt(value);
+                  filler_size = (old_capacity - value) * kPointerSize;
+                } else {
+                  ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
+                  FixedDoubleArray* fast_double_elements =
+                      FixedDoubleArray::cast(elements());
+                  fast_double_elements->set_length(value);
+                  filler_start = fast_double_elements->address() +
+                      FixedDoubleArray::OffsetOfElementAt(value);
+                  filler_size = (old_capacity - value) * kDoubleSize;
+                }
+                GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
+              }
+            } else {
+              // Otherwise, fill the unused tail with holes.
+              int old_length = FastD2I(JSArray::cast(this)->length()->Number());
+              if (GetElementsKind() == FAST_ELEMENTS) {
+                FixedArray* fast_elements = FixedArray::cast(elements());
+                for (int i = value; i < old_length; i++) {
+                  fast_elements->set_the_hole(i);
+                }
+              } else {
+                ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
+                FixedDoubleArray* fast_double_elements =
+                    FixedDoubleArray::cast(elements());
+                for (int i = value; i < old_length; i++) {
+                  fast_double_elements->set_the_hole(i);
+                }
+              }
             }
             JSArray::cast(this)->set_length(Smi::cast(smi_length));
           }
@@ -6940,11 +7697,15 @@
         int new_capacity = value > min ? value : min;
         if (new_capacity <= kMaxFastElementsLength ||
             !ShouldConvertToSlowElements(new_capacity)) {
-          Object* obj;
-          { MaybeObject* maybe_obj =
-                SetFastElementsCapacityAndLength(new_capacity, value);
-            if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+          MaybeObject* result;
+          if (GetElementsKind() == FAST_ELEMENTS) {
+            result = SetFastElementsCapacityAndLength(new_capacity, value);
+          }  else {
+            ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
+            result = SetFastDoubleElementsCapacityAndLength(new_capacity,
+                                                            value);
           }
+          if (result->IsFailure()) return result;
           return this;
         }
         break;
@@ -6969,7 +7730,16 @@
         }
         return this;
       }
-      default:
+      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case EXTERNAL_BYTE_ELEMENTS:
+      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+      case EXTERNAL_SHORT_ELEMENTS:
+      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+      case EXTERNAL_INT_ELEMENTS:
+      case EXTERNAL_UNSIGNED_INT_ELEMENTS:
+      case EXTERNAL_FLOAT_ELEMENTS:
+      case EXTERNAL_DOUBLE_ELEMENTS:
+      case EXTERNAL_PIXEL_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -7000,53 +7770,74 @@
 
 Object* Map::GetPrototypeTransition(Object* prototype) {
   FixedArray* cache = prototype_transitions();
-  int capacity = cache->length();
-  if (capacity == 0) return NULL;
-  int finger = Smi::cast(cache->get(0))->value();
-  for (int i = 1; i < finger; i += 2) {
-    if (cache->get(i) == prototype) return cache->get(i + 1);
+  int number_of_transitions = NumberOfProtoTransitions();
+  const int proto_offset =
+      kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset;
+  const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset;
+  const int step = kProtoTransitionElementsPerEntry;
+  for (int i = 0; i < number_of_transitions; i++) {
+    if (cache->get(proto_offset + i * step) == prototype) {
+      Object* map = cache->get(map_offset + i * step);
+      ASSERT(map->IsMap());
+      return map;
+    }
   }
   return NULL;
 }
 
 
 MaybeObject* Map::PutPrototypeTransition(Object* prototype, Map* map) {
+  ASSERT(map->IsMap());
+  ASSERT(HeapObject::cast(prototype)->map()->IsMap());
   // Don't cache prototype transition if this map is shared.
   if (is_shared() || !FLAG_cache_prototype_transitions) return this;
 
   FixedArray* cache = prototype_transitions();
 
-  int capacity = cache->length();
+  const int step = kProtoTransitionElementsPerEntry;
+  const int header = kProtoTransitionHeaderSize;
 
-  int finger = (capacity == 0) ? 1 : Smi::cast(cache->get(0))->value();
+  int capacity = (cache->length() - header) / step;
 
-  if (finger >= capacity) {
+  int transitions = NumberOfProtoTransitions() + 1;
+
+  if (transitions > capacity) {
     if (capacity > kMaxCachedPrototypeTransitions) return this;
 
     FixedArray* new_cache;
-    { MaybeObject* maybe_cache = heap()->AllocateFixedArray(finger * 2 + 1);
+    // Grow array by factor 2 over and above what we need.
+    { MaybeObject* maybe_cache =
+          heap()->AllocateFixedArray(transitions * 2 * step + header);
       if (!maybe_cache->To<FixedArray>(&new_cache)) return maybe_cache;
     }
 
-    for (int i = 1; i < capacity; i++) new_cache->set(i, cache->get(i));
+    for (int i = 0; i < capacity * step; i++) {
+      new_cache->set(i + header, cache->get(i + header));
+    }
     cache = new_cache;
     set_prototype_transitions(cache);
   }
 
-  cache->set(finger, prototype);
-  cache->set(finger + 1, map);
-  cache->set(0, Smi::FromInt(finger + 2));
+  int last = transitions - 1;
+
+  cache->set(header + last * step + kProtoTransitionPrototypeOffset, prototype);
+  cache->set(header + last * step + kProtoTransitionMapOffset, map);
+  SetNumberOfProtoTransitions(transitions);
 
   return cache;
 }
 
 
-MaybeObject* JSObject::SetPrototype(Object* value,
-                                    bool skip_hidden_prototypes) {
+MaybeObject* JSReceiver::SetPrototype(Object* value,
+                                      bool skip_hidden_prototypes) {
+#ifdef DEBUG
+  int size = Size();
+#endif
+
   Heap* heap = GetHeap();
   // Silently ignore the change if value is not a JSObject or null.
   // SpiderMonkey behaves this way.
-  if (!value->IsJSObject() && !value->IsNull()) return value;
+  if (!value->IsJSReceiver() && !value->IsNull()) return value;
 
   // From 8.6.2 Object Internal Methods
   // ...
@@ -7057,7 +7848,7 @@
   // or [[Extensible]] must not violate the invariants defined in the preceding
   // paragraph.
   if (!this->map()->is_extensible()) {
-    HandleScope scope;
+    HandleScope scope(heap->isolate());
     Handle<Object> handle(this, heap->isolate());
     return heap->isolate()->Throw(
         *FACTORY->NewTypeError("non_extensible_proto",
@@ -7071,13 +7862,13 @@
   for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) {
     if (JSObject::cast(pt) == this) {
       // Cycle detected.
-      HandleScope scope;
+      HandleScope scope(heap->isolate());
       return heap->isolate()->Throw(
           *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0)));
     }
   }
 
-  JSObject* real_receiver = this;
+  JSReceiver* real_receiver = this;
 
   if (skip_hidden_prototypes) {
     // Find the first object in the chain whose prototype object is not
@@ -7113,12 +7904,12 @@
   real_receiver->set_map(Map::cast(new_map));
 
   heap->ClearInstanceofCache();
-
+  ASSERT(size == Size());
   return value;
 }
 
 
-bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
   switch (GetElementsKind()) {
     case FAST_ELEMENTS: {
       uint32_t length = IsJSArray() ?
@@ -7145,7 +7936,8 @@
     case EXTERNAL_INT_ELEMENTS:
     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
     case EXTERNAL_FLOAT_ELEMENTS:
-    case EXTERNAL_DOUBLE_ELEMENTS: {
+    case EXTERNAL_DOUBLE_ELEMENTS:
+    case FAST_DOUBLE_ELEMENTS: {
       ExternalArray* array = ExternalArray::cast(elements());
       if (index < static_cast<uint32_t>(array->length())) {
         return true;
@@ -7159,7 +7951,7 @@
       }
       break;
     }
-    default:
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       break;
   }
@@ -7173,14 +7965,14 @@
 }
 
 
-bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) {
   Isolate* isolate = GetIsolate();
   // Make sure that the top context does not change when doing
   // callbacks or interceptor calls.
   AssertNoContextChange ncc;
   HandleScope scope(isolate);
   Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
-  Handle<JSObject> receiver_handle(receiver);
+  Handle<JSReceiver> receiver_handle(receiver);
   Handle<JSObject> holder_handle(this);
   CustomArguments args(isolate, interceptor->data(), receiver, this);
   v8::AccessorInfo info(args.end());
@@ -7273,23 +8065,68 @@
       if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT;
       break;
     }
+    case FAST_DOUBLE_ELEMENTS:
+      UNREACHABLE();
+      break;
     case DICTIONARY_ELEMENTS: {
       if (element_dictionary()->FindEntry(index) !=
-              NumberDictionary::kNotFound) {
+          NumberDictionary::kNotFound) {
         return DICTIONARY_ELEMENT;
       }
       break;
     }
-    default:
-      UNREACHABLE();
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      // Aliased parameters and non-aliased elements in a fast backing store
+      // behave as FAST_ELEMENT.  Non-aliased elements in a dictionary
+      // backing store behave as DICTIONARY_ELEMENT.
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      uint32_t length = parameter_map->length();
+      Object* probe =
+          index < (length - 2) ? parameter_map->get(index + 2) : NULL;
+      if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
+      // If not aliased, check the arguments.
+      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+      if (arguments->IsDictionary()) {
+        NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+        if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) {
+          return DICTIONARY_ELEMENT;
+        }
+      } else {
+        length = arguments->length();
+        probe = (index < length) ? arguments->get(index) : NULL;
+        if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
+      }
       break;
+    }
   }
 
   return UNDEFINED_ELEMENT;
 }
 
 
-bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementInElements(FixedArray* elements,
+                                    ElementsKind kind,
+                                    uint32_t index) {
+  ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
+  if (kind == FAST_ELEMENTS) {
+    int length = IsJSArray()
+        ? Smi::cast(JSArray::cast(this)->length())->value()
+        : elements->length();
+    if (index < static_cast<uint32_t>(length) &&
+        !elements->get(index)->IsTheHole()) {
+      return true;
+    }
+  } else {
+    if (NumberDictionary::cast(elements)->FindEntry(index) !=
+        NumberDictionary::kNotFound) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
   // Check access rights if needed.
   if (IsAccessCheckNeeded()) {
     Heap* heap = GetHeap();
@@ -7304,7 +8141,8 @@
     return HasElementWithInterceptor(receiver, index);
   }
 
-  switch (GetElementsKind()) {
+  ElementsKind kind = GetElementsKind();
+  switch (kind) {
     case FAST_ELEMENTS: {
       uint32_t length = IsJSArray() ?
           static_cast<uint32_t>
@@ -7314,6 +8152,15 @@
           !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
       break;
     }
+    case FAST_DOUBLE_ELEMENTS: {
+      uint32_t length = IsJSArray() ?
+          static_cast<uint32_t>
+              (Smi::cast(JSArray::cast(this)->length())->value()) :
+          static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
+      if ((index < length) &&
+          !FixedDoubleArray::cast(elements())->is_the_hole(index)) return true;
+      break;
+    }
     case EXTERNAL_PIXEL_ELEMENTS: {
       ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
       if (index < static_cast<uint32_t>(pixels->length())) {
@@ -7342,9 +8189,19 @@
       }
       break;
     }
-    default:
-      UNREACHABLE();
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      uint32_t length = parameter_map->length();
+      Object* probe =
+          (index < length - 2) ? parameter_map->get(index + 2) : NULL;
+      if (probe != NULL && !probe->IsTheHole()) return true;
+
+      // Not a mapped parameter, check the arguments.
+      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+      kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
+      if (HasElementInElements(arguments, kind, index)) return true;
       break;
+    }
   }
 
   // Handle [] on String objects.
@@ -7410,7 +8267,7 @@
     Handle<JSObject> self(JSObject::cast(receiver));
     Handle<JSObject> holder_handle(JSObject::cast(holder));
     Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
-    Handle<String> key(isolate->factory()->NumberToString(number));
+    Handle<String> key = isolate->factory()->NumberToString(number);
     LOG(isolate, ApiNamedPropertyAccess("load", *self, *key));
     CustomArguments args(isolate, data->data(), *self, *holder_handle);
     v8::AccessorInfo info(args.end());
@@ -7444,7 +8301,8 @@
 MaybeObject* JSObject::SetElementWithCallback(Object* structure,
                                               uint32_t index,
                                               Object* value,
-                                              JSObject* holder) {
+                                              JSObject* holder,
+                                              StrictModeFlag strict_mode) {
   Isolate* isolate = GetIsolate();
   HandleScope scope(isolate);
 
@@ -7483,10 +8341,13 @@
   }
 
   if (structure->IsFixedArray()) {
-    Object* setter = FixedArray::cast(structure)->get(kSetterIndex);
+    Handle<Object> setter(FixedArray::cast(structure)->get(kSetterIndex));
     if (setter->IsJSFunction()) {
-     return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value);
+     return SetPropertyWithDefinedSetter(JSFunction::cast(*setter), value);
     } else {
+      if (strict_mode == kNonStrictMode) {
+        return value;
+      }
       Handle<Object> holder_handle(holder, isolate);
       Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
       Handle<Object> args[2] = { key, holder_handle };
@@ -7501,6 +8362,30 @@
 }
 
 
+bool JSObject::HasFastArgumentsElements() {
+  Heap* heap = GetHeap();
+  if (!elements()->IsFixedArray()) return false;
+  FixedArray* elements = FixedArray::cast(this->elements());
+  if (elements->map() != heap->non_strict_arguments_elements_map()) {
+    return false;
+  }
+  FixedArray* arguments = FixedArray::cast(elements->get(1));
+  return !arguments->IsDictionary();
+}
+
+
+bool JSObject::HasDictionaryArgumentsElements() {
+  Heap* heap = GetHeap();
+  if (!elements()->IsFixedArray()) return false;
+  FixedArray* elements = FixedArray::cast(this->elements());
+  if (elements->map() != heap->non_strict_arguments_elements_map()) {
+    return false;
+  }
+  FixedArray* arguments = FixedArray::cast(elements->get(1));
+  return arguments->IsDictionary();
+}
+
+
 // Adding n elements in fast case is O(n*n).
 // Note: revisit design to have dual undefined values to capture absent
 // elements.
@@ -7508,27 +8393,215 @@
                                       Object* value,
                                       StrictModeFlag strict_mode,
                                       bool check_prototype) {
-  ASSERT(HasFastElements());
+  ASSERT(HasFastElements() || HasFastArgumentsElements());
 
-  Object* elms_obj;
-  { MaybeObject* maybe_elms_obj = EnsureWritableFastElements();
-    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
+  FixedArray* backing_store = FixedArray::cast(elements());
+  if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) {
+    backing_store = FixedArray::cast(backing_store->get(1));
+  } else {
+    Object* writable;
+    MaybeObject* maybe = EnsureWritableFastElements();
+    if (!maybe->ToObject(&writable)) return maybe;
+    backing_store = FixedArray::cast(writable);
   }
-  FixedArray* elms = FixedArray::cast(elms_obj);
-  uint32_t elms_length = static_cast<uint32_t>(elms->length());
+  uint32_t length = static_cast<uint32_t>(backing_store->length());
 
   if (check_prototype &&
-      (index >= elms_length || elms->get(index)->IsTheHole())) {
+      (index >= length || backing_store->get(index)->IsTheHole())) {
     bool found;
-    MaybeObject* result =
-        SetElementWithCallbackSetterInPrototypes(index, value, &found);
+    MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index,
+                                                                   value,
+                                                                   &found,
+                                                                   strict_mode);
     if (found) return result;
   }
 
+  // Check whether there is extra space in fixed array.
+  if (index < length) {
+    backing_store->set(index, value);
+    if (IsJSArray()) {
+      // Update the length of the array if needed.
+      uint32_t array_length = 0;
+      CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
+      if (index >= array_length) {
+        JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
+      }
+    }
+    return value;
+  }
 
-  // Check whether there is extra space in fixed array..
+  // Allow gap in fast case.
+  if ((index - length) < kMaxGap) {
+    // Try allocating extra space.
+    int new_capacity = NewElementsCapacity(index + 1);
+    if (new_capacity <= kMaxFastElementsLength ||
+        !ShouldConvertToSlowElements(new_capacity)) {
+      ASSERT(static_cast<uint32_t>(new_capacity) > index);
+      Object* new_elements;
+      MaybeObject* maybe =
+          SetFastElementsCapacityAndLength(new_capacity, index + 1);
+      if (!maybe->ToObject(&new_elements)) return maybe;
+      FixedArray::cast(new_elements)->set(index, value);
+      return value;
+    }
+  }
+
+  // Otherwise default to slow case.
+  MaybeObject* result = NormalizeElements();
+  if (result->IsFailure()) return result;
+  return SetDictionaryElement(index, value, strict_mode, check_prototype);
+}
+
+
+MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
+                                            Object* value,
+                                            StrictModeFlag strict_mode,
+                                            bool check_prototype) {
+  ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
+  Isolate* isolate = GetIsolate();
+  Heap* heap = isolate->heap();
+
+  // Insert element in the dictionary.
+  FixedArray* elements = FixedArray::cast(this->elements());
+  bool is_arguments =
+      (elements->map() == heap->non_strict_arguments_elements_map());
+  NumberDictionary* dictionary = NULL;
+  if (is_arguments) {
+    dictionary = NumberDictionary::cast(elements->get(1));
+  } else {
+    dictionary = NumberDictionary::cast(elements);
+  }
+
+  int entry = dictionary->FindEntry(index);
+  if (entry != NumberDictionary::kNotFound) {
+    Object* element = dictionary->ValueAt(entry);
+    PropertyDetails details = dictionary->DetailsAt(entry);
+    if (details.type() == CALLBACKS) {
+      return SetElementWithCallback(element, index, value, this, strict_mode);
+    } else {
+      dictionary->UpdateMaxNumberKey(index);
+      // If put fails in strict mode, throw an exception.
+      if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) {
+        Handle<Object> holder(this);
+        Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
+        Handle<Object> args[2] = { number, holder };
+        Handle<Object> error =
+            isolate->factory()->NewTypeError("strict_read_only_property",
+                                             HandleVector(args, 2));
+        return isolate->Throw(*error);
+      }
+    }
+  } else {
+    // Index not already used. Look for an accessor in the prototype chain.
+    if (check_prototype) {
+      bool found;
+      MaybeObject* result =
+          SetElementWithCallbackSetterInPrototypes(
+              index, value, &found, strict_mode);
+      if (found) return result;
+    }
+    // When we set the is_extensible flag to false we always force the
+    // element into dictionary mode (and force them to stay there).
+    if (!map()->is_extensible()) {
+      if (strict_mode == kNonStrictMode) {
+        return isolate->heap()->undefined_value();
+      } else {
+        Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
+        Handle<String> name = isolate->factory()->NumberToString(number);
+        Handle<Object> args[1] = { name };
+        Handle<Object> error =
+            isolate->factory()->NewTypeError("object_not_extensible",
+                                             HandleVector(args, 1));
+        return isolate->Throw(*error);
+      }
+    }
+    Object* new_dictionary;
+    MaybeObject* maybe = dictionary->AtNumberPut(index, value);
+    if (!maybe->ToObject(&new_dictionary)) return maybe;
+    if (dictionary != NumberDictionary::cast(new_dictionary)) {
+      if (is_arguments) {
+        elements->set(1, new_dictionary);
+      } else {
+        set_elements(HeapObject::cast(new_dictionary));
+      }
+      dictionary = NumberDictionary::cast(new_dictionary);
+    }
+  }
+
+  // Update the array length if this JSObject is an array.
+  if (IsJSArray()) {
+    MaybeObject* result =
+        JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value);
+    if (result->IsFailure()) return result;
+  }
+
+  // Attempt to put this object back in fast case.
+  if (ShouldConvertToFastElements()) {
+    uint32_t new_length = 0;
+    if (IsJSArray()) {
+      CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
+    } else {
+      new_length = dictionary->max_number_key() + 1;
+    }
+    MaybeObject* result = ShouldConvertToFastDoubleElements()
+        ? SetFastDoubleElementsCapacityAndLength(new_length, new_length)
+        : SetFastElementsCapacityAndLength(new_length, new_length);
+    if (result->IsFailure()) return result;
+#ifdef DEBUG
+    if (FLAG_trace_normalization) {
+      PrintF("Object elements are fast case again:\n");
+      Print();
+    }
+#endif
+  }
+  return value;
+}
+
+
+MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement(
+    uint32_t index,
+    Object* value,
+    StrictModeFlag strict_mode,
+    bool check_prototype) {
+  ASSERT(HasFastDoubleElements());
+
+  FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
+  uint32_t elms_length = static_cast<uint32_t>(elms->length());
+
+  // If storing to an element that isn't in the array, pass the store request
+  // up the prototype chain before storing in the receiver's elements.
+  if (check_prototype &&
+      (index >= elms_length || elms->is_the_hole(index))) {
+    bool found;
+    MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index,
+                                                                   value,
+                                                                   &found,
+                                                                   strict_mode);
+    if (found) return result;
+  }
+
+  // If the value object is not a heap number, switch to fast elements and try
+  // again.
+  bool value_is_smi = value->IsSmi();
+  if (!value->IsNumber()) {
+    Object* obj;
+    uint32_t length = elms_length;
+    if (IsJSArray()) {
+      CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
+    }
+    MaybeObject* maybe_obj =
+        SetFastElementsCapacityAndLength(elms_length, length);
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+    return SetFastElement(index, value, strict_mode, check_prototype);
+  }
+
+  double double_value = value_is_smi
+      ? static_cast<double>(Smi::cast(value)->value())
+      : HeapNumber::cast(value)->value();
+
+  // Check whether there is extra space in the fixed array.
   if (index < elms_length) {
-    elms->set(index, value);
+    elms->set(index, double_value);
     if (IsJSArray()) {
       // Update the length of the array if needed.
       uint32_t array_length = 0;
@@ -7549,15 +8622,19 @@
       ASSERT(static_cast<uint32_t>(new_capacity) > index);
       Object* obj;
       { MaybeObject* maybe_obj =
-            SetFastElementsCapacityAndLength(new_capacity, index + 1);
+            SetFastDoubleElementsCapacityAndLength(new_capacity,
+                                                   index + 1);
         if (!maybe_obj->ToObject(&obj)) return maybe_obj;
       }
-      FixedArray::cast(elements())->set(index, value);
+      FixedDoubleArray::cast(elements())->set(index, double_value);
       return value;
     }
   }
 
   // Otherwise default to slow case.
+  ASSERT(HasFastDoubleElements());
+  ASSERT(map()->has_fast_double_elements());
+  ASSERT(elements()->IsFixedDoubleArray());
   Object* obj;
   { MaybeObject* maybe_obj = NormalizeElements();
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
@@ -7575,7 +8652,7 @@
   if (IsAccessCheckNeeded()) {
     Heap* heap = GetHeap();
     if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) {
-      HandleScope scope;
+      HandleScope scope(heap->isolate());
       Handle<Object> value_handle(value);
       heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
       return *value_handle;
@@ -7614,8 +8691,9 @@
   Isolate* isolate = GetIsolate();
   switch (GetElementsKind()) {
     case FAST_ELEMENTS:
-      // Fast case.
       return SetFastElement(index, value, strict_mode, check_prototype);
+    case FAST_DOUBLE_ELEMENTS:
+      return SetFastDoubleElement(index, value, strict_mode, check_prototype);
     case EXTERNAL_PIXEL_ELEMENTS: {
       ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
       return pixels->SetValue(index, value);
@@ -7655,101 +8733,30 @@
       ExternalDoubleArray* array = ExternalDoubleArray::cast(elements());
       return array->SetValue(index, value);
     }
-    case DICTIONARY_ELEMENTS: {
-      // Insert element in the dictionary.
-      FixedArray* elms = FixedArray::cast(elements());
-      NumberDictionary* dictionary = NumberDictionary::cast(elms);
-
-      int entry = dictionary->FindEntry(index);
-      if (entry != NumberDictionary::kNotFound) {
-        Object* element = dictionary->ValueAt(entry);
-        PropertyDetails details = dictionary->DetailsAt(entry);
-        if (details.type() == CALLBACKS) {
-          return SetElementWithCallback(element, index, value, this);
-        } else {
-          dictionary->UpdateMaxNumberKey(index);
-          // If put fails instrict mode, throw exception.
-          if (!dictionary->ValueAtPut(entry, value) &&
-              strict_mode == kStrictMode) {
-            Handle<Object> holder(this);
-            Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
-            Handle<Object> args[2] = { number, holder };
-            return isolate->Throw(
-                *isolate->factory()->NewTypeError("strict_read_only_property",
-                                                  HandleVector(args, 2)));
-          }
-        }
+    case DICTIONARY_ELEMENTS:
+      return SetDictionaryElement(index, value, strict_mode, check_prototype);
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      uint32_t length = parameter_map->length();
+      Object* probe =
+          (index < length - 2) ? parameter_map->get(index + 2) : NULL;
+      if (probe != NULL && !probe->IsTheHole()) {
+        Context* context = Context::cast(parameter_map->get(0));
+        int context_index = Smi::cast(probe)->value();
+        ASSERT(!context->get(context_index)->IsTheHole());
+        context->set(context_index, value);
+        return value;
       } else {
-        // Index not already used. Look for an accessor in the prototype chain.
-        if (check_prototype) {
-          bool found;
-          MaybeObject* result =
-              // Strict mode not needed. No-setter case already handled.
-              SetElementWithCallbackSetterInPrototypes(index, value, &found);
-          if (found) return result;
-        }
-        // When we set the is_extensible flag to false we always force
-        // the element into dictionary mode (and force them to stay there).
-        if (!map()->is_extensible()) {
-          if (strict_mode == kNonStrictMode) {
-            return isolate->heap()->undefined_value();
-          } else {
-            Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
-            Handle<String> index_string(
-                isolate->factory()->NumberToString(number));
-            Handle<Object> args[1] = { index_string };
-            return isolate->Throw(
-                *isolate->factory()->NewTypeError("object_not_extensible",
-                                                  HandleVector(args, 1)));
-          }
-        }
-        Object* result;
-        { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value);
-          if (!maybe_result->ToObject(&result)) return maybe_result;
-        }
-        if (elms != FixedArray::cast(result)) {
-          set_elements(FixedArray::cast(result));
-        }
-      }
-
-      // Update the array length if this JSObject is an array.
-      if (IsJSArray()) {
-        JSArray* array = JSArray::cast(this);
-        Object* return_value;
-        { MaybeObject* maybe_return_value =
-              array->JSArrayUpdateLengthFromIndex(index, value);
-          if (!maybe_return_value->ToObject(&return_value)) {
-            return maybe_return_value;
-          }
-        }
-      }
-
-      // Attempt to put this object back in fast case.
-      if (ShouldConvertToFastElements()) {
-        uint32_t new_length = 0;
-        if (IsJSArray()) {
-          CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
+        // Object is not mapped, defer to the arguments.
+        FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+        if (arguments->IsDictionary()) {
+          return SetDictionaryElement(index, value, strict_mode,
+                                      check_prototype);
         } else {
-          new_length = NumberDictionary::cast(elements())->max_number_key() + 1;
+          return SetFastElement(index, value, strict_mode, check_prototype);
         }
-        Object* obj;
-        { MaybeObject* maybe_obj =
-              SetFastElementsCapacityAndLength(new_length, new_length);
-          if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-        }
-#ifdef DEBUG
-        if (FLAG_trace_normalization) {
-          PrintF("Object elements are fast case again:\n");
-          Print();
-        }
-#endif
       }
-
-      return value;
     }
-    default:
-      UNREACHABLE();
-      break;
   }
   // All possible cases have been handled above. Add a return to avoid the
   // complaints from the compiler.
@@ -7789,6 +8796,15 @@
       }
       break;
     }
+    case FAST_DOUBLE_ELEMENTS: {
+      FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
+      if (index < static_cast<uint32_t>(elms->length())) {
+        if (!elms->is_the_hole(index)) {
+          return GetHeap()->NumberFromDouble(elms->get(index));
+        }
+      }
+      break;
+    }
     case EXTERNAL_PIXEL_ELEMENTS:
     case EXTERNAL_BYTE_ELEMENTS:
     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
@@ -7820,8 +8836,8 @@
       }
       break;
     }
-    default:
-      UNREACHABLE();
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNIMPLEMENTED();
       break;
   }
 
@@ -7892,6 +8908,16 @@
       }
       break;
     }
+    case FAST_DOUBLE_ELEMENTS: {
+      FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
+      if (index < static_cast<uint32_t>(elms->length())) {
+        if (!elms->is_the_hole(index)) {
+          double double_value = elms->get(index);
+          return GetHeap()->NumberFromDouble(double_value);
+        }
+      }
+      break;
+    }
     case EXTERNAL_PIXEL_ELEMENTS:
     case EXTERNAL_BYTE_ELEMENTS:
     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
@@ -7923,6 +8949,40 @@
       }
       break;
     }
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      uint32_t length = parameter_map->length();
+      Object* probe =
+          (index < length - 2) ? parameter_map->get(index + 2) : NULL;
+      if (probe != NULL && !probe->IsTheHole()) {
+        Context* context = Context::cast(parameter_map->get(0));
+        int context_index = Smi::cast(probe)->value();
+        ASSERT(!context->get(context_index)->IsTheHole());
+        return context->get(context_index);
+      } else {
+        // Object is not mapped, defer to the arguments.
+        FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+        if (arguments->IsDictionary()) {
+          NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+          int entry = dictionary->FindEntry(index);
+          if (entry != NumberDictionary::kNotFound) {
+            Object* element = dictionary->ValueAt(entry);
+            PropertyDetails details = dictionary->DetailsAt(entry);
+            if (details.type() == CALLBACKS) {
+              return GetElementWithCallback(receiver,
+                                            element,
+                                            index,
+                                            this);
+            }
+            return element;
+          }
+        } else if (index < static_cast<uint32_t>(arguments->length())) {
+          Object* value = arguments->get(index);
+          if (!value->IsTheHole()) return value;
+        }
+      }
+      break;
+    }
   }
 
   Object* pt = GetPrototype();
@@ -8011,10 +9071,14 @@
       }
       break;
     }
+    case FAST_DOUBLE_ELEMENTS:
     case FAST_ELEMENTS:
     case DICTIONARY_ELEMENTS:
       UNREACHABLE();
       break;
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNIMPLEMENTED();
+      break;
   }
   return GetHeap()->undefined_value();
 }
@@ -8024,12 +9088,39 @@
   int capacity = 0;
   int number_of_elements = 0;
 
+  FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
+  FixedArray* backing_store = NULL;
   switch (GetElementsKind()) {
-    case FAST_ELEMENTS: {
-      FixedArray* elms = FixedArray::cast(elements());
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
+      backing_store_base =
+          FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
+      backing_store = FixedArray::cast(backing_store_base);
+      if (backing_store->IsDictionary()) {
+        NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
+        capacity = dictionary->Capacity();
+        number_of_elements = dictionary->NumberOfElements();
+        break;
+      }
+      // Fall through.
+    case FAST_ELEMENTS:
+      backing_store = FixedArray::cast(backing_store_base);
+      capacity = backing_store->length();
+      for (int i = 0; i < capacity; ++i) {
+        if (!backing_store->get(i)->IsTheHole()) ++number_of_elements;
+      }
+      break;
+    case DICTIONARY_ELEMENTS: {
+      NumberDictionary* dictionary =
+          NumberDictionary::cast(FixedArray::cast(elements()));
+      capacity = dictionary->Capacity();
+      number_of_elements = dictionary->NumberOfElements();
+      break;
+    }
+    case FAST_DOUBLE_ELEMENTS: {
+      FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
       capacity = elms->length();
       for (int i = 0; i < capacity; i++) {
-        if (!elms->get(i)->IsTheHole()) number_of_elements++;
+        if (!elms->is_the_hole(i)) number_of_elements++;
       }
       break;
     }
@@ -8044,43 +9135,48 @@
     case EXTERNAL_DOUBLE_ELEMENTS: {
       return true;
     }
-    case DICTIONARY_ELEMENTS: {
-      NumberDictionary* dictionary = NumberDictionary::cast(elements());
-      capacity = dictionary->Capacity();
-      number_of_elements = dictionary->NumberOfElements();
-      break;
-    }
-    default:
-      UNREACHABLE();
-      break;
   }
-
-  if (capacity == 0) return true;
-  return (number_of_elements > (capacity / 2));
+  return (capacity == 0) || (number_of_elements > (capacity / 2));
 }
 
 
 bool JSObject::ShouldConvertToSlowElements(int new_capacity) {
-  ASSERT(HasFastElements());
   // Keep the array in fast case if the current backing storage is
   // almost filled and if the new capacity is no more than twice the
   // old capacity.
-  int elements_length = FixedArray::cast(elements())->length();
+  int elements_length = 0;
+  if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) {
+    FixedArray* backing_store = FixedArray::cast(elements());
+    elements_length = FixedArray::cast(backing_store->get(1))->length();
+  } else if (HasFastElements()) {
+    elements_length = FixedArray::cast(elements())->length();
+  } else if (HasFastDoubleElements()) {
+    elements_length = FixedDoubleArray::cast(elements())->length();
+  } else {
+    UNREACHABLE();
+  }
   return !HasDenseElements() || ((new_capacity / 2) > elements_length);
 }
 
 
 bool JSObject::ShouldConvertToFastElements() {
-  ASSERT(HasDictionaryElements());
-  NumberDictionary* dictionary = NumberDictionary::cast(elements());
+  ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
   // If the elements are sparse, we should not go back to fast case.
   if (!HasDenseElements()) return false;
-  // If an element has been added at a very high index in the elements
-  // dictionary, we cannot go back to fast case.
-  if (dictionary->requires_slow_elements()) return false;
   // An object requiring access checks is never allowed to have fast
   // elements.  If it had fast elements we would skip security checks.
   if (IsAccessCheckNeeded()) return false;
+
+  FixedArray* elements = FixedArray::cast(this->elements());
+  NumberDictionary* dictionary = NULL;
+  if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
+    dictionary = NumberDictionary::cast(elements->get(1));
+  } else {
+    dictionary = NumberDictionary::cast(elements);
+  }
+  // If an element has been added at a very high index in the elements
+  // dictionary, we cannot go back to fast case.
+  if (dictionary->requires_slow_elements()) return false;
   // If the dictionary backing storage takes up roughly half as much
   // space as a fast-case backing storage would the array should have
   // fast elements.
@@ -8095,6 +9191,23 @@
 }
 
 
+bool JSObject::ShouldConvertToFastDoubleElements() {
+  if (FLAG_unbox_double_arrays) {
+    ASSERT(HasDictionaryElements());
+    NumberDictionary* dictionary = NumberDictionary::cast(elements());
+    for (int i = 0; i < dictionary->Capacity(); i++) {
+      Object* key = dictionary->KeyAt(i);
+      if (key->IsNumber()) {
+        if (!dictionary->ValueAt(i)->IsNumber()) return false;
+      }
+    }
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
 // Certain compilers request function template instantiation when they
 // see the definition of the other template functions in the
 // class. This requires us to have the template functions put
@@ -8159,7 +9272,7 @@
 
 
 MaybeObject* JSObject::GetPropertyPostInterceptor(
-    JSObject* receiver,
+    JSReceiver* receiver,
     String* name,
     PropertyAttributes* attributes) {
   // Check local property in holder, ignore interceptor.
@@ -8177,7 +9290,7 @@
 
 
 MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
-    JSObject* receiver,
+    JSReceiver* receiver,
     String* name,
     PropertyAttributes* attributes) {
   // Check local property in holder, ignore interceptor.
@@ -8191,13 +9304,13 @@
 
 
 MaybeObject* JSObject::GetPropertyWithInterceptor(
-    JSObject* receiver,
+    JSReceiver* receiver,
     String* name,
     PropertyAttributes* attributes) {
   Isolate* isolate = GetIsolate();
   InterceptorInfo* interceptor = GetNamedInterceptor();
   HandleScope scope(isolate);
-  Handle<JSObject> receiver_handle(receiver);
+  Handle<JSReceiver> receiver_handle(receiver);
   Handle<JSObject> holder_handle(this);
   Handle<String> name_handle(name);
 
@@ -8283,12 +9396,15 @@
       ExternalArray* array = ExternalArray::cast(elements());
       return index < static_cast<uint32_t>(array->length());
     }
+    case FAST_DOUBLE_ELEMENTS:
+      UNREACHABLE();
+      break;
     case DICTIONARY_ELEMENTS: {
       return element_dictionary()->FindEntry(index)
           != NumberDictionary::kNotFound;
     }
-    default:
-      UNREACHABLE();
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
+      UNIMPLEMENTED();
       break;
   }
   // All possibilities have been handled above already.
@@ -8460,7 +9576,9 @@
     }
     ASSERT(storage->length() >= index);
   } else {
-    property_dictionary()->CopyKeysTo(storage, index);
+    property_dictionary()->CopyKeysTo(storage,
+                                      index,
+                                      StringDictionary::UNSORTED);
   }
 }
 
@@ -8503,6 +9621,21 @@
       ASSERT(!storage || storage->length() >= counter);
       break;
     }
+    case FAST_DOUBLE_ELEMENTS: {
+      int length = IsJSArray() ?
+          Smi::cast(JSArray::cast(this)->length())->value() :
+          FixedDoubleArray::cast(elements())->length();
+      for (int i = 0; i < length; i++) {
+        if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
+          if (storage != NULL) {
+            storage->set(counter, Smi::FromInt(i));
+          }
+          counter++;
+        }
+      }
+      ASSERT(!storage || storage->length() >= counter);
+      break;
+    }
     case EXTERNAL_PIXEL_ELEMENTS: {
       int length = ExternalPixelArray::cast(elements())->length();
       while (counter < length) {
@@ -8534,14 +9667,52 @@
     }
     case DICTIONARY_ELEMENTS: {
       if (storage != NULL) {
-        element_dictionary()->CopyKeysTo(storage, filter);
+        element_dictionary()->CopyKeysTo(storage,
+                                         filter,
+                                         NumberDictionary::SORTED);
       }
-      counter = element_dictionary()->NumberOfElementsFilterAttributes(filter);
+      counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
       break;
     }
-    default:
-      UNREACHABLE();
+    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      FixedArray* parameter_map = FixedArray::cast(elements());
+      int mapped_length = parameter_map->length() - 2;
+      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+      if (arguments->IsDictionary()) {
+        // Copy the keys from arguments first, because Dictionary::CopyKeysTo
+        // will insert in storage starting at index 0.
+        NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+        if (storage != NULL) {
+          dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED);
+        }
+        counter += dictionary->NumberOfElementsFilterAttributes(filter);
+        for (int i = 0; i < mapped_length; ++i) {
+          if (!parameter_map->get(i + 2)->IsTheHole()) {
+            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
+            ++counter;
+          }
+        }
+        if (storage != NULL) storage->SortPairs(storage, counter);
+
+      } else {
+        int backing_length = arguments->length();
+        int i = 0;
+        for (; i < mapped_length; ++i) {
+          if (!parameter_map->get(i + 2)->IsTheHole()) {
+            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
+            ++counter;
+          } else if (i < backing_length && !arguments->get(i)->IsTheHole()) {
+            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
+            ++counter;
+          }
+        }
+        for (; i < backing_length; ++i) {
+          if (storage != NULL) storage->set(counter, Smi::FromInt(i));
+          ++counter;
+        }
+      }
       break;
+    }
   }
 
   if (this->IsJSValue()) {
@@ -9008,6 +10179,40 @@
 
 
 template<typename Shape, typename Key>
+MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
+  ASSERT(NumberOfElements() < new_table->Capacity());
+
+  AssertNoAllocation no_gc;
+  WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
+
+  // Copy prefix to new array.
+  for (int i = kPrefixStartIndex;
+       i < kPrefixStartIndex + Shape::kPrefixSize;
+       i++) {
+    new_table->set(i, get(i), mode);
+  }
+
+  // Rehash the elements.
+  int capacity = Capacity();
+  for (int i = 0; i < capacity; i++) {
+    uint32_t from_index = EntryToIndex(i);
+    Object* k = get(from_index);
+    if (IsKey(k)) {
+      uint32_t hash = Shape::HashForObject(key, k);
+      uint32_t insertion_index =
+          EntryToIndex(new_table->FindInsertionEntry(hash));
+      for (int j = 0; j < Shape::kEntrySize; j++) {
+        new_table->set(insertion_index + j, get(from_index + j), mode);
+      }
+    }
+  }
+  new_table->SetNumberOfElements(NumberOfElements());
+  new_table->SetNumberOfDeletedElements(0);
+  return new_table;
+}
+
+
+template<typename Shape, typename Key>
 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
   int capacity = Capacity();
   int nof = NumberOfElements() + n;
@@ -9029,32 +10234,36 @@
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
 
-  AssertNoAllocation no_gc;
-  HashTable* table = HashTable::cast(obj);
-  WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc);
+  return Rehash(HashTable::cast(obj), key);
+}
 
-  // Copy prefix to new array.
-  for (int i = kPrefixStartIndex;
-       i < kPrefixStartIndex + Shape::kPrefixSize;
-       i++) {
-    table->set(i, get(i), mode);
+
+template<typename Shape, typename Key>
+MaybeObject* HashTable<Shape, Key>::Shrink(Key key) {
+  int capacity = Capacity();
+  int nof = NumberOfElements();
+
+  // Shrink to fit the number of elements if only a quarter of the
+  // capacity is filled with elements.
+  if (nof > (capacity >> 2)) return this;
+  // Allocate a new dictionary with room for at least the current
+  // number of elements. The allocation method will make sure that
+  // there is extra room in the dictionary for additions. Don't go
+  // lower than room for 16 elements.
+  int at_least_room_for = nof;
+  if (at_least_room_for < 16) return this;
+
+  const int kMinCapacityForPretenure = 256;
+  bool pretenure =
+      (at_least_room_for > kMinCapacityForPretenure) &&
+      !GetHeap()->InNewSpace(this);
+  Object* obj;
+  { MaybeObject* maybe_obj =
+        Allocate(at_least_room_for, pretenure ? TENURED : NOT_TENURED);
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
-  // Rehash the elements.
-  for (int i = 0; i < capacity; i++) {
-    uint32_t from_index = EntryToIndex(i);
-    Object* k = get(from_index);
-    if (IsKey(k)) {
-      uint32_t hash = Shape::HashForObject(key, k);
-      uint32_t insertion_index =
-          EntryToIndex(table->FindInsertionEntry(hash));
-      for (int j = 0; j < Shape::kEntrySize; j++) {
-        table->set(insertion_index + j, get(from_index + j), mode);
-      }
-    }
-  }
-  table->SetNumberOfElements(NumberOfElements());
-  table->SetNumberOfDeletedElements(0);
-  return table;
+
+  return Rehash(HashTable::cast(obj), key);
 }
 
 
@@ -9101,7 +10310,9 @@
     Object*);
 
 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo(
-    FixedArray*, PropertyAttributes);
+    FixedArray*,
+    PropertyAttributes,
+    Dictionary<NumberDictionaryShape, uint32_t>::SortMode);
 
 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty(
     int, JSObject::DeleteMode);
@@ -9109,8 +10320,16 @@
 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty(
     int, JSObject::DeleteMode);
 
+template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink(
+    String*);
+
+template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink(
+    uint32_t);
+
 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo(
-    FixedArray*, int);
+    FixedArray*,
+    int,
+    Dictionary<StringDictionaryShape, String*>::SortMode);
 
 template int
 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes(
@@ -9253,8 +10472,6 @@
 // If the object is in dictionary mode, it is converted to fast elements
 // mode.
 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
-  ASSERT(!HasExternalArrayElements());
-
   Heap* heap = GetHeap();
 
   if (HasDictionaryElements()) {
@@ -9284,6 +10501,9 @@
 
     set_map(new_map);
     set_elements(fast_elements);
+  } else if (HasExternalArrayElements()) {
+    // External arrays cannot have holes or undefined elements.
+    return Smi::FromInt(ExternalArray::cast(elements())->length());
   } else {
     Object* obj;
     { MaybeObject* maybe_obj = EnsureWritableFastElements();
@@ -9615,6 +10835,7 @@
     UNREACHABLE();
     return NULL;
   }
+
  private:
   uint32_t c1_;
   uint32_t c2_;
@@ -9993,11 +11214,11 @@
 
 template<typename Shape, typename Key>
 Object* Dictionary<Shape, Key>::DeleteProperty(int entry,
-                                               JSObject::DeleteMode mode) {
+                                               JSReceiver::DeleteMode mode) {
   Heap* heap = Dictionary<Shape, Key>::GetHeap();
   PropertyDetails details = DetailsAt(entry);
   // Ignore attributes if forcing a deletion.
-  if (details.IsDontDelete() && mode != JSObject::FORCE_DELETION) {
+  if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) {
     return heap->false_value();
   }
   SetEntry(entry, heap->null_value(), heap->null_value());
@@ -10007,6 +11228,12 @@
 
 
 template<typename Shape, typename Key>
+MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) {
+  return HashTable<Shape, Key>::Shrink(key);
+}
+
+
+template<typename Shape, typename Key>
 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
   int entry = this->FindEntry(key);
 
@@ -10155,8 +11382,10 @@
 
 
 template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage,
-                                        PropertyAttributes filter) {
+void Dictionary<Shape, Key>::CopyKeysTo(
+    FixedArray* storage,
+    PropertyAttributes filter,
+    typename Dictionary<Shape, Key>::SortMode sort_mode) {
   ASSERT(storage->length() >= NumberOfEnumElements());
   int capacity = HashTable<Shape, Key>::Capacity();
   int index = 0;
@@ -10169,7 +11398,9 @@
        if ((attr & filter) == 0) storage->set(index++, k);
      }
   }
-  storage->SortPairs(storage, index);
+  if (sort_mode == Dictionary<Shape, Key>::SORTED) {
+    storage->SortPairs(storage, index);
+  }
   ASSERT(storage->length() >= index);
 }
 
@@ -10197,7 +11428,8 @@
 template<typename Shape, typename Key>
 void Dictionary<Shape, Key>::CopyKeysTo(
     FixedArray* storage,
-    int index) {
+    int index,
+    typename Dictionary<Shape, Key>::SortMode sort_mode) {
   ASSERT(storage->length() >= NumberOfElementsFilterAttributes(
       static_cast<PropertyAttributes>(NONE)));
   int capacity = HashTable<Shape, Key>::Capacity();
@@ -10209,6 +11441,9 @@
       storage->set(index++, k);
     }
   }
+  if (sort_mode == Dictionary<Shape, Key>::SORTED) {
+    storage->SortPairs(storage, index);
+  }
   ASSERT(storage->length() >= index);
 }
 
diff --git a/src/objects.h b/src/objects.h
index 332b2e4..2aa6b4a 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -48,16 +48,19 @@
 //   - Object
 //     - Smi          (immediate small integer)
 //     - HeapObject   (superclass for everything allocated in the heap)
-//       - JSObject
-//         - JSArray
-//         - JSRegExp
-//         - JSFunction
-//         - GlobalObject
-//           - JSGlobalObject
-//           - JSBuiltinsObject
-//         - JSGlobalProxy
-//         - JSValue
-//         - JSMessageObject
+//       - JSReceiver  (suitable for property access)
+//         - JSObject
+//           - JSArray
+//           - JSRegExp
+//           - JSFunction
+//           - GlobalObject
+//             - JSGlobalObject
+//             - JSBuiltinsObject
+//           - JSGlobalProxy
+//           - JSValue
+//           - JSMessageObject
+//         - JSProxy
+//           - JSFunctionProxy
 //       - ByteArray
 //       - ExternalArray
 //         - ExternalPixelArray
@@ -91,7 +94,6 @@
 //       - Code
 //       - Map
 //       - Oddball
-//       - JSProxy
 //       - Foreign
 //       - SharedFunctionInfo
 //       - Struct
@@ -134,7 +136,6 @@
 // They are used both in property dictionaries and instance descriptors.
 class PropertyDetails BASE_EMBEDDED {
  public:
-
   PropertyDetails(PropertyAttributes attributes,
                   PropertyType type,
                   int index = 0) {
@@ -214,6 +215,7 @@
   class StorageField:    public BitField<uint32_t,           8, 32-8> {};
 
   static const int kInitialIndex = 1;
+
  private:
   uint32_t value_;
 };
@@ -289,7 +291,6 @@
   V(JS_GLOBAL_PROPERTY_CELL_TYPE)                                              \
                                                                                \
   V(HEAP_NUMBER_TYPE)                                                          \
-  V(JS_PROXY_TYPE)                                                             \
   V(FOREIGN_TYPE)                                                              \
   V(BYTE_ARRAY_TYPE)                                                           \
   /* Note: the order of these external array */                                \
@@ -315,6 +316,7 @@
   V(TYPE_SWITCH_INFO_TYPE)                                                     \
   V(SCRIPT_TYPE)                                                               \
   V(CODE_CACHE_TYPE)                                                           \
+  V(POLYMORPHIC_CODE_CACHE_TYPE)                                               \
                                                                                \
   V(FIXED_ARRAY_TYPE)                                                          \
   V(SHARED_FUNCTION_INFO_TYPE)                                                 \
@@ -328,9 +330,11 @@
   V(JS_BUILTINS_OBJECT_TYPE)                                                   \
   V(JS_GLOBAL_PROXY_TYPE)                                                      \
   V(JS_ARRAY_TYPE)                                                             \
+  V(JS_PROXY_TYPE)                                                             \
   V(JS_REGEXP_TYPE)                                                            \
                                                                                \
   V(JS_FUNCTION_TYPE)                                                          \
+  V(JS_FUNCTION_PROXY_TYPE)                                                    \
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 #define INSTANCE_TYPE_LIST_DEBUGGER(V)                                         \
@@ -424,7 +428,8 @@
   V(SIGNATURE_INFO, SignatureInfo, signature_info)                             \
   V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info)                        \
   V(SCRIPT, Script, script)                                                    \
-  V(CODE_CACHE, CodeCache, code_cache)
+  V(CODE_CACHE, CodeCache, code_cache)                                         \
+  V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache)
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 #define STRUCT_LIST_DEBUGGER(V)                                                \
@@ -518,7 +523,6 @@
   // objects.
   HEAP_NUMBER_TYPE,
   FOREIGN_TYPE,
-  JS_PROXY_TYPE,
   BYTE_ARRAY_TYPE,
   EXTERNAL_BYTE_ARRAY_TYPE,  // FIRST_EXTERNAL_ARRAY_TYPE
   EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE,
@@ -529,6 +533,7 @@
   EXTERNAL_FLOAT_ARRAY_TYPE,
   EXTERNAL_DOUBLE_ARRAY_TYPE,
   EXTERNAL_PIXEL_ARRAY_TYPE,  // LAST_EXTERNAL_ARRAY_TYPE
+  FIXED_DOUBLE_ARRAY_TYPE,
   FILLER_TYPE,  // LAST_DATA_TYPE
 
   // Structs.
@@ -542,6 +547,7 @@
   TYPE_SWITCH_INFO_TYPE,
   SCRIPT_TYPE,
   CODE_CACHE_TYPE,
+  POLYMORPHIC_CODE_CACHE_TYPE,
   // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT
   // is defined. However as include/v8.h contain some of the instance type
   // constants always having them avoids them getting different numbers
@@ -554,21 +560,23 @@
 
   JS_MESSAGE_OBJECT_TYPE,
 
-  JS_VALUE_TYPE,  // FIRST_JS_OBJECT_TYPE
+  JS_VALUE_TYPE,  // FIRST_NON_CALLABLE_OBJECT_TYPE, FIRST_JS_RECEIVER_TYPE
   JS_OBJECT_TYPE,
   JS_CONTEXT_EXTENSION_OBJECT_TYPE,
   JS_GLOBAL_OBJECT_TYPE,
   JS_BUILTINS_OBJECT_TYPE,
   JS_GLOBAL_PROXY_TYPE,
   JS_ARRAY_TYPE,
+  JS_PROXY_TYPE,
 
-  JS_REGEXP_TYPE,  // LAST_JS_OBJECT_TYPE, FIRST_FUNCTION_CLASS_TYPE
+  JS_REGEXP_TYPE,  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE
 
-  JS_FUNCTION_TYPE,
+  JS_FUNCTION_TYPE,  // FIRST_CALLABLE_SPEC_OBJECT_TYPE
+  JS_FUNCTION_PROXY_TYPE,  // LAST_CALLABLE_SPEC_OBJECT_TYPE
 
   // Pseudo-types
   FIRST_TYPE = 0x0,
-  LAST_TYPE = JS_FUNCTION_TYPE,
+  LAST_TYPE = JS_FUNCTION_PROXY_TYPE,
   INVALID_TYPE = FIRST_TYPE - 1,
   FIRST_NONSTRING_TYPE = MAP_TYPE,
   // Boundaries for testing for an external array.
@@ -576,14 +584,22 @@
   LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE,
   // Boundary for promotion to old data space/old pointer space.
   LAST_DATA_TYPE = FILLER_TYPE,
-  // Boundaries for testing the type is a JavaScript "object".  Note that
-  // function objects are not counted as objects, even though they are
-  // implemented as such; only values whose typeof is "object" are included.
-  FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
-  LAST_JS_OBJECT_TYPE = JS_REGEXP_TYPE,
-  // RegExp objects have [[Class]] "function" because they are callable.
-  // All types from this type and above are objects with [[Class]] "function".
-  FIRST_FUNCTION_CLASS_TYPE = JS_REGEXP_TYPE
+  // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
+  // Note that there is no range for JSObject or JSProxy, since their subtypes
+  // are not continuous in this enum! The enum ranges instead reflect the
+  // external class names, where proxies are treated as either ordinary objects,
+  // or functions.
+  FIRST_JS_RECEIVER_TYPE = JS_VALUE_TYPE,
+  LAST_JS_RECEIVER_TYPE = LAST_TYPE,
+  // Boundaries for testing the types for which typeof is "object".
+  FIRST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_VALUE_TYPE,
+  LAST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_REGEXP_TYPE,
+  // Boundaries for testing the types for which typeof is "function".
+  FIRST_CALLABLE_SPEC_OBJECT_TYPE = JS_FUNCTION_TYPE,
+  LAST_CALLABLE_SPEC_OBJECT_TYPE = JS_FUNCTION_PROXY_TYPE,
+  // Boundaries for testing whether the type is a JavaScript object.
+  FIRST_SPEC_OBJECT_TYPE = FIRST_NONCALLABLE_SPEC_OBJECT_TYPE,
+  LAST_SPEC_OBJECT_TYPE = LAST_CALLABLE_SPEC_OBJECT_TYPE
 };
 
 static const int kExternalArrayTypeCount = LAST_EXTERNAL_ARRAY_TYPE -
@@ -709,6 +725,7 @@
   V(ExternalDoubleArray)                       \
   V(ExternalPixelArray)                        \
   V(ByteArray)                                 \
+  V(JSReceiver)                                \
   V(JSObject)                                  \
   V(JSContextExtensionObject)                  \
   V(Map)                                       \
@@ -716,8 +733,8 @@
   V(DeoptimizationInputData)                   \
   V(DeoptimizationOutputData)                  \
   V(FixedArray)                                \
+  V(FixedDoubleArray)                          \
   V(Context)                                   \
-  V(CatchContext)                              \
   V(GlobalContext)                             \
   V(JSFunction)                                \
   V(Code)                                      \
@@ -730,6 +747,7 @@
   V(Boolean)                                   \
   V(JSArray)                                   \
   V(JSProxy)                                   \
+  V(JSFunctionProxy)                           \
   V(JSRegExp)                                  \
   V(HashTable)                                 \
   V(Dictionary)                                \
@@ -738,6 +756,7 @@
   V(NormalizedMapCache)                        \
   V(CompilationCacheTable)                     \
   V(CodeCacheHashTable)                        \
+  V(PolymorphicCodeCacheHashTable)             \
   V(MapCache)                                  \
   V(Primitive)                                 \
   V(GlobalObject)                              \
@@ -782,6 +801,10 @@
   // Extract the number.
   inline double Number();
 
+  // Returns true if the object is of the correct type to be used as a
+  // implementation of a JSObject's elements.
+  inline bool HasValidElements();
+
   inline bool HasSpecificClassOf(String* name);
 
   MUST_USE_RESULT MaybeObject* ToObject();             // ECMA-262 9.9.
@@ -1332,11 +1355,9 @@
 };
 
 
-// The JSObject describes real heap allocated JavaScript objects with
-// properties.
-// Note that the map of JSObject changes during execution to enable inline
-// caching.
-class JSObject: public HeapObject {
+// JSReceiver includes types on which properties can be defined, i.e.,
+// JSObject and JSProxy.
+class JSReceiver: public HeapObject {
  public:
   enum DeleteMode {
     NORMAL_DELETION,
@@ -1344,11 +1365,77 @@
     FORCE_DELETION
   };
 
+  // Casting.
+  static inline JSReceiver* cast(Object* obj);
+
+  // Can cause GC.
+  MUST_USE_RESULT MaybeObject* SetProperty(String* key,
+                                           Object* value,
+                                           PropertyAttributes attributes,
+                                           StrictModeFlag strict_mode);
+  MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
+                                           String* key,
+                                           Object* value,
+                                           PropertyAttributes attributes,
+                                           StrictModeFlag strict_mode);
+
+  MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
+
+  // Returns the class name ([[Class]] property in the specification).
+  String* class_name();
+
+  // Returns the constructor name (the name (possibly, inferred name) of the
+  // function that was used to instantiate the object).
+  String* constructor_name();
+
+  inline PropertyAttributes GetPropertyAttribute(String* name);
+  PropertyAttributes GetPropertyAttributeWithReceiver(JSReceiver* receiver,
+                                                      String* name);
+  PropertyAttributes GetLocalPropertyAttribute(String* name);
+
+  // Can cause a GC.
+  inline bool HasProperty(String* name);
+  inline bool HasLocalProperty(String* name);
+
+  // Return the object's prototype (might be Heap::null_value()).
+  inline Object* GetPrototype();
+
+  // Set the object's prototype (only JSReceiver and null are allowed).
+  MUST_USE_RESULT MaybeObject* SetPrototype(Object* value,
+                                            bool skip_hidden_prototypes);
+
+  // Lookup a property.  If found, the result is valid and has
+  // detailed information.
+  void LocalLookup(String* name, LookupResult* result);
+  void Lookup(String* name, LookupResult* result);
+
+ private:
+  PropertyAttributes GetPropertyAttribute(JSReceiver* receiver,
+                                          LookupResult* result,
+                                          String* name,
+                                          bool continue_search);
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
+};
+
+// The JSObject describes real heap allocated JavaScript objects with
+// properties.
+// Note that the map of JSObject changes during execution to enable inline
+// caching.
+class JSObject: public JSReceiver {
+ public:
   enum ElementsKind {
-    // The only "fast" kind.
+    // The "fast" kind for tagged values. Must be first to make it possible
+    // to efficiently check maps if they have fast elements.
     FAST_ELEMENTS,
-    // All the kinds below are "slow".
+
+    // The "fast" kind for unwrapped, non-tagged double values.
+    FAST_DOUBLE_ELEMENTS,
+
+    // The "slow" kind.
     DICTIONARY_ELEMENTS,
+    NON_STRICT_ARGUMENTS_ELEMENTS,
+    // The "fast" kind for external arrays
     EXTERNAL_BYTE_ELEMENTS,
     EXTERNAL_UNSIGNED_BYTE_ELEMENTS,
     EXTERNAL_SHORT_ELEMENTS,
@@ -1357,9 +1444,18 @@
     EXTERNAL_UNSIGNED_INT_ELEMENTS,
     EXTERNAL_FLOAT_ELEMENTS,
     EXTERNAL_DOUBLE_ELEMENTS,
-    EXTERNAL_PIXEL_ELEMENTS
+    EXTERNAL_PIXEL_ELEMENTS,
+
+    // Derived constants from ElementsKind
+    FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_BYTE_ELEMENTS,
+    LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS,
+    FIRST_ELEMENTS_KIND = FAST_ELEMENTS,
+    LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS
   };
 
+  static const int kElementsKindCount =
+    LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
+
   // [properties]: Backing storage for properties.
   // properties is a FixedArray in the fast case and a Dictionary in the
   // slow case.
@@ -1376,18 +1472,22 @@
   //
   // In the fast mode elements is a FixedArray and so each element can
   // be quickly accessed. This fact is used in the generated code. The
-  // elements array can have one of the two maps in this mode:
-  // fixed_array_map or fixed_cow_array_map (for copy-on-write
-  // arrays). In the latter case the elements array may be shared by a
-  // few objects and so before writing to any element the array must
-  // be copied. Use EnsureWritableFastElements in this case.
+  // elements array can have one of three maps in this mode:
+  // fixed_array_map, non_strict_arguments_elements_map or
+  // fixed_cow_array_map (for copy-on-write arrays). In the latter case
+  // the elements array may be shared by a few objects and so before
+  // writing to any element the array must be copied. Use
+  // EnsureWritableFastElements in this case.
   //
-  // In the slow mode elements is either a NumberDictionary or an ExternalArray.
+  // In the slow mode the elements is either a NumberDictionary, an
+  // ExternalArray, or a FixedArray parameter map for a (non-strict)
+  // arguments object.
   DECL_ACCESSORS(elements, HeapObject)
   inline void initialize_elements();
   MUST_USE_RESULT inline MaybeObject* ResetElements();
   inline ElementsKind GetElementsKind();
   inline bool HasFastElements();
+  inline bool HasFastDoubleElements();
   inline bool HasDictionaryElements();
   inline bool HasExternalPixelElements();
   inline bool HasExternalArrayElements();
@@ -1399,9 +1499,12 @@
   inline bool HasExternalUnsignedIntElements();
   inline bool HasExternalFloatElements();
   inline bool HasExternalDoubleElements();
+  bool HasFastArgumentsElements();
+  bool HasDictionaryArgumentsElements();
   inline bool AllowsSetElementsLength();
   inline NumberDictionary* element_dictionary();  // Gets slow elements.
-  // Requires: this->HasFastElements().
+
+  // Requires: HasFastElements().
   MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
 
   // Collects elements starting at index 0.
@@ -1412,11 +1515,7 @@
   // a dictionary, and it will stay a dictionary.
   MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
 
-  MUST_USE_RESULT MaybeObject* SetProperty(String* key,
-                                           Object* value,
-                                           PropertyAttributes attributes,
-                                           StrictModeFlag strict_mode);
-  MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
+  MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result,
                                            String* key,
                                            Object* value,
                                            PropertyAttributes attributes,
@@ -1425,11 +1524,14 @@
       LookupResult* result,
       String* name,
       Object* value,
-      bool check_prototype);
-  MUST_USE_RESULT MaybeObject* SetPropertyWithCallback(Object* structure,
-                                                       String* name,
-                                                       Object* value,
-                                                       JSObject* holder);
+      bool check_prototype,
+      StrictModeFlag strict_mode);
+  MUST_USE_RESULT MaybeObject* SetPropertyWithCallback(
+      Object* structure,
+      String* name,
+      Object* value,
+      JSObject* holder,
+      StrictModeFlag strict_mode);
   MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSFunction* setter,
                                                             Object* value);
   MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
@@ -1465,21 +1567,22 @@
   MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(String* name,
                                                         DeleteMode mode);
 
-  // Returns the class name ([[Class]] property in the specification).
-  String* class_name();
-
-  // Returns the constructor name (the name (possibly, inferred name) of the
-  // function that was used to instantiate the object).
-  String* constructor_name();
-
   // Retrieve interceptors.
   InterceptorInfo* GetNamedInterceptor();
   InterceptorInfo* GetIndexedInterceptor();
 
-  inline PropertyAttributes GetPropertyAttribute(String* name);
-  PropertyAttributes GetPropertyAttributeWithReceiver(JSObject* receiver,
-                                                      String* name);
-  PropertyAttributes GetLocalPropertyAttribute(String* name);
+  // Used from JSReceiver.
+  PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
+                                                         String* name,
+                                                         bool continue_search);
+  PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
+                                                         String* name,
+                                                         bool continue_search);
+  PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
+      Object* receiver,
+      LookupResult* result,
+      String* name,
+      bool continue_search);
 
   MUST_USE_RESULT MaybeObject* DefineAccessor(String* name,
                                               bool is_getter,
@@ -1496,14 +1599,14 @@
       String* name,
       PropertyAttributes* attributes);
   MaybeObject* GetPropertyWithInterceptor(
-      JSObject* receiver,
+      JSReceiver* receiver,
       String* name,
       PropertyAttributes* attributes);
   MaybeObject* GetPropertyPostInterceptor(
-      JSObject* receiver,
+      JSReceiver* receiver,
       String* name,
       PropertyAttributes* attributes);
-  MaybeObject* GetLocalPropertyPostInterceptor(JSObject* receiver,
+  MaybeObject* GetLocalPropertyPostInterceptor(JSReceiver* receiver,
                                                String* name,
                                                PropertyAttributes* attributes);
 
@@ -1511,15 +1614,6 @@
   // been modified since it was created.  May give false positives.
   bool IsDirty();
 
-  bool HasProperty(String* name) {
-    return GetPropertyAttribute(name) != ABSENT;
-  }
-
-  // Can cause a GC if it hits an interceptor.
-  bool HasLocalProperty(String* name) {
-    return GetLocalPropertyAttribute(name) != ABSENT;
-  }
-
   // If the receiver is a JSGlobalProxy this method will return its prototype,
   // otherwise the result is the receiver itself.
   inline Object* BypassGlobalProxy();
@@ -1556,17 +1650,13 @@
   // storage would.  In that case the JSObject should have fast
   // elements.
   bool ShouldConvertToFastElements();
-
-  // Return the object's prototype (might be Heap::null_value()).
-  inline Object* GetPrototype();
-
-  // Set the object's prototype (only JSObject and null are allowed).
-  MUST_USE_RESULT MaybeObject* SetPrototype(Object* value,
-                                            bool skip_hidden_prototypes);
+  // Returns true if the elements of JSObject contains only values that can be
+  // represented in a FixedDoubleArray.
+  bool ShouldConvertToFastDoubleElements();
 
   // Tells whether the index'th element is present.
   inline bool HasElement(uint32_t index);
-  bool HasElementWithReceiver(JSObject* receiver, uint32_t index);
+  bool HasElementWithReceiver(JSReceiver* receiver, uint32_t index);
 
   // Computes the new capacity when expanding the elements of a JSObject.
   static int NewElementsCapacity(int old_capacity) {
@@ -1594,20 +1684,30 @@
 
   LocalElementType HasLocalElement(uint32_t index);
 
-  bool HasElementWithInterceptor(JSObject* receiver, uint32_t index);
-  bool HasElementPostInterceptor(JSObject* receiver, uint32_t index);
+  bool HasElementWithInterceptor(JSReceiver* receiver, uint32_t index);
+  bool HasElementPostInterceptor(JSReceiver* receiver, uint32_t index);
 
   MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
                                               Object* value,
                                               StrictModeFlag strict_mode,
-                                              bool check_prototype = true);
+                                              bool check_prototype);
+  MUST_USE_RESULT MaybeObject* SetDictionaryElement(uint32_t index,
+                                                    Object* value,
+                                                    StrictModeFlag strict_mode,
+                                                    bool check_prototype);
+
+  MUST_USE_RESULT MaybeObject* SetFastDoubleElement(
+      uint32_t index,
+      Object* value,
+      StrictModeFlag strict_mode,
+      bool check_prototype = true);
 
   // Set the index'th array element.
   // A Failure object is returned if GC is needed.
   MUST_USE_RESULT MaybeObject* SetElement(uint32_t index,
                                           Object* value,
                                           StrictModeFlag strict_mode,
-                                          bool check_prototype = true);
+                                          bool check_prototype);
 
   // Returns the index'th element.
   // The undefined object if index is out of bounds.
@@ -1619,8 +1719,14 @@
   // failed.
   MaybeObject* GetExternalElement(uint32_t index);
 
+  // Replace the elements' backing store with fast elements of the given
+  // capacity.  Update the length for JSArrays.  Returns the new backing
+  // store.
   MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength(int capacity,
                                                                 int length);
+  MUST_USE_RESULT MaybeObject* SetFastDoubleElementsCapacityAndLength(
+      int capacity,
+      int length);
   MUST_USE_RESULT MaybeObject* SetSlowElements(Object* length);
 
   // Lookup interceptors are used for handling properties controlled by host
@@ -1648,7 +1754,6 @@
   // Lookup a property.  If found, the result is valid and has
   // detailed information.
   void LocalLookup(String* name, LookupResult* result);
-  void Lookup(String* name, LookupResult* result);
 
   // The following lookup functions skip interceptors.
   void LocalLookupRealNamedProperty(String* name, LookupResult* result);
@@ -1656,7 +1761,7 @@
   void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result);
   void LookupCallbackSetterInPrototypes(String* name, LookupResult* result);
   MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes(
-      uint32_t index, Object* value, bool* found);
+      uint32_t index, Object* value, bool* found, StrictModeFlag strict_mode);
   void LookupCallback(String* name, LookupResult* result);
 
   // Returns the number of properties on this object filtering out properties
@@ -1746,6 +1851,9 @@
   MUST_USE_RESULT MaybeObject* NormalizeProperties(
       PropertyNormalizationMode mode,
       int expected_additional_properties);
+
+  // Convert and update the elements backing store to be a NumberDictionary
+  // dictionary.  Returns the backing after conversion.
   MUST_USE_RESULT MaybeObject* NormalizeElements();
 
   MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code);
@@ -1868,7 +1976,8 @@
   MaybeObject* SetElementWithCallback(Object* structure,
                                       uint32_t index,
                                       Object* value,
-                                      JSObject* holder);
+                                      JSObject* holder,
+                                      StrictModeFlag strict_mode);
   MUST_USE_RESULT MaybeObject* SetElementWithInterceptor(
       uint32_t index,
       Object* value,
@@ -1890,21 +1999,16 @@
                                                             DeleteMode mode);
   MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index);
 
-  PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
-                                                         String* name,
-                                                         bool continue_search);
-  PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
-                                                         String* name,
-                                                         bool continue_search);
-  PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
-      Object* receiver,
-      LookupResult* result,
-      String* name,
-      bool continue_search);
-  PropertyAttributes GetPropertyAttribute(JSObject* receiver,
-                                          LookupResult* result,
-                                          String* name,
-                                          bool continue_search);
+  MUST_USE_RESULT MaybeObject* DeleteFastElement(uint32_t index);
+  MUST_USE_RESULT MaybeObject* DeleteDictionaryElement(uint32_t index,
+                                                       DeleteMode mode);
+
+  bool ReferencesObjectFromElements(FixedArray* elements,
+                                    ElementsKind kind,
+                                    Object* object);
+  bool HasElementInElements(FixedArray* elements,
+                            ElementsKind kind,
+                            uint32_t index);
 
   // Returns true if most of the elements backing storage is used.
   bool HasDenseElements();
@@ -1928,13 +2032,26 @@
 };
 
 
-// FixedArray describes fixed-sized arrays with element type Object*.
-class FixedArray: public HeapObject {
+// Common superclass for FixedArrays that allow implementations to share
+// common accessors and some code paths.
+class FixedArrayBase: public HeapObject {
  public:
   // [length]: length of the array.
   inline int length();
   inline void set_length(int value);
 
+  inline static FixedArrayBase* cast(Object* object);
+
+  // Layout description.
+  // Length is smi tagged when it is stored.
+  static const int kLengthOffset = HeapObject::kHeaderSize;
+  static const int kHeaderSize = kLengthOffset + kPointerSize;
+};
+
+
+// FixedArray describes fixed-sized arrays with element type Object*.
+class FixedArray: public FixedArrayBase {
+ public:
   // Setter and getter for elements.
   inline Object* get(int index);
   // Setter that uses write barrier.
@@ -1985,11 +2102,6 @@
   // Casting.
   static inline FixedArray* cast(Object* obj);
 
-  // Layout description.
-  // Length is smi tagged when it is stored.
-  static const int kLengthOffset = HeapObject::kHeaderSize;
-  static const int kHeaderSize = kLengthOffset + kPointerSize;
-
   // Maximal allowed size, in bytes, of a single FixedArray.
   // Prevents overflowing size computations, as well as extreme memory
   // consumption.
@@ -2037,6 +2149,60 @@
 };
 
 
+// FixedDoubleArray describes fixed-sized arrays with element type double.
+class FixedDoubleArray: public FixedArrayBase {
+ public:
+  inline void Initialize(FixedArray* from);
+  inline void Initialize(FixedDoubleArray* from);
+  inline void Initialize(NumberDictionary* from);
+
+  // Setter and getter for elements.
+  inline double get(int index);
+  inline void set(int index, double value);
+  inline void set_the_hole(int index);
+
+  // Checking for the hole.
+  inline bool is_the_hole(int index);
+
+  // Garbage collection support.
+  inline static int SizeFor(int length) {
+    return kHeaderSize + length * kDoubleSize;
+  }
+
+  // Code Generation support.
+  static int OffsetOfElementAt(int index) { return SizeFor(index); }
+
+  inline static bool is_the_hole_nan(double value);
+  inline static double hole_nan_as_double();
+  inline static double canonical_not_the_hole_nan_as_double();
+
+  // Casting.
+  static inline FixedDoubleArray* cast(Object* obj);
+
+  // Maximal allowed size, in bytes, of a single FixedDoubleArray.
+  // Prevents overflowing size computations, as well as extreme memory
+  // consumption.
+  static const int kMaxSize = 512 * MB;
+  // Maximally allowed length of a FixedArray.
+  static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
+
+  // Dispatched behavior.
+#ifdef OBJECT_PRINT
+  inline void FixedDoubleArrayPrint() {
+    FixedDoubleArrayPrint(stdout);
+  }
+  void FixedDoubleArrayPrint(FILE* out);
+#endif
+
+#ifdef DEBUG
+  void FixedDoubleArrayVerify();
+#endif
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
+};
+
+
 // DescriptorArrays are fixed arrays used to hold instance descriptors.
 // The format of the these objects is:
 // TODO(1399): It should be possible to make room for bit_field3 in the map
@@ -2365,7 +2531,6 @@
   int FindEntry(Isolate* isolate, Key key);
 
  protected:
-
   // Find the entry at which to insert element with the given key that
   // has the given hash value.
   uint32_t FindInsertionEntry(uint32_t hash);
@@ -2410,6 +2575,12 @@
     return (last + number) & (size - 1);
   }
 
+  // Rehashes this hash-table into the new table.
+  MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key);
+
+  // Attempt to shrink hash table after removal of key.
+  MUST_USE_RESULT MaybeObject* Shrink(Key key);
+
   // Ensure enough space for n additional elements.
   MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
 };
@@ -2532,7 +2703,6 @@
 template <typename Shape, typename Key>
 class Dictionary: public HashTable<Shape, Key> {
  public:
-
   static inline Dictionary<Shape, Key>* cast(Object* obj) {
     return reinterpret_cast<Dictionary<Shape, Key>*>(obj);
   }
@@ -2575,6 +2745,9 @@
   // Delete a property from the dictionary.
   Object* DeleteProperty(int entry, JSObject::DeleteMode mode);
 
+  // Attempt to shrink the dictionary after deletion of key.
+  MUST_USE_RESULT MaybeObject* Shrink(Key key);
+
   // Returns the number of elements in the dictionary filtering out properties
   // with the specified attributes.
   int NumberOfElementsFilterAttributes(PropertyAttributes filter);
@@ -2582,10 +2755,13 @@
   // Returns the number of enumerable elements in the dictionary.
   int NumberOfEnumElements();
 
+  enum SortMode { UNSORTED, SORTED };
   // Copies keys to preallocated fixed array.
-  void CopyKeysTo(FixedArray* storage, PropertyAttributes filter);
+  void CopyKeysTo(FixedArray* storage,
+                  PropertyAttributes filter,
+                  SortMode sort_mode);
   // Fill in details for properties into storage.
-  void CopyKeysTo(FixedArray* storage, int index);
+  void CopyKeysTo(FixedArray* storage, int index, SortMode sort_mode);
 
   // Accessors for next enumeration index.
   void SetNextEnumerationIndex(int index) {
@@ -2786,11 +2962,6 @@
 #ifdef DEBUG
   void NormalizedMapCacheVerify();
 #endif
-
- private:
-  static int Hash(Map* fast);
-
-  static bool CheckHit(Map* slow, Map* fast, PropertyNormalizationMode mode);
 };
 
 
@@ -3235,7 +3406,7 @@
   // Casting.
   static inline DeoptimizationInputData* cast(Object* obj);
 
-#ifdef OBJECT_PRINT
+#ifdef ENABLE_DISASSEMBLER
   void DeoptimizationInputDataPrint(FILE* out);
 #endif
 
@@ -3274,7 +3445,7 @@
   // Casting.
   static inline DeoptimizationOutputData* cast(Object* obj);
 
-#ifdef OBJECT_PRINT
+#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   void DeoptimizationOutputDataPrint(FILE* out);
 #endif
 };
@@ -3429,12 +3600,6 @@
   inline CheckType check_type();
   inline void set_check_type(CheckType value);
 
-  // [external array type]: For kind KEYED_EXTERNAL_ARRAY_LOAD_IC and
-  // KEYED_EXTERNAL_ARRAY_STORE_IC, identifies the type of external
-  // array that the code stub is specialized for.
-  inline ExternalArrayType external_array_type();
-  inline void set_external_array_type(ExternalArrayType value);
-
   // [type-recording unary op type]: For all UNARY_OP_IC.
   inline byte unary_op_type();
   inline void set_unary_op_type(byte value);
@@ -3590,7 +3755,6 @@
   static const int kOptimizableOffset = kKindSpecificFlagsOffset;
   static const int kStackSlotsOffset = kKindSpecificFlagsOffset;
   static const int kCheckTypeOffset = kKindSpecificFlagsOffset;
-  static const int kExternalArrayTypeOffset = kKindSpecificFlagsOffset;
 
   static const int kCompareStateOffset = kStubMajorKeyOffset + 1;
   static const int kUnaryOpTypeOffset = kStubMajorKeyOffset + 1;
@@ -3741,31 +3905,37 @@
   inline void set_is_extensible(bool value);
   inline bool is_extensible();
 
+  inline void set_elements_kind(JSObject::ElementsKind elements_kind) {
+    ASSERT(elements_kind < JSObject::kElementsKindCount);
+    ASSERT(JSObject::kElementsKindCount <= (1 << kElementsKindBitCount));
+    set_bit_field2((bit_field2() & ~kElementsKindMask) |
+        (elements_kind << kElementsKindShift));
+    ASSERT(this->elements_kind() == elements_kind);
+  }
+
+  inline JSObject::ElementsKind elements_kind() {
+    return static_cast<JSObject::ElementsKind>(
+        (bit_field2() & kElementsKindMask) >> kElementsKindShift);
+  }
+
   // Tells whether the instance has fast elements.
   // Equivalent to instance->GetElementsKind() == FAST_ELEMENTS.
-  inline void set_has_fast_elements(bool value) {
-    if (value) {
-      set_bit_field2(bit_field2() | (1 << kHasFastElements));
-    } else {
-      set_bit_field2(bit_field2() & ~(1 << kHasFastElements));
-    }
-  }
-
   inline bool has_fast_elements() {
-    return ((1 << kHasFastElements) & bit_field2()) != 0;
+    return elements_kind() == JSObject::FAST_ELEMENTS;
   }
 
-  // Tells whether an instance has pixel array elements.
-  inline void set_has_external_array_elements(bool value) {
-    if (value) {
-      set_bit_field2(bit_field2() | (1 << kHasExternalArrayElements));
-    } else {
-      set_bit_field2(bit_field2() & ~(1 << kHasExternalArrayElements));
-    }
+  inline bool has_fast_double_elements() {
+    return elements_kind() == JSObject::FAST_DOUBLE_ELEMENTS;
   }
 
   inline bool has_external_array_elements() {
-    return ((1 << kHasExternalArrayElements) & bit_field2()) != 0;
+    JSObject::ElementsKind kind(elements_kind());
+    return kind >= JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND &&
+        kind <= JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND;
+  }
+
+  inline bool has_dictionary_elements() {
+    return elements_kind() == JSObject::DICTIONARY_ELEMENTS;
   }
 
   // Tells whether the map is attached to SharedFunctionInfo
@@ -3818,6 +3988,26 @@
   DECL_ACCESSORS(prototype_transitions, FixedArray)
   inline FixedArray* unchecked_prototype_transitions();
 
+  static const int kProtoTransitionHeaderSize = 1;
+  static const int kProtoTransitionNumberOfEntriesOffset = 0;
+  static const int kProtoTransitionElementsPerEntry = 2;
+  static const int kProtoTransitionPrototypeOffset = 0;
+  static const int kProtoTransitionMapOffset = 1;
+
+  inline int NumberOfProtoTransitions() {
+    FixedArray* cache = unchecked_prototype_transitions();
+    if (cache->length() == 0) return 0;
+    return
+        Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value();
+  }
+
+  inline void SetNumberOfProtoTransitions(int value) {
+    FixedArray* cache = unchecked_prototype_transitions();
+    ASSERT(cache->length() != 0);
+    cache->set_unchecked(kProtoTransitionNumberOfEntriesOffset,
+                         Smi::FromInt(value));
+  }
+
   // Lookup in the map's instance descriptors and fill out the result
   // with the given holder if the name is found. The holder may be
   // NULL when this function is used from the compiler.
@@ -3834,18 +4024,23 @@
   // instance descriptors.
   MUST_USE_RESULT MaybeObject* CopyDropTransitions();
 
-  // Returns this map if it has the fast elements bit set, otherwise
+  // Returns this map if it already has elements that are fast, otherwise
   // returns a copy of the map, with all transitions dropped from the
-  // descriptors and the fast elements bit set.
+  // descriptors and the ElementsKind set to FAST_ELEMENTS.
   MUST_USE_RESULT inline MaybeObject* GetFastElementsMap();
 
-  // Returns this map if it has the fast elements bit cleared,
-  // otherwise returns a copy of the map, with all transitions dropped
-  // from the descriptors and the fast elements bit cleared.
+  // Returns this map if it already has fast elements that are doubles,
+  // otherwise returns a copy of the map, with all transitions dropped from the
+  // descriptors and the ElementsKind set to FAST_DOUBLE_ELEMENTS.
+  MUST_USE_RESULT inline MaybeObject* GetFastDoubleElementsMap();
+
+  // Returns this map if already has dictionary elements, otherwise returns a
+  // copy of the map, with all transitions dropped from the descriptors and the
+  // ElementsKind set to DICTIONARY_ELEMENTS.
   MUST_USE_RESULT inline MaybeObject* GetSlowElementsMap();
 
   // Returns a new map with all transitions dropped from the descriptors and the
-  // external array elements bit set.
+  // ElementsKind set to one of the value corresponding to array_type.
   MUST_USE_RESULT MaybeObject* GetExternalArrayElementsMap(
       ExternalArrayType array_type,
       bool safe_to_add_transition);
@@ -3894,6 +4089,21 @@
   // following back pointers.
   void ClearNonLiveTransitions(Heap* heap, Object* real_prototype);
 
+  // Computes a hash value for this map, to be used in HashTables and such.
+  int Hash();
+
+  // Compares this map to another to see if they describe equivalent objects.
+  // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
+  // it had exactly zero inobject properties.
+  // The "shared" flags of both this map and |other| are ignored.
+  bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
+
+  // Returns true if this map and |other| describe equivalent objects.
+  // The "shared" flags of both this map and |other| are ignored.
+  bool EquivalentTo(Map* other) {
+    return EquivalentToForNormalization(other, KEEP_INOBJECT_PROPERTIES);
+  }
+
   // Dispatched behavior.
 #ifdef OBJECT_PRINT
   inline void MapPrint() {
@@ -3986,13 +4196,21 @@
   // Bit positions for bit field 2
   static const int kIsExtensible = 0;
   static const int kFunctionWithPrototype = 1;
-  static const int kHasFastElements = 2;
-  static const int kStringWrapperSafeForDefaultValueOf = 3;
-  static const int kAttachedToSharedFunctionInfo = 4;
-  static const int kHasExternalArrayElements = 5;
+  static const int kStringWrapperSafeForDefaultValueOf = 2;
+  static const int kAttachedToSharedFunctionInfo = 3;
+  // No bits can be used after kElementsKindFirstBit, they are all reserved for
+  // storing ElementKind.  for anything other than storing the ElementKind.
+  static const int kElementsKindShift = 4;
+  static const int kElementsKindBitCount = 4;
+
+  // Derived values from bit field 2
+  static const int kElementsKindMask = (-1 << kElementsKindShift) &
+      ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1);
+  static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
+      (JSObject::FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1;
 
   // Bit positions for bit field 3
-  static const int kIsShared = 1;
+  static const int kIsShared = 0;
 
   // Layout of the default cache. It holds alternating name and code objects.
   static const int kCodeCacheEntrySize = 2;
@@ -4288,9 +4506,7 @@
   // False if there are definitely no live objects created from this function.
   // True if live objects _may_ exist (existence not guaranteed).
   // May go back from true to false after GC.
-  inline bool live_objects_may_exist();
-
-  inline void set_live_objects_may_exist(bool value);
+  DECL_BOOLEAN_ACCESSORS(live_objects_may_exist)
 
   // [instance class name]: class name for instances.
   DECL_ACCESSORS(instance_class_name, Object)
@@ -4349,12 +4565,10 @@
   inline void set_end_position(int end_position);
 
   // Is this function a function expression in the source code.
-  inline bool is_expression();
-  inline void set_is_expression(bool value);
+  DECL_BOOLEAN_ACCESSORS(is_expression)
 
   // Is this function a top-level function (scripts, evals).
-  inline bool is_toplevel();
-  inline void set_is_toplevel(bool value);
+  DECL_BOOLEAN_ACCESSORS(is_toplevel)
 
   // Bit field containing various information collected by the compiler to
   // drive optimization.
@@ -4381,8 +4595,7 @@
   // Indicates if this function can be lazy compiled.
   // This is used to determine if we can safely flush code from a function
   // when doing GC if we expect that the function will no longer be used.
-  inline bool allows_lazy_compilation();
-  inline void set_allows_lazy_compilation(bool flag);
+  DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
 
   // Indicates how many full GCs this function has survived with assigned
   // code object. Used to determine when it is relatively safe to flush
@@ -4396,19 +4609,36 @@
   // shared function info. If a function is repeatedly optimized or if
   // we cannot optimize the function we disable optimization to avoid
   // spending time attempting to optimize it again.
-  inline bool optimization_disabled();
-  inline void set_optimization_disabled(bool value);
+  DECL_BOOLEAN_ACCESSORS(optimization_disabled)
 
   // Indicates whether the function is a strict mode function.
-  inline bool strict_mode();
-  inline void set_strict_mode(bool value);
+  DECL_BOOLEAN_ACCESSORS(strict_mode)
 
-  // Indicates whether the function is a native ES5 function.
+  // False if the function definitely does not allocate an arguments object.
+  DECL_BOOLEAN_ACCESSORS(uses_arguments)
+
+  // True if the function has any duplicated parameter names.
+  DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
+
+  // Indicates whether the function is a native function.
   // These needs special threatment in .call and .apply since
   // null passed as the receiver should not be translated to the
   // global object.
-  inline bool es5_native();
-  inline void set_es5_native(bool value);
+  DECL_BOOLEAN_ACCESSORS(native)
+
+  // Indicates that the function was created by the Function function.
+  // Though it's anonymous, toString should treat it as if it had the name
+  // "anonymous".  We don't set the name itself so that the system does not
+  // see a binding for it.
+  DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
+
+  // Indicates whether the function is a bound function created using
+  // the bind function.
+  DECL_BOOLEAN_ACCESSORS(bound)
+
+  // Indicates that the function is anonymous (the name field can be set
+  // through the API, which does not change this flag).
+  DECL_BOOLEAN_ACCESSORS(is_anonymous)
 
   // Indicates whether or not the code in the shared function support
   // deoptimization.
@@ -4588,14 +4818,24 @@
   static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
 
   // Bit positions in compiler_hints.
-  static const int kHasOnlySimpleThisPropertyAssignments = 0;
-  static const int kAllowLazyCompilation = 1;
-  static const int kLiveObjectsMayExist = 2;
-  static const int kCodeAgeShift = 3;
-  static const int kCodeAgeMask = 0x7;
-  static const int kOptimizationDisabled = 6;
-  static const int kStrictModeFunction = 7;
-  static const int kES5Native = 8;
+  static const int kCodeAgeSize = 3;
+  static const int kCodeAgeMask = (1 << kCodeAgeSize) - 1;
+
+  enum CompilerHints {
+    kHasOnlySimpleThisPropertyAssignments,
+    kAllowLazyCompilation,
+    kLiveObjectsMayExist,
+    kCodeAgeShift,
+    kOptimizationDisabled = kCodeAgeShift + kCodeAgeSize,
+    kStrictModeFunction,
+    kUsesArguments,
+    kHasDuplicateParameters,
+    kNative,
+    kBoundFunction,
+    kIsAnonymous,
+    kNameShouldPrintAsAnonymous,
+    kCompilerHintsCount  // Pseudo entry
+  };
 
  private:
 #if V8_HOST_ARCH_32_BIT
@@ -4608,28 +4848,31 @@
   static const int kCompilerHintsSize = kIntSize;
 #endif
 
+  STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
+                SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
+
  public:
   // Constants for optimizing codegen for strict mode function and
-  // es5 native tests.
+  // native tests.
   // Allows to use byte-widgh instructions.
   static const int kStrictModeBitWithinByte =
       (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
 
-  static const int kES5NativeBitWithinByte =
-      (kES5Native + kCompilerHintsSmiTagSize) % kBitsPerByte;
+  static const int kNativeBitWithinByte =
+      (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
   static const int kStrictModeByteOffset = kCompilerHintsOffset +
       (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
-  static const int kES5NativeByteOffset = kCompilerHintsOffset +
-      (kES5Native + kCompilerHintsSmiTagSize) / kBitsPerByte;
+  static const int kNativeByteOffset = kCompilerHintsOffset +
+      (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
 #elif __BYTE_ORDER == __BIG_ENDIAN
   static const int kStrictModeByteOffset = kCompilerHintsOffset +
       (kCompilerHintsSize - 1) -
       ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
-  static const int kES5NativeByteOffset = kCompilerHintsOffset +
+  static const int kNativeByteOffset = kCompilerHintsOffset +
       (kCompilerHintsSize - 1) -
-      ((kES5Native + kCompilerHintsSmiTagSize) / kBitsPerByte);
+      ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
 #else
 #error Unknown byte ordering
 #endif
@@ -4686,9 +4929,6 @@
   // recompilation.
   inline bool IsMarkedForLazyRecompilation();
 
-  // Compute a hash code for the source code of this function.
-  uint32_t SourceHash();
-
   // Check whether or not this function is inlineable.
   bool IsInlineable();
 
@@ -4788,6 +5028,7 @@
   // Layout of the literals array.
   static const int kLiteralsPrefixSize = 1;
   static const int kLiteralGlobalContextIndex = 0;
+
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
 };
@@ -4826,7 +5067,6 @@
   static const int kSize = kContextOffset + kPointerSize;
 
  private:
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
 };
 
@@ -4882,7 +5122,6 @@
 // JavaScript global object.
 class JSGlobalObject: public GlobalObject {
  public:
-
   // Casting.
   static inline JSGlobalObject* cast(Object* obj);
 
@@ -5332,6 +5571,49 @@
 };
 
 
+class PolymorphicCodeCache: public Struct {
+ public:
+  DECL_ACCESSORS(cache, Object)
+
+  MUST_USE_RESULT MaybeObject* Update(MapList* maps,
+                                      Code::Flags flags,
+                                      Code* code);
+  Object* Lookup(MapList* maps, Code::Flags flags);
+
+  static inline PolymorphicCodeCache* cast(Object* obj);
+
+#ifdef OBJECT_PRINT
+  inline void PolymorphicCodeCachePrint() {
+    PolymorphicCodeCachePrint(stdout);
+  }
+  void PolymorphicCodeCachePrint(FILE* out);
+#endif
+#ifdef DEBUG
+  void PolymorphicCodeCacheVerify();
+#endif
+
+  static const int kCacheOffset = HeapObject::kHeaderSize;
+  static const int kSize = kCacheOffset + kPointerSize;
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCache);
+};
+
+
+class PolymorphicCodeCacheHashTable
+    : public HashTable<CodeCacheHashTableShape, HashTableKey*> {
+ public:
+  Object* Lookup(MapList* maps, int code_kind);
+  MUST_USE_RESULT MaybeObject* Put(MapList* maps, int code_kind, Code* code);
+
+  static inline PolymorphicCodeCacheHashTable* cast(Object* obj);
+
+  static const int kInitialSize = 64;
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCacheHashTable);
+};
+
+
 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
 
@@ -5370,7 +5652,6 @@
   static uint32_t MakeArrayIndexHash(uint32_t value, int length);
 
  private:
-
   uint32_t array_index() {
     ASSERT(is_array_index());
     return array_index_;
@@ -5427,6 +5708,7 @@
 #else
   inline void invalidate() { }
 #endif
+
  private:
   uint32_t type_;
 #ifdef DEBUG
@@ -5764,7 +6046,6 @@
 // The SeqString abstract class captures sequential string values.
 class SeqString: public String {
  public:
-
   // Casting.
   static inline SeqString* cast(Object* obj);
 
@@ -6199,14 +6480,37 @@
 
 
 // The JSProxy describes EcmaScript Harmony proxies
-class JSProxy: public HeapObject {
+class JSProxy: public JSReceiver {
  public:
   // [handler]: The handler property.
   DECL_ACCESSORS(handler, Object)
 
+  // [padding]: The padding slot (unused, see below).
+  DECL_ACCESSORS(padding, Object)
+
   // Casting.
   static inline JSProxy* cast(Object* obj);
 
+  bool HasPropertyWithHandler(String* name);
+
+  MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
+      String* name,
+      Object* value,
+      PropertyAttributes attributes,
+      StrictModeFlag strict_mode);
+
+  MUST_USE_RESULT MaybeObject* DeletePropertyWithHandler(
+      String* name,
+      DeleteMode mode);
+
+  MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
+      JSReceiver* receiver,
+      String* name,
+      bool* has_exception);
+
+  // Turn this into an (empty) JSObject.
+  void Fix();
+
   // Dispatched behavior.
 #ifdef OBJECT_PRINT
   inline void JSProxyPrint() {
@@ -6218,9 +6522,14 @@
   void JSProxyVerify();
 #endif
 
-  // Layout description.
+  // Layout description. We add padding so that a proxy has the same
+  // size as a virgin JSObject. This is essential for becoming a JSObject
+  // upon freeze.
   static const int kHandlerOffset = HeapObject::kHeaderSize;
-  static const int kSize = kHandlerOffset + kPointerSize;
+  static const int kPaddingOffset = kHandlerOffset + kPointerSize;
+  static const int kSize = kPaddingOffset + kPointerSize;
+
+  STATIC_CHECK(kSize == JSObject::kHeaderSize);
 
   typedef FixedBodyDescriptor<kHandlerOffset,
                               kHandlerOffset + kPointerSize,
@@ -6231,6 +6540,16 @@
 };
 
 
+// TODO(rossberg): Only a stub for now.
+class JSFunctionProxy: public JSProxy {
+ public:
+  // Casting.
+  static inline JSFunctionProxy* cast(Object* obj);
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy);
+};
+
 
 // Foreign describes objects pointing from JavaScript to C structures.
 // Since they cannot contain references to JS HeapObjects they can be
@@ -6531,6 +6850,7 @@
   DECL_ACCESSORS(instance_call_handler, Object)
   DECL_ACCESSORS(access_check_info, Object)
   DECL_ACCESSORS(flag, Smi)
+  DECL_ACCESSORS(prototype_attributes, Smi)
 
   // Following properties use flag bits.
   DECL_BOOLEAN_ACCESSORS(hidden_prototype)
@@ -6570,7 +6890,8 @@
   static const int kAccessCheckInfoOffset =
       kInstanceCallHandlerOffset + kPointerSize;
   static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
-  static const int kSize = kFlagOffset + kPointerSize;
+  static const int kPrototypeAttributesOffset = kFlagOffset + kPointerSize;
+  static const int kSize = kPrototypeAttributesOffset + kPointerSize;
 
  private:
   // Bit position in the flag, from least significant bit position.
diff --git a/src/parser.cc b/src/parser.cc
index 7ad6440..ece0cfe 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -411,6 +411,7 @@
   return result;
 }
 
+
 // ----------------------------------------------------------------------------
 // Target is a support class to facilitate manipulation of the
 // Parser's target_stack_ (the stack of potential 'break' and
@@ -536,7 +537,6 @@
 
 
 LexicalScope::~LexicalScope() {
-  parser_->top_scope_->Leave();
   parser_->top_scope_ = previous_scope_;
   parser_->lexical_scope_ = lexical_scope_parent_;
   parser_->with_nesting_level_ = previous_with_nesting_level_;
@@ -592,11 +592,11 @@
 FunctionLiteral* Parser::ParseProgram(Handle<String> source,
                                       bool in_global_context,
                                       StrictModeFlag strict_mode) {
-  CompilationZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
+  ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
 
   HistogramTimerScope timer(isolate()->counters()->parse());
   isolate()->counters()->total_parse_size()->Increment(source->length());
-  fni_ = new(zone()) FuncNameInferrer();
+  fni_ = new(zone()) FuncNameInferrer(isolate());
 
   // Initialize parser state.
   source->TryFlatten();
@@ -648,6 +648,7 @@
     }
     if (ok) {
       result = new(zone()) FunctionLiteral(
+          isolate(),
           no_name,
           top_scope_,
           body,
@@ -658,7 +659,8 @@
           0,
           0,
           source->length(),
-          false);
+          FunctionLiteral::ANONYMOUS_EXPRESSION,
+          false);  // Does not have duplicate parameters.
     } else if (stack_overflow_) {
       isolate()->StackOverflow();
     }
@@ -674,7 +676,7 @@
 }
 
 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
-  CompilationZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
+  ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
   HistogramTimerScope timer(isolate()->counters()->parse_lazy());
   Handle<String> source(String::cast(script_->source()));
   isolate()->counters()->total_parse_size()->Increment(source->length());
@@ -707,7 +709,7 @@
   ASSERT(target_stack_ == NULL);
 
   Handle<String> name(String::cast(shared_info->name()));
-  fni_ = new(zone()) FuncNameInferrer();
+  fni_ = new(zone()) FuncNameInferrer(isolate());
   fni_->PushEnclosingName(name);
 
   mode_ = PARSE_EAGERLY;
@@ -717,7 +719,6 @@
 
   {
     // Parse the function literal.
-    Handle<String> no_name = isolate()->factory()->empty_symbol();
     Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
     if (!info->closure().is_null()) {
       scope = Scope::DeserializeScopeChain(info, scope);
@@ -728,12 +729,17 @@
       top_scope_->EnableStrictMode();
     }
 
-    FunctionLiteralType type =
-        shared_info->is_expression() ? EXPRESSION : DECLARATION;
+    FunctionLiteral::Type type = shared_info->is_expression()
+        ? (shared_info->is_anonymous()
+              ? FunctionLiteral::ANONYMOUS_EXPRESSION
+              : FunctionLiteral::NAMED_EXPRESSION)
+        : FunctionLiteral::DECLARATION;
     bool ok = true;
     result = ParseFunctionLiteral(name,
-                                  false,    // Strict mode name already checked.
-                                  RelocInfo::kNoPosition, type, &ok);
+                                  false,  // Strict mode name already checked.
+                                  RelocInfo::kNoPosition,
+                                  type,
+                                  &ok);
     // Make sure the results agree.
     ASSERT(ok == (result != NULL));
   }
@@ -822,14 +828,24 @@
 // form expr.a = ...; expr.b = ...; etc.
 class InitializationBlockFinder : public ParserFinder {
  public:
-  InitializationBlockFinder()
-    : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {}
+  // We find and mark the initialization blocks in top level
+  // non-looping code only. This is because the optimization prevents
+  // reuse of the map transitions, so it should be used only for code
+  // that will only be run once.
+  InitializationBlockFinder(Scope* top_scope, Target* target)
+      : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
+                 !IsLoopTarget(target)),
+        first_in_block_(NULL),
+        last_in_block_(NULL),
+        block_size_(0) {}
 
   ~InitializationBlockFinder() {
+    if (!enabled_) return;
     if (InBlock()) EndBlock();
   }
 
   void Update(Statement* stat) {
+    if (!enabled_) return;
     Assignment* assignment = AsAssignment(stat);
     if (InBlock()) {
       if (BlockContinues(assignment)) {
@@ -850,6 +866,14 @@
   // the overhead exceeds the savings below this limit.
   static const int kMinInitializationBlock = 3;
 
+  static bool IsLoopTarget(Target* target) {
+    while (target != NULL) {
+      if (target->node()->AsIterationStatement() != NULL) return true;
+      target = target->previous();
+    }
+    return false;
+  }
+
   // Returns true if the expressions appear to denote the same object.
   // In the context of initialization blocks, we only consider expressions
   // of the form 'expr.x' or expr["x"].
@@ -912,6 +936,7 @@
 
   bool InBlock() { return first_in_block_ != NULL; }
 
+  const bool enabled_;
   Assignment* first_in_block_;
   Assignment* last_in_block_;
   int block_size_;
@@ -920,17 +945,18 @@
 };
 
 
-// A ThisNamedPropertyAssigmentFinder finds and marks statements of the form
+// A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
 // this.x = ...;, where x is a named property. It also determines whether a
 // function contains only assignments of this type.
-class ThisNamedPropertyAssigmentFinder : public ParserFinder {
+class ThisNamedPropertyAssignmentFinder : public ParserFinder {
  public:
-  explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate)
+  explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate)
       : isolate_(isolate),
         only_simple_this_property_assignments_(true),
-        names_(NULL),
-        assigned_arguments_(NULL),
-        assigned_constants_(NULL) {}
+        names_(0),
+        assigned_arguments_(0),
+        assigned_constants_(0) {
+  }
 
   void Update(Scope* scope, Statement* stat) {
     // Bail out if function already has property assignment that are
@@ -957,19 +983,17 @@
   // Returns a fixed array containing three elements for each assignment of the
   // form this.x = y;
   Handle<FixedArray> GetThisPropertyAssignments() {
-    if (names_ == NULL) {
+    if (names_.is_empty()) {
       return isolate_->factory()->empty_fixed_array();
     }
-    ASSERT(names_ != NULL);
-    ASSERT(assigned_arguments_ != NULL);
-    ASSERT_EQ(names_->length(), assigned_arguments_->length());
-    ASSERT_EQ(names_->length(), assigned_constants_->length());
+    ASSERT_EQ(names_.length(), assigned_arguments_.length());
+    ASSERT_EQ(names_.length(), assigned_constants_.length());
     Handle<FixedArray> assignments =
-        isolate_->factory()->NewFixedArray(names_->length() * 3);
-    for (int i = 0; i < names_->length(); i++) {
-      assignments->set(i * 3, *names_->at(i));
-      assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i)));
-      assignments->set(i * 3 + 2, *assigned_constants_->at(i));
+        isolate_->factory()->NewFixedArray(names_.length() * 3);
+    for (int i = 0; i < names_.length(); ++i) {
+      assignments->set(i * 3, *names_[i]);
+      assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i]));
+      assignments->set(i * 3 + 2, *assigned_constants_[i]);
     }
     return assignments;
   }
@@ -1026,18 +1050,37 @@
     AssignmentFromSomethingElse();
   }
 
+
+
+
+  // We will potentially reorder the property assignments, so they must be
+  // simple enough that the ordering does not matter.
   void AssignmentFromParameter(Handle<String> name, int index) {
-    EnsureAllocation();
-    names_->Add(name);
-    assigned_arguments_->Add(index);
-    assigned_constants_->Add(isolate_->factory()->undefined_value());
+    EnsureInitialized();
+    for (int i = 0; i < names_.length(); ++i) {
+      if (name->Equals(*names_[i])) {
+        assigned_arguments_[i] = index;
+        assigned_constants_[i] = isolate_->factory()->undefined_value();
+        return;
+      }
+    }
+    names_.Add(name);
+    assigned_arguments_.Add(index);
+    assigned_constants_.Add(isolate_->factory()->undefined_value());
   }
 
   void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
-    EnsureAllocation();
-    names_->Add(name);
-    assigned_arguments_->Add(-1);
-    assigned_constants_->Add(value);
+    EnsureInitialized();
+    for (int i = 0; i < names_.length(); ++i) {
+      if (name->Equals(*names_[i])) {
+        assigned_arguments_[i] = -1;
+        assigned_constants_[i] = value;
+        return;
+      }
+    }
+    names_.Add(name);
+    assigned_arguments_.Add(-1);
+    assigned_constants_.Add(value);
   }
 
   void AssignmentFromSomethingElse() {
@@ -1045,22 +1088,21 @@
     only_simple_this_property_assignments_ = false;
   }
 
-  void EnsureAllocation() {
-    if (names_ == NULL) {
-      ASSERT(assigned_arguments_ == NULL);
-      ASSERT(assigned_constants_ == NULL);
-      Zone* zone = isolate_->zone();
-      names_ = new(zone) ZoneStringList(4);
-      assigned_arguments_ = new(zone) ZoneList<int>(4);
-      assigned_constants_ = new(zone) ZoneObjectList(4);
+  void EnsureInitialized() {
+    if (names_.capacity() == 0) {
+      ASSERT(assigned_arguments_.capacity() == 0);
+      ASSERT(assigned_constants_.capacity() == 0);
+      names_.Initialize(4);
+      assigned_arguments_.Initialize(4);
+      assigned_constants_.Initialize(4);
     }
   }
 
   Isolate* isolate_;
   bool only_simple_this_property_assignments_;
-  ZoneStringList* names_;
-  ZoneList<int>* assigned_arguments_;
-  ZoneObjectList* assigned_constants_;
+  ZoneStringList names_;
+  ZoneList<int> assigned_arguments_;
+  ZoneObjectList assigned_constants_;
 };
 
 
@@ -1077,8 +1119,8 @@
   TargetScope scope(&this->target_stack_);
 
   ASSERT(processor != NULL);
-  InitializationBlockFinder block_finder;
-  ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
+  InitializationBlockFinder block_finder(top_scope_, target_stack_);
+  ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate());
   bool directive_prologue = true;     // Parsing directive prologue.
 
   while (peek() != end_token) {
@@ -1132,12 +1174,7 @@
       }
     }
 
-    // We find and mark the initialization blocks on top level code only.
-    // This is because the optimization prevents reuse of the map transitions,
-    // so it should be used only for code that will only be run once.
-    if (top_scope_->is_global_scope()) {
-      block_finder.Update(stat);
-    }
+    block_finder.Update(stat);
     // Find and mark all assignments to named properties in this (this.x =)
     if (top_scope_->is_function_scope()) {
       this_property_assignment_finder.Update(top_scope_, stat);
@@ -1247,7 +1284,7 @@
       // one must take great care not to treat it as a
       // fall-through. It is much easier just to wrap the entire
       // try-statement in a statement block and put the labels there
-      Block* result = new(zone()) Block(labels, 1, false);
+      Block* result = new(zone()) Block(isolate(), labels, 1, false);
       Target target(&this->target_stack_, result);
       TryStatement* statement = ParseTryStatement(CHECK_OK);
       if (statement) {
@@ -1269,9 +1306,6 @@
       return ParseFunctionDeclaration(ok);
     }
 
-    case Token::NATIVE:
-      return ParseNativeDeclaration(ok);
-
     case Token::DEBUGGER:
       stmt = ParseDebuggerStatement(ok);
       break;
@@ -1304,13 +1338,14 @@
   // to the calling function context.
   // Similarly, strict mode eval scope does not leak variable declarations to
   // the caller's scope so we declare all locals, too.
-  if (top_scope_->is_function_scope() ||
-      top_scope_->is_strict_mode_eval_scope()) {
+  Scope* declaration_scope = top_scope_->DeclarationScope();
+  if (declaration_scope->is_function_scope() ||
+      declaration_scope->is_strict_mode_eval_scope()) {
     // Declare the variable in the function scope.
-    var = top_scope_->LocalLookup(name);
+    var = declaration_scope->LocalLookup(name);
     if (var == NULL) {
       // Declare the name.
-      var = top_scope_->DeclareLocal(name, mode, Scope::VAR_OR_CONST);
+      var = declaration_scope->DeclareLocal(name, mode);
     } else {
       // The name was declared before; check for conflicting
       // re-declarations. If the previous declaration was a const or the
@@ -1326,7 +1361,7 @@
         Expression* expression =
             NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
                               type_string, name);
-        top_scope_->SetIllegalRedeclaration(expression);
+        declaration_scope->SetIllegalRedeclaration(expression);
       }
     }
   }
@@ -1347,14 +1382,18 @@
   // semantic issue as long as we keep the source order, but it may be
   // a performance issue since it may lead to repeated
   // Runtime::DeclareContextSlot() calls.
-  VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with());
-  top_scope_->AddDeclaration(new(zone()) Declaration(proxy, mode, fun));
+  VariableProxy* proxy = declaration_scope->NewUnresolved(name, false);
+  declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun));
 
   // For global const variables we bind the proxy to a variable.
-  if (mode == Variable::CONST && top_scope_->is_global_scope()) {
+  if (mode == Variable::CONST && declaration_scope->is_global_scope()) {
     ASSERT(resolve);  // should be set by all callers
     Variable::Kind kind = Variable::NORMAL;
-    var = new(zone()) Variable(top_scope_, name, Variable::CONST, true, kind);
+    var = new(zone()) Variable(declaration_scope,
+                               name,
+                               Variable::CONST,
+                               true,
+                               kind);
   }
 
   // If requested and we have a local variable, bind the proxy to the variable
@@ -1392,13 +1431,6 @@
 // declaration is resolved by looking up the function through a
 // callback provided by the extension.
 Statement* Parser::ParseNativeDeclaration(bool* ok) {
-  if (extension_ == NULL) {
-    ReportUnexpectedToken(Token::NATIVE);
-    *ok = false;
-    return NULL;
-  }
-
-  Expect(Token::NATIVE, CHECK_OK);
   Expect(Token::FUNCTION, CHECK_OK);
   Handle<String> name = ParseIdentifier(CHECK_OK);
   Expect(Token::LPAREN, CHECK_OK);
@@ -1417,7 +1449,7 @@
   // isn't lazily compiled. The extension structures are only
   // accessible while parsing the first time not when reparsing
   // because of lazy compilation.
-  top_scope_->ForceEagerCompilation();
+  top_scope_->DeclarationScope()->ForceEagerCompilation();
 
   // Compute the function template for the native function.
   v8::Handle<v8::FunctionTemplate> fun_template =
@@ -1443,10 +1475,10 @@
   // introduced dynamically when we meet their declarations, whereas
   // other functions are setup when entering the surrounding scope.
   SharedFunctionInfoLiteral* lit =
-      new(zone()) SharedFunctionInfoLiteral(shared);
+      new(zone()) SharedFunctionInfoLiteral(isolate(), shared);
   VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
   return new(zone()) ExpressionStatement(new(zone()) Assignment(
-      Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
+      isolate(), Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
 }
 
 
@@ -1455,12 +1487,13 @@
   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
   Expect(Token::FUNCTION, CHECK_OK);
   int function_token_position = scanner().location().beg_pos;
-  bool is_reserved = false;
-  Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
+  bool is_strict_reserved = false;
+  Handle<String> name = ParseIdentifierOrStrictReservedWord(
+      &is_strict_reserved, CHECK_OK);
   FunctionLiteral* fun = ParseFunctionLiteral(name,
-                                              is_reserved,
+                                              is_strict_reserved,
                                               function_token_position,
-                                              DECLARATION,
+                                              FunctionLiteral::DECLARATION,
                                               CHECK_OK);
   // Even if we're not at the top-level of the global or a function
   // scope, we treat is as such and introduce the function with it's
@@ -1478,12 +1511,16 @@
   // (ECMA-262, 3rd, 12.2)
   //
   // Construct block expecting 16 statements.
-  Block* result = new(zone()) Block(labels, 16, false);
+  Block* result = new(zone()) Block(isolate(), labels, 16, false);
   Target target(&this->target_stack_, result);
   Expect(Token::LBRACE, CHECK_OK);
+  InitializationBlockFinder block_finder(top_scope_, target_stack_);
   while (peek() != Token::RBRACE) {
     Statement* stat = ParseStatement(NULL, CHECK_OK);
-    if (stat && !stat->IsEmpty()) result->AddStatement(stat);
+    if (stat && !stat->IsEmpty()) {
+      result->AddStatement(stat);
+      block_finder.Update(stat);
+    }
   }
   Expect(Token::RBRACE, CHECK_OK);
   return result;
@@ -1494,8 +1531,8 @@
   // VariableStatement ::
   //   VariableDeclarations ';'
 
-  Expression* dummy;  // to satisfy the ParseVariableDeclarations() signature
-  Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK);
+  Handle<String> ignore;
+  Block* result = ParseVariableDeclarations(true, &ignore, CHECK_OK);
   ExpectSemicolon(CHECK_OK);
   return result;
 }
@@ -1513,18 +1550,19 @@
 // to initialize it properly. This mechanism is used for the parsing
 // of 'for-in' loops.
 Block* Parser::ParseVariableDeclarations(bool accept_IN,
-                                         Expression** var,
+                                         Handle<String>* out,
                                          bool* ok) {
   // VariableDeclarations ::
   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
 
   Variable::Mode mode = Variable::VAR;
   bool is_const = false;
+  Scope* declaration_scope = top_scope_->DeclarationScope();
   if (peek() == Token::VAR) {
     Consume(Token::VAR);
   } else if (peek() == Token::CONST) {
     Consume(Token::CONST);
-    if (top_scope_->is_strict_mode()) {
+    if (declaration_scope->is_strict_mode()) {
       ReportMessage("strict_const", Vector<const char*>::empty());
       *ok = false;
       return NULL;
@@ -1548,19 +1586,19 @@
   // is inside an initializer block, it is ignored.
   //
   // Create new block with one expected declaration.
-  Block* block = new(zone()) Block(NULL, 1, true);
-  VariableProxy* last_var = NULL;  // the last variable declared
+  Block* block = new(zone()) Block(isolate(), NULL, 1, true);
   int nvars = 0;  // the number of variables declared
+  Handle<String> name;
   do {
     if (fni_ != NULL) fni_->Enter();
 
     // Parse variable name.
     if (nvars > 0) Consume(Token::COMMA);
-    Handle<String> name = ParseIdentifier(CHECK_OK);
+    name = ParseIdentifier(CHECK_OK);
     if (fni_ != NULL) fni_->PushVariableName(name);
 
     // Strict mode variables may not be named eval or arguments
-    if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
+    if (declaration_scope->is_strict_mode() && IsEvalOrArguments(name)) {
       ReportMessage("strict_var_name", Vector<const char*>::empty());
       *ok = false;
       return NULL;
@@ -1578,11 +1616,10 @@
     // If we have a const declaration, in an inner scope, the proxy is always
     // bound to the declared variable (independent of possibly surrounding with
     // statements).
-    last_var = Declare(name, mode, NULL,
-                       is_const /* always bound for CONST! */,
-                       CHECK_OK);
+    Declare(name, mode, NULL, is_const /* always bound for CONST! */,
+            CHECK_OK);
     nvars++;
-    if (top_scope_->num_var_or_const() > kMaxNumFunctionLocals) {
+    if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
       ReportMessageAt(scanner().location(), "too_many_variables",
                       Vector<const char*>::empty());
       *ok = false;
@@ -1598,10 +1635,10 @@
     //
     //    var v; v = x;
     //
-    // In particular, we need to re-lookup 'v' as it may be a
-    // different 'v' than the 'v' in the declaration (if we are inside
-    // a 'with' statement that makes a object property with name 'v'
-    // visible).
+    // In particular, we need to re-lookup 'v' (in top_scope_, not
+    // declaration_scope) as it may be a different 'v' than the 'v' in the
+    // declaration (e.g., if we are inside a 'with' statement or 'catch'
+    // block).
     //
     // However, note that const declarations are different! A const
     // declaration of the form:
@@ -1616,6 +1653,7 @@
     // one - there is no re-lookup (see the last parameter of the
     // Declare() call above).
 
+    Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
     Expression* value = NULL;
     int position = -1;
     if (peek() == Token::ASSIGN) {
@@ -1623,7 +1661,11 @@
       position = scanner().location().beg_pos;
       value = ParseAssignmentExpression(accept_IN, CHECK_OK);
       // Don't infer if it is "a = function(){...}();"-like expression.
-      if (fni_ != NULL && value->AsCall() == NULL) fni_->Infer();
+      if (fni_ != NULL &&
+          value->AsCall() == NULL &&
+          value->AsCallNew() == NULL) {
+        fni_->Infer();
+      }
     }
 
     // Make sure that 'const c' actually initializes 'c' to undefined
@@ -1652,11 +1694,11 @@
     // browsers where the global object (window) has lots of
     // properties defined in prototype objects.
 
-    if (top_scope_->is_global_scope()) {
+    if (initialization_scope->is_global_scope()) {
       // Compute the arguments for the runtime call.
       ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
       // We have at least 1 parameter.
-      arguments->Add(new(zone()) Literal(name));
+      arguments->Add(NewLiteral(name));
       CallRuntime* initialize;
 
       if (is_const) {
@@ -1669,14 +1711,17 @@
         // the number of arguments (1 or 2).
         initialize =
             new(zone()) CallRuntime(
-              isolate()->factory()->InitializeConstGlobal_symbol(),
-              Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
-              arguments);
+                isolate(),
+                isolate()->factory()->InitializeConstGlobal_symbol(),
+                Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
+                arguments);
       } else {
         // Add strict mode.
         // We may want to pass singleton to avoid Literal allocations.
-        arguments->Add(NewNumberLiteral(
-            top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode));
+        StrictModeFlag flag = initialization_scope->is_strict_mode()
+            ? kStrictMode
+            : kNonStrictMode;
+        arguments->Add(NewNumberLiteral(flag));
 
         // Be careful not to assign a value to the global variable if
         // we're in a with. The initialization value should not
@@ -1693,9 +1738,10 @@
         // the number of arguments (2 or 3).
         initialize =
             new(zone()) CallRuntime(
-              isolate()->factory()->InitializeVarGlobal_symbol(),
-              Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
-              arguments);
+                isolate(),
+                isolate()->factory()->InitializeVarGlobal_symbol(),
+                Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
+                arguments);
       }
 
       block->AddStatement(new(zone()) ExpressionStatement(initialize));
@@ -1713,8 +1759,11 @@
     // the top context for variables). Sigh...
     if (value != NULL) {
       Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
+      bool in_with = is_const ? false : inside_with();
+      VariableProxy* proxy =
+          initialization_scope->NewUnresolved(name, in_with);
       Assignment* assignment =
-          new(zone()) Assignment(op, last_var, value, position);
+          new(zone()) Assignment(isolate(), op, proxy, value, position);
       if (block) {
         block->AddStatement(new(zone()) ExpressionStatement(assignment));
       }
@@ -1723,10 +1772,10 @@
     if (fni_ != NULL) fni_->Leave();
   } while (peek() == Token::COMMA);
 
-  if (!is_const && nvars == 1) {
-    // We have a single, non-const variable.
-    ASSERT(last_var != NULL);
-    *var = last_var;
+  // 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) {
+    *out = name;
   }
 
   return block;
@@ -1751,7 +1800,7 @@
   //   Identifier ':' Statement
   bool starts_with_idenfifier = peek_any_identifier();
   Expression* expr = ParseExpression(true, CHECK_OK);
-  if (peek() == Token::COLON && starts_with_idenfifier && expr &&
+  if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
       expr->AsVariableProxy() != NULL &&
       !expr->AsVariableProxy()->is_this()) {
     // Expression is a single identifier, and not, e.g., a parenthesized
@@ -1781,6 +1830,20 @@
     return ParseStatement(labels, ok);
   }
 
+  // If we have an extension, we allow a native function declaration.
+  // A native function declaration starts with "native function" with
+  // no line-terminator between the two words.
+  if (extension_ != NULL &&
+      peek() == Token::FUNCTION &&
+      !scanner().HasAnyLineTerminatorBeforeNext() &&
+      expr != NULL &&
+      expr->AsVariableProxy() != NULL &&
+      expr->AsVariableProxy()->name()->Equals(
+          isolate()->heap()->native_symbol()) &&
+      !scanner().literal_contains_escapes()) {
+    return ParseNativeDeclaration(ok);
+  }
+
   // Parsed expression statement.
   ExpectSemicolon(CHECK_OK);
   return new(zone()) ExpressionStatement(expr);
@@ -1803,7 +1866,8 @@
   } else {
     else_statement = EmptyStatement();
   }
-  return new(zone()) IfStatement(condition, then_statement, else_statement);
+  return new(zone()) IfStatement(
+      isolate(), condition, then_statement, else_statement);
 }
 
 
@@ -1814,7 +1878,7 @@
   Expect(Token::CONTINUE, CHECK_OK);
   Handle<String> label = Handle<String>::null();
   Token::Value tok = peek();
-  if (!scanner().has_line_terminator_before_next() &&
+  if (!scanner().HasAnyLineTerminatorBeforeNext() &&
       tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
     label = ParseIdentifier(CHECK_OK);
   }
@@ -1844,7 +1908,7 @@
   Expect(Token::BREAK, CHECK_OK);
   Handle<String> label;
   Token::Value tok = peek();
-  if (!scanner().has_line_terminator_before_next() &&
+  if (!scanner().HasAnyLineTerminatorBeforeNext() &&
       tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
     label = ParseIdentifier(CHECK_OK);
   }
@@ -1886,14 +1950,16 @@
   // function. See ECMA-262, section 12.9, page 67.
   //
   // To be consistent with KJS we report the syntax error at runtime.
-  if (!top_scope_->is_function_scope()) {
+  Scope* declaration_scope = top_scope_->DeclarationScope();
+  if (declaration_scope->is_global_scope() ||
+      declaration_scope->is_eval_scope()) {
     Handle<String> type = isolate()->factory()->illegal_return_symbol();
     Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
     return new(zone()) ExpressionStatement(throw_error);
   }
 
   Token::Value tok = peek();
-  if (scanner().has_line_terminator_before_next() ||
+  if (scanner().HasAnyLineTerminatorBeforeNext() ||
       tok == Token::SEMICOLON ||
       tok == Token::RBRACE ||
       tok == Token::EOS) {
@@ -1907,35 +1973,31 @@
 }
 
 
-Block* Parser::WithHelper(Expression* obj,
-                          ZoneStringList* labels,
-                          bool is_catch_block,
-                          bool* ok) {
+Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) {
   // Parse the statement and collect escaping labels.
-  ZoneList<Label*>* target_list = new(zone()) ZoneList<Label*>(0);
-  TargetCollector collector(target_list);
+  TargetCollector collector;
   Statement* stat;
   { Target target(&this->target_stack_, &collector);
     with_nesting_level_++;
-    top_scope_->RecordWithStatement();
+    top_scope_->DeclarationScope()->RecordWithStatement();
     stat = ParseStatement(labels, CHECK_OK);
     with_nesting_level_--;
   }
   // Create resulting block with two statements.
   // 1: Evaluate the with expression.
   // 2: The try-finally block evaluating the body.
-  Block* result = new(zone()) Block(NULL, 2, false);
+  Block* result = new(zone()) Block(isolate(), NULL, 2, false);
 
   if (result != NULL) {
-    result->AddStatement(new(zone()) WithEnterStatement(obj, is_catch_block));
+    result->AddStatement(new(zone()) EnterWithContextStatement(obj));
 
     // Create body block.
-    Block* body = new(zone()) Block(NULL, 1, false);
+    Block* body = new(zone()) Block(isolate(), NULL, 1, false);
     body->AddStatement(stat);
 
     // Create exit block.
-    Block* exit = new(zone()) Block(NULL, 1, false);
-    exit->AddStatement(new(zone()) WithExitStatement());
+    Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
+    exit->AddStatement(new(zone()) ExitContextStatement());
 
     // Return a try-finally statement.
     TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit);
@@ -1962,7 +2024,7 @@
   Expression* expr = ParseExpression(true, CHECK_OK);
   Expect(Token::RPAREN, CHECK_OK);
 
-  return WithHelper(expr, labels, false, CHECK_OK);
+  return WithHelper(expr, labels, CHECK_OK);
 }
 
 
@@ -1995,7 +2057,7 @@
     statements->Add(stat);
   }
 
-  return new(zone()) CaseClause(label, statements, pos);
+  return new(zone()) CaseClause(isolate(), label, statements, pos);
 }
 
 
@@ -2004,7 +2066,7 @@
   // SwitchStatement ::
   //   'switch' '(' Expression ')' '{' CaseClause* '}'
 
-  SwitchStatement* statement = new(zone()) SwitchStatement(labels);
+  SwitchStatement* statement = new(zone()) SwitchStatement(isolate(), labels);
   Target target(&this->target_stack_, statement);
 
   Expect(Token::SWITCH, CHECK_OK);
@@ -2032,7 +2094,7 @@
 
   Expect(Token::THROW, CHECK_OK);
   int pos = scanner().location().beg_pos;
-  if (scanner().has_line_terminator_before_next()) {
+  if (scanner().HasAnyLineTerminatorBeforeNext()) {
     ReportMessage("newline_after_throw", Vector<const char*>::empty());
     *ok = false;
     return NULL;
@@ -2040,7 +2102,8 @@
   Expression* exception = ParseExpression(true, CHECK_OK);
   ExpectSemicolon(CHECK_OK);
 
-  return new(zone()) ExpressionStatement(new(zone()) Throw(exception, pos));
+  return new(zone()) ExpressionStatement(
+      new(zone()) Throw(isolate(), exception, pos));
 }
 
 
@@ -2058,18 +2121,13 @@
 
   Expect(Token::TRY, CHECK_OK);
 
-  ZoneList<Label*>* target_list = new(zone()) ZoneList<Label*>(0);
-  TargetCollector collector(target_list);
+  TargetCollector try_collector;
   Block* try_block;
 
-  { Target target(&this->target_stack_, &collector);
+  { Target target(&this->target_stack_, &try_collector);
     try_block = ParseBlock(NULL, CHECK_OK);
   }
 
-  Block* catch_block = NULL;
-  Variable* catch_var = NULL;
-  Block* finally_block = NULL;
-
   Token::Value tok = peek();
   if (tok != Token::CATCH && tok != Token::FINALLY) {
     ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
@@ -2078,18 +2136,19 @@
   }
 
   // If we can break out from the catch block and there is a finally block,
-  // then we will need to collect jump targets from the catch block. Since
-  // we don't know yet if there will be a finally block, we always collect
-  // the jump targets.
-  ZoneList<Label*>* catch_target_list = new(zone()) ZoneList<Label*>(0);
-  TargetCollector catch_collector(catch_target_list);
-  bool has_catch = false;
+  // then we will need to collect escaping targets from the catch
+  // block. Since we don't know yet if there will be a finally block, we
+  // always collect the targets.
+  TargetCollector catch_collector;
+  Scope* catch_scope = NULL;
+  Variable* catch_variable = NULL;
+  Block* catch_block = NULL;
+  Handle<String> name;
   if (tok == Token::CATCH) {
-    has_catch = true;
     Consume(Token::CATCH);
 
     Expect(Token::LPAREN, CHECK_OK);
-    Handle<String> name = ParseIdentifier(CHECK_OK);
+    name = ParseIdentifier(CHECK_OK);
 
     if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
       ReportMessage("strict_catch_variable", Vector<const char*>::empty());
@@ -2100,17 +2159,39 @@
     Expect(Token::RPAREN, CHECK_OK);
 
     if (peek() == Token::LBRACE) {
-      // Allocate a temporary for holding the finally state while
-      // executing the finally block.
-      catch_var =
-          top_scope_->NewTemporary(isolate()->factory()->catch_var_symbol());
-      Literal* name_literal = new(zone()) Literal(name);
-      VariableProxy* catch_var_use = new(zone()) VariableProxy(catch_var);
-      Expression* obj =
-          new(zone()) CatchExtensionObject(name_literal, catch_var_use);
+      // Rewrite the catch body B to a single statement block
+      // { try B finally { PopContext }}.
+      Block* inner_body;
+      // We need to collect escapes from the body for both the inner
+      // try/finally used to pop the catch context and any possible outer
+      // try/finally.
+      TargetCollector inner_collector;
       { Target target(&this->target_stack_, &catch_collector);
-        catch_block = WithHelper(obj, NULL, true, CHECK_OK);
+        { Target target(&this->target_stack_, &inner_collector);
+          catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
+          if (top_scope_->is_strict_mode()) {
+            catch_scope->EnableStrictMode();
+          }
+          catch_variable = catch_scope->DeclareLocal(name, Variable::VAR);
+
+          Scope* saved_scope = top_scope_;
+          top_scope_ = catch_scope;
+          inner_body = ParseBlock(NULL, CHECK_OK);
+          top_scope_ = saved_scope;
+        }
       }
+
+      // Create exit block.
+      Block* inner_finally = new(zone()) Block(isolate(), NULL, 1, false);
+      inner_finally->AddStatement(new(zone()) ExitContextStatement());
+
+      // Create a try/finally statement.
+      TryFinallyStatement* inner_try_finally =
+          new(zone()) TryFinallyStatement(inner_body, inner_finally);
+      inner_try_finally->set_escaping_targets(inner_collector.targets());
+
+      catch_block = new(zone()) Block(isolate(), NULL, 1, false);
+      catch_block->AddStatement(inner_try_finally);
     } else {
       Expect(Token::LBRACE, CHECK_OK);
     }
@@ -2118,45 +2199,48 @@
     tok = peek();
   }
 
-  if (tok == Token::FINALLY || !has_catch) {
+  Block* finally_block = NULL;
+  if (tok == Token::FINALLY || catch_block == NULL) {
     Consume(Token::FINALLY);
-    // Declare a variable for holding the finally state while
-    // executing the finally block.
     finally_block = ParseBlock(NULL, CHECK_OK);
   }
 
   // Simplify the AST nodes by converting:
-  //   'try { } catch { } finally { }'
+  //   'try B0 catch B1 finally B2'
   // to:
-  //   'try { try { } catch { } } finally { }'
+  //   'try { try B0 catch B1 } finally B2'
 
   if (catch_block != NULL && finally_block != NULL) {
-    VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var);
+    // If we have both, create an inner try/catch.
+    ASSERT(catch_scope != NULL && catch_variable != NULL);
     TryCatchStatement* statement =
-        new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block);
-    statement->set_escaping_targets(collector.targets());
-    try_block = new(zone()) Block(NULL, 1, false);
+        new(zone()) TryCatchStatement(try_block,
+                                      catch_scope,
+                                      catch_variable,
+                                      catch_block);
+    statement->set_escaping_targets(try_collector.targets());
+    try_block = new(zone()) Block(isolate(), NULL, 1, false);
     try_block->AddStatement(statement);
-    catch_block = NULL;
+    catch_block = NULL;  // Clear to indicate it's been handled.
   }
 
   TryStatement* result = NULL;
   if (catch_block != NULL) {
     ASSERT(finally_block == NULL);
-    VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var);
+    ASSERT(catch_scope != NULL && catch_variable != NULL);
     result =
-        new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block);
-    result->set_escaping_targets(collector.targets());
+        new(zone()) TryCatchStatement(try_block,
+                                      catch_scope,
+                                      catch_variable,
+                                      catch_block);
   } else {
     ASSERT(finally_block != NULL);
     result = new(zone()) TryFinallyStatement(try_block, finally_block);
-    // Add the jump targets of the try block and the catch block.
-    for (int i = 0; i < collector.targets()->length(); i++) {
-      catch_collector.AddTarget(collector.targets()->at(i));
-    }
-    result->set_escaping_targets(catch_collector.targets());
+    // Combine the jump targets of the try block and the possible catch block.
+    try_collector.targets()->AddAll(*catch_collector.targets());
   }
 
+  result->set_escaping_targets(try_collector.targets());
   return result;
 }
 
@@ -2166,7 +2250,7 @@
   // DoStatement ::
   //   'do' Statement 'while' '(' Expression ')' ';'
 
-  DoWhileStatement* loop = new(zone()) DoWhileStatement(labels);
+  DoWhileStatement* loop = new(zone()) DoWhileStatement(isolate(), labels);
   Target target(&this->target_stack_, loop);
 
   Expect(Token::DO, CHECK_OK);
@@ -2197,7 +2281,7 @@
   // WhileStatement ::
   //   'while' '(' Expression ')' Statement
 
-  WhileStatement* loop = new(zone()) WhileStatement(labels);
+  WhileStatement* loop = new(zone()) WhileStatement(isolate(), labels);
   Target target(&this->target_stack_, loop);
 
   Expect(Token::WHILE, CHECK_OK);
@@ -2221,11 +2305,13 @@
   Expect(Token::LPAREN, CHECK_OK);
   if (peek() != Token::SEMICOLON) {
     if (peek() == Token::VAR || peek() == Token::CONST) {
-      Expression* each = NULL;
+      Handle<String> name;
       Block* variable_statement =
-          ParseVariableDeclarations(false, &each, CHECK_OK);
-      if (peek() == Token::IN && each != NULL) {
-        ForInStatement* loop = new(zone()) ForInStatement(labels);
+          ParseVariableDeclarations(false, &name, CHECK_OK);
+
+      if (peek() == Token::IN && !name.is_null()) {
+        VariableProxy* each = top_scope_->NewUnresolved(name, inside_with());
+        ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
         Target target(&this->target_stack_, loop);
 
         Expect(Token::IN, CHECK_OK);
@@ -2234,7 +2320,7 @@
 
         Statement* body = ParseStatement(NULL, CHECK_OK);
         loop->Initialize(each, enumerable, body);
-        Block* result = new(zone()) Block(NULL, 2, false);
+        Block* result = new(zone()) Block(isolate(), NULL, 2, false);
         result->AddStatement(variable_statement);
         result->AddStatement(loop);
         // Parsed for-in loop w/ variable/const declaration.
@@ -2255,7 +2341,7 @@
               isolate()->factory()->invalid_lhs_in_for_in_symbol();
           expression = NewThrowReferenceError(type);
         }
-        ForInStatement* loop = new(zone()) ForInStatement(labels);
+        ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
         Target target(&this->target_stack_, loop);
 
         Expect(Token::IN, CHECK_OK);
@@ -2274,7 +2360,7 @@
   }
 
   // Standard 'for' loop
-  ForStatement* loop = new(zone()) ForStatement(labels);
+  ForStatement* loop = new(zone()) ForStatement(isolate(), labels);
   Target target(&this->target_stack_, loop);
 
   // Parsed initializer at this point.
@@ -2310,7 +2396,8 @@
     Expect(Token::COMMA, CHECK_OK);
     int position = scanner().location().beg_pos;
     Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
-    result = new(zone()) BinaryOperation(Token::COMMA, result, right, position);
+    result = new(zone()) BinaryOperation(
+        isolate(), Token::COMMA, result, right, position);
   }
   return result;
 }
@@ -2376,13 +2463,13 @@
     if ((op == Token::INIT_VAR
          || op == Token::INIT_CONST
          || op == Token::ASSIGN)
-        && (right->AsCall() == NULL)) {
+        && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
       fni_->Infer();
     }
     fni_->Leave();
   }
 
-  return new(zone()) Assignment(op, expression, right, pos);
+  return new(zone()) Assignment(isolate(), op, expression, right, pos);
 }
 
 
@@ -2404,8 +2491,8 @@
   Expect(Token::COLON, CHECK_OK);
   int right_position = scanner().peek_location().beg_pos;
   Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
-  return new(zone()) Conditional(expression, left, right,
-                         left_position, right_position);
+  return new(zone()) Conditional(
+      isolate(), expression, left, right, left_position, right_position);
 }
 
 
@@ -2492,12 +2579,12 @@
         x = NewCompareNode(cmp, x, y, position);
         if (cmp != op) {
           // The comparison was negated - add a NOT.
-          x = new(zone()) UnaryOperation(Token::NOT, x, position);
+          x = new(zone()) UnaryOperation(isolate(), Token::NOT, x, position);
         }
 
       } else {
         // We have a "normal" binary operation.
-        x = new(zone()) BinaryOperation(op, x, y, position);
+        x = new(zone()) BinaryOperation(isolate(), op, x, y, position);
       }
     }
   }
@@ -2514,15 +2601,15 @@
     bool is_strict = (op == Token::EQ_STRICT);
     Literal* x_literal = x->AsLiteral();
     if (x_literal != NULL && x_literal->IsNull()) {
-      return new(zone()) CompareToNull(is_strict, y);
+      return new(zone()) CompareToNull(isolate(), is_strict, y);
     }
 
     Literal* y_literal = y->AsLiteral();
     if (y_literal != NULL && y_literal->IsNull()) {
-      return new(zone()) CompareToNull(is_strict, x);
+      return new(zone()) CompareToNull(isolate(), is_strict, x);
     }
   }
-  return new(zone()) CompareOperation(op, x, y, position);
+  return new(zone()) CompareOperation(isolate(), op, x, y, position);
 }
 
 
@@ -2545,18 +2632,26 @@
     int position = scanner().location().beg_pos;
     Expression* expression = ParseUnaryExpression(CHECK_OK);
 
-    // Compute some expressions involving only number literals.
-    if (expression != NULL && expression->AsLiteral() &&
-        expression->AsLiteral()->handle()->IsNumber()) {
-      double value = expression->AsLiteral()->handle()->Number();
-      switch (op) {
-        case Token::ADD:
-          return expression;
-        case Token::SUB:
-          return NewNumberLiteral(-value);
-        case Token::BIT_NOT:
-          return NewNumberLiteral(~DoubleToInt32(value));
-        default: break;
+    if (expression != NULL && (expression->AsLiteral() != NULL)) {
+      Handle<Object> literal = expression->AsLiteral()->handle();
+      if (op == Token::NOT) {
+        // Convert the literal to a boolean condition and negate it.
+        bool condition = literal->ToBoolean()->IsTrue();
+        Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
+        return NewLiteral(result);
+      } else if (literal->IsNumber()) {
+        // Compute some expressions involving only number literals.
+        double value = literal->Number();
+        switch (op) {
+          case Token::ADD:
+            return expression;
+          case Token::SUB:
+            return NewNumberLiteral(-value);
+          case Token::BIT_NOT:
+            return NewNumberLiteral(~DoubleToInt32(value));
+          default:
+            break;
+        }
       }
     }
 
@@ -2570,7 +2665,7 @@
       }
     }
 
-    return new(zone()) UnaryOperation(op, expression, position);
+    return new(zone()) UnaryOperation(isolate(), op, expression, position);
 
   } else if (Token::IsCountOp(op)) {
     op = Next();
@@ -2591,7 +2686,8 @@
     }
 
     int position = scanner().location().beg_pos;
-    return new(zone()) CountOperation(op,
+    return new(zone()) CountOperation(isolate(),
+                                      op,
                                       true /* prefix */,
                                       expression,
                                       position);
@@ -2607,7 +2703,7 @@
   //   LeftHandSideExpression ('++' | '--')?
 
   Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
-  if (!scanner().has_line_terminator_before_next() &&
+  if (!scanner().HasAnyLineTerminatorBeforeNext() &&
       Token::IsCountOp(peek())) {
     // Signal a reference error if the expression is an invalid
     // left-hand side expression.  We could report this as a syntax
@@ -2627,7 +2723,8 @@
     Token::Value next = Next();
     int position = scanner().location().beg_pos;
     expression =
-        new(zone()) CountOperation(next,
+        new(zone()) CountOperation(isolate(),
+                                   next,
                                    false /* postfix */,
                                    expression,
                                    position);
@@ -2653,7 +2750,7 @@
         Consume(Token::LBRACK);
         int pos = scanner().location().beg_pos;
         Expression* index = ParseExpression(true, CHECK_OK);
-        result = new(zone()) Property(result, index, pos);
+        result = new(zone()) Property(isolate(), result, index, pos);
         Expect(Token::RBRACK, CHECK_OK);
         break;
       }
@@ -2691,7 +2788,10 @@
         Consume(Token::PERIOD);
         int pos = scanner().location().beg_pos;
         Handle<String> name = ParseIdentifierName(CHECK_OK);
-        result = new(zone()) Property(result, new(zone()) Literal(name), pos);
+        result = new(zone()) Property(isolate(),
+                                      result,
+                                      NewLiteral(name),
+                                      pos);
         if (fni_ != NULL) fni_->PushLiteralName(name);
         break;
       }
@@ -2727,7 +2827,8 @@
 
   if (!stack->is_empty()) {
     int last = stack->pop();
-    result = new(zone()) CallNew(result,
+    result = new(zone()) CallNew(isolate(),
+                                 result,
                                  new(zone()) ZoneList<Expression*>(0),
                                  last);
   }
@@ -2758,12 +2859,19 @@
     Expect(Token::FUNCTION, CHECK_OK);
     int function_token_position = scanner().location().beg_pos;
     Handle<String> name;
-    bool is_reserved_name = false;
+    bool is_strict_reserved_name = false;
     if (peek_any_identifier()) {
-        name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
+      name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
+                                                 CHECK_OK);
     }
-    result = ParseFunctionLiteral(name, is_reserved_name,
-                                  function_token_position, NESTED, CHECK_OK);
+    FunctionLiteral::Type type = name.is_null()
+        ? FunctionLiteral::ANONYMOUS_EXPRESSION
+        : FunctionLiteral::NAMED_EXPRESSION;
+    result = ParseFunctionLiteral(name,
+                                  is_strict_reserved_name,
+                                  function_token_position,
+                                  type,
+                                  CHECK_OK);
   } else {
     result = ParsePrimaryExpression(CHECK_OK);
   }
@@ -2774,7 +2882,15 @@
         Consume(Token::LBRACK);
         int pos = scanner().location().beg_pos;
         Expression* index = ParseExpression(true, CHECK_OK);
-        result = new(zone()) Property(result, index, pos);
+        result = new(zone()) Property(isolate(), result, index, pos);
+        if (fni_ != NULL) {
+          if (index->IsPropertyName()) {
+            fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
+          } else {
+            fni_->PushLiteralName(
+                isolate()->factory()->anonymous_function_symbol());
+          }
+        }
         Expect(Token::RBRACK, CHECK_OK);
         break;
       }
@@ -2782,7 +2898,10 @@
         Consume(Token::PERIOD);
         int pos = scanner().location().beg_pos;
         Handle<String> name = ParseIdentifierName(CHECK_OK);
-        result = new(zone()) Property(result, new(zone()) Literal(name), pos);
+        result = new(zone()) Property(isolate(),
+                                      result,
+                                      NewLiteral(name),
+                                      pos);
         if (fni_ != NULL) fni_->PushLiteralName(name);
         break;
       }
@@ -2791,7 +2910,7 @@
         // Consume one of the new prefixes (already parsed).
         ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
         int last = stack->pop();
-        result = new CallNew(result, args, last);
+        result = new(zone()) CallNew(isolate(), result, args, last);
         break;
       }
       default:
@@ -2833,6 +2952,9 @@
       return ReportMessage("unexpected_token_identifier",
                            Vector<const char*>::empty());
     case Token::FUTURE_RESERVED_WORD:
+      return ReportMessage("unexpected_reserved",
+                           Vector<const char*>::empty());
+    case Token::FUTURE_STRICT_RESERVED_WORD:
       return ReportMessage(top_scope_->is_strict_mode() ?
                                "unexpected_strict_reserved" :
                                "unexpected_token_identifier",
@@ -2872,28 +2994,30 @@
   switch (peek()) {
     case Token::THIS: {
       Consume(Token::THIS);
-      VariableProxy* recv = top_scope_->receiver();
-      result = recv;
+      result = new(zone()) VariableProxy(isolate(), top_scope_->receiver());
       break;
     }
 
     case Token::NULL_LITERAL:
       Consume(Token::NULL_LITERAL);
-      result = new(zone()) Literal(isolate()->factory()->null_value());
+      result = new(zone()) Literal(
+          isolate(), isolate()->factory()->null_value());
       break;
 
     case Token::TRUE_LITERAL:
       Consume(Token::TRUE_LITERAL);
-      result = new(zone()) Literal(isolate()->factory()->true_value());
+      result = new(zone()) Literal(
+          isolate(), isolate()->factory()->true_value());
       break;
 
     case Token::FALSE_LITERAL:
       Consume(Token::FALSE_LITERAL);
-      result = new(zone()) Literal(isolate()->factory()->false_value());
+      result = new(zone()) Literal(
+          isolate(), isolate()->factory()->false_value());
       break;
 
     case Token::IDENTIFIER:
-    case Token::FUTURE_RESERVED_WORD: {
+    case Token::FUTURE_STRICT_RESERVED_WORD: {
       Handle<String> name = ParseIdentifier(CHECK_OK);
       if (fni_ != NULL) fni_->PushVariableName(name);
       result = top_scope_->NewUnresolved(name,
@@ -2915,7 +3039,7 @@
     case Token::STRING: {
       Consume(Token::STRING);
       Handle<String> symbol = GetSymbol(CHECK_OK);
-      result = new(zone()) Literal(symbol);
+      result = NewLiteral(symbol);
       if (fni_ != NULL) fni_->PushLiteralName(symbol);
       break;
     }
@@ -3042,8 +3166,8 @@
     literals->set_map(isolate()->heap()->fixed_cow_array_map());
   }
 
-  return new(zone()) ArrayLiteral(literals, values,
-                          literal_index, is_simple, depth);
+  return new(zone()) ArrayLiteral(
+      isolate(), literals, values, literal_index, is_simple, depth);
 }
 
 
@@ -3304,6 +3428,7 @@
   bool is_keyword = Token::IsKeyword(next);
   if (next == Token::IDENTIFIER || next == Token::NUMBER ||
       next == Token::FUTURE_RESERVED_WORD ||
+      next == Token::FUTURE_STRICT_RESERVED_WORD ||
       next == Token::STRING || is_keyword) {
     Handle<String> name;
     if (is_keyword) {
@@ -3315,7 +3440,7 @@
         ParseFunctionLiteral(name,
                              false,   // reserved words are allowed here
                              RelocInfo::kNoPosition,
-                             DECLARATION,
+                             FunctionLiteral::ANONYMOUS_EXPRESSION,
                              CHECK_OK);
     // Allow any number of parameters for compatiabilty with JSC.
     // Specification only allows zero parameters for get and one for set.
@@ -3345,7 +3470,6 @@
   ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode());
 
   Expect(Token::LBRACE, CHECK_OK);
-  Scanner::Location loc = scanner().location();
 
   while (peek() != Token::RBRACE) {
     if (fni_ != NULL) fni_->Enter();
@@ -3358,11 +3482,12 @@
 
     switch (next) {
       case Token::FUTURE_RESERVED_WORD:
+      case Token::FUTURE_STRICT_RESERVED_WORD:
       case Token::IDENTIFIER: {
         bool is_getter = false;
         bool is_setter = false;
         Handle<String> id =
-            ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
+            ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
         if (fni_ != NULL) fni_->PushLiteralName(id);
 
         if ((is_getter || is_setter) && peek() != Token::COLON) {
@@ -3386,7 +3511,7 @@
         }
         // Failed to parse as get/set property, so it's just a property
         // called "get" or "set".
-        key = new(zone()) Literal(id);
+        key = NewLiteral(id);
         break;
       }
       case Token::STRING: {
@@ -3398,7 +3523,7 @@
           key = NewNumberLiteral(index);
           break;
         }
-        key = new(zone()) Literal(string);
+        key = NewLiteral(string);
         break;
       }
       case Token::NUMBER: {
@@ -3414,7 +3539,7 @@
         if (Token::IsKeyword(next)) {
           Consume(next);
           Handle<String> string = GetSymbol(CHECK_OK);
-          key = new(zone()) Literal(string);
+          key = NewLiteral(string);
         } else {
           // Unexpected token.
           Token::Value next = Next();
@@ -3467,13 +3592,14 @@
                                        &is_simple,
                                        &fast_elements,
                                        &depth);
-  return new(zone()) ObjectLiteral(constant_properties,
-                           properties,
-                           literal_index,
-                           is_simple,
-                           fast_elements,
-                           depth,
-                           has_function);
+  return new(zone()) ObjectLiteral(isolate(),
+                                   constant_properties,
+                                   properties,
+                                   literal_index,
+                                   is_simple,
+                                   fast_elements,
+                                   depth,
+                                   has_function);
 }
 
 
@@ -3492,7 +3618,8 @@
   Handle<String> js_flags = NextLiteralString(TENURED);
   Next();
 
-  return new(zone()) RegExpLiteral(js_pattern, js_flags, literal_index);
+  return new(zone()) RegExpLiteral(
+      isolate(), js_pattern, js_flags, literal_index);
 }
 
 
@@ -3520,29 +3647,29 @@
 }
 
 
-FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
-                                              bool name_is_reserved,
+FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
+                                              bool name_is_strict_reserved,
                                               int function_token_position,
-                                              FunctionLiteralType type,
+                                              FunctionLiteral::Type type,
                                               bool* ok) {
   // Function ::
   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
-  bool is_named = !var_name.is_null();
 
-  // The name associated with this function. If it's a function expression,
-  // this is the actual function name, otherwise this is the name of the
-  // variable declared and initialized with the function (expression). In
-  // that case, we don't have a function name (it's empty).
-  Handle<String> name =
-      is_named ? var_name : isolate()->factory()->empty_symbol();
-  // The function name, if any.
-  Handle<String> function_name = isolate()->factory()->empty_symbol();
-  if (is_named && (type == EXPRESSION || type == NESTED)) {
-    function_name = name;
+  // Anonymous functions were passed either the empty symbol or a null
+  // handle as the function name.  Remember if we were passed a non-empty
+  // handle to decide whether to invoke function name inference.
+  bool should_infer_name = function_name.is_null();
+
+  // We want a non-null handle as the function name.
+  if (should_infer_name) {
+    function_name = isolate()->factory()->empty_symbol();
   }
 
   int num_parameters = 0;
-  Scope* scope = NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
+  // Function declarations are hoisted.
+  Scope* scope = (type == FunctionLiteral::DECLARATION)
+      ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false)
+      : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
   ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
   int materialized_literal_count;
   int expected_property_count;
@@ -3550,9 +3677,10 @@
   int end_pos;
   bool only_simple_this_property_assignments;
   Handle<FixedArray> this_property_assignments;
+  bool has_duplicate_parameters = false;
   // Parse function body.
   { LexicalScope lexical_scope(this, scope, isolate());
-    top_scope_->SetScopeName(name);
+    top_scope_->SetScopeName(function_name);
 
     //  FormalParameterList ::
     //    '(' (Identifier)*[','] ')'
@@ -3564,25 +3692,24 @@
 
     bool done = (peek() == Token::RPAREN);
     while (!done) {
-      bool is_reserved = false;
+      bool is_strict_reserved = false;
       Handle<String> param_name =
-          ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
+          ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
+                                              CHECK_OK);
 
       // Store locations for possible future error reports.
       if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
         name_loc = scanner().location();
       }
       if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
+        has_duplicate_parameters = true;
         dupe_loc = scanner().location();
       }
-      if (!reserved_loc.IsValid() && is_reserved) {
+      if (!reserved_loc.IsValid() && is_strict_reserved) {
         reserved_loc = scanner().location();
       }
 
-      Variable* parameter = top_scope_->DeclareLocal(param_name,
-                                                     Variable::VAR,
-                                                     Scope::PARAMETER);
-      top_scope_->AddParameter(parameter);
+      top_scope_->DeclareParameter(param_name);
       num_parameters++;
       if (num_parameters > kMaxNumFunctionParameters) {
         ReportMessageAt(scanner().location(), "too_many_parameters",
@@ -3603,46 +3730,56 @@
     // NOTE: We create a proxy and resolve it here so that in the
     // future we can change the AST to only refer to VariableProxies
     // instead of Variables and Proxis as is the case now.
-    if (!function_name.is_null() && function_name->length() > 0) {
+    if (type == FunctionLiteral::NAMED_EXPRESSION) {
       Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
       VariableProxy* fproxy =
           top_scope_->NewUnresolved(function_name, inside_with());
       fproxy->BindTo(fvar);
       body->Add(new(zone()) ExpressionStatement(
-                    new(zone()) Assignment(Token::INIT_CONST, fproxy,
-                                   new(zone()) ThisFunction(),
-                                   RelocInfo::kNoPosition)));
+          new(zone()) Assignment(isolate(),
+                                 Token::INIT_CONST,
+                                 fproxy,
+                                 new(zone()) ThisFunction(isolate()),
+                                 RelocInfo::kNoPosition)));
     }
 
-    // Determine if the function will be lazily compiled. The mode can
-    // only be PARSE_LAZILY if the --lazy flag is true.
+    // Determine if the function will be lazily compiled. The mode can only
+    // be PARSE_LAZILY if the --lazy flag is true.  We will not lazily
+    // compile if we do not have preparser data for the function.
     bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
                                top_scope_->outer_scope()->is_global_scope() &&
                                top_scope_->HasTrivialOuterContext() &&
-                               !parenthesized_function_);
+                               !parenthesized_function_ &&
+                               pre_data() != NULL);
     parenthesized_function_ = false;  // The bit was set for this function only.
 
-    int function_block_pos = scanner().location().beg_pos;
-    if (is_lazily_compiled && pre_data() != NULL) {
+    if (is_lazily_compiled) {
+      int function_block_pos = scanner().location().beg_pos;
       FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
       if (!entry.is_valid()) {
-        ReportInvalidPreparseData(name, CHECK_OK);
+        // There is no preparser data for the function, we will not lazily
+        // compile after all.
+        is_lazily_compiled = false;
+      } else {
+        end_pos = entry.end_pos();
+        if (end_pos <= function_block_pos) {
+          // End position greater than end of stream is safe, and hard to check.
+          ReportInvalidPreparseData(function_name, CHECK_OK);
+        }
+        isolate()->counters()->total_preparse_skipped()->Increment(
+            end_pos - function_block_pos);
+        // Seek to position just before terminal '}'.
+        scanner().SeekForward(end_pos - 1);
+        materialized_literal_count = entry.literal_count();
+        expected_property_count = entry.property_count();
+        if (entry.strict_mode()) top_scope_->EnableStrictMode();
+        only_simple_this_property_assignments = false;
+        this_property_assignments = isolate()->factory()->empty_fixed_array();
+        Expect(Token::RBRACE, CHECK_OK);
       }
-      end_pos = entry.end_pos();
-      if (end_pos <= function_block_pos) {
-        // End position greater than end of stream is safe, and hard to check.
-        ReportInvalidPreparseData(name, CHECK_OK);
-      }
-      isolate()->counters()->total_preparse_skipped()->Increment(
-          end_pos - function_block_pos);
-      // Seek to position just before terminal '}'.
-      scanner().SeekForward(end_pos - 1);
-      materialized_literal_count = entry.literal_count();
-      expected_property_count = entry.property_count();
-      only_simple_this_property_assignments = false;
-      this_property_assignments = isolate()->factory()->empty_fixed_array();
-      Expect(Token::RBRACE, CHECK_OK);
-    } else {
+    }
+
+    if (!is_lazily_compiled) {
       ParseSourceElements(body, Token::RBRACE, CHECK_OK);
 
       materialized_literal_count = lexical_scope.materialized_literal_count();
@@ -3657,7 +3794,7 @@
 
     // Validate strict mode.
     if (top_scope_->is_strict_mode()) {
-      if (IsEvalOrArguments(name)) {
+      if (IsEvalOrArguments(function_name)) {
         int position = function_token_position != RelocInfo::kNoPosition
             ? function_token_position
             : (start_pos > 0 ? start_pos - 1 : start_pos);
@@ -3679,7 +3816,7 @@
         *ok = false;
         return NULL;
       }
-      if (name_is_reserved) {
+      if (name_is_strict_reserved) {
         int position = function_token_position != RelocInfo::kNoPosition
             ? function_token_position
             : (start_pos > 0 ? start_pos - 1 : start_pos);
@@ -3700,7 +3837,8 @@
   }
 
   FunctionLiteral* function_literal =
-      new(zone()) FunctionLiteral(name,
+      new(zone()) FunctionLiteral(isolate(),
+                                  function_name,
                                   scope,
                                   body,
                                   materialized_literal_count,
@@ -3710,10 +3848,11 @@
                                   num_parameters,
                                   start_pos,
                                   end_pos,
-                                  (function_name->length() > 0));
+                                  type,
+                                  has_duplicate_parameters);
   function_literal->set_function_token_position(function_token_position);
 
-  if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
+  if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
   return function_literal;
 }
 
@@ -3729,7 +3868,7 @@
   if (extension_ != NULL) {
     // The extension structures are only accessible while parsing the
     // very first time not when reparsing because of lazy compilation.
-    top_scope_->ForceEagerCompilation();
+    top_scope_->DeclarationScope()->ForceEagerCompilation();
   }
 
   const Runtime::Function* function = Runtime::FunctionForSymbol(name);
@@ -3760,14 +3899,15 @@
   }
 
   // We have a valid intrinsics call or a call to a builtin.
-  return new(zone()) CallRuntime(name, function, args);
+  return new(zone()) CallRuntime(isolate(), name, function, args);
 }
 
 
 bool Parser::peek_any_identifier() {
   Token::Value next = peek();
   return next == Token::IDENTIFIER ||
-         next == Token::FUTURE_RESERVED_WORD;
+         next == Token::FUTURE_RESERVED_WORD ||
+         next == Token::FUTURE_STRICT_RESERVED_WORD;
 }
 
 
@@ -3805,7 +3945,7 @@
     Next();
     return;
   }
-  if (scanner().has_line_terminator_before_next() ||
+  if (scanner().HasAnyLineTerminatorBeforeNext() ||
       tok == Token::RBRACE ||
       tok == Token::EOS) {
     return;
@@ -3815,12 +3955,12 @@
 
 
 Literal* Parser::GetLiteralUndefined() {
-  return new(zone()) Literal(isolate()->factory()->undefined_value());
+  return NewLiteral(isolate()->factory()->undefined_value());
 }
 
 
 Literal* Parser::GetLiteralTheHole() {
-  return new(zone()) Literal(isolate()->factory()->the_hole_value());
+  return NewLiteral(isolate()->factory()->the_hole_value());
 }
 
 
@@ -3829,22 +3969,27 @@
 }
 
 
+// Parses and identifier that is valid for the current scope, in particular it
+// fails on strict mode future reserved keywords in a strict scope.
 Handle<String> Parser::ParseIdentifier(bool* ok) {
-  bool is_reserved;
-  return ParseIdentifierOrReservedWord(&is_reserved, ok);
+  if (top_scope_->is_strict_mode()) {
+    Expect(Token::IDENTIFIER, ok);
+  } else if (!Check(Token::IDENTIFIER)) {
+    Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+  }
+  if (!*ok) return Handle<String>();
+  return GetSymbol(ok);
 }
 
 
-Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
-                                                     bool* ok) {
-  *is_reserved = false;
-  if (top_scope_->is_strict_mode()) {
-    Expect(Token::IDENTIFIER, ok);
-  } else {
-    if (!Check(Token::IDENTIFIER)) {
-      Expect(Token::FUTURE_RESERVED_WORD, ok);
-      *is_reserved = true;
-    }
+// Parses and identifier or a strict mode future reserved word, and indicate
+// whether it is strict mode future reserved.
+Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
+    bool* is_strict_reserved, bool* ok) {
+  *is_strict_reserved = false;
+  if (!Check(Token::IDENTIFIER)) {
+    Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+    *is_strict_reserved = true;
   }
   if (!*ok) return Handle<String>();
   return GetSymbol(ok);
@@ -3854,8 +3999,9 @@
 Handle<String> Parser::ParseIdentifierName(bool* ok) {
   Token::Value next = Next();
   if (next != Token::IDENTIFIER &&
-          next != Token::FUTURE_RESERVED_WORD &&
-          !Token::IsKeyword(next)) {
+      next != Token::FUTURE_RESERVED_WORD &&
+      next != Token::FUTURE_STRICT_RESERVED_WORD &&
+      !Token::IsKeyword(next)) {
     ReportUnexpectedToken(next);
     *ok = false;
     return Handle<String>();
@@ -3896,12 +4042,12 @@
 }
 
 
-// This function reads an identifier and determines whether or not it
+// This function reads an identifier name and determines whether or not it
 // is 'get' or 'set'.
-Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
-                                                 bool* is_set,
-                                                 bool* ok) {
-  Handle<String> result = ParseIdentifier(ok);
+Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
+                                                     bool* is_set,
+                                                     bool* ok) {
+  Handle<String> result = ParseIdentifierName(ok);
   if (!*ok) return Handle<String>();
   if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
     const char* token = scanner().literal_ascii_string().start();
@@ -3970,7 +4116,7 @@
 
 
 Literal* Parser::NewNumberLiteral(double number) {
-  return new(zone()) Literal(isolate()->factory()->NewNumber(number, TENURED));
+  return NewLiteral(isolate()->factory()->NewNumber(number, TENURED));
 }
 
 
@@ -4017,10 +4163,15 @@
                                                                        TENURED);
 
   ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2);
-  args->Add(new(zone()) Literal(type));
-  args->Add(new(zone()) Literal(array));
-  return new(zone()) Throw(new(zone()) CallRuntime(constructor, NULL, args),
-                   scanner().location().beg_pos);
+  args->Add(NewLiteral(type));
+  args->Add(NewLiteral(array));
+  CallRuntime* call_constructor = new(zone()) CallRuntime(isolate(),
+                                                          constructor,
+                                                          NULL,
+                                                          args);
+  return new(zone()) Throw(isolate(),
+                           call_constructor,
+                           scanner().location().beg_pos);
 }
 
 // ----------------------------------------------------------------------------
@@ -4901,7 +5052,7 @@
                                   bool allow_lazy,
                                   ParserRecorder* recorder) {
   Isolate* isolate = Isolate::Current();
-  V8JavaScriptScanner scanner(isolate->unicode_cache());
+  JavaScriptScanner scanner(isolate->unicode_cache());
   scanner.Initialize(source);
   intptr_t stack_limit = isolate->stack_guard()->real_climit();
   if (!preparser::PreParser::PreParseProgram(&scanner,
@@ -4976,6 +5127,7 @@
     Parser parser(script, allow_natives_syntax, NULL, NULL);
     result = parser.ParseLazy(info);
   } else {
+    // Whether we allow %identifier(..) syntax.
     bool allow_natives_syntax =
         info->is_native() || FLAG_allow_natives_syntax;
     ScriptDataImpl* pre_data = info->pre_parse_data();
diff --git a/src/parser.h b/src/parser.h
index a7132ce..535b639 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -72,22 +72,14 @@
   FunctionEntry() : backing_(Vector<unsigned>::empty()) { }
 
   int start_pos() { return backing_[kStartPosOffset]; }
-  void set_start_pos(int value) { backing_[kStartPosOffset] = value; }
-
   int end_pos() { return backing_[kEndPosOffset]; }
-  void set_end_pos(int value) { backing_[kEndPosOffset] = value; }
-
   int literal_count() { return backing_[kLiteralCountOffset]; }
-  void set_literal_count(int value) { backing_[kLiteralCountOffset] = value; }
-
   int property_count() { return backing_[kPropertyCountOffset]; }
-  void set_property_count(int value) {
-    backing_[kPropertyCountOffset] = value;
-  }
+  bool strict_mode() { return backing_[kStrictModeOffset] != 0; }
 
   bool is_valid() { return backing_.length() > 0; }
 
-  static const int kSize = 4;
+  static const int kSize = 5;
 
  private:
   Vector<unsigned> backing_;
@@ -95,6 +87,7 @@
   static const int kEndPosOffset = 1;
   static const int kLiteralCountOffset = 2;
   static const int kPropertyCountOffset = 3;
+  static const int kStrictModeOffset = 4;
 };
 
 
@@ -443,7 +436,7 @@
                        const char* message,
                        Vector<Handle<String> > args);
 
- protected:
+ private:
   // Limit on number of function parameters is chosen arbitrarily.
   // Code::Flags uses only the low 17 bits of num-parameters to
   // construct a hashable id, so if more than 2^17 are allowed, this
@@ -473,7 +466,7 @@
   void ReportMessage(const char* message, Vector<const char*> args);
 
   bool inside_with() const { return with_nesting_level_ > 0; }
-  V8JavaScriptScanner& scanner()  { return scanner_; }
+  JavaScriptScanner& scanner()  { return scanner_; }
   Mode mode() const { return mode_; }
   ScriptDataImpl* pre_data() const { return pre_data_; }
 
@@ -491,17 +484,16 @@
   Statement* ParseNativeDeclaration(bool* ok);
   Block* ParseBlock(ZoneStringList* labels, bool* ok);
   Block* ParseVariableStatement(bool* ok);
-  Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok);
+  Block* ParseVariableDeclarations(bool accept_IN,
+                                   Handle<String>* out,
+                                   bool* ok);
   Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
                                                 bool* ok);
   IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
   Statement* ParseContinueStatement(bool* ok);
   Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
   Statement* ParseReturnStatement(bool* ok);
-  Block* WithHelper(Expression* obj,
-                    ZoneStringList* labels,
-                    bool is_catch_block,
-                    bool* ok);
+  Block* WithHelper(Expression* obj, ZoneStringList* labels, bool* ok);
   Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
   CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
   SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
@@ -560,17 +552,11 @@
   // in the object literal boilerplate.
   Handle<Object> GetBoilerplateValue(Expression* expression);
 
-  enum FunctionLiteralType {
-    EXPRESSION,
-    DECLARATION,
-    NESTED
-  };
-
   ZoneList<Expression*>* ParseArguments(bool* ok);
   FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
                                         bool name_is_reserved,
                                         int function_token_position,
-                                        FunctionLiteralType type,
+                                        FunctionLiteral::Type type,
                                         bool* ok);
 
 
@@ -633,11 +619,12 @@
   Literal* GetLiteralNumber(double value);
 
   Handle<String> ParseIdentifier(bool* ok);
-  Handle<String> ParseIdentifierOrReservedWord(bool* is_reserved, bool* ok);
+  Handle<String> ParseIdentifierOrStrictReservedWord(
+      bool* is_strict_reserved, bool* ok);
   Handle<String> ParseIdentifierName(bool* ok);
-  Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
-                                           bool* is_set,
-                                           bool* ok);
+  Handle<String> ParseIdentifierNameOrGetOrSet(bool* is_get,
+                                               bool* is_set,
+                                               bool* ok);
 
   // Strict mode validation of LValue expressions
   void CheckStrictModeLValue(Expression* expression,
@@ -675,9 +662,12 @@
   Expression* NewCall(Expression* expression,
                       ZoneList<Expression*>* arguments,
                       int pos) {
-    return new Call(expression, arguments, pos);
+    return new(zone()) Call(isolate(), expression, arguments, pos);
   }
 
+  inline Literal* NewLiteral(Handle<Object> handle) {
+    return new(zone()) Literal(isolate(), handle);
+  }
 
   // Create a number literal.
   Literal* NewNumberLiteral(double value);
@@ -705,7 +695,7 @@
   ZoneList<Handle<String> > symbol_cache_;
 
   Handle<Script> script_;
-  V8JavaScriptScanner scanner_;
+  JavaScriptScanner scanner_;
 
   Scope* top_scope_;
   int with_nesting_level_;
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index 6511328..5f283c3 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -166,23 +166,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  mprotect(address, size, PROT_READ);
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  mprotect(address, size, prot);
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -249,7 +232,6 @@
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // This function assumes that the layout of the file is as follows:
   // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
   // If we encounter an unexpected situation we abort scanning further entries.
@@ -306,7 +288,6 @@
   }
   free(lib_name);
   fclose(fp);
-#endif
 }
 
 
@@ -371,17 +352,15 @@
 
 
 
-Thread::Thread(Isolate* isolate, const Options& options)
+Thread::Thread(const Options& options)
     : data_(new PlatformData),
-      isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
+Thread::Thread(const char* name)
     : data_(new PlatformData),
-      isolate_(isolate),
       stack_size_(0) {
   set_name(name);
 }
@@ -399,7 +378,6 @@
   // one) so we initialize it here too.
   thread->data()->thread_ = pthread_self();
   ASSERT(thread->data()->thread_ != kNoThread);
-  Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
 }
@@ -594,8 +572,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 // ----------------------------------------------------------------------------
 // Cygwin profiler support.
 //
@@ -631,7 +607,7 @@
 class SamplerThread : public Thread {
  public:
   explicit SamplerThread(int interval)
-      : Thread(NULL, "SamplerThread"),
+      : Thread("SamplerThread"),
         interval_(interval) {}
 
   static void AddActiveSampler(Sampler* sampler) {
@@ -649,8 +625,7 @@
     ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
-      RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
-      instance_->Join();
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
       delete instance_;
       instance_ = NULL;
     }
@@ -773,7 +748,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
-
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 99264d2..9d9f1b7 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -181,20 +181,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -266,15 +252,12 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static unsigned StringToLong(char* buffer) {
   return static_cast<unsigned>(strtol(buffer, NULL, 16));  // NOLINT
 }
-#endif
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static const int MAP_LENGTH = 1024;
   int fd = open("/proc/self/maps", O_RDONLY);
   if (fd < 0) return;
@@ -311,7 +294,6 @@
     LOG(i::Isolate::Current(), SharedLibraryEvent(start_of_path, start, end));
   }
   close(fd);
-#endif
 }
 
 
@@ -398,17 +380,15 @@
 };
 
 
-Thread::Thread(Isolate* isolate, const Options& options)
+Thread::Thread(const Options& options)
     : data_(new PlatformData),
-      isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
+Thread::Thread(const char* name)
     : data_(new PlatformData),
-      isolate_(isolate),
       stack_size_(0) {
   set_name(name);
 }
@@ -426,7 +406,6 @@
   // one) so we initialize it here too.
   thread->data()->thread_ = pthread_self();
   ASSERT(thread->data()->thread_ != kNoThread);
-  Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
 }
@@ -591,8 +570,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 static pthread_t GetThreadID() {
   pthread_t thread_id = pthread_self();
   return thread_id;
@@ -660,7 +637,7 @@
   };
 
   explicit SignalSender(int interval)
-      : Thread(NULL, "SignalSender"),
+      : Thread("SignalSender"),
         interval_(interval) {}
 
   static void AddActiveSampler(Sampler* sampler) {
@@ -687,8 +664,7 @@
     ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
-      RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
-      instance_->Join();
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
       delete instance_;
       instance_ = NULL;
 
@@ -821,6 +797,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index d4d772c..37330be 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -78,13 +78,33 @@
 static Mutex* limit_mutex = NULL;
 
 
+static void* GetRandomMmapAddr() {
+  Isolate* isolate = Isolate::UncheckedCurrent();
+  // Note that the current isolate isn't set up in a call path via
+  // CpuFeatures::Probe. We don't care about randomization in this case because
+  // the code page is immediately freed.
+  if (isolate != NULL) {
+#ifdef V8_TARGET_ARCH_X64
+    uint64_t rnd1 = V8::RandomPrivate(isolate);
+    uint64_t rnd2 = V8::RandomPrivate(isolate);
+    uint64_t raw_addr = (rnd1 << 32) ^ rnd2;
+    raw_addr &= V8_UINT64_C(0x3ffffffff000);
+#else
+    uint32_t raw_addr = V8::RandomPrivate(isolate);
+    // The range 0x20000000 - 0x60000000 is relatively unpopulated across a
+    // variety of ASLR modes (PAE kernel, NX compat mode, etc).
+    raw_addr &= 0x3ffff000;
+    raw_addr += 0x20000000;
+#endif
+    return reinterpret_cast<void*>(raw_addr);
+  }
+  return NULL;
+}
+
+
 void OS::Setup() {
-  // Seed the random number generator.
-  // Convert the current time to a 64-bit integer first, before converting it
-  // to an unsigned. Going directly can cause an overflow and the seed to be
-  // set to all ones. The seed will be identical for different instances that
-  // call this setup code within the same millisecond.
-  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  // Seed the random number generator. We preserve microsecond resolution.
+  uint64_t seed = Ticks() ^ (getpid() << 16);
   srandom(static_cast<unsigned int>(seed));
   limit_mutex = CreateMutex();
 
@@ -367,10 +387,10 @@
 void* OS::Allocate(const size_t requested,
                    size_t* allocated,
                    bool is_executable) {
-  // TODO(805): Port randomization of allocated executable memory to Linux.
   const size_t msize = RoundUp(requested, sysconf(_SC_PAGESIZE));
   int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  void* addr = GetRandomMmapAddr();
+  void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (mbase == MAP_FAILED) {
     LOG(i::Isolate::Current(),
         StringEvent("OS::Allocate", "mmap failed"));
@@ -390,23 +410,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  mprotect(address, size, PROT_READ);
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  mprotect(address, size, prot);
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -483,7 +486,6 @@
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // This function assumes that the layout of the file is as follows:
   // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
   // If we encounter an unexpected situation we abort scanning further entries.
@@ -540,7 +542,6 @@
   }
   free(lib_name);
   fclose(fp);
-#endif
 }
 
 
@@ -548,7 +549,6 @@
 
 
 void OS::SignalCodeMovingGC() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Support for ll_prof.py.
   //
   // The Linux profiler built into the kernel logs all mmap's with
@@ -564,7 +564,6 @@
   ASSERT(addr != MAP_FAILED);
   munmap(addr, size);
   fclose(f);
-#endif
 }
 
 
@@ -607,7 +606,7 @@
 
 
 VirtualMemory::VirtualMemory(size_t size) {
-  address_ = mmap(NULL, size, PROT_NONE,
+  address_ = mmap(GetRandomMmapAddr(), size, PROT_NONE,
                   MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
                   kMmapFd, kMmapFdOffset);
   size_ = size;
@@ -653,17 +652,15 @@
   pthread_t thread_;  // Thread handle for pthread.
 };
 
-Thread::Thread(Isolate* isolate, const Options& options)
+Thread::Thread(const Options& options)
     : data_(new PlatformData()),
-      isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
+Thread::Thread(const char* name)
     : data_(new PlatformData()),
-      isolate_(isolate),
       stack_size_(0) {
   set_name(name);
 }
@@ -684,7 +681,6 @@
         0, 0, 0);
   thread->data()->thread_ = pthread_self();
   ASSERT(thread->data()->thread_ != kNoThread);
-  Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
 }
@@ -750,7 +746,6 @@
 
 class LinuxMutex : public Mutex {
  public:
-
   LinuxMutex() {
     pthread_mutexattr_t attrs;
     int result = pthread_mutexattr_init(&attrs);
@@ -759,6 +754,7 @@
     ASSERT(result == 0);
     result = pthread_mutex_init(&mutex_, &attrs);
     ASSERT(result == 0);
+    USE(result);
   }
 
   virtual ~LinuxMutex() { pthread_mutex_destroy(&mutex_); }
@@ -863,8 +859,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
 // Android runs a fairly new Linux kernel, so signal info is there,
 // but the C library doesn't have the structs defined.
@@ -975,7 +969,7 @@
   };
 
   explicit SignalSender(int interval)
-      : Thread(NULL, "SignalSender"),
+      : Thread("SignalSender"),
         vm_tgid_(getpid()),
         interval_(interval) {}
 
@@ -1012,8 +1006,7 @@
     ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
-      RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
-      instance_->Join();
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
       delete instance_;
       instance_ = NULL;
       RestoreSignalHandler();
@@ -1028,10 +1021,11 @@
       bool cpu_profiling_enabled =
           (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS);
       bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled();
-      if (cpu_profiling_enabled && !signal_handler_installed_)
+      if (cpu_profiling_enabled && !signal_handler_installed_) {
         InstallSignalHandler();
-      else if (!cpu_profiling_enabled && signal_handler_installed_)
+      } else if (!cpu_profiling_enabled && signal_handler_installed_) {
         RestoreSignalHandler();
+      }
       // When CPU profiling is enabled both JavaScript and C++ code is
       // profiled. We must not suspend.
       if (!cpu_profiling_enabled) {
@@ -1152,6 +1146,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 3e10b6a..be6e157 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -169,20 +169,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   usleep(1000 * milliseconds);
 }
@@ -248,7 +234,6 @@
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   unsigned int images_count = _dyld_image_count();
   for (unsigned int i = 0; i < images_count; ++i) {
     const mach_header* header = _dyld_get_image_header(i);
@@ -270,7 +255,6 @@
     LOG(Isolate::Current(),
         SharedLibraryEvent(_dyld_get_image_name(i), start, start + size));
   }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 }
 
 
@@ -398,17 +382,15 @@
   pthread_t thread_;  // Thread handle for pthread.
 };
 
-Thread::Thread(Isolate* isolate, const Options& options)
+Thread::Thread(const Options& options)
     : data_(new PlatformData),
-      isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
+Thread::Thread(const char* name)
     : data_(new PlatformData),
-      isolate_(isolate),
       stack_size_(0) {
   set_name(name);
 }
@@ -444,7 +426,6 @@
   thread->data()->thread_ = pthread_self();
   SetThreadName(thread->name());
   ASSERT(thread->data()->thread_ != kNoThread);
-  Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
 }
@@ -647,8 +628,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 class Sampler::PlatformData : public Malloced {
  public:
   PlatformData() : profiled_thread_(mach_thread_self()) {}
@@ -670,7 +649,7 @@
 class SamplerThread : public Thread {
  public:
   explicit SamplerThread(int interval)
-      : Thread(NULL, "SamplerThread"),
+      : Thread("SamplerThread"),
         interval_(interval) {}
 
   static void AddActiveSampler(Sampler* sampler) {
@@ -688,8 +667,7 @@
     ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
-      RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
-      instance_->Join();
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
       delete instance_;
       instance_ = NULL;
     }
@@ -825,6 +803,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index 295482d..8c2a863 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -217,20 +217,11 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
+void OS::Guard(void* address, const size_t size) {
   UNIMPLEMENTED();
 }
 
 
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   UNIMPLEMENTED();
 }
@@ -314,18 +305,16 @@
 };
 
 
-Thread::Thread(Isolate* isolate, const Options& options)
+Thread::Thread(const Options& options)
     : data_(new PlatformData()),
-      isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
   UNIMPLEMENTED();
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
+Thread::Thread(const char* name)
     : data_(new PlatformData()),
-      isolate_(isolate),
       stack_size_(0) {
   set_name(name);
   UNIMPLEMENTED();
@@ -439,7 +428,6 @@
   return new NullSemaphore(count);
 }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 
 class ProfileSampler::PlatformData  : public Malloced {
  public:
@@ -474,6 +462,5 @@
   UNIMPLEMENTED();
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index e90b3e8..973329b 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2006-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:
@@ -50,6 +50,7 @@
 #undef MAP_TYPE
 
 #include "v8.h"
+#include "v8threads.h"
 
 #include "platform.h"
 #include "vm-state-inl.h"
@@ -73,6 +74,9 @@
 }
 
 
+static Mutex* limit_mutex = NULL;
+
+
 void OS::Setup() {
   // Seed the random number generator.
   // Convert the current time to a 64-bit integer first, before converting it
@@ -81,6 +85,7 @@
   // call this setup code within the same millisecond.
   uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
   srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
 }
 
 
@@ -129,6 +134,9 @@
 
 
 static void UpdateAllocatedSpaceLimits(void* address, int size) {
+  ASSERT(limit_mutex != NULL);
+  ScopedLock lock(limit_mutex);
+
   lowest_ever_allocated = Min(lowest_ever_allocated, address);
   highest_ever_allocated =
       Max(highest_ever_allocated,
@@ -164,26 +172,13 @@
 
 
 void OS::Free(void* buf, const size_t length) {
+  // TODO(1240712): munmap has a return value which is ignored here.
   int result = munmap(buf, length);
   USE(result);
   ASSERT(result == 0);
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -255,15 +250,12 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static unsigned StringToLong(char* buffer) {
   return static_cast<unsigned>(strtol(buffer, NULL, 16));  // NOLINT
 }
-#endif
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static const int MAP_LENGTH = 1024;
   int fd = open("/proc/self/maps", O_RDONLY);
   if (fd < 0) return;
@@ -297,10 +289,9 @@
     // There may be no filename in this line.  Skip to next.
     if (start_of_path == NULL) continue;
     buffer[bytes_read] = 0;
-    LOG(SharedLibraryEvent(start_of_path, start, end));
+    LOG(i::Isolate::Current(), SharedLibraryEvent(start_of_path, start, end));
   }
   close(fd);
-#endif
 }
 
 
@@ -309,8 +300,30 @@
 
 
 int OS::StackWalk(Vector<OS::StackFrame> frames) {
-  UNIMPLEMENTED();
-  return 1;
+  int frames_size = frames.length();
+  ScopedVector<void*> addresses(frames_size);
+
+  int frames_count = backtrace(addresses.start(), frames_size);
+
+  char** symbols = backtrace_symbols(addresses.start(), frames_count);
+  if (symbols == NULL) {
+    return kStackWalkError;
+  }
+
+  for (int i = 0; i < frames_count; i++) {
+    frames[i].address = addresses[i];
+    // Format a text representation of the frame based on the information
+    // available.
+    SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen),
+             "%s",
+             symbols[i]);
+    // Make sure line termination is in place.
+    frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
+  }
+
+  free(symbols);
+
+  return frames_count;
 }
 
 
@@ -354,30 +367,26 @@
 
 bool VirtualMemory::Uncommit(void* address, size_t size) {
   return mmap(address, size, PROT_NONE,
-              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
+              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED,
               kMmapFd, kMmapFdOffset) != MAP_FAILED;
 }
 
 
 class Thread::PlatformData : public Malloced {
  public:
-  PlatformData() : thread_(kNoThread) {}
-
   pthread_t thread_;  // Thread handle for pthread.
 };
 
 
-Thread::Thread(Isolate* isolate, const Options& options)
-    : data_(new PlatformData()),
-      isolate_(isolate),
+Thread::Thread(const Options& options)
+    : data_(new PlatformData),
       stack_size_(options.stack_size) {
   set_name(options.name);
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
-    : data_(new PlatfromData()),
-      isolate_(isolate),
+Thread::Thread(const char* name)
+    : data_(new PlatformData),
       stack_size_(0) {
   set_name(name);
 }
@@ -395,7 +404,6 @@
   // one) so we initialize it here too.
   thread->data()->thread_ = pthread_self();
   ASSERT(thread->data()->thread_ != kNoThread);
-  Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
 }
@@ -416,7 +424,7 @@
     attr_ptr = &attr;
   }
   pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
-  ASSERT(IsValid());
+  ASSERT(data_->thread_ != kNoThread);
 }
 
 
@@ -461,7 +469,6 @@
 
 class OpenBSDMutex : public Mutex {
  public:
-
   OpenBSDMutex() {
     pthread_mutexattr_t attrs;
     int result = pthread_mutexattr_init(&attrs);
@@ -484,6 +491,16 @@
     return result;
   }
 
+  virtual bool TryLock() {
+    int result = pthread_mutex_trylock(&mutex_);
+    // Return false if the lock is busy and locking failed.
+    if (result == EBUSY) {
+      return false;
+    }
+    ASSERT(result == 0);  // Verify no other errors.
+    return true;
+  }
+
  private:
   pthread_mutex_t mutex_;   // Pthread mutex for POSIX platforms.
 };
@@ -536,11 +553,16 @@
 
   struct timespec ts;
   TIMEVAL_TO_TIMESPEC(&end_time, &ts);
+
+  int to = ts.tv_sec;
+
   while (true) {
     int result = sem_trywait(&sem_);
     if (result == 0) return true;  // Successfully got semaphore.
-    if (result == -1 && errno == ETIMEDOUT) return false;  // Timeout.
+    if (!to) return false;  // Timeout.
     CHECK(result == -1 && errno == EINTR);  // Signal caused spurious wakeup.
+    usleep(ts.tv_nsec / 1000);
+    to--;
   }
 }
 
@@ -550,35 +572,202 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-static Sampler* active_sampler_ = NULL;
-
-static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
-  USE(info);
-  if (signal != SIGPROF) return;
-  if (active_sampler_ == NULL) return;
-
-  TickSample sample;
-
-  // We always sample the VM state.
-  sample.state = VMState::current_state();
-
-  active_sampler_->Tick(&sample);
+static pthread_t GetThreadID() {
+  pthread_t thread_id = pthread_self();
+  return thread_id;
 }
 
 
 class Sampler::PlatformData : public Malloced {
  public:
-  PlatformData() {
-    signal_handler_installed_ = false;
+  PlatformData() : vm_tid_(GetThreadID()) {}
+
+  pthread_t vm_tid() const { return vm_tid_; }
+
+ private:
+  pthread_t vm_tid_;
+};
+
+
+static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
+  USE(info);
+  if (signal != SIGPROF) return;
+  Isolate* isolate = Isolate::UncheckedCurrent();
+  if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) {
+    // We require a fully initialized and entered isolate.
+    return;
+  }
+  if (v8::Locker::IsActive() &&
+      !isolate->thread_manager()->IsLockedByCurrentThread()) {
+    return;
   }
 
-  bool signal_handler_installed_;
-  struct sigaction old_signal_handler_;
-  struct itimerval old_timer_value_;
+  Sampler* sampler = isolate->logger()->sampler();
+  if (sampler == NULL || !sampler->IsActive()) return;
+
+  TickSample sample_obj;
+  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  if (sample == NULL) sample = &sample_obj;
+
+  // Extracting the sample from the context is extremely machine dependent.
+  ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
+  sample->state = isolate->current_vm_state();
+#if V8_HOST_ARCH_IA32
+  sample->pc = reinterpret_cast<Address>(ucontext->sc_eip);
+  sample->sp = reinterpret_cast<Address>(ucontext->sc_esp);
+  sample->fp = reinterpret_cast<Address>(ucontext->sc_ebp);
+#elif V8_HOST_ARCH_X64
+  sample->pc = reinterpret_cast<Address>(ucontext->sc_rip);
+  sample->sp = reinterpret_cast<Address>(ucontext->sc_rsp);
+  sample->fp = reinterpret_cast<Address>(ucontext->sc_rbp);
+#elif V8_HOST_ARCH_ARM
+  sample->pc = reinterpret_cast<Address>(ucontext->sc_r15);
+  sample->sp = reinterpret_cast<Address>(ucontext->sc_r13);
+  sample->fp = reinterpret_cast<Address>(ucontext->sc_r11);
+#endif
+  sampler->SampleStack(sample);
+  sampler->Tick(sample);
+}
+
+
+class SignalSender : public Thread {
+ public:
+  enum SleepInterval {
+    HALF_INTERVAL,
+    FULL_INTERVAL
+  };
+
+  explicit SignalSender(int interval)
+      : Thread("SignalSender"),
+        interval_(interval) {}
+
+  static void AddActiveSampler(Sampler* sampler) {
+    ScopedLock lock(mutex_);
+    SamplerRegistry::AddActiveSampler(sampler);
+    if (instance_ == NULL) {
+      // Install a signal handler.
+      struct sigaction sa;
+      sa.sa_sigaction = ProfilerSignalHandler;
+      sigemptyset(&sa.sa_mask);
+      sa.sa_flags = SA_RESTART | SA_SIGINFO;
+      signal_handler_installed_ =
+          (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
+
+      // Start a thread that sends SIGPROF signal to VM threads.
+      instance_ = new SignalSender(sampler->interval());
+      instance_->Start();
+    } else {
+      ASSERT(instance_->interval_ == sampler->interval());
+    }
+  }
+
+  static void RemoveActiveSampler(Sampler* sampler) {
+    ScopedLock lock(mutex_);
+    SamplerRegistry::RemoveActiveSampler(sampler);
+    if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
+      delete instance_;
+      instance_ = NULL;
+
+      // Restore the old signal handler.
+      if (signal_handler_installed_) {
+        sigaction(SIGPROF, &old_signal_handler_, 0);
+        signal_handler_installed_ = false;
+      }
+    }
+  }
+
+  // Implement Thread::Run().
+  virtual void Run() {
+    SamplerRegistry::State state;
+    while ((state = SamplerRegistry::GetState()) !=
+           SamplerRegistry::HAS_NO_SAMPLERS) {
+      bool cpu_profiling_enabled =
+          (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS);
+      bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled();
+      // When CPU profiling is enabled both JavaScript and C++ code is
+      // profiled. We must not suspend.
+      if (!cpu_profiling_enabled) {
+        if (rate_limiter_.SuspendIfNecessary()) continue;
+      }
+      if (cpu_profiling_enabled && runtime_profiler_enabled) {
+        if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) {
+          return;
+        }
+        Sleep(HALF_INTERVAL);
+        if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) {
+          return;
+        }
+        Sleep(HALF_INTERVAL);
+      } else {
+        if (cpu_profiling_enabled) {
+          if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile,
+                                                      this)) {
+            return;
+          }
+        }
+        if (runtime_profiler_enabled) {
+          if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile,
+                                                      NULL)) {
+            return;
+          }
+        }
+        Sleep(FULL_INTERVAL);
+      }
+    }
+  }
+
+  static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
+    if (!sampler->IsProfiling()) return;
+    SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender);
+    sender->SendProfilingSignal(sampler->platform_data()->vm_tid());
+  }
+
+  static void DoRuntimeProfile(Sampler* sampler, void* ignored) {
+    if (!sampler->isolate()->IsInitialized()) return;
+    sampler->isolate()->runtime_profiler()->NotifyTick();
+  }
+
+  void SendProfilingSignal(pthread_t tid) {
+    if (!signal_handler_installed_) return;
+    pthread_kill(tid, SIGPROF);
+  }
+
+  void Sleep(SleepInterval full_or_half) {
+    // Convert ms to us and subtract 100 us to compensate delays
+    // occuring during signal delivery.
+    useconds_t interval = interval_ * 1000 - 100;
+    if (full_or_half == HALF_INTERVAL) interval /= 2;
+    int result = usleep(interval);
+#ifdef DEBUG
+    if (result != 0 && errno != EINTR) {
+      fprintf(stderr,
+              "SignalSender usleep error; interval = %u, errno = %d\n",
+              interval,
+              errno);
+      ASSERT(result == 0 || errno == EINTR);
+    }
+#endif
+    USE(result);
+  }
+
+  const int interval_;
+  RuntimeProfilerRateLimiter rate_limiter_;
+
+  // Protects the process wide state below.
+  static Mutex* mutex_;
+  static SignalSender* instance_;
+  static bool signal_handler_installed_;
+  static struct sigaction old_signal_handler_;
+
+  DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
+Mutex* SignalSender::mutex_ = OS::CreateMutex();
+SignalSender* SignalSender::instance_ = NULL;
+struct sigaction SignalSender::old_signal_handler_;
+bool SignalSender::signal_handler_installed_ = false;
+
 
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
@@ -586,55 +775,28 @@
       profiling_(false),
       active_(false),
       samples_taken_(0) {
-  data_ = new PlatformData();
+  data_ = new PlatformData;
 }
 
 
 Sampler::~Sampler() {
+  ASSERT(!IsActive());
   delete data_;
 }
 
 
 void Sampler::Start() {
-  // There can only be one active sampler at the time on POSIX
-  // platforms.
-  if (active_sampler_ != NULL) return;
-
-  // Request profiling signals.
-  struct sigaction sa;
-  sa.sa_sigaction = ProfilerSignalHandler;
-  sigemptyset(&sa.sa_mask);
-  sa.sa_flags = SA_SIGINFO;
-  if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return;
-  data_->signal_handler_installed_ = true;
-
-  // Set the itimer to generate a tick for each interval.
-  itimerval itimer;
-  itimer.it_interval.tv_sec = interval_ / 1000;
-  itimer.it_interval.tv_usec = (interval_ % 1000) * 1000;
-  itimer.it_value.tv_sec = itimer.it_interval.tv_sec;
-  itimer.it_value.tv_usec = itimer.it_interval.tv_usec;
-  setitimer(ITIMER_PROF, &itimer, &data_->old_timer_value_);
-
-  // Set this sampler as the active sampler.
-  active_sampler_ = this;
-  active_ = true;
+  ASSERT(!IsActive());
+  SetActive(true);
+  SignalSender::AddActiveSampler(this);
 }
 
 
 void Sampler::Stop() {
-  // Restore old signal handler
-  if (data_->signal_handler_installed_) {
-    setitimer(ITIMER_PROF, &data_->old_timer_value_, NULL);
-    sigaction(SIGPROF, &data_->old_signal_handler_, 0);
-    data_->signal_handler_installed_ = false;
-  }
-
-  // This sampler is no longer the active sampler.
-  active_sampler_ = NULL;
-  active_ = false;
+  ASSERT(IsActive());
+  SignalSender::RemoveActiveSampler(this);
+  SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index c4b0fb8..1ea53c8 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -33,15 +33,19 @@
 #include <errno.h>
 #include <time.h>
 
+#include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/resource.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netdb.h>
 
+#undef MAP_TYPE
+
 #if defined(ANDROID)
 #define LOG_TAG "v8"
 #include <utils/Log.h>  // LOG_PRI_VA
@@ -54,6 +58,30 @@
 namespace v8 {
 namespace internal {
 
+
+// Maximum size of the virtual memory.  0 means there is no artificial
+// limit.
+
+intptr_t OS::MaxVirtualMemory() {
+  struct rlimit limit;
+  int result = getrlimit(RLIMIT_DATA, &limit);
+  if (result != 0) return 0;
+  return limit.rlim_cur;
+}
+
+
+// Get rid of writable permission on code allocations.
+void OS::ProtectCode(void* address, const size_t size) {
+  mprotect(address, size, PROT_READ | PROT_EXEC);
+}
+
+
+// Create guard pages.
+void OS::Guard(void* address, const size_t size) {
+  mprotect(address, size, PROT_NONE);
+}
+
+
 // ----------------------------------------------------------------------------
 // Math functions
 
@@ -118,7 +146,14 @@
 //
 
 FILE* OS::FOpen(const char* path, const char* mode) {
-  return fopen(path, mode);
+  FILE* file = fopen(path, mode);
+  if (file == NULL) return NULL;
+  struct stat file_stat;
+  if (fstat(fileno(file), &file_stat) != 0) return NULL;
+  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
+  if (is_regular_file) return file;
+  fclose(file);
+  return NULL;
 }
 
 
@@ -127,6 +162,11 @@
 }
 
 
+FILE* OS::OpenTemporaryFile() {
+  return tmpfile();
+}
+
+
 const char* const OS::LogFileOpenMode = "w";
 
 
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index 970c418..1e79f10 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -88,6 +88,7 @@
 }
 
 
+static Mutex* limit_mutex = NULL;
 void OS::Setup() {
   // Seed the random number generator.
   // Convert the current time to a 64-bit integer first, before converting it
@@ -96,6 +97,7 @@
   // call this setup code within the same millisecond.
   uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
   srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
 }
 
 
@@ -145,6 +147,9 @@
 
 
 static void UpdateAllocatedSpaceLimits(void* address, int size) {
+  ASSERT(limit_mutex != NULL);
+  ScopedLock lock(limit_mutex);
+
   lowest_ever_allocated = Min(lowest_ever_allocated, address);
   highest_ever_allocated =
       Max(highest_ever_allocated,
@@ -187,23 +192,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  mprotect(address, size, PROT_READ);
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  mprotect(address, size, prot);
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   useconds_t ms = static_cast<useconds_t>(milliseconds);
   usleep(1000 * ms);
@@ -381,17 +369,15 @@
   pthread_t thread_;  // Thread handle for pthread.
 };
 
-Thread::Thread(Isolate* isolate, const Options& options)
+Thread::Thread(const Options& options)
     : data_(new PlatformData()),
-      isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
+Thread::Thread(const char* name)
     : data_(new PlatformData()),
-      isolate_(isolate),
       stack_size_(0) {
   set_name(name);
 }
@@ -409,7 +395,6 @@
   // one) so we initialize it here too.
   thread->data()->thread_ = pthread_self();
   ASSERT(thread->data()->thread_ != kNoThread);
-  Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
 }
@@ -587,80 +572,171 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-static Sampler* active_sampler_ = NULL;
-static pthread_t vm_tid_ = 0;
-
-
 static pthread_t GetThreadID() {
   return pthread_self();
 }
 
-
 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
   USE(info);
   if (signal != SIGPROF) return;
-  if (active_sampler_ == NULL || !active_sampler_->IsActive()) return;
-  if (vm_tid_ != GetThreadID()) return;
+  Isolate* isolate = Isolate::UncheckedCurrent();
+  if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) {
+    // We require a fully initialized and entered isolate.
+    return;
+  }
+  if (v8::Locker::IsActive() &&
+      !isolate->thread_manager()->IsLockedByCurrentThread()) {
+    return;
+  }
+
+  Sampler* sampler = isolate->logger()->sampler();
+  if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent();
+  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
   ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
   mcontext_t& mcontext = ucontext->uc_mcontext;
-  sample->state = Top::current_vm_state();
+  sample->state = isolate->current_vm_state();
 
   sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
   sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
   sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
 
-  active_sampler_->SampleStack(sample);
-  active_sampler_->Tick(sample);
+  sampler->SampleStack(sample);
+  sampler->Tick(sample);
 }
 
-
 class Sampler::PlatformData : public Malloced {
  public:
+  PlatformData() : vm_tid_(GetThreadID()) {}
+
+  pthread_t vm_tid() const { return vm_tid_; }
+
+ private:
+  pthread_t vm_tid_;
+};
+
+
+class SignalSender : public Thread {
+ public:
   enum SleepInterval {
-    FULL_INTERVAL,
-    HALF_INTERVAL
+    HALF_INTERVAL,
+    FULL_INTERVAL
   };
 
-  explicit PlatformData(Sampler* sampler)
-      : sampler_(sampler),
-        signal_handler_installed_(false),
-        vm_tgid_(getpid()),
-        signal_sender_launched_(false) {
+  explicit SignalSender(int interval)
+      : Thread("SignalSender"),
+        interval_(interval) {}
+
+  static void InstallSignalHandler() {
+    struct sigaction sa;
+    sa.sa_sigaction = ProfilerSignalHandler;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART | SA_SIGINFO;
+    signal_handler_installed_ =
+        (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
   }
 
-  void SignalSender() {
-    while (sampler_->IsActive()) {
-      if (rate_limiter_.SuspendIfNecessary()) continue;
-      if (sampler_->IsProfiling() && RuntimeProfiler::IsEnabled()) {
-        SendProfilingSignal();
+  static void RestoreSignalHandler() {
+    if (signal_handler_installed_) {
+      sigaction(SIGPROF, &old_signal_handler_, 0);
+      signal_handler_installed_ = false;
+    }
+  }
+
+  static void AddActiveSampler(Sampler* sampler) {
+    ScopedLock lock(mutex_);
+    SamplerRegistry::AddActiveSampler(sampler);
+    if (instance_ == NULL) {
+      // Start a thread that will send SIGPROF signal to VM threads,
+      // when CPU profiling will be enabled.
+      instance_ = new SignalSender(sampler->interval());
+      instance_->Start();
+    } else {
+      ASSERT(instance_->interval_ == sampler->interval());
+    }
+  }
+
+  static void RemoveActiveSampler(Sampler* sampler) {
+    ScopedLock lock(mutex_);
+    SamplerRegistry::RemoveActiveSampler(sampler);
+    if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
+      delete instance_;
+      instance_ = NULL;
+      RestoreSignalHandler();
+    }
+  }
+
+  // Implement Thread::Run().
+  virtual void Run() {
+    SamplerRegistry::State state;
+    while ((state = SamplerRegistry::GetState()) !=
+           SamplerRegistry::HAS_NO_SAMPLERS) {
+      bool cpu_profiling_enabled =
+          (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS);
+      bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled();
+      if (cpu_profiling_enabled && !signal_handler_installed_) {
+        InstallSignalHandler();
+      } else if (!cpu_profiling_enabled && signal_handler_installed_) {
+        RestoreSignalHandler();
+      }
+
+      // When CPU profiling is enabled both JavaScript and C++ code is
+      // profiled. We must not suspend.
+      if (!cpu_profiling_enabled) {
+        if (rate_limiter_.SuspendIfNecessary()) continue;
+      }
+      if (cpu_profiling_enabled && runtime_profiler_enabled) {
+        if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) {
+          return;
+        }
         Sleep(HALF_INTERVAL);
-        RuntimeProfiler::NotifyTick();
+        if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) {
+          return;
+        }
         Sleep(HALF_INTERVAL);
       } else {
-        if (sampler_->IsProfiling()) SendProfilingSignal();
-        if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
+        if (cpu_profiling_enabled) {
+          if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile,
+                                                      this)) {
+            return;
+          }
+        }
+        if (runtime_profiler_enabled) {
+          if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile,
+                                                      NULL)) {
+            return;
+          }
+        }
         Sleep(FULL_INTERVAL);
       }
     }
   }
 
-  void SendProfilingSignal() {
+  static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
+    if (!sampler->IsProfiling()) return;
+    SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender);
+    sender->SendProfilingSignal(sampler->platform_data()->vm_tid());
+  }
+
+  static void DoRuntimeProfile(Sampler* sampler, void* ignored) {
+    if (!sampler->isolate()->IsInitialized()) return;
+    sampler->isolate()->runtime_profiler()->NotifyTick();
+  }
+
+  void SendProfilingSignal(pthread_t tid) {
     if (!signal_handler_installed_) return;
-    pthread_kill(vm_tid_, SIGPROF);
+    pthread_kill(tid, SIGPROF);
   }
 
   void Sleep(SleepInterval full_or_half) {
     // Convert ms to us and subtract 100 us to compensate delays
     // occuring during signal delivery.
-    useconds_t interval = sampler_->interval_ * 1000 - 100;
+    useconds_t interval = interval_ * 1000 - 100;
     if (full_or_half == HALF_INTERVAL) interval /= 2;
     int result = usleep(interval);
 #ifdef DEBUG
@@ -675,22 +751,22 @@
     USE(result);
   }
 
-  Sampler* sampler_;
-  bool signal_handler_installed_;
-  struct sigaction old_signal_handler_;
-  int vm_tgid_;
-  bool signal_sender_launched_;
-  pthread_t signal_sender_thread_;
+  const int interval_;
   RuntimeProfilerRateLimiter rate_limiter_;
+
+  // Protects the process wide state below.
+  static Mutex* mutex_;
+  static SignalSender* instance_;
+  static bool signal_handler_installed_;
+  static struct sigaction old_signal_handler_;
+
+  DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
-
-static void* SenderEntry(void* arg) {
-  Sampler::PlatformData* data =
-      reinterpret_cast<Sampler::PlatformData*>(arg);
-  data->SignalSender();
-  return 0;
-}
+Mutex* SignalSender::mutex_ = OS::CreateMutex();
+SignalSender* SignalSender::instance_ = NULL;
+struct sigaction SignalSender::old_signal_handler_;
+bool SignalSender::signal_handler_installed_ = false;
 
 
 Sampler::Sampler(Isolate* isolate, int interval)
@@ -699,65 +775,27 @@
       profiling_(false),
       active_(false),
       samples_taken_(0) {
-  data_ = new PlatformData(this);
+  data_ = new PlatformData;
 }
 
 
 Sampler::~Sampler() {
-  ASSERT(!data_->signal_sender_launched_);
+  ASSERT(!IsActive());
   delete data_;
 }
 
 
 void Sampler::Start() {
-  // There can only be one active sampler at the time on POSIX
-  // platforms.
   ASSERT(!IsActive());
-  vm_tid_ = GetThreadID();
-
-  // Request profiling signals.
-  struct sigaction sa;
-  sa.sa_sigaction = ProfilerSignalHandler;
-  sigemptyset(&sa.sa_mask);
-  sa.sa_flags = SA_RESTART | SA_SIGINFO;
-  data_->signal_handler_installed_ =
-      sigaction(SIGPROF, &sa, &data_->old_signal_handler_) == 0;
-
-  // Start a thread that sends SIGPROF signal to VM thread.
-  // Sending the signal ourselves instead of relying on itimer provides
-  // much better accuracy.
   SetActive(true);
-  if (pthread_create(
-          &data_->signal_sender_thread_, NULL, SenderEntry, data_) == 0) {
-    data_->signal_sender_launched_ = true;
-  }
-
-  // Set this sampler as the active sampler.
-  active_sampler_ = this;
+  SignalSender::AddActiveSampler(this);
 }
 
 
 void Sampler::Stop() {
+  ASSERT(IsActive());
+  SignalSender::RemoveActiveSampler(this);
   SetActive(false);
-
-  // Wait for signal sender termination (it will exit after setting
-  // active_ to false).
-  if (data_->signal_sender_launched_) {
-    Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
-    pthread_join(data_->signal_sender_thread_, NULL);
-    data_->signal_sender_launched_ = false;
-  }
-
-  // Restore old signal handler
-  if (data_->signal_handler_installed_) {
-    sigaction(SIGPROF, &data_->old_signal_handler_, 0);
-    data_->signal_handler_installed_ = false;
-  }
-
-  // This sampler is no longer the active sampler.
-  active_sampler_ = NULL;
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
diff --git a/src/platform-tls.h b/src/platform-tls.h
index 5649175..3251663 100644
--- a/src/platform-tls.h
+++ b/src/platform-tls.h
@@ -30,7 +30,7 @@
 #ifndef V8_PLATFORM_TLS_H_
 #define V8_PLATFORM_TLS_H_
 
-#ifdef V8_FAST_TLS
+#ifndef V8_NO_FAST_TLS
 
 // When fast TLS is requested we include the appropriate
 // implementation header.
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 390d3d9..e5df5ff 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -138,16 +138,39 @@
 }
 
 
+#define _TRUNCATE 0
+#define STRUNCATE 80
+
 int _vsnprintf_s(char* buffer, size_t sizeOfBuffer, size_t count,
                  const char* format, va_list argptr) {
+  ASSERT(count == _TRUNCATE);
   return _vsnprintf(buffer, sizeOfBuffer, format, argptr);
 }
-#define _TRUNCATE 0
 
 
-int strncpy_s(char* strDest, size_t numberOfElements,
-              const char* strSource, size_t count) {
-  strncpy(strDest, strSource, count);
+int strncpy_s(char* dest, size_t dest_size, const char* source, size_t count) {
+  CHECK(source != NULL);
+  CHECK(dest != NULL);
+  CHECK_GT(dest_size, 0);
+
+  if (count == _TRUNCATE) {
+    while (dest_size > 0 && *source != 0) {
+      *(dest++) = *(source++);
+      --dest_size;
+    }
+    if (dest_size == 0) {
+      *(dest - 1) = 0;
+      return STRUNCATE;
+    }
+  } else {
+    while (dest_size > 0 && count > 0 && *source != 0) {
+      *(dest++) = *(source++);
+      --dest_size;
+      --count;
+    }
+  }
+  CHECK_GT(dest_size, 0);
+  *dest = 0;
   return 0;
 }
 
@@ -169,6 +192,11 @@
 namespace v8 {
 namespace internal {
 
+intptr_t OS::MaxVirtualMemory() {
+  return 0;
+}
+
+
 double ceiling(double x) {
   return ceil(x);
 }
@@ -712,6 +740,24 @@
 }
 
 
+FILE* OS::OpenTemporaryFile() {
+  // tmpfile_s tries to use the root dir, don't use it.
+  char tempPathBuffer[MAX_PATH];
+  DWORD path_result = 0;
+  path_result = GetTempPathA(MAX_PATH, tempPathBuffer);
+  if (path_result > MAX_PATH || path_result == 0) return NULL;
+  UINT name_result = 0;
+  char tempNameBuffer[MAX_PATH];
+  name_result = GetTempFileNameA(tempPathBuffer, "", 0, tempNameBuffer);
+  if (name_result == 0) return NULL;
+  FILE* result = FOpen(tempNameBuffer, "w+");  // Same mode as tmpfile uses.
+  if (result != NULL) {
+    Remove(tempNameBuffer);  // Delete on close.
+  }
+  return result;
+}
+
+
 // Open log file in binary mode to avoid /n -> /r/n conversion.
 const char* const OS::LogFileOpenMode = "wb";
 
@@ -911,24 +957,17 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): VirtualProtect has a return value which is ignored here.
+void OS::ProtectCode(void* address, const size_t size) {
   DWORD old_protect;
-  VirtualProtect(address, size, PAGE_READONLY, &old_protect);
+  VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect);
 }
 
 
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): VirtualProtect has a return value which is ignored here.
-  DWORD new_protect = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
-  DWORD old_protect;
-  VirtualProtect(address, size, new_protect, &old_protect);
+void OS::Guard(void* address, const size_t size) {
+  DWORD oldprotect;
+  VirtualProtect(address, size, PAGE_READONLY | PAGE_GUARD, &oldprotect);
 }
 
-#endif
-
 
 void OS::Sleep(int milliseconds) {
   ::Sleep(milliseconds);
@@ -1473,10 +1512,6 @@
 // convention.
 static unsigned int __stdcall ThreadEntry(void* arg) {
   Thread* thread = reinterpret_cast<Thread*>(arg);
-  // This is also initialized by the last parameter to _beginthreadex() but we
-  // don't know which thread will run first (the original thread or the new
-  // one) so we initialize it here too.
-  Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return 0;
 }
@@ -1492,17 +1527,15 @@
 // Initialize a Win32 thread object. The thread has an invalid thread
 // handle until it is started.
 
-Thread::Thread(Isolate* isolate, const Options& options)
-    : isolate_(isolate),
-      stack_size_(options.stack_size) {
+Thread::Thread(const Options& options)
+    : stack_size_(options.stack_size) {
   data_ = new PlatformData(kNoThread);
   set_name(options.name);
 }
 
 
-Thread::Thread(Isolate* isolate, const char* name)
-    : isolate_(isolate),
-      stack_size_(0) {
+Thread::Thread(const char* name)
+    : stack_size_(0) {
   data_ = new PlatformData(kNoThread);
   set_name(name);
 }
@@ -1583,7 +1616,6 @@
 
 class Win32Mutex : public Mutex {
  public:
-
   Win32Mutex() { InitializeCriticalSection(&cs_); }
 
   virtual ~Win32Mutex() { DeleteCriticalSection(&cs_); }
@@ -1837,8 +1869,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 // ----------------------------------------------------------------------------
 // Win32 profiler support.
 
@@ -1872,7 +1902,7 @@
 class SamplerThread : public Thread {
  public:
   explicit SamplerThread(int interval)
-      : Thread(NULL, "SamplerThread"),
+      : Thread("SamplerThread"),
         interval_(interval) {}
 
   static void AddActiveSampler(Sampler* sampler) {
@@ -1890,8 +1920,7 @@
     ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
-      RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
-      instance_->Join();
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
       delete instance_;
       instance_ = NULL;
     }
@@ -2014,6 +2043,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform.h b/src/platform.h
index 725008a..6b2348c 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -177,6 +177,9 @@
   static FILE* FOpen(const char* path, const char* mode);
   static bool Remove(const char* path);
 
+  // Opens a temporary file, the file is auto removed on close.
+  static FILE* OpenTemporaryFile();
+
   // Log file open mode is platform-dependent due to line ends issues.
   static const char* const LogFileOpenMode;
 
@@ -203,15 +206,16 @@
                         size_t* allocated,
                         bool is_executable);
   static void Free(void* address, const size_t size);
+
+  // Mark code segments non-writable.
+  static void ProtectCode(void* address, const size_t size);
+
+  // Assign memory as a guard page so that access will cause an exception.
+  static void Guard(void* address, const size_t size);
+
   // Get the Alignment guaranteed by Allocate().
   static size_t AllocateAlignment();
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect a block of memory by marking it read-only/writable.
-  static void Protect(void* address, size_t size);
-  static void Unprotect(void* address, size_t size, bool is_executable);
-#endif
-
   // Returns an indication of whether a pointer is in a space that
   // has been allocated by Allocate().  This method may conservatively
   // always return false, but giving more accurate information may
@@ -288,6 +292,10 @@
   // positions indicated by the members of the CpuFeature enum from globals.h
   static uint64_t CpuFeaturesImpliedByPlatform();
 
+  // Maximum size of the virtual memory.  0 means there is no artificial
+  // limit.
+  static intptr_t MaxVirtualMemory();
+
   // Returns the double constant NAN
   static double nan_value();
 
@@ -384,9 +392,9 @@
     int stack_size;
   };
 
-  // Create new thread (with a value for storing in the TLS isolate field).
-  Thread(Isolate* isolate, const Options& options);
-  Thread(Isolate* isolate, const char* name);
+  // Create new thread.
+  explicit Thread(const Options& options);
+  explicit Thread(const char* name);
   virtual ~Thread();
 
   // Start new thread by calling the Run() method in the new thread.
@@ -433,7 +441,6 @@
   // A hint to the scheduler to let another thread run.
   static void YieldCPU();
 
-  Isolate* isolate() const { return isolate_; }
 
   // The thread name length is limited to 16 based on Linux's implementation of
   // prctl().
@@ -447,7 +454,6 @@
 
   PlatformData* data_;
 
-  Isolate* isolate_;
   char name_[kMaxThreadNameLength];
   int stack_size_;
 
@@ -601,7 +607,6 @@
   bool has_external_callback : 1;
 };
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 class Sampler {
  public:
   // Initialize sampler.
@@ -660,8 +665,6 @@
 };
 
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
 
 #endif  // V8_PLATFORM_H_
diff --git a/src/preparse-data-format.h b/src/preparse-data-format.h
index 64c4f18..e64326e 100644
--- a/src/preparse-data-format.h
+++ b/src/preparse-data-format.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -37,7 +37,7 @@
  public:
   // Layout and constants of the preparse data exchange format.
   static const unsigned kMagicNumber = 0xBadDead;
-  static const unsigned kCurrentVersion = 6;
+  static const unsigned kCurrentVersion = 7;
 
   static const int kMagicOffset = 0;
   static const int kVersionOffset = 1;
diff --git a/src/preparse-data.h b/src/preparse-data.h
index 551d2e8..c6503c4 100644
--- a/src/preparse-data.h
+++ b/src/preparse-data.h
@@ -48,7 +48,8 @@
   virtual void LogFunction(int start,
                            int end,
                            int literals,
-                           int properties) = 0;
+                           int properties,
+                           int strict_mode) = 0;
 
   // Logs a symbol creation of a literal or identifier.
   virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
@@ -84,11 +85,16 @@
   FunctionLoggingParserRecorder();
   virtual ~FunctionLoggingParserRecorder() {}
 
-  virtual void LogFunction(int start, int end, int literals, int properties) {
+  virtual void LogFunction(int start,
+                           int end,
+                           int literals,
+                           int properties,
+                           int strict_mode) {
     function_store_.Add(start);
     function_store_.Add(end);
     function_store_.Add(literals);
     function_store_.Add(properties);
+    function_store_.Add(strict_mode);
   }
 
   // Logs an error message and marks the log as containing an error.
diff --git a/src/preparser-api.cc b/src/preparser-api.cc
index a0d13ed..e0ab500 100644
--- a/src/preparser-api.cc
+++ b/src/preparser-api.cc
@@ -158,23 +158,6 @@
 };
 
 
-class StandAloneJavaScriptScanner : public JavaScriptScanner {
- public:
-  explicit StandAloneJavaScriptScanner(UnicodeCache* unicode_cache)
-      : JavaScriptScanner(unicode_cache) { }
-
-  void Initialize(UC16CharacterStream* source) {
-    source_ = source;
-    Init();
-    // Skip initial whitespace allowing HTML comment ends just like
-    // after a newline and scan first token.
-    has_line_terminator_before_next_ = true;
-    SkipWhiteSpace();
-    Scan();
-  }
-};
-
-
 // Functions declared by allocation.h and implemented in both api.cc (for v8)
 // or here (for a stand-alone preparser).
 
@@ -194,7 +177,7 @@
   internal::InputStreamUTF16Buffer buffer(input);
   uintptr_t stack_limit = reinterpret_cast<uintptr_t>(&buffer) - max_stack;
   internal::UnicodeCache unicode_cache;
-  internal::StandAloneJavaScriptScanner scanner(&unicode_cache);
+  internal::JavaScriptScanner scanner(&unicode_cache);
   scanner.Initialize(&buffer);
   internal::CompleteParserRecorder recorder;
   preparser::PreParser::PreParseResult result =
diff --git a/src/preparser.cc b/src/preparser.cc
index 86db379..c741b46 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -38,6 +38,8 @@
 #include "preparse-data.h"
 #include "preparser.h"
 
+#include "conversions-inl.h"
+
 namespace v8 {
 namespace preparser {
 
@@ -77,9 +79,14 @@
     return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
                            "unexpected_token_string", NULL);
   case i::Token::IDENTIFIER:
-  case i::Token::FUTURE_RESERVED_WORD:
     return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
                            "unexpected_token_identifier", NULL);
+  case i::Token::FUTURE_RESERVED_WORD:
+    return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
+                           "unexpected_reserved", NULL);
+  case i::Token::FUTURE_STRICT_RESERVED_WORD:
+    return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
+                           "unexpected_strict_reserved", NULL);
   default:
     const char* name = i::Token::String(token);
     ReportMessageAt(source_location.beg_pos, source_location.end_pos,
@@ -209,9 +216,6 @@
     case i::Token::FUNCTION:
       return ParseFunctionDeclaration(ok);
 
-    case i::Token::NATIVE:
-      return ParseNativeDeclaration(ok);
-
     case i::Token::DEBUGGER:
       return ParseDebuggerStatement(ok);
 
@@ -236,7 +240,7 @@
     // Strict mode violation, using either reserved word or eval/arguments
     // as name of strict function.
     const char* type = "strict_function_name";
-    if (identifier.IsFutureReserved()) {
+    if (identifier.IsFutureStrictReserved()) {
       type = "strict_reserved_word";
     }
     ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
@@ -246,29 +250,6 @@
 }
 
 
-// Language extension which is only enabled for source files loaded
-// through the API's extension mechanism.  A native function
-// declaration is resolved by looking up the function through a
-// callback provided by the extension.
-PreParser::Statement PreParser::ParseNativeDeclaration(bool* ok) {
-  Expect(i::Token::NATIVE, CHECK_OK);
-  Expect(i::Token::FUNCTION, CHECK_OK);
-  ParseIdentifier(CHECK_OK);
-  Expect(i::Token::LPAREN, CHECK_OK);
-  bool done = (peek() == i::Token::RPAREN);
-  while (!done) {
-    ParseIdentifier(CHECK_OK);
-    done = (peek() == i::Token::RPAREN);
-    if (!done) {
-      Expect(i::Token::COMMA, CHECK_OK);
-    }
-  }
-  Expect(i::Token::RPAREN, CHECK_OK);
-  Expect(i::Token::SEMICOLON, CHECK_OK);
-  return Statement::Default();
-}
-
-
 PreParser::Statement PreParser::ParseBlock(bool* ok) {
   // Block ::
   //   '{' Statement* '}'
@@ -362,8 +343,9 @@
   //   Identifier ':' Statement
 
   Expression expr = ParseExpression(true, CHECK_OK);
-  if (peek() == i::Token::COLON && expr.IsRawIdentifier()) {
-    if (!strict_mode() || !expr.AsIdentifier().IsFutureReserved()) {
+  if (expr.IsRawIdentifier()) {
+    if (peek() == i::Token::COLON &&
+        (!strict_mode() || !expr.AsIdentifier().IsFutureReserved())) {
       Consume(i::Token::COLON);
       i::Scanner::Location start_location = scanner_->peek_location();
       Statement statement = ParseStatement(CHECK_OK);
@@ -375,6 +357,9 @@
       }
       return Statement::Default();
     }
+    // Preparsing is disabled for extensions (because the extension details
+    // aren't passed to lazily compiled functions), so we don't
+    // accept "native function" in the preparser.
   }
   // Parsed expression statement.
   ExpectSemicolon(CHECK_OK);
@@ -405,7 +390,7 @@
 
   Expect(i::Token::CONTINUE, CHECK_OK);
   i::Token::Value tok = peek();
-  if (!scanner_->has_line_terminator_before_next() &&
+  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
       tok != i::Token::SEMICOLON &&
       tok != i::Token::RBRACE &&
       tok != i::Token::EOS) {
@@ -422,7 +407,7 @@
 
   Expect(i::Token::BREAK, CHECK_OK);
   i::Token::Value tok = peek();
-  if (!scanner_->has_line_terminator_before_next() &&
+  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
       tok != i::Token::SEMICOLON &&
       tok != i::Token::RBRACE &&
       tok != i::Token::EOS) {
@@ -448,7 +433,7 @@
   // This is not handled during preparsing.
 
   i::Token::Value tok = peek();
-  if (!scanner_->has_line_terminator_before_next() &&
+  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
       tok != i::Token::SEMICOLON &&
       tok != i::Token::RBRACE &&
       tok != i::Token::EOS) {
@@ -599,7 +584,7 @@
   //   'throw' [no line terminator] Expression ';'
 
   Expect(i::Token::THROW, CHECK_OK);
-  if (scanner_->has_line_terminator_before_next()) {
+  if (scanner_->HasAnyLineTerminatorBeforeNext()) {
     i::JavaScriptScanner::Location pos = scanner_->location();
     ReportMessageAt(pos.beg_pos, pos.end_pos,
                     "newline_after_throw", NULL);
@@ -822,7 +807,7 @@
 
   i::Scanner::Location before = scanner_->peek_location();
   Expression expression = ParseLeftHandSideExpression(CHECK_OK);
-  if (!scanner_->has_line_terminator_before_next() &&
+  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
       i::Token::IsCountOp(peek())) {
     if (strict_mode() && expression.IsIdentifier() &&
         expression.AsIdentifier().IsEvalOrArguments()) {
@@ -1001,7 +986,16 @@
       break;
     }
 
-    case i::Token::FUTURE_RESERVED_WORD:
+    case i::Token::FUTURE_RESERVED_WORD: {
+      Next();
+      i::Scanner::Location location = scanner_->location();
+      ReportMessageAt(location.beg_pos, location.end_pos,
+                      "reserved_word", NULL);
+      *ok = false;
+      return Expression::Default();
+    }
+
+    case i::Token::FUTURE_STRICT_RESERVED_WORD:
       if (strict_mode()) {
         Next();
         i::Scanner::Location location = scanner_->location();
@@ -1100,15 +1094,17 @@
     i::Token::Value next = peek();
     switch (next) {
       case i::Token::IDENTIFIER:
-      case i::Token::FUTURE_RESERVED_WORD: {
+      case i::Token::FUTURE_RESERVED_WORD:
+      case i::Token::FUTURE_STRICT_RESERVED_WORD: {
         bool is_getter = false;
         bool is_setter = false;
-        ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
+        ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
         if ((is_getter || is_setter) && peek() != i::Token::COLON) {
             i::Token::Value name = Next();
             bool is_keyword = i::Token::IsKeyword(name);
             if (name != i::Token::IDENTIFIER &&
                 name != i::Token::FUTURE_RESERVED_WORD &&
+                name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
                 name != i::Token::NUMBER &&
                 name != i::Token::STRING &&
                 !is_keyword) {
@@ -1256,7 +1252,8 @@
     int end_pos = scanner_->location().end_pos;
     log_->LogFunction(function_block_pos, end_pos,
                       function_scope.materialized_literal_count(),
-                      function_scope.expected_properties());
+                      function_scope.expected_properties(),
+                      strict_mode() ? 1 : 0);
   } else {
     ParseSourceElements(i::Token::RBRACE, CHECK_OK);
     Expect(i::Token::RBRACE, CHECK_OK);
@@ -1295,7 +1292,7 @@
     Next();
     return;
   }
-  if (scanner_->has_line_terminator_before_next() ||
+  if (scanner_->HasAnyLineTerminatorBeforeNext() ||
       tok == i::Token::RBRACE ||
       tok == i::Token::EOS) {
     return;
@@ -1333,6 +1330,9 @@
   LogSymbol();
   if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
     return Identifier::FutureReserved();
+  } else if (scanner_->current_token() ==
+             i::Token::FUTURE_STRICT_RESERVED_WORD) {
+    return Identifier::FutureStrictReserved();
   }
   if (scanner_->is_literal_ascii()) {
     // Detect strict-mode poison words.
@@ -1350,11 +1350,22 @@
 
 
 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
-  if (!Check(i::Token::FUTURE_RESERVED_WORD)) {
-    Expect(i::Token::IDENTIFIER, ok);
-    if (!*ok) return Identifier::Default();
+  i::Token::Value next = Next();
+  switch (next) {
+    case i::Token::FUTURE_RESERVED_WORD: {
+      i::Scanner::Location location = scanner_->location();
+      ReportMessageAt(location.beg_pos, location.end_pos,
+                      "reserved_word", NULL);
+      *ok = false;
+    }
+      // FALLTHROUGH
+    case i::Token::FUTURE_STRICT_RESERVED_WORD:
+    case i::Token::IDENTIFIER:
+      return GetIdentifierSymbol();
+    default:
+      *ok = false;
+      return Identifier::Default();
   }
-  return GetIdentifierSymbol();
 }
 
 
@@ -1394,6 +1405,8 @@
                                               bool* ok) {
   const char* type = eval_args_type;
   if (identifier.IsFutureReserved()) {
+    type = "reserved_word";
+  } else if (identifier.IsFutureStrictReserved()) {
     type = "strict_reserved_word";
   }
   if (strict_mode()) {
@@ -1416,7 +1429,8 @@
     return Identifier::Default();
   }
   if (next == i::Token::IDENTIFIER ||
-      next == i::Token::FUTURE_RESERVED_WORD) {
+      next == i::Token::FUTURE_RESERVED_WORD ||
+      next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
     return GetIdentifierSymbol();
   }
   *ok = false;
@@ -1428,10 +1442,10 @@
 
 // This function reads an identifier and determines whether or not it
 // is 'get' or 'set'.
-PreParser::Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get,
-                                                           bool* is_set,
-                                                           bool* ok) {
-  Identifier result = ParseIdentifier(ok);
+PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
+                                                               bool* is_set,
+                                                               bool* ok) {
+  Identifier result = ParseIdentifierName(ok);
   if (!*ok) return Identifier::Default();
   if (scanner_->is_literal_ascii() &&
       scanner_->literal_length() == 3) {
@@ -1445,6 +1459,7 @@
 bool PreParser::peek_any_identifier() {
   i::Token::Value next = peek();
   return next == i::Token::IDENTIFIER ||
-         next == i::Token::FUTURE_RESERVED_WORD;
+         next == i::Token::FUTURE_RESERVED_WORD ||
+         next == i::Token::FUTURE_STRICT_RESERVED_WORD;
 }
 } }  // v8::preparser
diff --git a/src/preparser.h b/src/preparser.h
index 2efd53e..3d72c97 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -93,15 +93,23 @@
     static Identifier FutureReserved()  {
       return Identifier(kFutureReservedIdentifier);
     }
+    static Identifier FutureStrictReserved()  {
+      return Identifier(kFutureStrictReservedIdentifier);
+    }
     bool IsEval() { return type_ == kEvalIdentifier; }
     bool IsArguments() { return type_ == kArgumentsIdentifier; }
     bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
     bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
+    bool IsFutureStrictReserved() {
+      return type_ == kFutureStrictReservedIdentifier;
+    }
     bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
+
    private:
     enum Type {
       kUnknownIdentifier,
       kFutureReservedIdentifier,
+      kFutureStrictReservedIdentifier,
       kEvalIdentifier,
       kArgumentsIdentifier
     };
@@ -372,7 +380,6 @@
   SourceElements ParseSourceElements(int end_token, bool* ok);
   Statement ParseStatement(bool* ok);
   Statement ParseFunctionDeclaration(bool* ok);
-  Statement ParseNativeDeclaration(bool* ok);
   Statement ParseBlock(bool* ok);
   Statement ParseVariableStatement(bool* ok);
   Statement ParseVariableDeclarations(bool accept_IN, int* num_decl, bool* ok);
@@ -411,7 +418,9 @@
 
   Identifier ParseIdentifier(bool* ok);
   Identifier ParseIdentifierName(bool* ok);
-  Identifier ParseIdentifierOrGetOrSet(bool* is_get, bool* is_set, bool* ok);
+  Identifier ParseIdentifierNameOrGetOrSet(bool* is_get,
+                                           bool* is_set,
+                                           bool* ok);
 
   // Logs the currently parsed literal as a symbol in the preparser data.
   void LogSymbol();
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index 60288a9..f18b320 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -123,15 +123,16 @@
 }
 
 
-void PrettyPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
-  Print("<enter with> (");
+void PrettyPrinter::VisitEnterWithContextStatement(
+    EnterWithContextStatement* node) {
+  Print("<enter with context> (");
   Visit(node->expression());
   Print(") ");
 }
 
 
-void PrettyPrinter::VisitWithExitStatement(WithExitStatement* node) {
-  Print("<exit with>");
+void PrettyPrinter::VisitExitContextStatement(ExitContextStatement* node) {
+  Print("<exit context>");
 }
 
 
@@ -201,7 +202,8 @@
   Print("try ");
   Visit(node->try_block());
   Print(" catch (");
-  Visit(node->catch_var());
+  const bool quote = false;
+  PrintLiteral(node->variable()->name(), quote);
   Print(") ");
   Visit(node->catch_block());
 }
@@ -282,15 +284,6 @@
 }
 
 
-void PrettyPrinter::VisitCatchExtensionObject(CatchExtensionObject* node) {
-  Print("{ ");
-  Visit(node->key());
-  Print(": ");
-  Visit(node->value());
-  Print(" }");
-}
-
-
 void PrettyPrinter::VisitSlot(Slot* node) {
   switch (node->type()) {
     case Slot::PARAMETER:
@@ -805,13 +798,14 @@
 }
 
 
-void AstPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
-  PrintIndentedVisit("WITH ENTER", node->expression());
+void AstPrinter::VisitEnterWithContextStatement(
+    EnterWithContextStatement* node) {
+  PrintIndentedVisit("ENTER WITH CONTEXT", node->expression());
 }
 
 
-void AstPrinter::VisitWithExitStatement(WithExitStatement* node) {
-  PrintIndented("WITH EXIT\n");
+void AstPrinter::VisitExitContextStatement(ExitContextStatement* node) {
+  PrintIndented("EXIT CONTEXT\n");
 }
 
 
@@ -862,7 +856,9 @@
 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
   IndentedScope indent(this, "TRY CATCH");
   PrintIndentedVisit("TRY", node->try_block());
-  PrintIndentedVisit("CATCHVAR", node->catch_var());
+  PrintLiteralWithModeIndented("CATCHVAR",
+                               node->variable(),
+                               node->variable()->name());
   PrintIndentedVisit("CATCH", node->catch_block());
 }
 
@@ -962,13 +958,6 @@
 }
 
 
-void AstPrinter::VisitCatchExtensionObject(CatchExtensionObject* node) {
-  IndentedScope indent(this, "CatchExtensionObject");
-  PrintIndentedVisit("KEY", node->key());
-  PrintIndentedVisit("VALUE", node->value());
-}
-
-
 void AstPrinter::VisitSlot(Slot* node) {
   PrintIndented("SLOT ");
   PrettyPrinter::VisitSlot(node);
@@ -1205,14 +1194,15 @@
 }
 
 
-void JsonAstBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
-  TagScope tag(this, "WithEnterStatement");
+void JsonAstBuilder::VisitEnterWithContextStatement(
+    EnterWithContextStatement* stmt) {
+  TagScope tag(this, "EnterWithContextStatement");
   Visit(stmt->expression());
 }
 
 
-void JsonAstBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
-  TagScope tag(this, "WithExitStatement");
+void JsonAstBuilder::VisitExitContextStatement(ExitContextStatement* stmt) {
+  TagScope tag(this, "ExitContextStatement");
 }
 
 
@@ -1254,8 +1244,10 @@
 
 void JsonAstBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
   TagScope tag(this, "TryCatchStatement");
+  { AttributesScope attributes(this);
+    AddAttribute("variable", stmt->variable()->name());
+  }
   Visit(stmt->try_block());
-  Visit(stmt->catch_var());
   Visit(stmt->catch_block());
 }
 
@@ -1360,13 +1352,6 @@
 }
 
 
-void JsonAstBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
-  TagScope tag(this, "CatchExtensionObject");
-  Visit(expr->key());
-  Visit(expr->value());
-}
-
-
 void JsonAstBuilder::VisitAssignment(Assignment* expr) {
   TagScope tag(this, "Assignment");
   {
@@ -1386,10 +1371,6 @@
 
 void JsonAstBuilder::VisitProperty(Property* expr) {
   TagScope tag(this, "Property");
-  {
-    AttributesScope attributes(this);
-    AddAttribute("type", expr->is_synthetic() ? "SYNTHETIC" : "NORMAL");
-  }
   Visit(expr->obj());
   Visit(expr->key());
 }
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 747e5c7..8f4bc6c 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -28,8 +28,6 @@
 #ifndef V8_PROFILE_GENERATOR_INL_H_
 #define V8_PROFILE_GENERATOR_INL_H_
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "profile-generator.h"
 
 namespace v8 {
@@ -123,6 +121,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 #endif  // V8_PROFILE_GENERATOR_INL_H_
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index c954c4f..07426f2 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -25,8 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 
 #include "profile-generator-inl.h"
@@ -1096,7 +1094,7 @@
       : retained_size_(0) {
   }
 
-  int reained_size() const { return retained_size_; }
+  int retained_size() const { return retained_size_; }
 
   void Apply(HeapEntry** entry_ptr) {
     if ((*entry_ptr)->painted_reachable()) {
@@ -1137,7 +1135,7 @@
 
   RetainedSizeCalculator ret_size_calc;
   snapshot()->IterateEntries(&ret_size_calc);
-  retained_size_ = ret_size_calc.reained_size();
+  retained_size_ = ret_size_calc.retained_size();
   ASSERT((retained_size_ & kExactRetainedSizeTag) == 0);
   retained_size_ |= kExactRetainedSizeTag;
 }
@@ -1602,6 +1600,28 @@
 }
 
 
+const char* HeapObjectsSet::GetTag(Object* obj) {
+  HeapObject* object = HeapObject::cast(obj);
+  HashMap::Entry* cache_entry =
+      entries_.Lookup(object, HeapEntriesMap::Hash(object), false);
+  if (cache_entry != NULL
+      && cache_entry->value != HeapEntriesMap::kHeapEntryPlaceholder) {
+    return reinterpret_cast<const char*>(cache_entry->value);
+  } else {
+    return NULL;
+  }
+}
+
+
+void HeapObjectsSet::SetTag(Object* obj, const char* tag) {
+  if (!obj->IsHeapObject()) return;
+  HeapObject* object = HeapObject::cast(obj);
+  HashMap::Entry* cache_entry =
+      entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
+  cache_entry->value = const_cast<char*>(tag);
+}
+
+
 HeapObject *const V8HeapExplorer::kInternalRootObject =
     reinterpret_cast<HeapObject*>(
         static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId));
@@ -1613,7 +1633,8 @@
 V8HeapExplorer::V8HeapExplorer(
     HeapSnapshot* snapshot,
     SnapshottingProgressReportingInterface* progress)
-    : snapshot_(snapshot),
+    : heap_(Isolate::Current()->heap()),
+      snapshot_(snapshot),
       collection_(snapshot_->collection()),
       progress_(progress),
       filler_(NULL) {
@@ -1639,6 +1660,18 @@
     return snapshot_->AddRootEntry(children_count);
   } else if (object == kGcRootsObject) {
     return snapshot_->AddGcRootsEntry(children_count, retainers_count);
+  } else if (object->IsJSGlobalObject()) {
+    const char* tag = objects_tags_.GetTag(object);
+    const char* name = collection_->names()->GetName(
+        GetConstructorNameForHeapProfile(JSObject::cast(object)));
+    if (tag != NULL) {
+      name = collection_->names()->GetFormatted("%s / %s", name, tag);
+    }
+    return AddEntry(object,
+                    HeapEntry::kObject,
+                    name,
+                    children_count,
+                    retainers_count);
   } else if (object->IsJSFunction()) {
     JSFunction* func = JSFunction::cast(object);
     SharedFunctionInfo* shared = func->shared();
@@ -1691,10 +1724,14 @@
                         : "",
                     children_count,
                     retainers_count);
-  } else if (object->IsFixedArray() || object->IsByteArray()) {
+  } else if (object->IsFixedArray() ||
+             object->IsFixedDoubleArray() ||
+             object->IsByteArray() ||
+             object->IsExternalArray()) {
+    const char* tag = objects_tags_.GetTag(object);
     return AddEntry(object,
                     HeapEntry::kArray,
-                    "",
+                    tag != NULL ? tag : "",
                     children_count,
                     retainers_count);
   } else if (object->IsHeapNumber()) {
@@ -1780,6 +1817,7 @@
     ASSERT(Memory::Object_at(field)->IsHeapObject());
     *field |= kFailureTag;
   }
+
  private:
   bool CheckVisitedAndUnmark(Object** field) {
     if ((*field)->IsFailure()) {
@@ -1801,15 +1839,13 @@
   HeapEntry* entry = GetEntry(obj);
   if (entry == NULL) return;  // No interest in this object.
 
+  bool extract_indexed_refs = true;
   if (obj->IsJSGlobalProxy()) {
     // We need to reference JS global objects from snapshot's root.
     // We use JSGlobalProxy because this is what embedder (e.g. browser)
     // uses for the global object.
     JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
     SetRootShortcutReference(proxy->map()->prototype());
-    SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
-    IndexedReferencesExtractor refs_extractor(this, obj, entry);
-    obj->Iterate(&refs_extractor);
   } else if (obj->IsJSObject()) {
     JSObject* js_obj = JSObject::cast(obj);
     ExtractClosureReferences(js_obj, entry);
@@ -1817,7 +1853,7 @@
     ExtractElementReferences(js_obj, entry);
     ExtractInternalReferences(js_obj, entry);
     SetPropertyReference(
-        obj, entry, HEAP->Proto_symbol(), js_obj->GetPrototype());
+        obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype());
     if (obj->IsJSFunction()) {
       JSFunction* js_fun = JSFunction::cast(js_obj);
       Object* proto_or_map = js_fun->prototype_or_initial_map();
@@ -1825,39 +1861,49 @@
         if (!proto_or_map->IsMap()) {
           SetPropertyReference(
               obj, entry,
-              HEAP->prototype_symbol(), proto_or_map,
+              heap_->prototype_symbol(), proto_or_map,
               JSFunction::kPrototypeOrInitialMapOffset);
         } else {
           SetPropertyReference(
               obj, entry,
-              HEAP->prototype_symbol(), js_fun->prototype());
+              heap_->prototype_symbol(), js_fun->prototype());
         }
       }
       SetInternalReference(js_fun, entry,
                            "shared", js_fun->shared(),
                            JSFunction::kSharedFunctionInfoOffset);
+      TagObject(js_fun->unchecked_context(), "(context)");
       SetInternalReference(js_fun, entry,
                            "context", js_fun->unchecked_context(),
                            JSFunction::kContextOffset);
+      TagObject(js_fun->literals(), "(function literals)");
       SetInternalReference(js_fun, entry,
                            "literals", js_fun->literals(),
                            JSFunction::kLiteralsOffset);
     }
+    TagObject(js_obj->properties(), "(object properties)");
     SetInternalReference(obj, entry,
                          "properties", js_obj->properties(),
                          JSObject::kPropertiesOffset);
+    TagObject(js_obj->elements(), "(object elements)");
     SetInternalReference(obj, entry,
                          "elements", js_obj->elements(),
                          JSObject::kElementsOffset);
-    SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
-    IndexedReferencesExtractor refs_extractor(this, obj, entry);
-    obj->Iterate(&refs_extractor);
   } else if (obj->IsString()) {
     if (obj->IsConsString()) {
       ConsString* cs = ConsString::cast(obj);
       SetInternalReference(obj, entry, 1, cs->first());
       SetInternalReference(obj, entry, 2, cs->second());
     }
+    extract_indexed_refs = false;
+  } else if (obj->IsGlobalContext()) {
+    Context* context = Context::cast(obj);
+    TagObject(context->jsfunction_result_caches(),
+              "(context func. result caches)");
+    TagObject(context->normalized_map_cache(), "(context norm. map cache)");
+    TagObject(context->runtime_context(), "(runtime context)");
+    TagObject(context->map_cache(), "(context map cache)");
+    TagObject(context->data(), "(context data)");
   } else if (obj->IsMap()) {
     Map* map = Map::cast(obj);
     SetInternalReference(obj, entry,
@@ -1866,6 +1912,7 @@
                          "constructor", map->constructor(),
                          Map::kConstructorOffset);
     if (!map->instance_descriptors()->IsEmpty()) {
+      TagObject(map->instance_descriptors(), "(map descriptors)");
       SetInternalReference(obj, entry,
                            "descriptors", map->instance_descriptors(),
                            Map::kInstanceDescriptorsOrBitField3Offset);
@@ -1873,9 +1920,6 @@
     SetInternalReference(obj, entry,
                          "code_cache", map->code_cache(),
                          Map::kCodeCacheOffset);
-    SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
-    IndexedReferencesExtractor refs_extractor(this, obj, entry);
-    obj->Iterate(&refs_extractor);
   } else if (obj->IsSharedFunctionInfo()) {
     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
     SetInternalReference(obj, entry,
@@ -1884,16 +1928,61 @@
     SetInternalReference(obj, entry,
                          "code", shared->unchecked_code(),
                          SharedFunctionInfo::kCodeOffset);
+    TagObject(shared->scope_info(), "(function scope info)");
+    SetInternalReference(obj, entry,
+                         "scope_info", shared->scope_info(),
+                         SharedFunctionInfo::kScopeInfoOffset);
     SetInternalReference(obj, entry,
                          "instance_class_name", shared->instance_class_name(),
                          SharedFunctionInfo::kInstanceClassNameOffset);
     SetInternalReference(obj, entry,
                          "script", shared->script(),
                          SharedFunctionInfo::kScriptOffset);
-    SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
-    IndexedReferencesExtractor refs_extractor(this, obj, entry);
-    obj->Iterate(&refs_extractor);
-  } else {
+  } else if (obj->IsScript()) {
+    Script* script = Script::cast(obj);
+    SetInternalReference(obj, entry,
+                         "source", script->source(),
+                         Script::kSourceOffset);
+    SetInternalReference(obj, entry,
+                         "name", script->name(),
+                         Script::kNameOffset);
+    SetInternalReference(obj, entry,
+                         "data", script->data(),
+                         Script::kDataOffset);
+    SetInternalReference(obj, entry,
+                         "context_data", script->context_data(),
+                         Script::kContextOffset);
+    TagObject(script->line_ends(), "(script line ends)");
+    SetInternalReference(obj, entry,
+                         "line_ends", script->line_ends(),
+                         Script::kLineEndsOffset);
+  } else if (obj->IsDescriptorArray()) {
+    DescriptorArray* desc_array = DescriptorArray::cast(obj);
+    if (desc_array->length() > DescriptorArray::kContentArrayIndex) {
+      Object* content_array =
+          desc_array->get(DescriptorArray::kContentArrayIndex);
+      TagObject(content_array, "(map descriptor content)");
+      SetInternalReference(obj, entry,
+                           "content", content_array,
+                           FixedArray::OffsetOfElementAt(
+                               DescriptorArray::kContentArrayIndex));
+    }
+  } else if (obj->IsCodeCache()) {
+    CodeCache* code_cache = CodeCache::cast(obj);
+    TagObject(code_cache->default_cache(), "(default code cache)");
+    SetInternalReference(obj, entry,
+                         "default_cache", code_cache->default_cache(),
+                         CodeCache::kDefaultCacheOffset);
+    TagObject(code_cache->normal_type_cache(), "(code type cache)");
+    SetInternalReference(obj, entry,
+                         "type_cache", code_cache->normal_type_cache(),
+                         CodeCache::kNormalTypeCacheOffset);
+  } else if (obj->IsCode()) {
+    Code* code = Code::cast(obj);
+    TagObject(code->unchecked_relocation_info(), "(code relocation info)");
+    TagObject(code->unchecked_deoptimization_data(), "(code deopt data)");
+  }
+  if (extract_indexed_refs) {
     SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
     IndexedReferencesExtractor refs_extractor(this, obj, entry);
     obj->Iterate(&refs_extractor);
@@ -2051,7 +2140,7 @@
   }
   SetRootGcRootsReference();
   RootsReferencesExtractor extractor(this);
-  HEAP->IterateRoots(&extractor, VISIT_ALL);
+  heap_->IterateRoots(&extractor, VISIT_ALL);
   filler_ = NULL;
   return progress_->ProgressReport(false);
 }
@@ -2206,6 +2295,76 @@
 }
 
 
+void V8HeapExplorer::TagObject(Object* obj, const char* tag) {
+  if (obj->IsHeapObject() &&
+      !obj->IsOddball() &&
+      obj != heap_->raw_unchecked_empty_byte_array() &&
+      obj != heap_->raw_unchecked_empty_fixed_array() &&
+      obj != heap_->raw_unchecked_empty_fixed_double_array() &&
+      obj != heap_->raw_unchecked_empty_descriptor_array()) {
+    objects_tags_.SetTag(obj, tag);
+  }
+}
+
+
+class GlobalObjectsEnumerator : public ObjectVisitor {
+ public:
+  virtual void VisitPointers(Object** start, Object** end) {
+    for (Object** p = start; p < end; p++) {
+      if ((*p)->IsGlobalContext()) {
+        Context* context = Context::cast(*p);
+        JSObject* proxy = context->global_proxy();
+        if (proxy->IsJSGlobalProxy()) {
+          Object* global = proxy->map()->prototype();
+          if (global->IsJSGlobalObject()) {
+            objects_.Add(Handle<JSGlobalObject>(JSGlobalObject::cast(global)));
+          }
+        }
+      }
+    }
+  }
+  int count() { return objects_.length(); }
+  Handle<JSGlobalObject>& at(int i) { return objects_[i]; }
+
+ private:
+  List<Handle<JSGlobalObject> > objects_;
+};
+
+
+// Modifies heap. Must not be run during heap traversal.
+void V8HeapExplorer::TagGlobalObjects() {
+  Isolate* isolate = Isolate::Current();
+  GlobalObjectsEnumerator enumerator;
+  isolate->global_handles()->IterateAllRoots(&enumerator);
+  Handle<String> document_string =
+      isolate->factory()->NewStringFromAscii(CStrVector("document"));
+  Handle<String> url_string =
+      isolate->factory()->NewStringFromAscii(CStrVector("URL"));
+  const char** urls = NewArray<const char*>(enumerator.count());
+  for (int i = 0, l = enumerator.count(); i < l; ++i) {
+    urls[i] = NULL;
+    Handle<JSGlobalObject> global_obj = enumerator.at(i);
+    Object* obj_document;
+    if (global_obj->GetProperty(*document_string)->ToObject(&obj_document) &&
+       obj_document->IsJSObject()) {
+      JSObject* document = JSObject::cast(obj_document);
+      Object* obj_url;
+      if (document->GetProperty(*url_string)->ToObject(&obj_url) &&
+          obj_url->IsString()) {
+        urls[i] = collection_->names()->GetName(String::cast(obj_url));
+      }
+    }
+  }
+
+  AssertNoAllocation no_allocation;
+  for (int i = 0, l = enumerator.count(); i < l; ++i) {
+    objects_tags_.SetTag(*enumerator.at(i), urls[i]);
+  }
+
+  DeleteArray(urls);
+}
+
+
 class GlobalHandlesExtractor : public ObjectVisitor {
  public:
   explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer)
@@ -2448,6 +2607,7 @@
                                   HeapEntry*) {
     entries_->CountReference(parent_ptr, child_ptr);
   }
+
  private:
   HeapEntriesMap* entries_;
 };
@@ -2519,6 +2679,7 @@
                               child_entry,
                               retainer_index);
   }
+
  private:
   HeapSnapshot* snapshot_;
   HeapSnapshotsCollection* collection_;
@@ -2527,6 +2688,8 @@
 
 
 bool HeapSnapshotGenerator::GenerateSnapshot() {
+  v8_heap_explorer_.TagGlobalObjects();
+
   AssertNoAllocation no_alloc;
 
   SetProgressTotal(4);  // 2 passes + dominators + sizes.
@@ -3094,5 +3257,3 @@
 }
 
 } }  // namespace v8::internal
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 5b789ac..d1c2b38 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -28,8 +28,6 @@
 #ifndef V8_PROFILE_GENERATOR_H_
 #define V8_PROFILE_GENERATOR_H_
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "allocation.h"
 #include "hashmap.h"
 #include "../include/v8-profiler.h"
@@ -638,8 +636,7 @@
 class HeapSnapshot {
  public:
   enum Type {
-    kFull = v8::HeapSnapshot::kFull,
-    kAggregated = v8::HeapSnapshot::kAggregated
+    kFull = v8::HeapSnapshot::kFull
   };
 
   HeapSnapshot(HeapSnapshotsCollection* collection,
@@ -859,6 +856,8 @@
   void Clear();
   bool Contains(Object* object);
   void Insert(Object* obj);
+  const char* GetTag(Object* obj);
+  void SetTag(Object* obj, const char* tag);
 
  private:
   HashMap entries_;
@@ -920,6 +919,7 @@
   void AddRootEntries(SnapshotFillerInterface* filler);
   int EstimateObjectsCount();
   bool IterateAndExtractReferences(SnapshotFillerInterface* filler);
+  void TagGlobalObjects();
 
   static HeapObject* const kInternalRootObject;
 
@@ -971,13 +971,16 @@
   void SetRootShortcutReference(Object* child);
   void SetRootGcRootsReference();
   void SetGcRootsReference(Object* child);
+  void TagObject(Object* obj, const char* tag);
 
   HeapEntry* GetEntry(Object* obj);
 
+  Heap* heap_;
   HeapSnapshot* snapshot_;
   HeapSnapshotsCollection* collection_;
   SnapshottingProgressReportingInterface* progress_;
   SnapshotFillerInterface* filler_;
+  HeapObjectsSet objects_tags_;
 
   static HeapObject* const kGcRootsObject;
 
@@ -1121,6 +1124,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 #endif  // V8_PROFILE_GENERATOR_H_
diff --git a/src/property.h b/src/property.h
index 87f9ea3..ddecc92 100644
--- a/src/property.h
+++ b/src/property.h
@@ -206,6 +206,7 @@
     lookup_type_ = HANDLER_TYPE;
     holder_ = NULL;
     details_ = PropertyDetails(NONE, HANDLER);
+    cacheable_ = false;
   }
 
   void InterceptorResult(JSObject* holder) {
diff --git a/src/proxy.js b/src/proxy.js
index c11852b..27524bd 100644
--- a/src/proxy.js
+++ b/src/proxy.js
@@ -60,7 +60,9 @@
 }
 
 $Proxy.create = function(handler, proto) {
-  if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
+  if (!IS_SPEC_OBJECT(handler))
+    throw MakeTypeError("handler_non_object", ["create"])
+  if (!IS_SPEC_OBJECT(proto)) proto = null  // Mozilla does this...
   return %CreateJSProxy(handler, proto)
 }
 
@@ -73,11 +75,75 @@
 
 function DerivedGetTrap(receiver, name) {
   var desc = this.getPropertyDescriptor(name)
-  if (IS_UNDEFINED(desc)) { return desc; }
+  if (IS_UNDEFINED(desc)) { return desc }
   if ('value' in desc) {
     return desc.value
   } else {
-    if (IS_UNDEFINED(desc.get)) { return desc.get; }
-    return desc.get.call(receiver)  // The proposal says so...
+    if (IS_UNDEFINED(desc.get)) { return desc.get }
+    // The proposal says: desc.get.call(receiver)
+    return %_CallFunction(receiver, desc.get)
   }
 }
+
+function DerivedSetTrap(receiver, name, val) {
+  var desc = this.getOwnPropertyDescriptor(name)
+  if (desc) {
+    if ('writable' in desc) {
+      if (desc.writable) {
+        desc.value = val
+        this.defineProperty(name, desc)
+        return true
+      } else {
+        return false
+      }
+    } else { // accessor
+      if (desc.set) {
+        // The proposal says: desc.set.call(receiver, val)
+        %_CallFunction(receiver, val, desc.set)
+        return true
+      } else {
+        return false
+      }
+    }
+  }
+  desc = this.getPropertyDescriptor(name)
+  if (desc) {
+    if ('writable' in desc) {
+      if (desc.writable) {
+        // fall through
+      } else {
+        return false
+      }
+    } else { // accessor
+      if (desc.set) {
+        // The proposal says: desc.set.call(receiver, val)
+        %_CallFunction(receiver, val, desc.set)
+        return true
+      } else {
+        return false
+      }
+    }
+  }
+  this.defineProperty(name, {
+    value: val,
+    writable: true,
+    enumerable: true,
+    configurable: true});
+  return true;
+}
+
+function DerivedHasTrap(name) {
+  return !!this.getPropertyDescriptor(name)
+}
+
+function DerivedKeysTrap() {
+  var names = this.getOwnPropertyNames()
+  var enumerableNames = []
+  for (var i = 0, count = 0; i < names.length; ++i) {
+    var name = names[i]
+    if (this.getOwnPropertyDescriptor(TO_STRING_INLINE(name)).enumerable) {
+      enumerableNames[count++] = names[i]
+    }
+  }
+  return enumerableNames
+}
diff --git a/src/rewriter.cc b/src/rewriter.cc
index efe8044..e8ca5b9 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -66,9 +66,13 @@
 
   Expression* SetResult(Expression* value) {
     result_assigned_ = true;
-    VariableProxy* result_proxy = new VariableProxy(result_);
-    return new Assignment(Token::ASSIGN, result_proxy, value,
-                          RelocInfo::kNoPosition);
+    Zone* zone = isolate()->zone();
+    VariableProxy* result_proxy = new(zone) VariableProxy(isolate(), result_);
+    return new(zone) Assignment(isolate(),
+                                Token::ASSIGN,
+                                result_proxy,
+                                value,
+                                RelocInfo::kNoPosition);
   }
 
   // Node visitors.
@@ -197,137 +201,18 @@
 void Processor::VisitDeclaration(Declaration* node) {}
 void Processor::VisitEmptyStatement(EmptyStatement* node) {}
 void Processor::VisitReturnStatement(ReturnStatement* node) {}
-void Processor::VisitWithEnterStatement(WithEnterStatement* node) {}
-void Processor::VisitWithExitStatement(WithExitStatement* node) {}
+void Processor::VisitEnterWithContextStatement(
+    EnterWithContextStatement* node) {
+}
+void Processor::VisitExitContextStatement(ExitContextStatement* node) {}
 void Processor::VisitDebuggerStatement(DebuggerStatement* node) {}
 
 
 // Expressions are never visited yet.
-void Processor::VisitFunctionLiteral(FunctionLiteral* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitSharedFunctionInfoLiteral(
-    SharedFunctionInfoLiteral* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitConditional(Conditional* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitVariableProxy(VariableProxy* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitLiteral(Literal* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitRegExpLiteral(RegExpLiteral* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitArrayLiteral(ArrayLiteral* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitObjectLiteral(ObjectLiteral* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitCatchExtensionObject(CatchExtensionObject* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitAssignment(Assignment* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitThrow(Throw* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitProperty(Property* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitCall(Call* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitCallNew(CallNew* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitCallRuntime(CallRuntime* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitUnaryOperation(UnaryOperation* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitCountOperation(CountOperation* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitBinaryOperation(BinaryOperation* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitCompareOperation(CompareOperation* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitCompareToNull(CompareToNull* node) {
-  USE(node);
-  UNREACHABLE();
-}
-
-
-void Processor::VisitThisFunction(ThisFunction* node) {
-  USE(node);
-  UNREACHABLE();
-}
+#define DEF_VISIT(type)                                         \
+  void Processor::Visit##type(type* expr) { UNREACHABLE(); }
+EXPRESSION_NODE_LIST(DEF_VISIT)
+#undef DEF_VISIT
 
 
 // Assumes code has been parsed and scopes have been analyzed.  Mutates the
@@ -337,7 +222,7 @@
   ASSERT(function != NULL);
   Scope* scope = function->scope();
   ASSERT(scope != NULL);
-  if (scope->is_function_scope()) return true;
+  if (!scope->is_global_scope() && !scope->is_eval_scope()) return true;
 
   ZoneList<Statement*>* body = function->body();
   if (!body->is_empty()) {
@@ -348,8 +233,10 @@
     if (processor.HasStackOverflow()) return false;
 
     if (processor.result_assigned()) {
-      VariableProxy* result_proxy = new VariableProxy(result);
-      body->Add(new ReturnStatement(result_proxy));
+      Isolate* isolate = info->isolate();
+      Zone* zone = isolate->zone();
+      VariableProxy* result_proxy = new(zone) VariableProxy(isolate, result);
+      body->Add(new(zone) ReturnStatement(result_proxy));
     }
   }
 
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index ce9a308..917f6d0 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -43,32 +43,6 @@
 namespace internal {
 
 
-class PendingListNode : public Malloced {
- public:
-  explicit PendingListNode(JSFunction* function);
-  ~PendingListNode() { Destroy(); }
-
-  PendingListNode* next() const { return next_; }
-  void set_next(PendingListNode* node) { next_ = node; }
-  Handle<JSFunction> function() { return Handle<JSFunction>::cast(function_); }
-
-  // If the function is garbage collected before we've had the chance
-  // to optimize it the weak handle will be null.
-  bool IsValid() { return !function_.is_null(); }
-
-  // Returns the number of microseconds this node has been pending.
-  int Delay() const { return static_cast<int>(OS::Ticks() - start_); }
-
- private:
-  void Destroy();
-  static void WeakCallback(v8::Persistent<v8::Value> object, void* data);
-
-  PendingListNode* next_;
-  Handle<Object> function_;  // Weak handle.
-  int64_t start_;
-};
-
-
 // Optimization sampler constants.
 static const int kSamplerFrameCount = 2;
 static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 };
@@ -80,39 +54,14 @@
 static const int kSamplerThresholdDelta = 1;
 
 static const int kSamplerThresholdSizeFactorInit = 3;
-static const int kSamplerThresholdSizeFactorMin = 1;
-static const int kSamplerThresholdSizeFactorDelta = 1;
 
 static const int kSizeLimit = 1500;
 
 
-PendingListNode::PendingListNode(JSFunction* function) : next_(NULL) {
-  GlobalHandles* global_handles = Isolate::Current()->global_handles();
-  function_ = global_handles->Create(function);
-  start_ = OS::Ticks();
-  global_handles->MakeWeak(function_.location(), this, &WeakCallback);
-}
-
-
-void PendingListNode::Destroy() {
-  if (!IsValid()) return;
-  GlobalHandles* global_handles = Isolate::Current()->global_handles();
-  global_handles->Destroy(function_.location());
-  function_= Handle<Object>::null();
-}
-
-
-void PendingListNode::WeakCallback(v8::Persistent<v8::Value>, void* data) {
-  reinterpret_cast<PendingListNode*>(data)->Destroy();
-}
-
-
 Atomic32 RuntimeProfiler::state_ = 0;
 // TODO(isolates): Create the semaphore lazily and clean it up when no
 // longer required.
-#ifdef ENABLE_LOGGING_AND_PROFILING
 Semaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0);
-#endif
 
 #ifdef DEBUG
 bool RuntimeProfiler::has_been_globally_setup_ = false;
@@ -125,16 +74,8 @@
       sampler_threshold_(kSamplerThresholdInit),
       sampler_threshold_size_factor_(kSamplerThresholdSizeFactorInit),
       sampler_ticks_until_threshold_adjustment_(
-        kSamplerTicksBetweenThresholdAdjustment),
-      js_ratio_(0),
-      sampler_window_position_(0),
-      optimize_soon_list_(NULL),
-      state_window_position_(0),
-      state_window_ticks_(0) {
-  state_counts_[IN_NON_JS_STATE] = kStateWindowSize;
-  state_counts_[IN_JS_STATE] = 0;
-  STATIC_ASSERT(IN_NON_JS_STATE == 0);
-  memset(state_window_, 0, sizeof(state_window_));
+          kSamplerTicksBetweenThresholdAdjustment),
+      sampler_window_position_(0) {
   ClearSampleBuffer();
 }
 
@@ -148,16 +89,13 @@
 }
 
 
-void RuntimeProfiler::Optimize(JSFunction* function, bool eager, int delay) {
+void RuntimeProfiler::Optimize(JSFunction* function) {
   ASSERT(function->IsOptimizable());
   if (FLAG_trace_opt) {
-    PrintF("[marking (%s) ", eager ? "eagerly" : "lazily");
+    PrintF("[marking ");
     function->PrintName();
     PrintF(" 0x%" V8PRIxPTR, reinterpret_cast<intptr_t>(function->address()));
     PrintF(" for recompilation");
-    if (delay > 0) {
-      PrintF(" (delayed %0.3f ms)", static_cast<double>(delay) / 1000);
-    }
     PrintF("]\n");
   }
 
@@ -185,7 +123,7 @@
   // We are not prepared to do OSR for a function that already has an
   // allocated arguments object.  The optimized code would bypass it for
   // arguments accesses, which is unsound.  Don't try OSR.
-  if (shared->scope_info()->HasArgumentsShadow()) return;
+  if (shared->uses_arguments()) return;
 
   // We're using on-stack replacement: patch the unoptimized code so that
   // any back edge in any unoptimized frame will trigger on-stack
@@ -243,20 +181,6 @@
 
 void RuntimeProfiler::OptimizeNow() {
   HandleScope scope(isolate_);
-  PendingListNode* current = optimize_soon_list_;
-  while (current != NULL) {
-    PendingListNode* next = current->next();
-    if (current->IsValid()) {
-      Handle<JSFunction> function = current->function();
-      int delay = current->Delay();
-      if (function->IsOptimizable()) {
-        Optimize(*function, true, delay);
-      }
-    }
-    delete current;
-    current = next;
-  }
-  optimize_soon_list_ = NULL;
 
   // Run through the JavaScript frames and collect them. If we already
   // have a sample of the function, we mark it for optimizations
@@ -303,24 +227,9 @@
         : 1;
 
     int threshold = sampler_threshold_ * threshold_size_factor;
-    int current_js_ratio = NoBarrier_Load(&js_ratio_);
-
-    // Adjust threshold depending on the ratio of time spent
-    // in JS code.
-    if (current_js_ratio < 20) {
-      // If we spend less than 20% of the time in JS code,
-      // do not optimize.
-      continue;
-    } else if (current_js_ratio < 75) {
-      // Below 75% of time spent in JS code, only optimize very
-      // frequently used functions.
-      threshold *= 3;
-    }
 
     if (LookupSample(function) >= threshold) {
-      Optimize(function, false, 0);
-      isolate_->compilation_cache()->MarkForEagerOptimizing(
-          Handle<JSFunction>(function));
+      Optimize(function);
     }
   }
 
@@ -333,42 +242,8 @@
 }
 
 
-void RuntimeProfiler::OptimizeSoon(JSFunction* function) {
-  if (!function->IsOptimizable()) return;
-  PendingListNode* node = new PendingListNode(function);
-  node->set_next(optimize_soon_list_);
-  optimize_soon_list_ = node;
-}
-
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-void RuntimeProfiler::UpdateStateRatio(SamplerState current_state) {
-  SamplerState old_state = state_window_[state_window_position_];
-  state_counts_[old_state]--;
-  state_window_[state_window_position_] = current_state;
-  state_counts_[current_state]++;
-  ASSERT(IsPowerOf2(kStateWindowSize));
-  state_window_position_ = (state_window_position_ + 1) &
-      (kStateWindowSize - 1);
-  // Note: to calculate correct ratio we have to track how many valid
-  // ticks are actually in the state window, because on profiler
-  // startup this number can be less than the window size.
-  state_window_ticks_ = Min(kStateWindowSize, state_window_ticks_ + 1);
-  NoBarrier_Store(&js_ratio_, state_counts_[IN_JS_STATE] * 100 /
-                  state_window_ticks_);
-}
-#endif
-
-
 void RuntimeProfiler::NotifyTick() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  // Record state sample.
-  SamplerState state = IsSomeIsolateInJS()
-      ? IN_JS_STATE
-      : IN_NON_JS_STATE;
-  UpdateStateRatio(state);
   isolate_->stack_guard()->RequestRuntimeProfilerTick();
-#endif
 }
 
 
@@ -416,7 +291,6 @@
 
 
 void RuntimeProfiler::HandleWakeUp(Isolate* isolate) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // The profiler thread must still be waiting.
   ASSERT(NoBarrier_Load(&state_) >= 0);
   // In IsolateEnteredJS we have already incremented the counter and
@@ -424,8 +298,6 @@
   // to get the right count of active isolates.
   NoBarrier_AtomicIncrement(&state_, 1);
   semaphore_->Signal();
-  isolate->ResetEagerOptimizingData();
-#endif
 }
 
 
@@ -435,20 +307,33 @@
 
 
 bool RuntimeProfiler::WaitForSomeIsolateToEnterJS() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Atomic32 old_state = NoBarrier_CompareAndSwap(&state_, 0, -1);
   ASSERT(old_state >= -1);
   if (old_state != 0) return false;
   semaphore_->Wait();
-#endif
   return true;
 }
 
 
-void RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  semaphore_->Signal();
-#endif
+void RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(Thread* thread) {
+  // Do a fake increment. If the profiler is waiting on the semaphore,
+  // the returned state is 0, which can be left as an initial state in
+  // case profiling is restarted later. If the profiler is not
+  // waiting, the increment will prevent it from waiting, but has to
+  // be undone after the profiler is stopped.
+  Atomic32 new_state = NoBarrier_AtomicIncrement(&state_, 1);
+  ASSERT(new_state >= 0);
+  if (new_state == 0) {
+    // The profiler thread is waiting. Wake it up. It must check for
+    // stop conditions before attempting to wait again.
+    semaphore_->Signal();
+  }
+  thread->Join();
+  // The profiler thread is now stopped. Undo the increment in case it
+  // was not waiting.
+  if (new_state != 0) {
+    NoBarrier_AtomicIncrement(&state_, -1);
+  }
 }
 
 
@@ -470,18 +355,9 @@
 
 
 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  static const int kNonJSTicksThreshold = 100;
-  if (RuntimeProfiler::IsSomeIsolateInJS()) {
-    non_js_ticks_ = 0;
-  } else {
-    if (non_js_ticks_ < kNonJSTicksThreshold) {
-      ++non_js_ticks_;
-    } else {
-      return RuntimeProfiler::WaitForSomeIsolateToEnterJS();
-    }
+  if (!RuntimeProfiler::IsSomeIsolateInJS()) {
+    return RuntimeProfiler::WaitForSomeIsolateToEnterJS();
   }
-#endif
   return false;
 }
 
diff --git a/src/runtime-profiler.h b/src/runtime-profiler.h
index 692b4ff..3f3ab07 100644
--- a/src/runtime-profiler.h
+++ b/src/runtime-profiler.h
@@ -37,7 +37,6 @@
 class Isolate;
 class JSFunction;
 class Object;
-class PendingListNode;
 class Semaphore;
 
 class RuntimeProfiler {
@@ -52,7 +51,6 @@
   }
 
   void OptimizeNow();
-  void OptimizeSoon(JSFunction* function);
 
   void NotifyTick();
 
@@ -86,10 +84,9 @@
   static bool IsSomeIsolateInJS();
   static bool WaitForSomeIsolateToEnterJS();
 
-  // When shutting down we join the profiler thread. Doing so while
-  // it's waiting on a semaphore will cause a deadlock, so we have to
-  // wake it up first.
-  static void WakeUpRuntimeProfilerThreadBeforeShutdown();
+  // Stops the runtime profiler thread when profiling support is being
+  // turned off.
+  static void StopRuntimeProfilerThreadBeforeShutdown(Thread* thread);
 
   void UpdateSamplesAfterScavenge();
   void RemoveDeadSamples();
@@ -106,7 +103,7 @@
 
   static void HandleWakeUp(Isolate* isolate);
 
-  void Optimize(JSFunction* function, bool eager, int delay);
+  void Optimize(JSFunction* function);
 
   void AttemptOnStackReplacement(JSFunction* function);
 
@@ -118,31 +115,16 @@
 
   void AddSample(JSFunction* function, int weight);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  void UpdateStateRatio(SamplerState current_state);
-#endif
-
   Isolate* isolate_;
 
   int sampler_threshold_;
   int sampler_threshold_size_factor_;
   int sampler_ticks_until_threshold_adjustment_;
 
-  // The ratio of ticks spent in JS code in percent.
-  Atomic32 js_ratio_;
-
   Object* sampler_window_[kSamplerWindowSize];
   int sampler_window_position_;
   int sampler_window_weight_[kSamplerWindowSize];
 
-  // Support for pending 'optimize soon' requests.
-  PendingListNode* optimize_soon_list_;
-
-  SamplerState state_window_[kStateWindowSize];
-  int state_window_position_;
-  int state_window_ticks_;
-  int state_counts_[2];
-
   // Possible state values:
   //   -1            => the profiler thread is waiting on the semaphore
   //   0 or positive => the number of isolates running JavaScript code.
@@ -159,7 +141,7 @@
 // Rate limiter intended to be used in the profiler thread.
 class RuntimeProfilerRateLimiter BASE_EMBEDDED {
  public:
-  RuntimeProfilerRateLimiter() : non_js_ticks_(0) { }
+  RuntimeProfilerRateLimiter() {}
 
   // Suspends the current thread (which must be the profiler thread)
   // when not executing JavaScript to minimize CPU usage. Returns
@@ -170,8 +152,6 @@
   bool SuspendIfNecessary();
 
  private:
-  int non_js_ticks_;
-
   DISALLOW_COPY_AND_ASSIGN(RuntimeProfilerRateLimiter);
 };
 
diff --git a/src/runtime.cc b/src/runtime.cc
index 77b3f66..8f14565 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -45,6 +45,7 @@
 #include "json-parser.h"
 #include "liveedit.h"
 #include "liveobjectlist-inl.h"
+#include "misc-intrinsics.h"
 #include "parser.h"
 #include "platform.h"
 #include "runtime-profiler.h"
@@ -81,19 +82,19 @@
   RUNTIME_ASSERT(obj->IsBoolean());                                   \
   bool name = (obj)->IsTrue();
 
-// Cast the given object to a Smi and store its value in an int variable
-// with the given name.  If the object is not a Smi call IllegalOperation
+// 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_CHECKED(name, obj)                            \
-  RUNTIME_ASSERT(obj->IsSmi());                                   \
-  int name = Smi::cast(obj)->value();
+#define CONVERT_SMI_ARG_CHECKED(name, index)                         \
+  RUNTIME_ASSERT(args[index]->IsSmi());                              \
+  int name = args.smi_at(index);
 
-// Cast the given object to a double and store it in a variable with
-// the given name.  If the object is not a number (as opposed to
+// 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_CHECKED(name, obj)                            \
-  RUNTIME_ASSERT(obj->IsNumber());                                   \
-  double name = (obj)->Number();
+#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
@@ -482,7 +483,7 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
   CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_CHECKED(literals_index, args[1]);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_CHECKED(FixedArray, elements, 2);
 
   Handle<Object> object =
@@ -499,9 +500,9 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 4);
   CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_CHECKED(literals_index, args[1]);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
-  CONVERT_SMI_CHECKED(flags, args[3]);
+  CONVERT_SMI_ARG_CHECKED(flags, 3);
   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
 
@@ -525,9 +526,9 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 4);
   CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_CHECKED(literals_index, args[1]);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
-  CONVERT_SMI_CHECKED(flags, args[3]);
+  CONVERT_SMI_ARG_CHECKED(flags, 3);
   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
 
@@ -551,7 +552,7 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
   CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_CHECKED(literals_index, args[1]);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_CHECKED(FixedArray, elements, 2);
 
   // Check if boilerplate exists. If not, create it first.
@@ -570,7 +571,7 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
   CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_CHECKED(literals_index, args[1]);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_CHECKED(FixedArray, elements, 2);
 
   // Check if boilerplate exists. If not, create it first.
@@ -594,34 +595,30 @@
   Object* handler = args[0];
   Object* prototype = args[1];
   Object* used_prototype =
-      (prototype->IsJSObject() || prototype->IsJSProxy()) ? prototype
-          : isolate->heap()->null_value();
+      prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
   return isolate->heap()->AllocateJSProxy(handler, used_prototype);
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) {
-  ASSERT(args.length() == 2);
-  CONVERT_CHECKED(String, key, args[0]);
-  Object* value = args[1];
-  ASSERT(!value->IsFailure());
-  // Create a catch context extension object.
-  JSFunction* constructor =
-      isolate->context()->global_context()->
-          context_extension_function();
-  Object* object;
-  { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor);
-    if (!maybe_object->ToObject(&object)) return maybe_object;
-  }
-  // Assign the exception value to the catch variable and make sure
-  // that the catch variable is DontDelete.
-  { MaybeObject* maybe_value =
-        // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4.
-        JSObject::cast(object)->SetProperty(
-            key, value, DONT_DELETE, kNonStrictMode);
-    if (!maybe_value->ToObject(&value)) return maybe_value;
-  }
-  return object;
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
+  ASSERT(args.length() == 1);
+  Object* obj = args[0];
+  return isolate->heap()->ToBoolean(obj->IsJSProxy());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
+  ASSERT(args.length() == 1);
+  CONVERT_CHECKED(JSProxy, proxy, args[0]);
+  return proxy->handler();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
+  ASSERT(args.length() == 1);
+  CONVERT_CHECKED(JSProxy, proxy, args[0]);
+  proxy->Fix();
+  return proxy;
 }
 
 
@@ -634,6 +631,28 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 1);
+  CONVERT_CHECKED(JSReceiver, input_obj, args[0]);
+  Object* obj = input_obj;
+  // We don't expect access checks to be needed on JSProxy objects.
+  ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
+  do {
+    if (obj->IsAccessCheckNeeded() &&
+        !isolate->MayNamedAccess(JSObject::cast(obj),
+                                 isolate->heap()->Proto_symbol(),
+                                 v8::ACCESS_GET)) {
+      isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET);
+      return isolate->heap()->undefined_value();
+    }
+    obj = obj->GetPrototype();
+  } while (obj->IsJSObject() &&
+           JSObject::cast(obj)->map()->is_hidden_prototype());
+  return obj;
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
@@ -874,7 +893,13 @@
           ASSERT(proto->IsJSGlobalObject());
           holder = Handle<JSObject>(JSObject::cast(proto));
         }
-        NumberDictionary* dictionary = holder->element_dictionary();
+        FixedArray* elements = FixedArray::cast(holder->elements());
+        NumberDictionary* dictionary = NULL;
+        if (elements->map() == heap->non_strict_arguments_elements_map()) {
+          dictionary = NumberDictionary::cast(elements->get(1));
+        } else {
+          dictionary = NumberDictionary::cast(elements);
+        }
         int entry = dictionary->FindEntry(index);
         ASSERT(entry != NumberDictionary::kNotFound);
         PropertyDetails details = dictionary->DetailsAt(entry);
@@ -973,8 +998,7 @@
     ASSERT(proto->IsJSGlobalObject());
     obj = JSObject::cast(proto);
   }
-  return obj->map()->is_extensible() ? isolate->heap()->true_value()
-                                     : isolate->heap()->false_value();
+  return isolate->heap()->ToBoolean(obj->map()->is_extensible());
 }
 
 
@@ -1040,8 +1064,7 @@
     Map::cast(new_map)->set_is_access_check_needed(false);
     object->set_map(Map::cast(new_map));
   }
-  return needs_access_checks ? isolate->heap()->true_value()
-                             : isolate->heap()->false_value();
+  return isolate->heap()->ToBoolean(needs_access_checks);
 }
 
 
@@ -1084,9 +1107,8 @@
 
   Handle<Context> context = args.at<Context>(0);
   CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
-  bool is_eval = Smi::cast(args[2])->value() == 1;
-  StrictModeFlag strict_mode =
-      static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
+  bool is_eval = args.smi_at(2) == 1;
+  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
   ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
 
   // Compute the property attributes. According to ECMA-262, section
@@ -1225,13 +1247,12 @@
 
   CONVERT_ARG_CHECKED(Context, context, 0);
   Handle<String> name(String::cast(args[1]));
-  PropertyAttributes mode =
-      static_cast<PropertyAttributes>(Smi::cast(args[2])->value());
+  PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
   RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
   Handle<Object> initial_value(args[3], isolate);
 
-  // Declarations are always done in the function context.
-  context = Handle<Context>(context->fcontext());
+  // Declarations are always done in a function or global context.
+  context = Handle<Context>(context->declaration_context());
 
   int index;
   PropertyAttributes attributes;
@@ -1285,7 +1306,7 @@
     Handle<JSObject> context_ext;
     if (context->has_extension()) {
       // The function context's extension context exists - use it.
-      context_ext = Handle<JSObject>(context->extension());
+      context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
     } else {
       // The function context's extension context does not exists - allocate
       // it.
@@ -1339,8 +1360,7 @@
   CONVERT_ARG_CHECKED(String, name, 0);
   GlobalObject* global = isolate->context()->global();
   RUNTIME_ASSERT(args[1]->IsSmi());
-  StrictModeFlag strict_mode =
-      static_cast<StrictModeFlag>(Smi::cast(args[1])->value());
+  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(1));
   ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
 
   // According to ECMA-262, section 12.2, page 62, the property must
@@ -1519,8 +1539,8 @@
   CONVERT_ARG_CHECKED(Context, context, 1);
   Handle<String> name(String::cast(args[2]));
 
-  // Initializations are always done in the function context.
-  context = Handle<Context>(context->fcontext());
+  // Initializations are always done in a function or global context.
+  context = Handle<Context>(context->declaration_context());
 
   int index;
   PropertyAttributes attributes;
@@ -1541,14 +1561,12 @@
   // In that case, the initialization behaves like a normal assignment
   // to property 'x'.
   if (index >= 0) {
-    // Property was found in a context.
     if (holder->IsContext()) {
-      // The holder cannot be the function context.  If it is, there
-      // should have been a const redeclaration error when declaring
-      // the const property.
-      ASSERT(!holder.is_identical_to(context));
-      if ((attributes & READ_ONLY) == 0) {
-        Handle<Context>::cast(holder)->set(index, *value);
+      // Property was found in a context.  Perform the assignment if we
+      // found some non-constant or an uninitialized constant.
+      Handle<Context> context = Handle<Context>::cast(holder);
+      if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
+        context->set(index, *value);
       }
     } else {
       // The holder is an arguments object.
@@ -1622,7 +1640,7 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 2);
   CONVERT_ARG_CHECKED(JSObject, object, 0);
-  CONVERT_SMI_CHECKED(properties, args[1]);
+  CONVERT_SMI_ARG_CHECKED(properties, 1);
   if (object->HasFastProperties()) {
     NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
   }
@@ -1637,7 +1655,7 @@
   CONVERT_ARG_CHECKED(String, subject, 1);
   // 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.
-  CONVERT_SMI_CHECKED(index, args[2]);
+  CONVERT_SMI_ARG_CHECKED(index, 2);
   CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
   RUNTIME_ASSERT(last_match_info->HasFastElements());
   RUNTIME_ASSERT(index >= 0);
@@ -1654,7 +1672,7 @@
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
   ASSERT(args.length() == 3);
-  CONVERT_SMI_CHECKED(elements_count, args[0]);
+  CONVERT_SMI_ARG_CHECKED(elements_count, 0);
   if (elements_count > JSArray::kMaxFastElementsLength) {
     return isolate->ThrowIllegalOperation();
   }
@@ -1809,7 +1827,7 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 4);
   CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  int index = Smi::cast(args[1])->value();
+  int index = args.smi_at(1);
   Handle<String> pattern = args.at<String>(2);
   Handle<String> flags = args.at<String>(3);
 
@@ -1855,6 +1873,33 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 1);
+  CONVERT_CHECKED(JSFunction, f, args[0]);
+  return isolate->heap()->ToBoolean(
+      f->shared()->name_should_print_as_anonymous());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 1);
+  CONVERT_CHECKED(JSFunction, f, args[0]);
+  f->shared()->set_name_should_print_as_anonymous(true);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+
+  CONVERT_CHECKED(JSFunction, fun, args[0]);
+  fun->shared()->set_bound(true);
+  return isolate->heap()->undefined_value();
+}
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
@@ -1953,8 +1998,7 @@
   ASSERT(args.length() == 1);
 
   CONVERT_CHECKED(JSFunction, f, args[0]);
-  return f->shared()->IsApiFunction() ? isolate->heap()->true_value()
-                                      : isolate->heap()->false_value();
+  return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
 }
 
 
@@ -1963,8 +2007,7 @@
   ASSERT(args.length() == 1);
 
   CONVERT_CHECKED(JSFunction, f, args[0]);
-  return f->IsBuiltin() ? isolate->heap()->true_value() :
-                          isolate->heap()->false_value();
+  return isolate->heap()->ToBoolean(f->IsBuiltin());
 }
 
 
@@ -2035,7 +2078,7 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 2);
   CONVERT_ARG_CHECKED(JSFunction, function, 0);
-  CONVERT_SMI_CHECKED(num, args[1]);
+  CONVERT_SMI_ARG_CHECKED(num, 1);
   RUNTIME_ASSERT(num >= 0);
   SetExpectedNofProperties(function, num);
   return isolate->heap()->undefined_value();
@@ -2259,24 +2302,24 @@
 
     Handle<String> joined_string;
     if (is_ascii_) {
-      joined_string = NewRawAsciiString(character_count_);
+      Handle<SeqAsciiString> seq = NewRawAsciiString(character_count_);
       AssertNoAllocation no_alloc;
-      SeqAsciiString* seq = SeqAsciiString::cast(*joined_string);
       char* char_buffer = seq->GetChars();
       StringBuilderConcatHelper(*subject_,
                                 char_buffer,
                                 *array_builder_.array(),
                                 array_builder_.length());
+      joined_string = Handle<String>::cast(seq);
     } else {
       // Non-ASCII.
-      joined_string = NewRawTwoByteString(character_count_);
+      Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
       AssertNoAllocation no_alloc;
-      SeqTwoByteString* seq = SeqTwoByteString::cast(*joined_string);
       uc16* char_buffer = seq->GetChars();
       StringBuilderConcatHelper(*subject_,
                                 char_buffer,
                                 *array_builder_.array(),
                                 array_builder_.length());
+      joined_string = Handle<String>::cast(seq);
     }
     return joined_string;
   }
@@ -2294,15 +2337,13 @@
   }
 
  private:
-  Handle<String> NewRawAsciiString(int size) {
-    CALL_HEAP_FUNCTION(heap_->isolate(),
-                       heap_->AllocateRawAsciiString(size), String);
+  Handle<SeqAsciiString> NewRawAsciiString(int length) {
+    return heap_->isolate()->factory()->NewRawAsciiString(length);
   }
 
 
-  Handle<String> NewRawTwoByteString(int size) {
-    CALL_HEAP_FUNCTION(heap_->isolate(),
-                       heap_->AllocateRawTwoByteString(size), String);
+  Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
+    return heap_->isolate()->factory()->NewRawTwoByteString(length);
   }
 
 
@@ -2338,6 +2379,7 @@
   int parts() {
     return parts_.length();
   }
+
  private:
   enum PartType {
     SUBJECT_PREFIX = 1,
@@ -2614,7 +2656,7 @@
   int capture_count = regexp_handle->CaptureCount();
 
   // CompiledReplacement uses zone allocation.
-  CompilationZoneScope zone(isolate, DELETE_ON_EXIT);
+  ZoneScope zone(isolate, DELETE_ON_EXIT);
   CompiledReplacement compiled_replacement;
   compiled_replacement.Compile(replacement_handle,
                                capture_count,
@@ -3088,17 +3130,17 @@
   ASSERT(args.length() == 3);
 
   CONVERT_CHECKED(String, value, args[0]);
-  Object* from = args[1];
-  Object* to = args[2];
   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 (from->IsSmi() && to->IsSmi()) {
-    start = Smi::cast(from)->value();
-    end = Smi::cast(to)->value();
+  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_CHECKED(from_number, from);
-    CONVERT_DOUBLE_CHECKED(to_number, to);
+    CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
+    CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
     start = FastD2I(from_number);
     end = FastD2I(to_number);
   }
@@ -3128,11 +3170,11 @@
   }
   int length = subject->length();
 
-  CompilationZoneScope zone_space(isolate, DELETE_ON_EXIT);
+  ZoneScope zone_space(isolate, DELETE_ON_EXIT);
   ZoneList<int> offsets(8);
+  int start;
+  int end;
   do {
-    int start;
-    int end;
     {
       AssertNoAllocation no_alloc;
       FixedArray* elements = FixedArray::cast(regexp_info->elements());
@@ -3141,20 +3183,23 @@
     }
     offsets.Add(start);
     offsets.Add(end);
-    int index = start < end ? end : end + 1;
-    if (index > length) break;
-    match = RegExpImpl::Exec(regexp, subject, index, regexp_info);
+    if (start == end) if (++end > length) break;
+    match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
     if (match.is_null()) {
       return Failure::Exception();
     }
   } while (!match->IsNull());
   int matches = offsets.length() / 2;
   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
-  for (int i = 0; i < matches ; i++) {
+  Handle<String> substring = isolate->factory()->
+    NewSubString(subject, offsets.at(0), offsets.at(1));
+  elements->set(0, *substring);
+  for (int i = 1; i < matches ; i++) {
     int from = offsets.at(i * 2);
     int to = offsets.at(i * 2 + 1);
-    Handle<String> match = isolate->factory()->NewSubString(subject, from, to);
-    elements->set(i, *match);
+    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));
@@ -3304,6 +3349,7 @@
   OffsetsVector registers(required_registers);
   Vector<int32_t> register_vector(registers.vector(), registers.length());
   int subject_length = subject->length();
+  bool first = true;
 
   for (;;) {  // Break on failure, return on exception.
     RegExpImpl::IrregexpResult result =
@@ -3321,9 +3367,15 @@
       }
       match_end = register_vector[1];
       HandleScope loop_scope(isolate);
-      builder->Add(*isolate->factory()->NewSubString(subject,
-                                                     match_start,
-                                                     match_end));
+      if (!first) {
+        builder->Add(*isolate->factory()->NewProperSubString(subject,
+                                                             match_start,
+                                                             match_end));
+      } else {
+        builder->Add(*isolate->factory()->NewSubString(subject,
+                                                       match_start,
+                                                       match_end));
+      }
       if (match_start != match_end) {
         pos = match_end;
       } else {
@@ -3336,6 +3388,7 @@
       ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
       return result;
     }
+    first = false;
   }
 
   if (match_start >= 0) {
@@ -3387,7 +3440,7 @@
     // at the end, so we have two vectors that we swap between.
     OffsetsVector registers2(required_registers);
     Vector<int> prev_register_vector(registers2.vector(), registers2.length());
-
+    bool first = true;
     do {
       int match_start = register_vector[0];
       builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
@@ -3405,18 +3458,30 @@
         // subject, i.e., 3 + capture count in total.
         Handle<FixedArray> elements =
             isolate->factory()->NewFixedArray(3 + capture_count);
-        Handle<String> match = isolate->factory()->NewSubString(subject,
-                                                                match_start,
-                                                                match_end);
+        Handle<String> match;
+        if (!first) {
+          match = isolate->factory()->NewProperSubString(subject,
+                                                         match_start,
+                                                         match_end);
+        } else {
+          match = isolate->factory()->NewSubString(subject,
+                                                   match_start,
+                                                   match_end);
+        }
         elements->set(0, *match);
         for (int i = 1; i <= capture_count; i++) {
           int start = register_vector[i * 2];
           if (start >= 0) {
             int end = register_vector[i * 2 + 1];
             ASSERT(start <= end);
-            Handle<String> substring = isolate->factory()->NewSubString(subject,
-                                                                        start,
-                                                                        end);
+            Handle<String> substring;
+            if (!first) {
+              substring = isolate->factory()->NewProperSubString(subject,
+                                                                 start,
+                                                                 end);
+            } else {
+              substring = isolate->factory()->NewSubString(subject, start, end);
+            }
             elements->set(i, *substring);
           } else {
             ASSERT(register_vector[i * 2 + 1] < 0);
@@ -3446,6 +3511,7 @@
                                             subject,
                                             pos,
                                             register_vector);
+      first = false;
     } while (result == RegExpImpl::RE_SUCCESS);
 
     if (result != RegExpImpl::RE_EXCEPTION) {
@@ -3492,7 +3558,8 @@
   if (result_array->HasFastElements()) {
     result_elements =
         Handle<FixedArray>(FixedArray::cast(result_array->elements()));
-  } else {
+  }
+  if (result_elements.is_null() || result_elements->length() < 16) {
     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
   }
   FixedArrayBuilder builder(result_elements);
@@ -3534,13 +3601,13 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
   NoHandleAllocation ha;
   ASSERT(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() && args[1]->IsSmi()) {
-    int value = Smi::cast(args[0])->value();
-    int radix = Smi::cast(args[1])->value();
+  if (args[0]->IsSmi()) {
+    int value = args.smi_at(0);
     if (value >= 0 && value < radix) {
-      RUNTIME_ASSERT(radix <= 36);
       // Character array used for conversion.
       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
       return isolate->heap()->
@@ -3549,7 +3616,7 @@
   }
 
   // Slow case.
-  CONVERT_DOUBLE_CHECKED(value, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
     return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
   }
@@ -3559,9 +3626,6 @@
     }
     return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
   }
-  CONVERT_DOUBLE_CHECKED(radix_number, args[1]);
-  int radix = FastD2I(radix_number);
-  RUNTIME_ASSERT(2 <= radix && radix <= 36);
   char* str = DoubleToRadixCString(value, radix);
   MaybeObject* result =
       isolate->heap()->AllocateStringFromAscii(CStrVector(str));
@@ -3574,7 +3638,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(value, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
     return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
   }
@@ -3584,7 +3648,7 @@
     }
     return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
   }
-  CONVERT_DOUBLE_CHECKED(f_number, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   int f = FastD2I(f_number);
   RUNTIME_ASSERT(f >= 0);
   char* str = DoubleToFixedCString(value, f);
@@ -3599,7 +3663,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(value, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
     return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
   }
@@ -3609,7 +3673,7 @@
     }
     return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
   }
-  CONVERT_DOUBLE_CHECKED(f_number, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   int f = FastD2I(f_number);
   RUNTIME_ASSERT(f >= -1 && f <= 20);
   char* str = DoubleToExponentialCString(value, f);
@@ -3624,7 +3688,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(value, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
     return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
   }
@@ -3634,7 +3698,7 @@
     }
     return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
   }
-  CONVERT_DOUBLE_CHECKED(f_number, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   int f = FastD2I(f_number);
   RUNTIME_ASSERT(f >= 1 && f <= 21);
   char* str = DoubleToPrecisionCString(value, f);
@@ -3724,8 +3788,7 @@
   if (name->AsArrayIndex(&index)) {
     return GetElementOrCharAt(isolate, object, index);
   } else {
-    PropertyAttributes attr;
-    return object->GetProperty(*name, &attr);
+    return object->GetProperty(*name);
   }
 }
 
@@ -3797,7 +3860,7 @@
     // Fast case for string indexing using [] with a smi index.
     HandleScope scope(isolate);
     Handle<String> str = args.at<String>(0);
-    int index = Smi::cast(args[1])->value();
+    int index = args.smi_at(1);
     if (index >= 0 && index < str->length()) {
       Handle<Object> result = GetCharAt(str, index);
       return *result;
@@ -3840,7 +3903,7 @@
        || result.type() == CONSTANT_FUNCTION)) {
     Object* ok;
     { MaybeObject* maybe_ok =
-          obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
+          obj->DeleteProperty(name, JSReceiver::NORMAL_DELETION);
       if (!maybe_ok->ToObject(&ok)) return maybe_ok;
     }
   }
@@ -3896,17 +3959,25 @@
       return isolate->Throw(*error);
     }
 
-    NormalizeElements(js_object);
-    Handle<NumberDictionary> dictionary(js_object->element_dictionary());
+    Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
     // Make sure that we never go back to fast case.
     dictionary->set_requires_slow_elements();
     PropertyDetails details = PropertyDetails(attr, NORMAL);
-    NumberDictionarySet(dictionary, index, obj_value, details);
+    Handle<NumberDictionary> extended_dictionary =
+        NumberDictionarySet(dictionary, index, obj_value, details);
+    if (*extended_dictionary != *dictionary) {
+      if (js_object->GetElementsKind() ==
+          JSObject::NON_STRICT_ARGUMENTS_ELEMENTS) {
+        FixedArray::cast(js_object->elements())->set(1, *extended_dictionary);
+      } else {
+        js_object->set_elements(*extended_dictionary);
+      }
+    }
     return *obj_value;
   }
 
   LookupResult result;
-  js_object->LookupRealNamedProperty(*name, &result);
+  js_object->LocalLookupRealNamedProperty(*name, &result);
 
   // To be compatible with safari we do not change the value on API objects
   // in defineProperty. Firefox disagrees here, and actually changes the value.
@@ -3946,6 +4017,28 @@
 }
 
 
+// Special case for elements if any of the flags are true.
+// If elements are in fast case we always implicitly assume that:
+// DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false.
+static MaybeObject* NormalizeObjectSetElement(Isolate* isolate,
+                                              Handle<JSObject> js_object,
+                                              uint32_t index,
+                                              Handle<Object> value,
+                                              PropertyAttributes attr) {
+  // Normalize the elements to enable attributes on the property.
+  Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
+  // Make sure that we never go back to fast case.
+  dictionary->set_requires_slow_elements();
+  PropertyDetails details = PropertyDetails(attr, NORMAL);
+  Handle<NumberDictionary> extended_dictionary =
+      NumberDictionarySet(dictionary, index, value, details);
+  if (*extended_dictionary != *dictionary) {
+    js_object->set_elements(*extended_dictionary);
+  }
+  return *value;
+}
+
+
 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
                                         Handle<Object> object,
                                         Handle<Object> key,
@@ -3981,6 +4074,10 @@
       return *value;
     }
 
+    if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
+      return NormalizeObjectSetElement(isolate, js_object, index, value, attr);
+    }
+
     Handle<Object> result = SetElement(js_object, index, value, strict_mode);
     if (result.is_null()) return Failure::Exception();
     return *value;
@@ -3989,6 +4086,13 @@
   if (key->IsString()) {
     Handle<Object> result;
     if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
+      if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
+        return NormalizeObjectSetElement(isolate,
+                                         js_object,
+                                         index,
+                                         value,
+                                         attr);
+      }
       result = SetElement(js_object, index, value, strict_mode);
     } else {
       Handle<String> key_string = Handle<String>::cast(key);
@@ -4006,7 +4110,7 @@
   Handle<String> name = Handle<String>::cast(converted);
 
   if (name->AsArrayIndex(&index)) {
-    return js_object->SetElement(index, *value, strict_mode);
+    return js_object->SetElement(index, *value, strict_mode, true);
   } else {
     return js_object->SetProperty(*name, *value, attr, strict_mode);
   }
@@ -4034,12 +4138,12 @@
       return *value;
     }
 
-    return js_object->SetElement(index, *value, kNonStrictMode);
+    return js_object->SetElement(index, *value, kNonStrictMode, true);
   }
 
   if (key->IsString()) {
     if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
-      return js_object->SetElement(index, *value, kNonStrictMode);
+      return js_object->SetElement(index, *value, kNonStrictMode, true);
     } else {
       Handle<String> key_string = Handle<String>::cast(key);
       key_string->TryFlatten();
@@ -4056,7 +4160,7 @@
   Handle<String> name = Handle<String>::cast(converted);
 
   if (name->AsArrayIndex(&index)) {
-    return js_object->SetElement(index, *value, kNonStrictMode);
+    return js_object->SetElement(index, *value, kNonStrictMode, true);
   } else {
     return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
   }
@@ -4064,24 +4168,25 @@
 
 
 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
-                                                Handle<JSObject> js_object,
+                                                Handle<JSReceiver> receiver,
                                                 Handle<Object> key) {
   HandleScope scope(isolate);
 
   // Check if the given key is an array index.
   uint32_t index;
-  if (key->ToArrayIndex(&index)) {
+  if (receiver->IsJSObject() && 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 (js_object->IsStringObjectWithCharacterAt(index)) {
+    if (receiver->IsStringObjectWithCharacterAt(index)) {
       return isolate->heap()->true_value();
     }
 
-    return js_object->DeleteElement(index, JSObject::FORCE_DELETION);
+    return JSObject::cast(*receiver)->DeleteElement(
+        index, JSReceiver::FORCE_DELETION);
   }
 
   Handle<String> key_string;
@@ -4096,7 +4201,7 @@
   }
 
   key_string->TryFlatten();
-  return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION);
+  return receiver->DeleteProperty(*key_string, JSReceiver::FORCE_DELETION);
 }
 
 
@@ -4107,7 +4212,7 @@
   Handle<Object> object = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
   Handle<Object> value = args.at<Object>(2);
-  CONVERT_SMI_CHECKED(unchecked_attributes, args[3]);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
   RUNTIME_ASSERT(
       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
   // Compute attributes.
@@ -4116,7 +4221,7 @@
 
   StrictModeFlag strict_mode = kNonStrictMode;
   if (args.length() == 5) {
-    CONVERT_SMI_CHECKED(strict_unchecked, args[4]);
+    CONVERT_SMI_ARG_CHECKED(strict_unchecked, 4);
     RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
                    strict_unchecked == kNonStrictMode);
     strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
@@ -4131,10 +4236,10 @@
 }
 
 
-// Set the ES5 native flag on the function.
+// 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(MaybeObject*, Runtime_SetES5Flag) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
   NoHandleAllocation ha;
   RUNTIME_ASSERT(args.length() == 1);
 
@@ -4142,7 +4247,7 @@
 
   if (object->IsJSFunction()) {
     JSFunction* func = JSFunction::cast(*object);
-    func->shared()->set_es5_native(true);
+    func->shared()->set_native(true);
   }
   return isolate->heap()->undefined_value();
 }
@@ -4175,12 +4280,12 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 3);
 
-  CONVERT_CHECKED(JSObject, object, args[0]);
+  CONVERT_CHECKED(JSReceiver, object, args[0]);
   CONVERT_CHECKED(String, key, args[1]);
-  CONVERT_SMI_CHECKED(strict, args[2]);
+  CONVERT_SMI_ARG_CHECKED(strict, 2);
   return object->DeleteProperty(key, (strict == kStrictMode)
-                                      ? JSObject::STRICT_DELETION
-                                      : JSObject::NORMAL_DELETION);
+                                      ? JSReceiver::STRICT_DELETION
+                                      : JSReceiver::NORMAL_DELETION);
 }
 
 
@@ -4244,11 +4349,11 @@
   NoHandleAllocation na;
   ASSERT(args.length() == 2);
 
-  // Only JS objects can have properties.
-  if (args[0]->IsJSObject()) {
-    JSObject* object = JSObject::cast(args[0]);
+  // Only JS receivers can have properties.
+  if (args[0]->IsJSReceiver()) {
+    JSReceiver* receiver = JSReceiver::cast(args[0]);
     CONVERT_CHECKED(String, key, args[1]);
-    if (object->HasProperty(key)) return isolate->heap()->true_value();
+    if (receiver->HasProperty(key)) return isolate->heap()->true_value();
   }
   return isolate->heap()->false_value();
 }
@@ -4649,7 +4754,7 @@
       }
       ASSERT(heap_obj->IsUndefined());
       return isolate->heap()->undefined_symbol();
-    case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE:
+    case JS_FUNCTION_TYPE:
       return isolate->heap()->function_symbol();
     default:
       // For any kind of object not handled above, the spec rule for
@@ -5023,6 +5128,8 @@
 // Doing JSON quoting cannot make the string more than this many times larger.
 static const int kJsonQuoteWorstCaseBlowup = 6;
 
+static const int kSpaceForQuotesAndComma = 3;
+static const int kSpaceForBrackets = 2;
 
 // Covers the entire ASCII range (all other characters are unchanged by JSON
 // quoting).
@@ -5110,13 +5217,51 @@
 }
 
 
+template <typename SinkChar, typename SourceChar>
+static inline SinkChar* WriteQuoteJsonString(
+    Isolate* isolate,
+    SinkChar* write_cursor,
+    Vector<const SourceChar> characters) {
+  // SinkChar is only char if SourceChar is guaranteed to be char.
+  ASSERT(sizeof(SinkChar) >= sizeof(SourceChar));
+  const SourceChar* read_cursor = characters.start();
+  const SourceChar* end = read_cursor + characters.length();
+  *(write_cursor++) = '"';
+  while (read_cursor < end) {
+    SourceChar c = *(read_cursor++);
+    if (sizeof(SourceChar) > 1u &&
+        static_cast<unsigned>(c) >= kQuoteTableLength) {
+      *(write_cursor++) = static_cast<SinkChar>(c);
+    } else {
+      int len = JsonQuoteLengths[static_cast<unsigned>(c)];
+      const char* replacement = JsonQuotes +
+          static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
+      write_cursor[0] = replacement[0];
+      if (len > 1) {
+        write_cursor[1] = replacement[1];
+        if (len > 2) {
+          ASSERT(len == 6);
+          write_cursor[2] = replacement[2];
+          write_cursor[3] = replacement[3];
+          write_cursor[4] = replacement[4];
+          write_cursor[5] = replacement[5];
+        }
+      }
+      write_cursor += len;
+    }
+  }
+  *(write_cursor++) = '"';
+  return write_cursor;
+}
+
+
 template <typename Char, typename StringType, bool comma>
 static MaybeObject* QuoteJsonString(Isolate* isolate,
                                     Vector<const Char> characters) {
   int length = characters.length();
   isolate->counters()->quote_json_char_count()->Increment(length);
-  const int kSpaceForQuotes = 2 + (comma ? 1 :0);
-  int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
+  int worst_case_length =
+        length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotesAndComma;
   if (worst_case_length > kMaxGuaranteedNewSpaceString) {
     return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
   }
@@ -5141,34 +5286,9 @@
   Char* write_cursor = reinterpret_cast<Char*>(
       new_string->address() + SeqAsciiString::kHeaderSize);
   if (comma) *(write_cursor++) = ',';
-  *(write_cursor++) = '"';
-
-  const Char* read_cursor = characters.start();
-  const Char* end = read_cursor + length;
-  while (read_cursor < end) {
-    Char c = *(read_cursor++);
-    if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
-      *(write_cursor++) = c;
-    } else {
-      int len = JsonQuoteLengths[static_cast<unsigned>(c)];
-      const char* replacement = JsonQuotes +
-          static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
-      write_cursor[0] = replacement[0];
-      if (len > 1) {
-        write_cursor[1] = replacement[1];
-        if (len > 2) {
-          ASSERT(len == 6);
-          write_cursor[2] = replacement[2];
-          write_cursor[3] = replacement[3];
-          write_cursor[4] = replacement[4];
-          write_cursor[5] = replacement[5];
-        }
-      }
-      write_cursor += len;
-    }
-  }
-  *(write_cursor++) = '"';
-
+  write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
+                                                  write_cursor,
+                                                  characters);
   int final_length = static_cast<int>(
       write_cursor - reinterpret_cast<Char*>(
           new_string->address() + SeqAsciiString::kHeaderSize));
@@ -5222,11 +5342,106 @@
   }
 }
 
+
+template <typename Char, typename StringType>
+static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
+                                         FixedArray* array,
+                                         int worst_case_length) {
+  int length = array->length();
+
+  MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
+                                                         worst_case_length);
+  Object* new_object;
+  if (!new_alloc->ToObject(&new_object)) {
+    return new_alloc;
+  }
+  if (!isolate->heap()->new_space()->Contains(new_object)) {
+    // Even if our string is small enough to fit in new space we still have to
+    // handle it being allocated in old space as may happen in the third
+    // attempt.  See CALL_AND_RETRY in heap-inl.h and similar code in
+    // CEntryStub::GenerateCore.
+    return isolate->heap()->undefined_value();
+  }
+  AssertNoAllocation no_gc;
+  StringType* new_string = StringType::cast(new_object);
+  ASSERT(isolate->heap()->new_space()->Contains(new_string));
+
+  STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
+  Char* write_cursor = reinterpret_cast<Char*>(
+      new_string->address() + SeqAsciiString::kHeaderSize);
+  *(write_cursor++) = '[';
+  for (int i = 0; i < length; i++) {
+    if (i != 0) *(write_cursor++) = ',';
+    String* str = String::cast(array->get(i));
+    if (str->IsTwoByteRepresentation()) {
+      write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
+                                                      write_cursor,
+                                                      str->ToUC16Vector());
+    } else {
+      write_cursor = WriteQuoteJsonString<Char, char>(isolate,
+                                                      write_cursor,
+                                                      str->ToAsciiVector());
+    }
+  }
+  *(write_cursor++) = ']';
+
+  int final_length = static_cast<int>(
+      write_cursor - reinterpret_cast<Char*>(
+          new_string->address() + SeqAsciiString::kHeaderSize));
+  isolate->heap()->new_space()->
+      template ShrinkStringAtAllocationBoundary<StringType>(
+          new_string, final_length);
+  return new_string;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 1);
+  CONVERT_CHECKED(JSArray, array, args[0]);
+
+  if (!array->HasFastElements()) return isolate->heap()->undefined_value();
+  FixedArray* elements = FixedArray::cast(array->elements());
+  int n = elements->length();
+  bool ascii = true;
+  int total_length = 0;
+
+  for (int i = 0; i < n; i++) {
+    Object* elt = elements->get(i);
+    if (!elt->IsString()) return isolate->heap()->undefined_value();
+    String* element = String::cast(elt);
+    if (!element->IsFlat()) return isolate->heap()->undefined_value();
+    total_length += element->length();
+    if (ascii && element->IsTwoByteRepresentation()) {
+      ascii = false;
+    }
+  }
+
+  int worst_case_length =
+      kSpaceForBrackets + n * kSpaceForQuotesAndComma
+      + total_length * kJsonQuoteWorstCaseBlowup;
+
+  if (worst_case_length > kMaxGuaranteedNewSpaceString) {
+    return isolate->heap()->undefined_value();
+  }
+
+  if (ascii) {
+    return QuoteJsonStringArray<char, SeqAsciiString>(isolate,
+                                                      elements,
+                                                      worst_case_length);
+  } else {
+    return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate,
+                                                        elements,
+                                                        worst_case_length);
+  }
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
   NoHandleAllocation ha;
 
   CONVERT_CHECKED(String, s, args[0]);
-  CONVERT_SMI_CHECKED(radix, args[1]);
+  CONVERT_SMI_ARG_CHECKED(radix, 1);
 
   s->TryFlatten();
 
@@ -5573,6 +5788,27 @@
 }
 
 
+void FindAsciiStringIndices(Vector<const char> subject,
+                            char pattern,
+                            ZoneList<int>* indices,
+                            unsigned int limit) {
+  ASSERT(limit > 0);
+  // Collect indices of pattern in subject using memchr.
+  // Stop after finding at most limit values.
+  const char* subject_start = reinterpret_cast<const char*>(subject.start());
+  const char* subject_end = subject_start + subject.length();
+  const char* pos = subject_start;
+  while (limit > 0) {
+    pos = reinterpret_cast<const char*>(
+        memchr(pos, pattern, subject_end - pos));
+    if (pos == NULL) return;
+    indices->Add(static_cast<int>(pos - subject_start));
+    pos++;
+    limit--;
+  }
+}
+
+
 template <typename SubjectChar, typename PatternChar>
 void FindStringIndices(Isolate* isolate,
                        Vector<const SubjectChar> subject,
@@ -5580,11 +5816,11 @@
                        ZoneList<int>* indices,
                        unsigned int limit) {
   ASSERT(limit > 0);
-  // Collect indices of pattern in subject, and the end-of-string index.
+  // Collect indices of pattern in subject.
   // Stop after finding at most limit values.
-  StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
   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;
@@ -5627,11 +5863,19 @@
     if (subject->IsAsciiRepresentation()) {
       Vector<const char> subject_vector = subject->ToAsciiVector();
       if (pattern->IsAsciiRepresentation()) {
-        FindStringIndices(isolate,
-                          subject_vector,
-                          pattern->ToAsciiVector(),
-                          &indices,
-                          limit);
+        Vector<const char> pattern_vector = pattern->ToAsciiVector();
+        if (pattern_vector.length() == 1) {
+          FindAsciiStringIndices(subject_vector,
+                                 pattern_vector[0],
+                                 &indices,
+                                 limit);
+        } else {
+          FindStringIndices(isolate,
+                            subject_vector,
+                            pattern_vector,
+                            &indices,
+                            limit);
+        }
       } else {
         FindStringIndices(isolate,
                           subject_vector,
@@ -5682,7 +5926,7 @@
     HandleScope local_loop_handle;
     int part_end = indices.at(i);
     Handle<String> substring =
-        isolate->factory()->NewSubString(subject, part_start, part_end);
+        isolate->factory()->NewProperSubString(subject, part_start, part_end);
     elements->set(i, *substring);
     part_start = part_end + pattern_length;
   }
@@ -5815,7 +6059,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
 
-  CONVERT_DOUBLE_CHECKED(number, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
 
   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   if (number > 0 && number <= Smi::kMaxValue) {
@@ -5829,7 +6073,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
 
-  CONVERT_DOUBLE_CHECKED(number, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
 
   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   if (number > 0 && number <= Smi::kMaxValue) {
@@ -5857,7 +6101,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
 
-  CONVERT_DOUBLE_CHECKED(number, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
 
   // We do not include 0 so that we don't have to treat +0 / -0 cases.
   if (number > 0 && number <= Smi::kMaxValue) {
@@ -5899,8 +6143,8 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   return isolate->heap()->NumberFromDouble(x + y);
 }
 
@@ -5909,8 +6153,8 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   return isolate->heap()->NumberFromDouble(x - y);
 }
 
@@ -5919,8 +6163,8 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   return isolate->heap()->NumberFromDouble(x * y);
 }
 
@@ -5929,7 +6173,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->heap()->NumberFromDouble(-x);
 }
 
@@ -5946,8 +6190,8 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   return isolate->heap()->NumberFromDouble(x / y);
 }
 
@@ -5956,8 +6200,8 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
 
   x = modulo(x, y);
   // NumberFromDouble may return a Smi instead of a Number object
@@ -6022,7 +6266,7 @@
     isolate->context()->mark_out_of_memory();
     return Failure::OutOfMemoryException();
   }
-  int array_length = Smi::cast(args[1])->value();
+  int array_length = args.smi_at(1);
   CONVERT_CHECKED(String, special, args[2]);
 
   // This assumption is used by the slice encoding in one or two smis.
@@ -6135,7 +6379,7 @@
     isolate->context()->mark_out_of_memory();
     return Failure::OutOfMemoryException();
   }
-  int array_length = Smi::cast(args[1])->value();
+  int array_length = args.smi_at(1);
   CONVERT_CHECKED(String, separator, args[2]);
 
   if (!array->HasFastElements()) {
@@ -6413,8 +6657,8 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
   if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
   if (x == y) return Smi::FromInt(EQUAL);
@@ -6450,8 +6694,8 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 3);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   if (isnan(x) || isnan(y)) return args[2];
   if (x == y) return Smi::FromInt(EQUAL);
   if (isless(x, y)) return Smi::FromInt(LESS);
@@ -6474,50 +6718,69 @@
   // If the integers are equal so are the string representations.
   if (x_value == y_value) return Smi::FromInt(EQUAL);
 
-  // If one of the integers are zero the normal integer order is the
+  // 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);
+  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_value = -x_value;
-    y_value = -y_value;
+    x_scaled = -x_value;
+    y_scaled = -y_value;
   }
 
-  // Arrays for the individual characters of the two Smis.  Smis are
-  // 31 bit integers and 10 decimal digits are therefore enough.
-  // TODO(isolates): maybe we should simply allocate 20 bytes on the stack.
-  int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms();
-  int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms();
+  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.
 
-  // Convert the integers to arrays of their decimal digits.
-  int x_index = 0;
-  int y_index = 0;
-  while (x_value > 0) {
-    x_elms[x_index++] = x_value % 10;
-    x_value /= 10;
-  }
-  while (y_value > 0) {
-    y_elms[y_index++] = y_value % 10;
-    y_value /= 10;
+  // 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;
   }
 
-  // Loop through the arrays of decimal digits finding the first place
-  // where they differ.
-  while (--x_index >= 0 && --y_index >= 0) {
-    int diff = x_elms[x_index] - y_elms[y_index];
-    if (diff != 0) return Smi::FromInt(diff);
-  }
-
-  // If one array is a suffix of the other array, the longest array is
-  // the representation of the largest of the Smis in the
-  // lexicographic ordering.
-  return Smi::FromInt(x_index - y_index);
+  if (x_scaled < y_scaled) return Smi::FromInt(LESS);
+  if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
+  return Smi::FromInt(tie);
 }
 
 
@@ -6624,7 +6887,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_acos()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
 }
 
@@ -6634,7 +6897,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_asin()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
 }
 
@@ -6644,7 +6907,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_atan()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
 }
 
@@ -6657,8 +6920,8 @@
   ASSERT(args.length() == 2);
   isolate->counters()->math_atan2()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   double result;
   if (isinf(x) && isinf(y)) {
     // Make sure that the result in case of two infinite arguments
@@ -6680,7 +6943,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_ceil()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->heap()->NumberFromDouble(ceiling(x));
 }
 
@@ -6690,7 +6953,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_cos()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
 }
 
@@ -6700,7 +6963,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_exp()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::EXP, x);
 }
 
@@ -6710,7 +6973,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_floor()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->heap()->NumberFromDouble(floor(x));
 }
 
@@ -6720,7 +6983,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_log()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
 }
 
@@ -6730,16 +6993,16 @@
   ASSERT(args.length() == 2);
   isolate->counters()->math_pow()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  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 = Smi::cast(args[1])->value();
+    int y = args.smi_at(1);
     return isolate->heap()->NumberFromDouble(power_double_int(x, y));
   }
 
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   return isolate->heap()->AllocateHeapNumber(power_double_double(x, y));
 }
 
@@ -6748,8 +7011,8 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
-  CONVERT_DOUBLE_CHECKED(y, args[1]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
   if (y == 0) {
     return Smi::FromInt(1);
   } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
@@ -6808,7 +7071,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_sin()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
 }
 
@@ -6818,7 +7081,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_sqrt()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->heap()->AllocateHeapNumber(sqrt(x));
 }
 
@@ -6828,7 +7091,7 @@
   ASSERT(args.length() == 1);
   isolate->counters()->math_tan()->Increment();
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
 }
 
@@ -6882,9 +7145,9 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 3);
 
-  CONVERT_SMI_CHECKED(year, args[0]);
-  CONVERT_SMI_CHECKED(month, args[1]);
-  CONVERT_SMI_CHECKED(date, args[2]);
+  CONVERT_SMI_ARG_CHECKED(year, 0);
+  CONVERT_SMI_ARG_CHECKED(month, 1);
+  CONVERT_SMI_ARG_CHECKED(date, 2);
 
   return Smi::FromInt(MakeDay(year, month, date));
 }
@@ -7181,7 +7444,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
 
-  CONVERT_DOUBLE_CHECKED(t, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(t, 0);
   CONVERT_CHECKED(JSArray, res_array, args[1]);
 
   int year, month, day;
@@ -7201,12 +7464,109 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 3);
+
+  Handle<JSFunction> callee = args.at<JSFunction>(0);
+  Object** parameters = reinterpret_cast<Object**>(args[1]);
+  const int argument_count = Smi::cast(args[2])->value();
+
+  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()->non_strict_arguments_elements_map());
+
+      Handle<Map> old_map(result->map());
+      Handle<Map> new_map =
+          isolate->factory()->CopyMapDropTransitions(old_map);
+      new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
+
+      result->set_map(*new_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;
+      }
+
+      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.parameter_name(index);
+        int context_slot_count = scope_info.number_of_context_slots();
+        bool duplicate = false;
+        for (int j = index + 1; j < parameter_count; ++j) {
+          if (scope_info.parameter_name(j).is_identical_to(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 = Context::MIN_CONTEXT_SLOTS;
+               j < context_slot_count;
+               ++j) {
+            if (scope_info.context_slot_name(j).is_identical_to(name)) {
+              context_index = j;
+              break;
+            }
+          }
+          ASSERT(context_index >= 0);
+          arguments->set_the_hole(index);
+          parameter_map->set(index + 2, Smi::FromInt(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;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 3);
 
   JSFunction* callee = JSFunction::cast(args[0]);
   Object** parameters = reinterpret_cast<Object**>(args[1]);
-  const int length = Smi::cast(args[2])->value();
+  const int length = args.smi_at(2);
 
   Object* result;
   { MaybeObject* maybe_result =
@@ -7243,10 +7603,8 @@
   CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
   CONVERT_BOOLEAN_CHECKED(pretenure, args[2]);
 
-  // Allocate global closures in old space and allocate local closures
-  // in new space. Additionally pretenure closures that are assigned
+  // The caller ensures that we pretenure closures that are assigned
   // directly to properties.
-  pretenure = pretenure || (context->global_context() == *context);
   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
   Handle<JSFunction> result =
       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
@@ -7366,7 +7724,7 @@
 
   // 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()) {
+  if (!function->should_have_prototype() && !function->shared()->bound()) {
     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
     Handle<Object> type_error =
         isolate->factory()->NewTypeError("not_constructor", arguments);
@@ -7507,7 +7865,7 @@
   ASSERT(args.length() == 1);
   RUNTIME_ASSERT(args[0]->IsSmi());
   Deoptimizer::BailoutType type =
-      static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value());
+      static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
   ASSERT(isolate->heap()->IsAllocationAllowed());
   int frames = deoptimizer->output_count();
@@ -7538,7 +7896,6 @@
     }
   }
 
-  isolate->compilation_cache()->MarkForLazyOptimizing(function);
   if (type == Deoptimizer::EAGER) {
     RUNTIME_ASSERT(function->IsOptimized());
   } else {
@@ -7594,6 +7951,15 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
+#if defined(USE_SIMULATOR)
+  return isolate->heap()->true_value();
+#else
+  return isolate->heap()->false_value();
+#endif
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
@@ -7633,7 +7999,7 @@
   CONVERT_ARG_CHECKED(JSFunction, function, 0);
 
   // We're not prepared to handle a function with arguments object.
-  ASSERT(!function->shared()->scope_info()->HasArgumentsShadow());
+  ASSERT(!function->shared()->uses_arguments());
 
   // We have hit a back edge in an unoptimized frame for a function that was
   // selected for on-stack replacement.  Find the unoptimized code object.
@@ -7757,7 +8123,7 @@
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NewContext) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
 
@@ -7775,50 +8141,73 @@
 }
 
 
-MUST_USE_RESULT static MaybeObject* PushContextHelper(Isolate* isolate,
-                                                      Object* object,
-                                                      bool is_catch_context) {
-  // Convert the object to a proper JavaScript object.
-  Object* js_object = object;
-  if (!js_object->IsJSObject()) {
-    MaybeObject* maybe_js_object = js_object->ToObject();
-    if (!maybe_js_object->ToObject(&js_object)) {
-      if (!Failure::cast(maybe_js_object)->IsInternalError()) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 2);
+  JSObject* extension_object;
+  if (args[0]->IsJSObject()) {
+    extension_object = JSObject::cast(args[0]);
+  } else {
+    // Convert the object to a proper JavaScript object.
+    MaybeObject* maybe_js_object = args[0]->ToObject();
+    if (!maybe_js_object->To(&extension_object)) {
+      if (Failure::cast(maybe_js_object)->IsInternalError()) {
+        HandleScope scope(isolate);
+        Handle<Object> handle = args.at<Object>(0);
+        Handle<Object> result =
+            isolate->factory()->NewTypeError("with_expression",
+                                             HandleVector(&handle, 1));
+        return isolate->Throw(*result);
+      } else {
         return maybe_js_object;
       }
-      HandleScope scope(isolate);
-      Handle<Object> handle(object, isolate);
-      Handle<Object> result =
-          isolate->factory()->NewTypeError("with_expression",
-                                           HandleVector(&handle, 1));
-      return isolate->Throw(*result);
     }
   }
 
-  Object* result;
-  { MaybeObject* maybe_result = isolate->heap()->AllocateWithContext(
-      isolate->context(), JSObject::cast(js_object), is_catch_context);
-    if (!maybe_result->ToObject(&result)) return maybe_result;
+  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 global context.
+    function = isolate->context()->global_context()->closure();
+  } else {
+    function = JSFunction::cast(args[1]);
   }
 
-  Context* context = Context::cast(result);
+  Context* context;
+  MaybeObject* maybe_context =
+      isolate->heap()->AllocateWithContext(function,
+                                           isolate->context(),
+                                           extension_object);
+  if (!maybe_context->To(&context)) return maybe_context;
   isolate->set_context(context);
-
-  return result;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_PushContext) {
-  NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
-  return PushContextHelper(isolate, args[0], false);
+  return context;
 }
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
   NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
-  return PushContextHelper(isolate, args[0], true);
+  ASSERT(args.length() == 3);
+  String* name = String::cast(args[0]);
+  Object* thrown_object = args[1];
+  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 global context.
+    function = isolate->context()->global_context()->closure();
+  } else {
+    function = JSFunction::cast(args[2]);
+  }
+  Context* context;
+  MaybeObject* maybe_context =
+      isolate->heap()->AllocateCatchContext(function,
+                                            isolate->context(),
+                                            name,
+                                            thrown_object);
+  if (!maybe_context->To(&context)) return maybe_context;
+  isolate->set_context(context);
+  return context;
 }
 
 
@@ -7853,9 +8242,9 @@
   // index is non-negative.
   Handle<JSObject> object = Handle<JSObject>::cast(holder);
   if (index >= 0) {
-    return object->DeleteElement(index, JSObject::NORMAL_DELETION);
+    return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
   } else {
-    return object->DeleteProperty(*name, JSObject::NORMAL_DELETION);
+    return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
   }
 }
 
@@ -8008,7 +8397,7 @@
   Handle<Object> value(args[0], isolate);
   CONVERT_ARG_CHECKED(Context, context, 1);
   CONVERT_ARG_CHECKED(String, name, 2);
-  CONVERT_SMI_CHECKED(strict_unchecked, args[3]);
+  CONVERT_SMI_ARG_CHECKED(strict_unchecked, 3);
   RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
                  strict_unchecked == kNonStrictMode);
   StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
@@ -8322,7 +8711,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   const char* zone = OS::LocalTimezone(x);
   return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
 }
@@ -8340,7 +8729,7 @@
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
 
-  CONVERT_DOUBLE_CHECKED(x, args[0]);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
   return isolate->heap()->NumberFromDouble(OS::DaylightSavingsOffset(x));
 }
 
@@ -8358,7 +8747,14 @@
   ASSERT_EQ(1, args.length());
   CONVERT_ARG_CHECKED(String, source, 0);
 
-  Handle<Object> result = JsonParser::Parse(source);
+  source = Handle<String>(source->TryFlattenGetString());
+  // Optimized fast case where we only have ascii characters.
+  Handle<Object> result;
+  if (source->IsSeqAsciiString()) {
+    result = JsonParser<true>::Parse(source);
+  } else {
+    result = JsonParser<false>::Parse(source);
+  }
   if (result.is_null()) {
     // Syntax error or stack overflow in scanner.
     ASSERT(isolate->has_pending_exception());
@@ -8474,12 +8870,7 @@
     // Stop search when eval is found or when the global context is
     // reached.
     if (attributes != ABSENT || context->IsGlobalContext()) break;
-    if (context->is_function_context()) {
-      context = Handle<Context>(Context::cast(context->closure()->context()),
-                                isolate);
-    } else {
-      context = Handle<Context>(context->previous(), isolate);
-    }
+    context = Handle<Context>(context->previous(), isolate);
   }
 
   // If eval could not be resolved, it has been deleted and we need to
@@ -8512,8 +8903,7 @@
   return CompileGlobalEval(isolate,
                            args.at<String>(1),
                            args.at<Object>(2),
-                           static_cast<StrictModeFlag>(
-                                Smi::cast(args[3])->value()));
+                           static_cast<StrictModeFlag>(args.smi_at(3)));
 }
 
 
@@ -8534,8 +8924,7 @@
   return CompileGlobalEval(isolate,
                            args.at<String>(1),
                            args.at<Object>(2),
-                           static_cast<StrictModeFlag>(
-                                Smi::cast(args[3])->value()));
+                           static_cast<StrictModeFlag>(args.smi_at(3)));
 }
 
 
@@ -8596,8 +8985,8 @@
   }
   Object* obj;
   // Strict not needed. Used for cycle detection in Array join implementation.
-  { MaybeObject* maybe_obj = array->SetFastElement(length, element,
-                                                   kNonStrictMode);
+  { MaybeObject* maybe_obj =
+        array->SetFastElement(length, element, kNonStrictMode, true);
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
   return isolate->heap()->true_value();
@@ -9497,9 +9886,7 @@
       details->set(0, *value);
       details->set(1, property_details);
       if (hasJavaScriptAccessors) {
-        details->set(2,
-                     caught_exception ? isolate->heap()->true_value()
-                                      : isolate->heap()->false_value());
+        details->set(2, isolate->heap()->ToBoolean(caught_exception));
         details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
         details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
       }
@@ -9623,11 +10010,79 @@
     // If there is no JavaScript stack frame count is 0.
     return Smi::FromInt(0);
   }
-  for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) n++;
+
+  for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
+    n += it.frame()->GetInlineCount();
+  }
   return Smi::FromInt(n);
 }
 
 
+class FrameInspector {
+ public:
+  FrameInspector(JavaScriptFrame* frame,
+                 int inlined_frame_index,
+                 Isolate* isolate)
+      : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
+    // Calculate the deoptimized frame.
+    if (frame->is_optimized()) {
+      deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
+          frame, inlined_frame_index, isolate);
+    }
+    has_adapted_arguments_ = frame_->has_adapted_arguments();
+    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);
+  }
+
+  // To inspect all the provided arguments the frame might need to be
+  // replaced with the arguments frame.
+  void SetArgumentsFrame(JavaScriptFrame* frame) {
+    ASSERT(has_adapted_arguments_);
+    frame_ = frame;
+    is_optimized_ = frame_->is_optimized();
+    ASSERT(!is_optimized_);
+  }
+
+ private:
+  JavaScriptFrame* frame_;
+  DeoptimizedFrameInfo* deoptimized_frame_;
+  Isolate* isolate_;
+  bool is_optimized_;
+  bool has_adapted_arguments_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameInspector);
+};
+
+
 static const int kFrameDetailsFrameIdIndex = 0;
 static const int kFrameDetailsReceiverIndex = 1;
 static const int kFrameDetailsFunctionIndex = 2;
@@ -9636,7 +10091,7 @@
 static const int kFrameDetailsSourcePositionIndex = 5;
 static const int kFrameDetailsConstructCallIndex = 6;
 static const int kFrameDetailsAtReturnIndex = 7;
-static const int kFrameDetailsDebuggerFrameIndex = 8;
+static const int kFrameDetailsFlagsIndex = 8;
 static const int kFrameDetailsFirstDynamicIndex = 9;
 
 // Return an array with frame details
@@ -9652,7 +10107,7 @@
 // 5: Source position
 // 6: Constructor call
 // 7: Is at return
-// 8: Debugger frame
+// 8: Flags
 // Arguments name, value
 // Locals name, value
 // Return value if any
@@ -9675,16 +10130,22 @@
     // If there are no JavaScript stack frames return undefined.
     return heap->undefined_value();
   }
+
+  int inlined_frame_index = 0;  // Inlined frame index in optimized frame.
+
   int count = 0;
   JavaScriptFrameIterator it(isolate, id);
   for (; !it.done(); it.Advance()) {
-    if (count == index) break;
-    count++;
+    if (index < count + it.frame()->GetInlineCount()) break;
+    count += it.frame()->GetInlineCount();
   }
   if (it.done()) return heap->undefined_value();
 
-  bool is_optimized_frame =
-      it.frame()->LookupCode()->kind() == Code::OPTIMIZED_FUNCTION;
+  if (it.frame()->is_optimized()) {
+    inlined_frame_index =
+        it.frame()->GetInlineCount() - (index - count) - 1;
+  }
+  FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate);
 
   // Traverse the saved contexts chain to find the active context for the
   // selected frame.
@@ -9701,17 +10162,18 @@
   int position =
       it.frame()->LookupCode()->SourcePosition(it.frame()->pc());
 
-  // Check for constructor frame.
-  bool constructor = it.frame()->IsConstructor();
+  // Check for constructor frame. Inlined frames cannot be construct calls.
+  bool inlined_frame =
+      it.frame()->is_optimized() && inlined_frame_index != 0;
+  bool constructor = !inlined_frame && it.frame()->IsConstructor();
 
   // Get scope info and read from it for local variable information.
   Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
-  Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
+  Handle<SharedFunctionInfo> shared(function->shared());
+  Handle<SerializedScopeInfo> scope_info(shared->scope_info());
+  ASSERT(*scope_info != SerializedScopeInfo::Empty());
   ScopeInfo<> info(*scope_info);
 
-  // Get the context.
-  Handle<Context> context(Context::cast(it.frame()->context()));
-
   // Get the locals names and values into a temporary array.
   //
   // TODO(1240907): Hide compiler-introduced stack variables
@@ -9720,31 +10182,20 @@
   Handle<FixedArray> locals =
       isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
 
-  // Fill in the names of the locals.
-  for (int i = 0; i < info.NumberOfLocals(); i++) {
-    locals->set(i * 2, *info.LocalName(i));
-  }
-
   // Fill in the values of the locals.
-  for (int i = 0; i < info.NumberOfLocals(); i++) {
-    if (is_optimized_frame) {
-      // If we are inspecting an optimized frame use undefined as the
-      // value for all locals.
-      //
-      // TODO(1140): We should be able to get the correct values
-      // for locals in optimized frames.
-      locals->set(i * 2 + 1, isolate->heap()->undefined_value());
-    } else if (i < info.number_of_stack_slots()) {
-      // Get the value from the stack.
-      locals->set(i * 2 + 1, it.frame()->GetExpression(i));
-    } else {
-      // Traverse the context chain to the function context as all local
-      // variables stored in the context will be on the function context.
+  int i = 0;
+  for (; i < info.number_of_stack_slots(); ++i) {
+    // Use the value from the stack.
+    locals->set(i * 2, *info.LocalName(i));
+    locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
+  }
+  if (i < info.NumberOfLocals()) {
+    // Get the context containing declarations.
+    Handle<Context> context(
+        Context::cast(it.frame()->context())->declaration_context());
+    for (; i < info.NumberOfLocals(); ++i) {
       Handle<String> name = info.LocalName(i);
-      while (!context->is_function_context()) {
-        context = Handle<Context>(context->previous());
-      }
-      ASSERT(context->is_function_context());
+      locals->set(i * 2, *name);
       locals->set(i * 2 + 1,
                   context->get(scope_info->ContextSlotIndex(*name, NULL)));
     }
@@ -9753,7 +10204,7 @@
   // 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_frame && index == 0) {
+  if (!it.frame()->is_optimized() && index == 0) {
     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
   }
 
@@ -9793,14 +10244,22 @@
   // 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.
-  it.AdvanceToArgumentsFrame();
+  if (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 = info.number_of_parameters();
-  if (argument_count < it.frame()->ComputeParametersCount()) {
-    argument_count = it.frame()->ComputeParametersCount();
+  if (argument_count < frame_inspector.GetParametersCount()) {
+    argument_count = frame_inspector.GetParametersCount();
   }
+#ifdef DEBUG
+  if (it.frame()->is_optimized()) {
+    ASSERT_EQ(argument_count, frame_inspector.GetParametersCount());
+  }
+#endif
 
   // Calculate the size of the result.
   int details_size = kFrameDetailsFirstDynamicIndex +
@@ -9812,7 +10271,7 @@
   details->set(kFrameDetailsFrameIdIndex, *frame_id);
 
   // Add the function (same as in function frame).
-  details->set(kFrameDetailsFunctionIndex, it.frame()->function());
+  details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
 
   // Add the arguments count.
   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
@@ -9834,10 +10293,19 @@
   // Add the at return information.
   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
 
-  // Add information on whether this frame is invoked in the debugger context.
-  details->set(kFrameDetailsDebuggerFrameIndex,
-               heap->ToBoolean(*save->context() ==
-                   *isolate->debug()->debug_context()));
+  // 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 (it.frame()->is_optimized()) {
+    flags |= 1 << 1;
+    flags |= inlined_frame_index << 2;
+  }
+  details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
 
   // Fill the dynamic part.
   int details_index = kFrameDetailsFirstDynamicIndex;
@@ -9851,14 +10319,10 @@
       details->set(details_index++, heap->undefined_value());
     }
 
-    // Parameter value. If we are inspecting an optimized frame, use
-    // undefined as the value.
-    //
-    // TODO(3141533): We should be able to get the actual parameter
-    // value for optimized frames.
-    if (!is_optimized_frame &&
-        (i < it.frame()->ComputeParametersCount())) {
-      details->set(details_index++, it.frame()->GetParameter(i));
+    // Parameter value.
+    if (i < it.frame()->ComputeParametersCount()) {
+      // Get the value from the stack.
+      details->set(details_index++, frame_inspector.GetParameter(i));
     } else {
       details->set(details_index++, heap->undefined_value());
     }
@@ -9878,10 +10342,11 @@
   // 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()) {
-    // If the receiver is NOT a JSObject 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
+  if (!receiver->IsJSObject() && !shared->strict_mode() && !shared->native()) {
+    // 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
     // global context.
     it.Advance();
@@ -9911,18 +10376,14 @@
     int context_index = serialized_scope_info->ContextSlotIndex(
         *scope_info.context_slot_name(i), NULL);
 
-    // Don't include the arguments shadow (.arguments) context variable.
-    if (*scope_info.context_slot_name(i) !=
-        isolate->heap()->arguments_shadow_symbol()) {
-      RETURN_IF_EMPTY_HANDLE_VALUE(
-          isolate,
-          SetProperty(scope_object,
-                      scope_info.context_slot_name(i),
-                      Handle<Object>(context->get(context_index), isolate),
-                      NONE,
-                      kNonStrictMode),
-          false);
-    }
+    RETURN_IF_EMPTY_HANDLE_VALUE(
+        isolate,
+        SetProperty(scope_object,
+                    scope_info.context_slot_name(i),
+                    Handle<Object>(context->get(context_index), isolate),
+                    NONE,
+                    kNonStrictMode),
+        false);
   }
 
   return true;
@@ -9931,12 +10392,15 @@
 
 // Create a plain JSObject which materializes the local scope for the specified
 // frame.
-static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
-                                              JavaScriptFrame* frame) {
+static Handle<JSObject> MaterializeLocalScope(
+    Isolate* isolate,
+    JavaScriptFrame* frame,
+    int inlined_frame_index) {
   Handle<JSFunction> function(JSFunction::cast(frame->function()));
   Handle<SharedFunctionInfo> shared(function->shared());
   Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
   ScopeInfo<> scope_info(*serialized_scope_info);
+  FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
 
   // Allocate and initialize a JSObject with all the arguments, stack locals
   // heap locals and extension properties of the debugged function.
@@ -9949,55 +10413,58 @@
         isolate,
         SetProperty(local_scope,
                     scope_info.parameter_name(i),
-                    Handle<Object>(frame->GetParameter(i), isolate),
+                    Handle<Object>(frame_inspector.GetParameter(i)),
                     NONE,
                     kNonStrictMode),
         Handle<JSObject>());
   }
 
   // Second fill all stack locals.
-  for (int i = 0; i < scope_info.number_of_stack_slots(); i++) {
+  for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
     RETURN_IF_EMPTY_HANDLE_VALUE(
         isolate,
         SetProperty(local_scope,
                     scope_info.stack_slot_name(i),
-                    Handle<Object>(frame->GetExpression(i), isolate),
+                    Handle<Object>(frame_inspector.GetExpression(i)),
                     NONE,
                     kNonStrictMode),
         Handle<JSObject>());
   }
 
-  // Third fill all context locals.
-  Handle<Context> frame_context(Context::cast(frame->context()));
-  Handle<Context> function_context(frame_context->fcontext());
-  if (!CopyContextLocalsToScopeObject(isolate,
-                                      serialized_scope_info, scope_info,
-                                      function_context, local_scope)) {
-    return Handle<JSObject>();
-  }
+  if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
+    // Third fill all context locals.
+    Handle<Context> frame_context(Context::cast(frame->context()));
+    Handle<Context> function_context(frame_context->declaration_context());
+    if (!CopyContextLocalsToScopeObject(isolate,
+                                        serialized_scope_info, scope_info,
+                                        function_context, local_scope)) {
+      return Handle<JSObject>();
+    }
 
-  // Finally copy any properties from the function context extension. This will
-  // be variables introduced by eval.
-  if (function_context->closure() == *function) {
-    if (function_context->has_extension() &&
-        !function_context->IsGlobalContext()) {
-      Handle<JSObject> ext(JSObject::cast(function_context->extension()));
-      Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
-      for (int i = 0; i < keys->length(); i++) {
-        // Names of variables introduced by eval are strings.
-        ASSERT(keys->get(i)->IsString());
-        Handle<String> key(String::cast(keys->get(i)));
-        RETURN_IF_EMPTY_HANDLE_VALUE(
-            isolate,
-            SetProperty(local_scope,
-                        key,
-                        GetProperty(ext, key),
-                        NONE,
-                        kNonStrictMode),
-            Handle<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->IsGlobalContext()) {
+        Handle<JSObject> ext(JSObject::cast(function_context->extension()));
+        Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
+        for (int i = 0; i < keys->length(); i++) {
+          // Names of variables introduced by eval are strings.
+          ASSERT(keys->get(i)->IsString());
+          Handle<String> key(String::cast(keys->get(i)));
+          RETURN_IF_EMPTY_HANDLE_VALUE(
+              isolate,
+              SetProperty(local_scope,
+                          key,
+                          GetProperty(ext, key),
+                          NONE,
+                          kNonStrictMode),
+              Handle<JSObject>());
+        }
       }
     }
   }
+
   return local_scope;
 }
 
@@ -10006,7 +10473,7 @@
 // context.
 static Handle<JSObject> MaterializeClosure(Isolate* isolate,
                                            Handle<Context> context) {
-  ASSERT(context->is_function_context());
+  ASSERT(context->IsFunctionContext());
 
   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
@@ -10017,29 +10484,6 @@
   Handle<JSObject> closure_scope =
       isolate->factory()->NewJSObject(isolate->object_function());
 
-  // Check whether the arguments shadow object exists.
-  int arguments_shadow_index =
-      shared->scope_info()->ContextSlotIndex(
-          isolate->heap()->arguments_shadow_symbol(), NULL);
-  if (arguments_shadow_index >= 0) {
-    // In this case all the arguments are available in the arguments shadow
-    // object.
-    Handle<JSObject> arguments_shadow(
-        JSObject::cast(context->get(arguments_shadow_index)));
-    for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
-      // We don't expect exception-throwing getters on the arguments shadow.
-      Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
-      RETURN_IF_EMPTY_HANDLE_VALUE(
-          isolate,
-          SetProperty(closure_scope,
-                      scope_info.parameter_name(i),
-                      Handle<Object>(element, isolate),
-                      NONE,
-                      kNonStrictMode),
-          Handle<JSObject>());
-    }
-  }
-
   // Fill all context locals to the context extension.
   if (!CopyContextLocalsToScopeObject(isolate,
                                       serialized_scope_info, scope_info,
@@ -10071,6 +10515,23 @@
 }
 
 
+// Create a plain JSObject which materializes the scope for the specified
+// catch context.
+static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
+                                              Handle<Context> context) {
+  ASSERT(context->IsCatchContext());
+  Handle<String> name(String::cast(context->extension()));
+  Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX));
+  Handle<JSObject> catch_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+  RETURN_IF_EMPTY_HANDLE_VALUE(
+      isolate,
+      SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
+      Handle<JSObject>());
+  return catch_scope;
+}
+
+
 // Iterate over the actual scopes visible from a stack frame. All scopes are
 // backed by an actual context except the local scope, which is inserted
 // "artifically" in the context chain.
@@ -10081,16 +10542,15 @@
     ScopeTypeLocal,
     ScopeTypeWith,
     ScopeTypeClosure,
-    // Every catch block contains an implicit with block (its parameter is
-    // a JSContextExtensionObject) that extends current scope with a variable
-    // holding exception object. Such with blocks are treated as scopes of their
-    // own type.
     ScopeTypeCatch
   };
 
-  ScopeIterator(Isolate* isolate, JavaScriptFrame* frame)
+  ScopeIterator(Isolate* isolate,
+                JavaScriptFrame* frame,
+                int inlined_frame_index)
     : isolate_(isolate),
       frame_(frame),
+      inlined_frame_index_(inlined_frame_index),
       function_(JSFunction::cast(frame->function())),
       context_(Context::cast(frame->context())),
       local_done_(false),
@@ -10105,11 +10565,11 @@
       int index = function_->shared()->scope_info()->
           StackSlotIndex(isolate_->heap()->result_symbol());
       at_local_ = index < 0;
-    } else if (context_->is_function_context()) {
+    } else if (context_->IsFunctionContext()) {
       at_local_ = true;
     } else if (context_->closure() != *function_) {
-      // The context_ is a with block from the outer function.
-      ASSERT(context_->has_extension());
+      // The context_ is a with or catch block from the outer function.
+      ASSERT(context_->IsWithContext() || context_->IsCatchContext());
       at_local_ = true;
     }
   }
@@ -10139,16 +10599,12 @@
     }
 
     // Move to the next context.
-    if (context_->is_function_context()) {
-      context_ = Handle<Context>(Context::cast(context_->closure()->context()));
-    } else {
-      context_ = Handle<Context>(context_->previous());
-    }
+    context_ = Handle<Context>(context_->previous(), isolate_);
 
     // If passing the local scope indicate that the current scope is now the
     // local scope.
     if (!local_done_ &&
-        (context_->IsGlobalContext() || (context_->is_function_context()))) {
+        (context_->IsGlobalContext() || context_->IsFunctionContext())) {
       at_local_ = true;
     }
   }
@@ -10162,18 +10618,13 @@
       ASSERT(context_->global()->IsGlobalObject());
       return ScopeTypeGlobal;
     }
-    if (context_->is_function_context()) {
+    if (context_->IsFunctionContext()) {
       return ScopeTypeClosure;
     }
-    ASSERT(context_->has_extension());
-    // Current scope is either an explicit with statement or a with statement
-    // implicitely generated for a catch block.
-    // If the extension object here is a JSContextExtensionObject then
-    // current with statement is one frome a catch block otherwise it's a
-    // regular with statement.
-    if (context_->extension()->IsJSContextExtensionObject()) {
+    if (context_->IsCatchContext()) {
       return ScopeTypeCatch;
     }
+    ASSERT(context_->IsWithContext());
     return ScopeTypeWith;
   }
 
@@ -10182,20 +10633,17 @@
     switch (Type()) {
       case ScopeIterator::ScopeTypeGlobal:
         return Handle<JSObject>(CurrentContext()->global());
-        break;
       case ScopeIterator::ScopeTypeLocal:
         // Materialize the content of the local scope into a JSObject.
-        return MaterializeLocalScope(isolate_, frame_);
-        break;
+        return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_);
       case ScopeIterator::ScopeTypeWith:
-      case ScopeIterator::ScopeTypeCatch:
         // Return the with object.
-        return Handle<JSObject>(CurrentContext()->extension());
-        break;
+        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());
-        break;
     }
     UNREACHABLE();
     return Handle<JSObject>();
@@ -10226,8 +10674,7 @@
         if (!CurrentContext().is_null()) {
           CurrentContext()->Print();
           if (CurrentContext()->has_extension()) {
-            Handle<JSObject> extension =
-                Handle<JSObject>(CurrentContext()->extension());
+            Handle<Object> extension(CurrentContext()->extension());
             if (extension->IsJSContextExtensionObject()) {
               extension->Print();
             }
@@ -10236,34 +10683,27 @@
         break;
       }
 
-      case ScopeIterator::ScopeTypeWith: {
+      case ScopeIterator::ScopeTypeWith:
         PrintF("With:\n");
-        Handle<JSObject> extension =
-            Handle<JSObject>(CurrentContext()->extension());
-        extension->Print();
+        CurrentContext()->extension()->Print();
         break;
-      }
 
-      case ScopeIterator::ScopeTypeCatch: {
+      case ScopeIterator::ScopeTypeCatch:
         PrintF("Catch:\n");
-        Handle<JSObject> extension =
-            Handle<JSObject>(CurrentContext()->extension());
-        extension->Print();
+        CurrentContext()->extension()->Print();
+        CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
         break;
-      }
 
-      case ScopeIterator::ScopeTypeClosure: {
+      case ScopeIterator::ScopeTypeClosure:
         PrintF("Closure:\n");
         CurrentContext()->Print();
         if (CurrentContext()->has_extension()) {
-          Handle<JSObject> extension =
-              Handle<JSObject>(CurrentContext()->extension());
+          Handle<Object> extension(CurrentContext()->extension());
           if (extension->IsJSContextExtensionObject()) {
             extension->Print();
           }
         }
         break;
-      }
 
       default:
         UNREACHABLE();
@@ -10275,6 +10715,7 @@
  private:
   Isolate* isolate_;
   JavaScriptFrame* frame_;
+  int inlined_frame_index_;
   Handle<JSFunction> function_;
   Handle<Context> context_;
   bool local_done_;
@@ -10303,7 +10744,9 @@
 
   // Count the visible scopes.
   int n = 0;
-  for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
+  for (ScopeIterator it(isolate, frame, 0);
+       !it.Done();
+       it.Next()) {
     n++;
   }
 
@@ -10318,14 +10761,15 @@
 // Return an array with scope details
 // args[0]: number: break id
 // args[1]: number: frame index
-// args[2]: number: scope 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(MaybeObject*, Runtime_GetScopeDetails) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 3);
+  ASSERT(args.length() == 4);
 
   // Check arguments.
   Object* check;
@@ -10334,7 +10778,8 @@
     if (!maybe_check->ToObject(&check)) return maybe_check;
   }
   CONVERT_CHECKED(Smi, wrapped_id, args[1]);
-  CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]);
+  CONVERT_NUMBER_CHECKED(int, inlined_frame_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);
@@ -10343,7 +10788,7 @@
 
   // Find the requested scope.
   int n = 0;
-  ScopeIterator it(isolate, frame);
+  ScopeIterator it(isolate, frame, inlined_frame_index);
   for (; !it.Done() && n < index; it.Next()) {
     n++;
   }
@@ -10373,7 +10818,9 @@
   // Print the scopes for the top frame.
   StackFrameLocator locator;
   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
-  for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
+  for (ScopeIterator it(isolate, frame, 0);
+       !it.Done();
+       it.Next()) {
     it.DebugPrint();
   }
 #endif
@@ -10730,19 +11177,35 @@
 
 // Creates a copy of the with context chain. The copy of the context chain is
 // is linked to the function context supplied.
-static Handle<Context> CopyWithContextChain(Handle<Context> context_chain,
-                                            Handle<Context> function_context) {
-  // At the bottom of the chain. Return the function context to link to.
-  if (context_chain->is_function_context()) {
-    return function_context;
+static Handle<Context> CopyWithContextChain(Isolate* isolate,
+                                            Handle<JSFunction> function,
+                                            Handle<Context> current,
+                                            Handle<Context> base) {
+  // At the end of the chain. Return the base context to link to.
+  if (current->IsFunctionContext() || current->IsGlobalContext()) {
+    return base;
   }
 
-  // Recursively copy the with contexts.
-  Handle<Context> previous(context_chain->previous());
-  Handle<JSObject> extension(JSObject::cast(context_chain->extension()));
-  Handle<Context> context = CopyWithContextChain(previous, function_context);
-  return context->GetIsolate()->factory()->NewWithContext(
-      context, extension, context_chain->IsCatchContext());
+  // Recursively copy the with and catch contexts.
+  HandleScope scope(isolate);
+  Handle<Context> previous(current->previous());
+  Handle<Context> new_previous =
+      CopyWithContextChain(isolate, function, previous, base);
+  Handle<Context> new_current;
+  if (current->IsCatchContext()) {
+    Handle<String> name(String::cast(current->extension()));
+    Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
+    new_current =
+        isolate->factory()->NewCatchContext(function,
+                                            new_previous,
+                                            name,
+                                            thrown_object);
+  } else {
+    Handle<JSObject> extension(JSObject::cast(current->extension()));
+    new_current =
+        isolate->factory()->NewWithContext(function, new_previous, extension);
+  }
+  return scope.CloseAndEscape(new_current);
 }
 
 
@@ -10750,6 +11213,7 @@
 // Runtime_DebugEvaluate.
 static Handle<Object> GetArgumentsObject(Isolate* isolate,
                                          JavaScriptFrame* frame,
+                                         int inlined_frame_index,
                                          Handle<JSFunction> function,
                                          Handle<SerializedScopeInfo> scope_info,
                                          const ScopeInfo<>* sinfo,
@@ -10773,7 +11237,9 @@
     }
   }
 
-  const int length = frame->ComputeParametersCount();
+  FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
+
+  int length = frame_inspector.GetParametersCount();
   Handle<JSObject> arguments =
       isolate->factory()->NewArgumentsObject(function, length);
   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
@@ -10781,7 +11247,7 @@
   AssertNoAllocation no_gc;
   WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
   for (int i = 0; i < length; i++) {
-    array->set(i, frame->GetParameter(i), mode);
+    array->set(i, frame_inspector.GetParameter(i), mode);
   }
   arguments->set_elements(*array);
   return arguments;
@@ -10808,7 +11274,7 @@
 
   // Check the execution state and decode arguments frame and source to be
   // evaluated.
-  ASSERT(args.length() == 5);
+  ASSERT(args.length() == 6);
   Object* check_result;
   { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
       RUNTIME_ARGUMENTS(isolate, args));
@@ -10817,9 +11283,10 @@
     }
   }
   CONVERT_CHECKED(Smi, wrapped_id, args[1]);
-  CONVERT_ARG_CHECKED(String, source, 2);
-  CONVERT_BOOLEAN_CHECKED(disable_break, args[3]);
-  Handle<Object> additional_context(args[4]);
+  CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
+  CONVERT_ARG_CHECKED(String, source, 3);
+  CONVERT_BOOLEAN_CHECKED(disable_break, args[4]);
+  Handle<Object> additional_context(args[5]);
 
   // Handle the processing of break.
   DisableBreak disable_break_save(disable_break);
@@ -10859,7 +11326,8 @@
 #endif
 
   // Materialize the content of the local scope into a JSObject.
-  Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame);
+  Handle<JSObject> local_scope = MaterializeLocalScope(
+      isolate, frame, inlined_frame_index);
   RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
 
   // Allocate a new context for the debug evaluation and set the extension
@@ -10870,12 +11338,13 @@
   context->set_extension(*local_scope);
   // Copy any with contexts present and chain them in front of this context.
   Handle<Context> frame_context(Context::cast(frame->context()));
-  Handle<Context> function_context(frame_context->fcontext());
-  context = CopyWithContextChain(frame_context, context);
+  Handle<Context> function_context(frame_context->declaration_context());
+  context = CopyWithContextChain(isolate, go_between, frame_context, context);
 
   if (additional_context->IsJSObject()) {
-    context = isolate->factory()->NewWithContext(context,
-        Handle<JSObject>::cast(additional_context), false);
+    Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
+    context =
+        isolate->factory()->NewWithContext(go_between, context, extension);
   }
 
   // Wrap the evaluation statement in a new function compiled in the newly
@@ -10907,7 +11376,8 @@
                       &has_pending_exception);
   if (has_pending_exception) return Failure::Exception();
 
-  Handle<Object> arguments = GetArgumentsObject(isolate, frame,
+  Handle<Object> arguments = GetArgumentsObject(isolate,
+                                                frame, inlined_frame_index,
                                                 function, scope_info,
                                                 &sinfo, function_context);
 
@@ -11597,10 +12067,9 @@
 // Deletes the specified live object list.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
 #ifdef LIVE_OBJECT_LIST
-  CONVERT_SMI_CHECKED(id, args[0]);
+  CONVERT_SMI_ARG_CHECKED(id, 0);
   bool success = LiveObjectList::Delete(id);
-  return success ? isolate->heap()->true_value() :
-                   isolate->heap()->false_value();
+  return isolate->heap()->ToBoolean(success);
 #else
   return isolate->heap()->undefined_value();
 #endif
@@ -11615,10 +12084,10 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
 #ifdef LIVE_OBJECT_LIST
   HandleScope scope;
-  CONVERT_SMI_CHECKED(id1, args[0]);
-  CONVERT_SMI_CHECKED(id2, args[1]);
-  CONVERT_SMI_CHECKED(start, args[2]);
-  CONVERT_SMI_CHECKED(count, args[3]);
+  CONVERT_SMI_ARG_CHECKED(id1, 0);
+  CONVERT_SMI_ARG_CHECKED(id2, 1);
+  CONVERT_SMI_ARG_CHECKED(start, 2);
+  CONVERT_SMI_ARG_CHECKED(count, 3);
   CONVERT_ARG_CHECKED(JSObject, filter_obj, 4);
   EnterDebugger enter_debugger;
   return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
@@ -11632,7 +12101,7 @@
 // This is only used for obj ids shown in live object lists.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObj) {
 #ifdef LIVE_OBJECT_LIST
-  CONVERT_SMI_CHECKED(obj_id, args[0]);
+  CONVERT_SMI_ARG_CHECKED(obj_id, 0);
   Object* result = LiveObjectList::GetObj(obj_id);
   return result;
 #else
@@ -11659,7 +12128,7 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
 #ifdef LIVE_OBJECT_LIST
   HandleScope scope;
-  CONVERT_SMI_CHECKED(obj_id, args[0]);
+  CONVERT_SMI_ARG_CHECKED(obj_id, 0);
   RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject());
   RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
   RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
@@ -11676,11 +12145,11 @@
   }
   int start = 0;
   if (args[3]->IsSmi()) {
-    start = Smi::cast(args[3])->value();
+    start = args.smi_at(3);
   }
   int limit = Smi::kMaxValue;
   if (args[4]->IsSmi()) {
-    limit = Smi::cast(args[4])->value();
+    limit = args.smi_at(4);
   }
 
   return LiveObjectList::GetObjRetainers(obj_id,
@@ -11699,8 +12168,8 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
 #ifdef LIVE_OBJECT_LIST
   HandleScope scope;
-  CONVERT_SMI_CHECKED(obj_id1, args[0]);
-  CONVERT_SMI_CHECKED(obj_id2, args[1]);
+  CONVERT_SMI_ARG_CHECKED(obj_id1, 0);
+  CONVERT_SMI_ARG_CHECKED(obj_id2, 1);
   RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject());
 
   Handle<JSObject> instance_filter;
@@ -11721,8 +12190,8 @@
 // previously captured live object lists.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
 #ifdef LIVE_OBJECT_LIST
-  CONVERT_SMI_CHECKED(start, args[0]);
-  CONVERT_SMI_CHECKED(count, args[1]);
+  CONVERT_SMI_ARG_CHECKED(start, 0);
+  CONVERT_SMI_ARG_CHECKED(count, 1);
   return LiveObjectList::Info(start, count);
 #else
   return isolate->heap()->undefined_value();
@@ -11735,7 +12204,7 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrintLOLObj) {
 #ifdef LIVE_OBJECT_LIST
   HandleScope scope;
-  CONVERT_SMI_CHECKED(obj_id, args[0]);
+  CONVERT_SMI_ARG_CHECKED(obj_id, 0);
   Object* result = LiveObjectList::PrintObj(obj_id);
   return result;
 #else
@@ -11763,8 +12232,8 @@
 RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
 #ifdef LIVE_OBJECT_LIST
   HandleScope scope;
-  CONVERT_SMI_CHECKED(id1, args[0]);
-  CONVERT_SMI_CHECKED(id2, args[1]);
+  CONVERT_SMI_ARG_CHECKED(id1, 0);
+  CONVERT_SMI_ARG_CHECKED(id2, 1);
   CONVERT_ARG_CHECKED(JSObject, filter_obj, 2);
 
   EnterDebugger enter_debugger;
@@ -11777,29 +12246,19 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) {
   NoHandleAllocation ha;
-  ASSERT(args.length() == 2);
-
-  CONVERT_CHECKED(Smi, smi_modules, args[0]);
-  CONVERT_CHECKED(Smi, smi_tag, args[1]);
-  v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
+  v8::V8::ResumeProfiler();
   return isolate->heap()->undefined_value();
 }
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerPause) {
   NoHandleAllocation ha;
-  ASSERT(args.length() == 2);
-
-  CONVERT_CHECKED(Smi, smi_modules, args[0]);
-  CONVERT_CHECKED(Smi, smi_tag, args[1]);
-  v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
+  v8::V8::PauseProfiler();
   return isolate->heap()->undefined_value();
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 // Finds the script object from the script data. NOTE: This operation uses
 // heap traversal to find the function generated for the source position
@@ -11856,8 +12315,9 @@
 // call to this function is encountered it is skipped.  The seen_caller
 // in/out parameter is used to remember if the caller has been seen
 // yet.
-static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
-    bool* seen_caller) {
+static bool ShowFrameInStackTrace(StackFrame* raw_frame,
+                                  Object* caller,
+                                  bool* seen_caller) {
   // Only display JS frames.
   if (!raw_frame->is_java_script())
     return false;
@@ -11870,11 +12330,25 @@
     *seen_caller = true;
     return false;
   }
-  // Skip all frames until we've seen the caller.  Also, skip the most
-  // obvious builtin calls.  Some builtin calls (such as Number.ADD
-  // which is invoked using 'call') are very difficult to recognize
-  // so we're leaving them in for now.
-  return *seen_caller && !frame->receiver()->IsJSBuiltinsObject();
+  // Skip all frames until we've seen the caller.
+  if (!(*seen_caller)) return false;
+  // Also, skip the most obvious builtin calls. We recognize builtins
+  // as (1) functions called with the builtins object as the receiver and
+  // as (2) functions from native scripts called with undefined as the
+  // receiver (direct calls to helper functions in the builtins
+  // code). Some builtin calls (such as Number.ADD which is invoked
+  // using 'call') are very difficult to recognize so we're leaving
+  // them in for now.
+  if (frame->receiver()->IsJSBuiltinsObject()) {
+    return false;
+  }
+  JSFunction* fun = JSFunction::cast(raw_fun);
+  Object* raw_script = fun->shared()->script();
+  if (frame->receiver()->IsUndefined() && raw_script->IsScript()) {
+    int script_type = Script::cast(raw_script)->type()->value();
+    return script_type != Script::TYPE_NATIVE;
+  }
+  return true;
 }
 
 
@@ -11954,8 +12428,8 @@
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
   ASSERT(args.length() == 2);
-  OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) +
-                                    Smi::cast(args[1])->value());
+  OS::PrintError("abort: %s\n",
+                 reinterpret_cast<char*>(args[0]) + args.smi_at(1));
   isolate->PrintStack();
   OS::Abort();
   UNREACHABLE();
@@ -12157,6 +12631,28 @@
 }
 
 
+#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
+  RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) {     \
+    CONVERT_CHECKED(JSObject, obj, args[0]);              \
+    return isolate->heap()->ToBoolean(obj->Has##Name());  \
+  }
+
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
+
+#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
+
 // ----------------------------------------------------------------------------
 // Implementation of Runtime
 
diff --git a/src/runtime.h b/src/runtime.h
index d3223d1..9a2cf1d 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -67,6 +67,7 @@
   F(SpecialArrayFunctions, 1, 1) \
   F(GetGlobalReceiver, 0, 1) \
   \
+  F(GetPrototype, 1, 1) \
   F(IsInPrototypeChain, 2, 1) \
   F(SetHiddenPrototype, 2, 1) \
   \
@@ -81,18 +82,20 @@
   F(GetFunctionDelegate, 1, 1) \
   F(GetConstructorDelegate, 1, 1) \
   F(NewArgumentsFast, 3, 1) \
+  F(NewStrictArgumentsFast, 3, 1) \
   F(LazyCompile, 1, 1) \
   F(LazyRecompile, 1, 1) \
   F(NotifyDeoptimized, 1, 1) \
   F(NotifyOSR, 0, 1) \
   F(DeoptimizeFunction, 1, 1) \
+  F(RunningInSimulator, 0, 1) \
   F(OptimizeFunctionOnNextCall, 1, 1) \
   F(GetOptimizationStatus, 1, 1) \
   F(GetOptimizationCount, 1, 1) \
   F(CompileForOnStackReplacement, 1, 1) \
   F(SetNewFunctionAttributes, 1, 1) \
   F(AllocateInNewSpace, 1, 1) \
-  F(SetES5Flag, 1, 1) \
+  F(SetNativeFlag, 1, 1) \
   \
   /* Array join support */ \
   F(PushIfAbsent, 2, 1) \
@@ -114,6 +117,7 @@
   F(URIUnescape, 1, 1) \
   F(QuoteJSONString, 1, 1) \
   F(QuoteJSONStringComma, 1, 1) \
+  F(QuoteJSONStringArray, 1, 1) \
   \
   F(NumberToString, 1, 1) \
   F(NumberToStringSkipCache, 1, 1) \
@@ -208,6 +212,9 @@
   F(FunctionSetPrototype, 2, 1) \
   F(FunctionGetName, 1, 1) \
   F(FunctionSetName, 2, 1) \
+  F(FunctionNameShouldPrintAsAnonymous, 1, 1) \
+  F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1) \
+  F(FunctionSetBound, 1, 1) \
   F(FunctionRemovePrototype, 1, 1) \
   F(FunctionGetSourceCode, 1, 1) \
   F(FunctionGetScript, 1, 1) \
@@ -277,9 +284,9 @@
   \
   /* Harmony proxies */ \
   F(CreateJSProxy, 2, 1) \
-  \
-  /* Catch context extension objects */ \
-  F(CreateCatchExtensionObject, 2, 1) \
+  F(IsJSProxy, 1, 1) \
+  F(GetHandler, 1, 1) \
+  F(Fix, 1, 1) \
   \
   /* Statements */ \
   F(NewClosure, 3, 1) \
@@ -293,9 +300,9 @@
   F(PromoteScheduledException, 0, 1) \
   \
   /* Contexts */ \
-  F(NewContext, 1, 1) \
-  F(PushContext, 1, 1) \
-  F(PushCatchContext, 1, 1) \
+  F(NewFunctionContext, 1, 1) \
+  F(PushWithContext, 2, 1) \
+  F(PushCatchContext, 3, 1) \
   F(DeleteContextSlot, 2, 1) \
   F(LoadContextSlot, 2, 2) \
   F(LoadContextSlotNoReferenceError, 2, 2) \
@@ -330,7 +337,26 @@
   F(MessageGetScript, 1, 1) \
   \
   /* Pseudo functions - handled as macros by parser */ \
-  F(IS_VAR, 1, 1)
+  F(IS_VAR, 1, 1) \
+  \
+  /* expose boolean functions from objects-inl.h */ \
+  F(HasFastElements, 1, 1) \
+  F(HasFastDoubleElements, 1, 1) \
+  F(HasDictionaryElements, 1, 1) \
+  F(HasExternalPixelElements, 1, 1) \
+  F(HasExternalArrayElements, 1, 1) \
+  F(HasExternalByteElements, 1, 1) \
+  F(HasExternalUnsignedByteElements, 1, 1) \
+  F(HasExternalShortElements, 1, 1) \
+  F(HasExternalUnsignedShortElements, 1, 1) \
+  F(HasExternalIntElements, 1, 1) \
+  F(HasExternalUnsignedIntElements, 1, 1) \
+  F(HasExternalFloatElements, 1, 1) \
+  F(HasExternalDoubleElements, 1, 1) \
+  /* profiler */ \
+  F(ProfilerResume, 0, 1) \
+  F(ProfilerPause, 0, 1)
+
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
@@ -349,7 +375,7 @@
   F(GetFrameCount, 1, 1) \
   F(GetFrameDetails, 2, 1) \
   F(GetScopeCount, 2, 1) \
-  F(GetScopeDetails, 3, 1) \
+  F(GetScopeDetails, 4, 1) \
   F(DebugPrintScopes, 0, 1) \
   F(GetThreadCount, 1, 1) \
   F(GetThreadDetails, 2, 1) \
@@ -362,7 +388,7 @@
   F(IsBreakOnException, 1, 1) \
   F(PrepareStep, 3, 1) \
   F(ClearStepping, 0, 1) \
-  F(DebugEvaluate, 5, 1) \
+  F(DebugEvaluate, 6, 1) \
   F(DebugEvaluateGlobal, 4, 1) \
   F(DebugGetLoadedScripts, 0, 1) \
   F(DebugReferencedBy, 3, 1) \
@@ -407,14 +433,6 @@
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
 #endif
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-#define RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F) \
-  F(ProfilerResume, 2, 1) \
-  F(ProfilerPause, 2, 1)
-#else
-#define RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F)
-#endif
-
 #ifdef DEBUG
 #define RUNTIME_FUNCTION_LIST_DEBUG(F) \
   /* Testing */ \
@@ -432,8 +450,7 @@
   RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
   RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
   RUNTIME_FUNCTION_LIST_DEBUG(F) \
-  RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
-  RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F)
+  RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
 
 // ----------------------------------------------------------------------------
 // INLINE_FUNCTION_LIST defines all inlined functions accessed
@@ -466,7 +483,8 @@
   F(IsRegExpEquivalent, 2, 1)                                                \
   F(HasCachedArrayIndex, 1, 1)                                               \
   F(GetCachedArrayIndex, 1, 1)                                               \
-  F(FastAsciiArrayJoin, 2, 1)
+  F(FastAsciiArrayJoin, 2, 1)                                                \
+  F(IsNativeOrStrictMode, 1, 1)
 
 
 // ----------------------------------------------------------------------------
@@ -494,7 +512,6 @@
 
 class RuntimeState {
  public:
-
   StaticResource<StringInputBuffer>* string_input_buffer() {
     return &string_input_buffer_;
   }
@@ -516,12 +533,6 @@
   StringInputBuffer* string_locale_compare_buf2() {
     return &string_locale_compare_buf2_;
   }
-  int* smi_lexicographic_compare_x_elms() {
-    return smi_lexicographic_compare_x_elms_;
-  }
-  int* smi_lexicographic_compare_y_elms() {
-    return smi_lexicographic_compare_y_elms_;
-  }
 
  private:
   RuntimeState() {}
@@ -533,8 +544,6 @@
   StringInputBuffer string_input_buffer_compare_bufy_;
   StringInputBuffer string_locale_compare_buf1_;
   StringInputBuffer string_locale_compare_buf2_;
-  int smi_lexicographic_compare_x_elms_[10];
-  int smi_lexicographic_compare_y_elms_[10];
 
   friend class Isolate;
   friend class Runtime;
@@ -630,7 +639,7 @@
 
   MUST_USE_RESULT static MaybeObject* ForceDeleteObjectProperty(
       Isolate* isolate,
-      Handle<JSObject> object,
+      Handle<JSReceiver> object,
       Handle<Object> key);
 
   MUST_USE_RESULT static MaybeObject* GetObjectProperty(
diff --git a/src/runtime.js b/src/runtime.js
index 77b97ae..4b600df 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -354,7 +354,8 @@
   if (!IS_SPEC_OBJECT(x)) {
     throw %MakeTypeError('invalid_in_operator_use', [this, x]);
   }
-  return %_IsNonNegativeSmi(this) ? %HasElement(x, this) : %HasProperty(x, %ToString(this));
+  return %_IsNonNegativeSmi(this) && !%IsJSProxy(x) ?
+    %HasElement(x, this) : %HasProperty(x, %ToString(this));
 }
 
 
diff --git a/src/scanner-base.cc b/src/scanner-base.cc
index e15ef41..16f8db5 100644
--- a/src/scanner-base.cc
+++ b/src/scanner-base.cc
@@ -77,9 +77,22 @@
   : Scanner(scanner_contants), octal_pos_(Location::invalid()) { }
 
 
+void JavaScriptScanner::Initialize(UC16CharacterStream* source) {
+  source_ = source;
+  // Need to capture identifiers in order to recognize "get" and "set"
+  // in object literals.
+  Init();
+  // Skip initial whitespace allowing HTML comment ends just like
+  // after a newline and scan first token.
+  has_line_terminator_before_next_ = true;
+  SkipWhiteSpace();
+  Scan();
+}
+
 Token::Value JavaScriptScanner::Next() {
   current_ = next_;
   has_line_terminator_before_next_ = false;
+  has_multiline_comment_before_next_ = false;
   Scan();
   return current_.token;
 }
@@ -144,7 +157,7 @@
   // to be part of the single-line comment; it is recognized
   // separately by the lexical grammar and becomes part of the
   // stream of input elements for the syntactic grammar (see
-  // ECMA-262, section 7.4, page 12).
+  // ECMA-262, section 7.4).
   while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
     Advance();
   }
@@ -160,13 +173,14 @@
   while (c0_ >= 0) {
     char ch = c0_;
     Advance();
+    if (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;
+    }
     // If we have reached the end of the multi-line comment, we
     // consume the '/' and insert a whitespace. This way all
-    // multi-line comments are treated as whitespace - even the ones
-    // containing line terminators. This contradicts ECMA-262, section
-    // 7.4, page 12, that says that multi-line comments containing
-    // line terminators should be treated as a line terminator, but it
-    // matches the behaviour of SpiderMonkey and KJS.
+    // multi-line comments are treated as whitespace.
     if (ch == '*' && c0_ == '/') {
       c0_ = ' ';
       return Token::WHITESPACE;
@@ -448,6 +462,7 @@
     // of the end of a function (at the "}" token). It doesn't matter
     // whether there was a line terminator in the part we skip.
     has_line_terminator_before_next_ = false;
+    has_multiline_comment_before_next_ = false;
   }
   Scan();
 }
@@ -784,7 +799,7 @@
   { NULL,     I,              Token::ILLEGAL },
   { NULL,     UNMATCHABLE,    Token::ILLEGAL },
   { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { "let",    KEYWORD_PREFIX, Token::FUTURE_RESERVED_WORD },
+  { "let",    KEYWORD_PREFIX, Token::FUTURE_STRICT_RESERVED_WORD },
   { NULL,     UNMATCHABLE,    Token::ILLEGAL },
   { NULL,     N,              Token::ILLEGAL },
   { NULL,     UNMATCHABLE,    Token::ILLEGAL },
@@ -797,7 +812,7 @@
   { NULL,     V,              Token::ILLEGAL },
   { NULL,     W,              Token::ILLEGAL },
   { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { "yield",  KEYWORD_PREFIX, Token::FUTURE_RESERVED_WORD }
+  { "yield",  KEYWORD_PREFIX, Token::FUTURE_STRICT_RESERVED_WORD }
 };
 
 
@@ -834,7 +849,7 @@
     case C:
       if (MatchState(input, 'a', CA)) return;
       if (MatchKeywordStart(input, "class", 1,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_RESERVED_WORD)) return;
       if (MatchState(input, 'o', CO)) return;
       break;
     case CA:
@@ -860,14 +875,14 @@
     case E:
       if (MatchKeywordStart(input, "else", 1, Token::ELSE)) return;
       if (MatchKeywordStart(input, "enum", 1,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_RESERVED_WORD)) return;
       if (MatchState(input, 'x', EX)) return;
       break;
     case EX:
       if (MatchKeywordStart(input, "export", 2,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_RESERVED_WORD)) return;
       if (MatchKeywordStart(input, "extends", 2,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_RESERVED_WORD)) return;
       break;
     case F:
       if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return;
@@ -885,41 +900,40 @@
       break;
     case IMP:
       if (MatchKeywordStart(input, "implements", 3,
-         Token::FUTURE_RESERVED_WORD )) return;
+                            Token::FUTURE_STRICT_RESERVED_WORD )) return;
       if (MatchKeywordStart(input, "import", 3,
-         Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_RESERVED_WORD)) return;
       break;
     case IN:
       token_ = Token::IDENTIFIER;
       if (MatchKeywordStart(input, "interface", 2,
-         Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_STRICT_RESERVED_WORD)) return;
       if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) return;
       break;
     case N:
-      if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return;
       if (MatchKeywordStart(input, "new", 1, Token::NEW)) return;
       if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return;
       break;
     case P:
       if (MatchKeywordStart(input, "package", 1,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_STRICT_RESERVED_WORD)) return;
       if (MatchState(input, 'r', PR)) return;
       if (MatchKeywordStart(input, "public", 1,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_STRICT_RESERVED_WORD)) return;
       break;
     case PR:
       if (MatchKeywordStart(input, "private", 2,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_STRICT_RESERVED_WORD)) return;
       if (MatchKeywordStart(input, "protected", 2,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_STRICT_RESERVED_WORD)) return;
       break;
     case S:
       if (MatchKeywordStart(input, "static", 1,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_STRICT_RESERVED_WORD)) return;
       if (MatchKeywordStart(input, "super", 1,
-          Token::FUTURE_RESERVED_WORD)) return;
+                            Token::FUTURE_RESERVED_WORD)) return;
       if (MatchKeywordStart(input, "switch", 1,
-          Token::SWITCH)) return;
+                            Token::SWITCH)) return;
       break;
     case T:
       if (MatchState(input, 'h', TH)) return;
diff --git a/src/scanner-base.h b/src/scanner-base.h
index 02566dd..3d67d4e 100644
--- a/src/scanner-base.h
+++ b/src/scanner-base.h
@@ -471,12 +471,16 @@
 
   explicit JavaScriptScanner(UnicodeCache* scanner_contants);
 
+  void Initialize(UC16CharacterStream* source);
+
   // Returns the next token.
   Token::Value Next();
 
-  // Returns true if there was a line terminator before the peek'ed token.
-  bool has_line_terminator_before_next() const {
-    return has_line_terminator_before_next_;
+  // Returns true if there was a line terminator before the peek'ed token,
+  // possibly inside a multi-line comment.
+  bool HasAnyLineTerminatorBeforeNext() const {
+    return has_line_terminator_before_next_ ||
+           has_multiline_comment_before_next_;
   }
 
   // Scans the input as a regular expression pattern, previous
@@ -529,7 +533,13 @@
   // Start position of the octal literal last scanned.
   Location octal_pos_;
 
+  // Whether there is a line terminator whitespace character after
+  // the current token, and  before the next. Does not count newlines
+  // inside multiline comments.
   bool has_line_terminator_before_next_;
+  // Whether there is a multi-line comment that contains a
+  // line-terminator after the current token, and before the next.
+  bool has_multiline_comment_before_next_;
 };
 
 
@@ -539,14 +549,26 @@
 class KeywordMatcher {
 //  Incrementally recognize keywords.
 //
-//  Recognized keywords:
-//      break case catch const* continue debugger* default delete do else
-//      finally false for function if in instanceof native* new null
-//      return switch this throw true try typeof var void while with
+//  We distinguish between normal future reserved words and words that are
+//  considered to be future reserved words only in strict mode as required by
+//  ECMA-262 7.6.1.2.
 //
-//  *: Actually "future reserved keywords". These are the only ones we
-//     recognize, the remaining are allowed as identifiers.
-//     In ES5 strict mode, we should disallow all reserved keywords.
+//  Recognized as keywords:
+//      break, case, catch, const*, continue, debugger, default, delete, do,
+//      else, finally, false, for, function, if, in, instanceof, new, null,
+//      return, switch, this, throw, true, try, typeof, var, void, while, with.
+//
+//  Recognized as Future Reserved Keywords:
+//      class, enum, export, extends, import, super.
+//
+//  Recognized as Future Reserved Keywords (strict mode only):
+//      implements, interface, let, package, private, protected, public,
+//      static, yield.
+//
+//  *: Actually a "future reserved keyword". It's the only one we are
+//     recognizing outside of ES5 strict mode, the remaining are allowed
+//     as identifiers.
+//
  public:
   KeywordMatcher()
       : state_(INITIAL),
diff --git a/src/scanner.cc b/src/scanner.cc
index 21a0c2d..5919073 100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -324,22 +324,4 @@
   complete_ = true;
 }
 
-
-// ----------------------------------------------------------------------------
-// V8JavaScriptScanner
-
-
-void V8JavaScriptScanner::Initialize(UC16CharacterStream* source) {
-  source_ = source;
-  // Need to capture identifiers in order to recognize "get" and "set"
-  // in object literals.
-  Init();
-  // Skip initial whitespace allowing HTML comment ends just like
-  // after a newline and scan first token.
-  has_line_terminator_before_next_ = true;
-  SkipWhiteSpace();
-  Scan();
-}
-
-
 } }  // namespace v8::internal
diff --git a/src/scanner.h b/src/scanner.h
index 804fac8..e66dd60 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -126,21 +126,6 @@
   const uc16* raw_data_;  // Pointer to the actual array of characters.
 };
 
-
-// ----------------------------------------------------------------------------
-// V8JavaScriptScanner
-// JavaScript scanner getting its input from either a V8 String or a unicode
-// CharacterStream.
-
-class V8JavaScriptScanner : public JavaScriptScanner {
- public:
-  explicit V8JavaScriptScanner(UnicodeCache* unicode_cache)
-      : JavaScriptScanner(unicode_cache) {}
-
-  void Initialize(UC16CharacterStream* source);
-};
-
-
 } }  // namespace v8::internal
 
 #endif  // V8_SCANNER_H_
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index ccc2cc8..3e18368 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -32,6 +32,8 @@
 #include "scopeinfo.h"
 #include "scopes.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/scopeinfo.h b/src/scopeinfo.h
index ff72013..86c33f6 100644
--- a/src/scopeinfo.h
+++ b/src/scopeinfo.h
@@ -117,11 +117,6 @@
   // Is this scope a strict mode scope?
   bool IsStrictMode();
 
-  // Does this scope have an arguments shadow?
-  bool HasArgumentsShadow() {
-    return StackSlotIndex(GetHeap()->arguments_shadow_symbol()) >= 0;
-  }
-
   // Return the number of stack slots for code.
   int NumberOfStackSlots();
 
diff --git a/src/scopes.cc b/src/scopes.cc
index 6102442..390a0b6 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -34,6 +34,8 @@
 #include "prettyprinter.h"
 #include "scopeinfo.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
@@ -114,70 +116,72 @@
 
 // Dummy constructor
 Scope::Scope(Type type)
-  : inner_scopes_(0),
-    variables_(false),
-    temps_(0),
-    params_(0),
-    unresolved_(0),
-    decls_(0) {
+    : isolate_(Isolate::Current()),
+      inner_scopes_(0),
+      variables_(false),
+      temps_(0),
+      params_(0),
+      unresolved_(0),
+      decls_(0),
+      already_resolved_(false) {
   SetDefaults(type, NULL, Handle<SerializedScopeInfo>::null());
-  ASSERT(!resolved());
 }
 
 
 Scope::Scope(Scope* outer_scope, Type type)
-  : inner_scopes_(4),
-    variables_(),
-    temps_(4),
-    params_(4),
-    unresolved_(16),
-    decls_(4) {
+    : isolate_(Isolate::Current()),
+      inner_scopes_(4),
+      variables_(),
+      temps_(4),
+      params_(4),
+      unresolved_(16),
+      decls_(4),
+      already_resolved_(false) {
   SetDefaults(type, outer_scope, Handle<SerializedScopeInfo>::null());
   // At some point we might want to provide outer scopes to
   // eval scopes (by walking the stack and reading the scope info).
   // In that case, the ASSERT below needs to be adjusted.
   ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL));
   ASSERT(!HasIllegalRedeclaration());
-  ASSERT(!resolved());
 }
 
 
 Scope::Scope(Scope* inner_scope, Handle<SerializedScopeInfo> scope_info)
-  : inner_scopes_(4),
-    variables_(),
-    temps_(4),
-    params_(4),
-    unresolved_(16),
-    decls_(4) {
+    : isolate_(Isolate::Current()),
+      inner_scopes_(4),
+      variables_(),
+      temps_(4),
+      params_(4),
+      unresolved_(16),
+      decls_(4),
+      already_resolved_(true) {
   ASSERT(!scope_info.is_null());
   SetDefaults(FUNCTION_SCOPE, NULL, scope_info);
-  ASSERT(resolved());
   if (scope_info->HasHeapAllocatedLocals()) {
     num_heap_slots_ = scope_info_->NumberOfContextSlots();
   }
-
   AddInnerScope(inner_scope);
+}
 
-  // This scope's arguments shadow (if present) is context-allocated if an inner
-  // scope accesses this one's parameters.  Allocate the arguments_shadow_
-  // variable if necessary.
-  Isolate* isolate = Isolate::Current();
-  Variable::Mode mode;
-  int arguments_shadow_index =
-      scope_info_->ContextSlotIndex(
-          isolate->heap()->arguments_shadow_symbol(), &mode);
-  if (arguments_shadow_index >= 0) {
-    ASSERT(mode == Variable::INTERNAL);
-    arguments_shadow_ = new Variable(
-        this,
-        isolate->factory()->arguments_shadow_symbol(),
-        Variable::INTERNAL,
-        true,
-        Variable::ARGUMENTS);
-    arguments_shadow_->set_rewrite(
-        new Slot(arguments_shadow_, Slot::CONTEXT, arguments_shadow_index));
-    arguments_shadow_->set_is_used(true);
-  }
+
+Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
+    : isolate_(Isolate::Current()),
+      inner_scopes_(1),
+      variables_(),
+      temps_(0),
+      params_(0),
+      unresolved_(0),
+      decls_(0),
+      already_resolved_(true) {
+  SetDefaults(CATCH_SCOPE, NULL, Handle<SerializedScopeInfo>::null());
+  AddInnerScope(inner_scope);
+  ++num_var_or_const_;
+  Variable* variable = variables_.Declare(this,
+                                          catch_variable_name,
+                                          Variable::VAR,
+                                          true,  // Valid left-hand side.
+                                          Variable::NORMAL);
+  AllocateHeapSlot(variable);
 }
 
 
@@ -186,12 +190,11 @@
                         Handle<SerializedScopeInfo> scope_info) {
   outer_scope_ = outer_scope;
   type_ = type;
-  scope_name_ = FACTORY->empty_symbol();
+  scope_name_ = isolate_->factory()->empty_symbol();
   dynamics_ = NULL;
   receiver_ = NULL;
   function_ = NULL;
   arguments_ = NULL;
-  arguments_shadow_ = NULL;
   illegal_redecl_ = NULL;
   scope_inside_with_ = false;
   scope_contains_with_ = false;
@@ -212,30 +215,43 @@
 
 Scope* Scope::DeserializeScopeChain(CompilationInfo* info,
                                     Scope* global_scope) {
+  // Reconstruct the outer scope chain from a closure's context chain.
   ASSERT(!info->closure().is_null());
-  // If we have a serialized scope info, reuse it.
+  Context* context = info->closure()->context();
+  Scope* current_scope = NULL;
   Scope* innermost_scope = NULL;
-  Scope* scope = NULL;
-
-  SerializedScopeInfo* scope_info = info->closure()->shared()->scope_info();
-  if (scope_info != SerializedScopeInfo::Empty()) {
-    JSFunction* current = *info->closure();
-    do {
-      current = current->context()->closure();
-      Handle<SerializedScopeInfo> scope_info(current->shared()->scope_info());
-      if (*scope_info != SerializedScopeInfo::Empty()) {
-        scope = new Scope(scope, scope_info);
-        if (innermost_scope == NULL) innermost_scope = scope;
-      } else {
-        ASSERT(current->context()->IsGlobalContext());
+  bool contains_with = false;
+  while (!context->IsGlobalContext()) {
+    if (context->IsWithContext()) {
+      // All the inner scopes are inside a with.
+      contains_with = true;
+      for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
+        s->scope_inside_with_ = true;
       }
-    } while (!current->context()->IsGlobalContext());
+    } else {
+      if (context->IsFunctionContext()) {
+        SerializedScopeInfo* scope_info =
+            context->closure()->shared()->scope_info();
+        current_scope =
+            new Scope(current_scope, Handle<SerializedScopeInfo>(scope_info));
+      } else {
+        ASSERT(context->IsCatchContext());
+        String* name = String::cast(context->extension());
+        current_scope = new Scope(current_scope, Handle<String>(name));
+      }
+      if (contains_with) current_scope->RecordWithStatement();
+      if (innermost_scope == NULL) innermost_scope = current_scope;
+    }
+
+    // Forget about a with when we move to a context for a different function.
+    if (context->previous()->closure() != context->closure()) {
+      contains_with = false;
+    }
+    context = context->previous();
   }
 
-  global_scope->AddInnerScope(scope);
-  if (innermost_scope == NULL) innermost_scope = global_scope;
-
-  return innermost_scope;
+  global_scope->AddInnerScope(current_scope);
+  return (innermost_scope == NULL) ? global_scope : innermost_scope;
 }
 
 
@@ -260,7 +276,7 @@
 
 
 void Scope::Initialize(bool inside_with) {
-  ASSERT(!resolved());
+  ASSERT(!already_resolved());
 
   // Add this scope as a new inner scope of the outer scope.
   if (outer_scope_ != NULL) {
@@ -278,73 +294,64 @@
   // instead load them directly from the stack. Currently, the only
   // such parameter is 'this' which is passed on the stack when
   // invoking scripts
-  Variable* var =
-      variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR,
-                         false, Variable::THIS);
-  var->set_rewrite(new Slot(var, Slot::PARAMETER, -1));
-  receiver_ = var;
+  if (is_catch_scope()) {
+    ASSERT(outer_scope() != NULL);
+    receiver_ = outer_scope()->receiver();
+  } else {
+    Variable* var =
+        variables_.Declare(this,
+                           isolate_->factory()->this_symbol(),
+                           Variable::VAR,
+                           false,
+                           Variable::THIS);
+    var->set_rewrite(NewSlot(var, Slot::PARAMETER, -1));
+    receiver_ = var;
+  }
 
   if (is_function_scope()) {
     // Declare 'arguments' variable which exists in all functions.
     // Note that it might never be accessed, in which case it won't be
     // allocated during variable allocation.
-    variables_.Declare(this, FACTORY->arguments_symbol(), Variable::VAR,
-                       true, Variable::ARGUMENTS);
+    variables_.Declare(this,
+                       isolate_->factory()->arguments_symbol(),
+                       Variable::VAR,
+                       true,
+                       Variable::ARGUMENTS);
   }
 }
 
 
 Variable* Scope::LocalLookup(Handle<String> name) {
   Variable* result = variables_.Lookup(name);
-  if (result != NULL || !resolved()) {
+  if (result != NULL || scope_info_.is_null()) {
     return result;
   }
-  // If the scope is resolved, we can find a variable in serialized scope info.
-
-  // We should never lookup 'arguments' in this scope
-  // as it is implicitly present in any scope.
-  ASSERT(*name != *FACTORY->arguments_symbol());
-
-  // Assert that there is no local slot with the given name.
+  // If we have a serialized scope info, we might find the variable there.
+  //
+  // We should never lookup 'arguments' in this scope as it is implicitly
+  // present in every scope.
+  ASSERT(*name != *isolate_->factory()->arguments_symbol());
+  // There should be no local slot with the given name.
   ASSERT(scope_info_->StackSlotIndex(*name) < 0);
 
   // Check context slot lookup.
   Variable::Mode mode;
   int index = scope_info_->ContextSlotIndex(*name, &mode);
-  if (index >= 0) {
-    Variable* var =
-        variables_.Declare(this, name, mode, true, Variable::NORMAL);
-    var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
-    return var;
+  if (index < 0) {
+    // Check parameters.
+    mode = Variable::VAR;
+    index = scope_info_->ParameterIndex(*name);
+    if (index < 0) {
+      // Check the function name.
+      index = scope_info_->FunctionContextSlotIndex(*name);
+      if (index < 0) return NULL;
+    }
   }
 
-  index = scope_info_->ParameterIndex(*name);
-  if (index >= 0) {
-    // ".arguments" must be present in context slots.
-    ASSERT(arguments_shadow_ != NULL);
-    Variable* var =
-        variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
-    Property* rewrite =
-        new Property(new VariableProxy(arguments_shadow_),
-                     new Literal(Handle<Object>(Smi::FromInt(index))),
-                     RelocInfo::kNoPosition,
-                     Property::SYNTHETIC);
-    rewrite->set_is_arguments_access(true);
-    var->set_rewrite(rewrite);
-    return var;
-  }
-
-  index = scope_info_->FunctionContextSlotIndex(*name);
-  if (index >= 0) {
-    // Check that there is no local slot with the given name.
-    ASSERT(scope_info_->StackSlotIndex(*name) < 0);
-    Variable* var =
-        variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
-    var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
-    return var;
-  }
-
-  return NULL;
+  Variable* var =
+      variables_.Declare(this, name, mode, true, Variable::NORMAL);
+  var->set_rewrite(NewSlot(var, Slot::CONTEXT, index));
+  return var;
 }
 
 
@@ -366,17 +373,22 @@
 }
 
 
-Variable* Scope::DeclareLocal(Handle<String> name,
-                              Variable::Mode mode,
-                              LocalType type) {
-  // DYNAMIC variables are introduces during variable allocation,
-  // INTERNAL variables are allocated explicitly, and TEMPORARY
-  // variables are allocated via NewTemporary().
-  ASSERT(!resolved());
+void Scope::DeclareParameter(Handle<String> name) {
+  ASSERT(!already_resolved());
+  ASSERT(is_function_scope());
+  Variable* var =
+      variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
+  params_.Add(var);
+}
+
+
+Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
+  ASSERT(!already_resolved());
+  // This function handles VAR and CONST modes.  DYNAMIC variables are
+  // introduces during variable allocation, INTERNAL variables are allocated
+  // explicitly, and TEMPORARY variables are allocated via NewTemporary().
   ASSERT(mode == Variable::VAR || mode == Variable::CONST);
-  if (type == VAR_OR_CONST) {
-    num_var_or_const_++;
-  }
+  ++num_var_or_const_;
   return variables_.Declare(this, name, mode, true, Variable::NORMAL);
 }
 
@@ -388,21 +400,15 @@
 }
 
 
-void Scope::AddParameter(Variable* var) {
-  ASSERT(is_function_scope());
-  ASSERT(LocalLookup(var->name()) == var);
-  params_.Add(var);
-}
-
-
 VariableProxy* Scope::NewUnresolved(Handle<String> name,
                                     bool inside_with,
                                     int position) {
   // Note that we must not share the unresolved variables with
   // the same name because they may be removed selectively via
   // RemoveUnresolved().
-  ASSERT(!resolved());
-  VariableProxy* proxy = new VariableProxy(name, false, inside_with, position);
+  ASSERT(!already_resolved());
+  VariableProxy* proxy = new(isolate_->zone()) VariableProxy(
+      isolate_, name, false, inside_with, position);
   unresolved_.Add(proxy);
   return proxy;
 }
@@ -421,7 +427,7 @@
 
 
 Variable* Scope::NewTemporary(Handle<String> name) {
-  ASSERT(!resolved());
+  ASSERT(!already_resolved());
   Variable* var =
       new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL);
   temps_.Add(var);
@@ -551,12 +557,22 @@
 }
 
 
+Scope* Scope::DeclarationScope() {
+  Scope* scope = this;
+  while (scope->is_catch_scope()) {
+    scope = scope->outer_scope();
+  }
+  return scope;
+}
+
+
 #ifdef DEBUG
 static const char* Header(Scope::Type type) {
   switch (type) {
     case Scope::EVAL_SCOPE: return "eval";
     case Scope::FUNCTION_SCOPE: return "function";
     case Scope::GLOBAL_SCOPE: return "global";
+    case Scope::CATCH_SCOPE: return "catch";
   }
   UNREACHABLE();
   return NULL;
@@ -692,7 +708,7 @@
     // Declare a new non-local.
     var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
     // Allocate it by giving it a dynamic lookup.
-    var->set_rewrite(new Slot(var, Slot::LOOKUP, -1));
+    var->set_rewrite(NewSlot(var, Slot::LOOKUP, -1));
   }
   return var;
 }
@@ -907,8 +923,10 @@
   // visible name.
   if ((var->is_this() || var->name()->length() > 0) &&
       (var->is_accessed_from_inner_scope() ||
-       scope_calls_eval_ || inner_scope_calls_eval_ ||
-       scope_contains_with_)) {
+       scope_calls_eval_ ||
+       inner_scope_calls_eval_ ||
+       scope_contains_with_ ||
+       is_catch_scope())) {
     var->set_is_used(true);
   }
   // Global variables do not need to be allocated.
@@ -917,73 +935,60 @@
 
 
 bool Scope::MustAllocateInContext(Variable* var) {
-  // If var is accessed from an inner scope, or if there is a
-  // possibility that it might be accessed from the current or an inner
-  // scope (through an eval() call), it must be allocated in the
-  // context.  Exception: temporary variables are not allocated in the
+  // If var is accessed from an inner scope, or if there is a possibility
+  // that it might be accessed from the current or an inner scope (through
+  // an eval() call or a runtime with lookup), it must be allocated in the
   // context.
-  return
-    var->mode() != Variable::TEMPORARY &&
-    (var->is_accessed_from_inner_scope() ||
-     scope_calls_eval_ || inner_scope_calls_eval_ ||
-     scope_contains_with_ || var->is_global());
+  //
+  // Exceptions: temporary variables are never allocated in a context;
+  // catch-bound variables are always allocated in a context.
+  if (var->mode() == Variable::TEMPORARY) return false;
+  if (is_catch_scope()) return true;
+  return var->is_accessed_from_inner_scope() ||
+      scope_calls_eval_ ||
+      inner_scope_calls_eval_ ||
+      scope_contains_with_ ||
+      var->is_global();
 }
 
 
 bool Scope::HasArgumentsParameter() {
   for (int i = 0; i < params_.length(); i++) {
-    if (params_[i]->name().is_identical_to(FACTORY->arguments_symbol()))
+    if (params_[i]->name().is_identical_to(
+            isolate_->factory()->arguments_symbol())) {
       return true;
+    }
   }
   return false;
 }
 
 
 void Scope::AllocateStackSlot(Variable* var) {
-  var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++));
+  var->set_rewrite(NewSlot(var, Slot::LOCAL, num_stack_slots_++));
 }
 
 
 void Scope::AllocateHeapSlot(Variable* var) {
-  var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++));
+  var->set_rewrite(NewSlot(var, Slot::CONTEXT, num_heap_slots_++));
 }
 
 
 void Scope::AllocateParameterLocals() {
   ASSERT(is_function_scope());
-  Variable* arguments = LocalLookup(FACTORY->arguments_symbol());
+  Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol());
   ASSERT(arguments != NULL);  // functions have 'arguments' declared implicitly
 
-  // Parameters are rewritten to arguments[i] if 'arguments' is used in
-  // a non-strict mode function. Strict mode code doesn't alias arguments.
-  bool rewrite_parameters = false;
+  bool uses_nonstrict_arguments = false;
 
   if (MustAllocate(arguments) && !HasArgumentsParameter()) {
     // 'arguments' is used. Unless there is also a parameter called
-    // 'arguments', we must be conservative and access all parameters via
-    // the arguments object: The i'th parameter is rewritten into
-    // '.arguments[i]' (*). If we have a parameter named 'arguments', a
-    // (new) value is always assigned to it via the function
-    // invocation. Then 'arguments' denotes that specific parameter value
-    // and cannot be used to access the parameters, which is why we don't
-    // need to rewrite in that case.
-    //
-    // (*) Instead of having a parameter called 'arguments', we may have an
-    // assignment to 'arguments' in the function body, at some arbitrary
-    // point in time (possibly through an 'eval()' call!). After that
-    // assignment any re-write of parameters would be invalid (was bug
-    // 881452). Thus, we introduce a shadow '.arguments'
-    // variable which also points to the arguments object. For rewrites we
-    // use '.arguments' which remains valid even if we assign to
-    // 'arguments'. To summarize: If we need to rewrite, we allocate an
-    // 'arguments' object dynamically upon function invocation. The compiler
-    // introduces 2 local variables 'arguments' and '.arguments', both of
-    // which originally point to the arguments object that was
-    // allocated. All parameters are rewritten into property accesses via
-    // the '.arguments' variable. Thus, any changes to properties of
-    // 'arguments' are reflected in the variables and vice versa. If the
-    // 'arguments' variable is changed, '.arguments' still points to the
-    // correct arguments object and the rewrites still work.
+    // 'arguments', we must be conservative and allocate all parameters to
+    // the context assuming they will be captured by the arguments object.
+    // If we have a parameter named 'arguments', a (new) value is always
+    // assigned to it via the function invocation. Then 'arguments' denotes
+    // that specific parameter value and cannot be used to access the
+    // parameters, which is why we don't need to allocate an arguments
+    // object in that case.
 
     // We are using 'arguments'. Tell the code generator that is needs to
     // allocate the arguments object by setting 'arguments_'.
@@ -992,76 +997,32 @@
     // In strict mode 'arguments' does not alias formal parameters.
     // Therefore in strict mode we allocate parameters as if 'arguments'
     // were not used.
-    rewrite_parameters = !is_strict_mode();
+    uses_nonstrict_arguments = !is_strict_mode();
   }
 
-  if (rewrite_parameters) {
-    // We also need the '.arguments' shadow variable. Declare it and create
-    // and bind the corresponding proxy. It's ok to declare it only now
-    // because it's a local variable that is allocated after the parameters
-    // have been allocated.
-    //
-    // Note: This is "almost" at temporary variable but we cannot use
-    // NewTemporary() because the mode needs to be INTERNAL since this
-    // variable may be allocated in the heap-allocated context (temporaries
-    // are never allocated in the context).
-    arguments_shadow_ = new Variable(this,
-                                     FACTORY->arguments_shadow_symbol(),
-                                     Variable::INTERNAL,
-                                     true,
-                                     Variable::ARGUMENTS);
-    arguments_shadow_->set_is_used(true);
-    temps_.Add(arguments_shadow_);
-
-    // Allocate the parameters by rewriting them into '.arguments[i]' accesses.
-    for (int i = 0; i < params_.length(); i++) {
-      Variable* var = params_[i];
-      ASSERT(var->scope() == this);
-      if (MustAllocate(var)) {
-        if (MustAllocateInContext(var)) {
-          // It is ok to set this only now, because arguments is a local
-          // variable that is allocated after the parameters have been
-          // allocated.
-          arguments_shadow_->MarkAsAccessedFromInnerScope();
-        }
-        Property* rewrite =
-            new Property(new VariableProxy(arguments_shadow_),
-                         new Literal(Handle<Object>(Smi::FromInt(i))),
-                         RelocInfo::kNoPosition,
-                         Property::SYNTHETIC);
-        rewrite->set_is_arguments_access(true);
-        var->set_rewrite(rewrite);
-      }
+  // The same parameter may occur multiple times in the parameters_ list.
+  // If it does, and if it is not copied into the context object, it must
+  // receive the highest parameter index for that parameter; thus iteration
+  // order is relevant!
+  for (int i = params_.length() - 1; i >= 0; --i) {
+    Variable* var = params_[i];
+    ASSERT(var->scope() == this);
+    if (uses_nonstrict_arguments) {
+      // Give the parameter a use from an inner scope, to force allocation
+      // to the context.
+      var->MarkAsAccessedFromInnerScope();
     }
 
-  } else {
-    // The arguments object is not used, so we can access parameters directly.
-    // The same parameter may occur multiple times in the parameters_ list.
-    // If it does, and if it is not copied into the context object, it must
-    // receive the highest parameter index for that parameter; thus iteration
-    // order is relevant!
-    for (int i = 0; i < params_.length(); i++) {
-      Variable* var = params_[i];
-      ASSERT(var->scope() == this);
-      if (MustAllocate(var)) {
-        if (MustAllocateInContext(var)) {
-          ASSERT(var->rewrite() == NULL ||
-                 (var->AsSlot() != NULL &&
-                  var->AsSlot()->type() == Slot::CONTEXT));
-          if (var->rewrite() == NULL) {
-            // Only set the heap allocation if the parameter has not
-            // been allocated yet.
-            AllocateHeapSlot(var);
-          }
-        } else {
-          ASSERT(var->rewrite() == NULL ||
-                 (var->AsSlot() != NULL &&
-                  var->AsSlot()->type() == Slot::PARAMETER));
-          // Set the parameter index always, even if the parameter
-          // was seen before! (We need to access the actual parameter
-          // supplied for the last occurrence of a multiply declared
-          // parameter.)
-          var->set_rewrite(new Slot(var, Slot::PARAMETER, i));
+    if (MustAllocate(var)) {
+      if (MustAllocateInContext(var)) {
+        ASSERT(var->rewrite() == NULL || var->IsContextSlot());
+        if (var->rewrite() == NULL) {
+          AllocateHeapSlot(var);
+        }
+      } else {
+        ASSERT(var->rewrite() == NULL || var->IsParameter());
+        if (var->rewrite() == NULL) {
+          var->set_rewrite(NewSlot(var, Slot::PARAMETER, i));
         }
       }
     }
@@ -1072,8 +1033,9 @@
 void Scope::AllocateNonParameterLocal(Variable* var) {
   ASSERT(var->scope() == this);
   ASSERT(var->rewrite() == NULL ||
-         (!var->IsVariable(FACTORY->result_symbol())) ||
-         (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL));
+         !var->IsVariable(isolate_->factory()->result_symbol()) ||
+         var->AsSlot() == NULL ||
+         var->AsSlot()->type() != Slot::LOCAL);
   if (var->rewrite() == NULL && MustAllocate(var)) {
     if (MustAllocateInContext(var)) {
       AllocateHeapSlot(var);
@@ -1115,7 +1077,7 @@
 
   // If scope is already resolved, we still need to allocate
   // variables in inner scopes which might not had been resolved yet.
-  if (resolved()) return;
+  if (already_resolved()) return;
   // The number of slots required for variables.
   num_stack_slots_ = 0;
   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
diff --git a/src/scopes.h b/src/scopes.h
index faa6fd9..e76fb50 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -90,20 +90,14 @@
   // Construction
 
   enum Type {
-    EVAL_SCOPE,     // the top-level scope for an 'eval' source
-    FUNCTION_SCOPE,  // the top-level scope for a function
-    GLOBAL_SCOPE    // the top-level scope for a program or a top-level eval
-  };
-
-  enum LocalType {
-    PARAMETER,
-    VAR_OR_CONST
+    EVAL_SCOPE,      // The top-level scope for an eval source.
+    FUNCTION_SCOPE,  // The top-level scope for a function.
+    GLOBAL_SCOPE,    // The top-level scope for a program or a top-level eval.
+    CATCH_SCOPE      // The scope introduced by catch.
   };
 
   Scope(Scope* outer_scope, Type type);
 
-  virtual ~Scope() { }
-
   // Compute top scope and allocate variables. For lazy compilation the top
   // scope only contains the single lazily compiled function, so this
   // doesn't re-allocate variables repeatedly.
@@ -115,33 +109,31 @@
   // The scope name is only used for printing/debugging.
   void SetScopeName(Handle<String> scope_name) { scope_name_ = scope_name; }
 
-  virtual void Initialize(bool inside_with);
-
-  // Called just before leaving a scope.
-  virtual void Leave() {
-    // No cleanup or fixup necessary.
-  }
+  void Initialize(bool inside_with);
 
   // ---------------------------------------------------------------------------
   // Declarations
 
   // Lookup a variable in this scope. Returns the variable or NULL if not found.
-  virtual Variable* LocalLookup(Handle<String> name);
+  Variable* LocalLookup(Handle<String> name);
 
   // Lookup a variable in this scope or outer scopes.
   // Returns the variable or NULL if not found.
-  virtual Variable* Lookup(Handle<String> name);
+  Variable* Lookup(Handle<String> name);
 
   // Declare the function variable for a function literal. This variable
   // is in an intermediate scope between this function scope and the the
   // outer scope. Only possible for function scopes; at most one variable.
   Variable* DeclareFunctionVar(Handle<String> name);
 
+  // Declare a parameter in this scope.  When there are duplicated
+  // parameters the rightmost one 'wins'.  However, the implementation
+  // expects all parameters to be declared and from left to right.
+  void DeclareParameter(Handle<String> name);
+
   // Declare a local variable in this scope. If the variable has been
   // declared before, the previously declared variable is returned.
-  virtual Variable* DeclareLocal(Handle<String> name,
-                                 Variable::Mode mode,
-                                 LocalType type);
+  Variable* DeclareLocal(Handle<String> name, Variable::Mode mode);
 
   // Declare an implicit global variable in this scope which must be a
   // global scope.  The variable was introduced (possibly from an inner
@@ -149,16 +141,10 @@
   // with statements or eval calls.
   Variable* DeclareGlobal(Handle<String> name);
 
-  // Add a parameter to the parameter list. The parameter must have been
-  // declared via Declare. The same parameter may occur more than once in
-  // the parameter list; they must be added in source order, from left to
-  // right.
-  void AddParameter(Variable* var);
-
   // Create a new unresolved variable.
-  virtual VariableProxy* NewUnresolved(Handle<String> name,
-                                       bool inside_with,
-                                       int position = RelocInfo::kNoPosition);
+  VariableProxy* NewUnresolved(Handle<String> name,
+                               bool inside_with,
+                               int position = RelocInfo::kNoPosition);
 
   // Remove a unresolved variable. During parsing, an unresolved variable
   // may have been added optimistically, but then only the variable name
@@ -172,7 +158,7 @@
   // for printing and cannot be used to find the variable.  In particular,
   // the only way to get hold of the temporary is by keeping the Variable*
   // around.
-  virtual Variable* NewTemporary(Handle<String> name);
+  Variable* NewTemporary(Handle<String> name);
 
   // Adds the specific declaration node to the list of declarations in
   // this scope. The declarations are processed as part of entering
@@ -217,6 +203,7 @@
   bool is_eval_scope() const { return type_ == EVAL_SCOPE; }
   bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
   bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
+  bool is_catch_scope() const { return type_ == CATCH_SCOPE; }
   bool is_strict_mode() const { return strict_mode_; }
   bool is_strict_mode_eval_scope() const {
     return is_eval_scope() && is_strict_mode();
@@ -240,13 +227,8 @@
   // ---------------------------------------------------------------------------
   // Accessors.
 
-  // A new variable proxy corresponding to the (function) receiver.
-  VariableProxy* receiver() const {
-    VariableProxy* proxy =
-        new VariableProxy(FACTORY->this_symbol(), true, false);
-    proxy->BindTo(receiver_);
-    return proxy;
-  }
+  // The variable corresponding the 'this' value.
+  Variable* receiver() { return receiver_; }
 
   // The variable holding the function literal for named function
   // literals, or NULL.
@@ -266,18 +248,12 @@
   int num_parameters() const { return params_.length(); }
 
   // The local variable 'arguments' if we need to allocate it; NULL otherwise.
-  // If arguments() exist, arguments_shadow() exists, too.
   Variable* arguments() const { return arguments_; }
 
-  // The '.arguments' shadow variable if we need to allocate it; NULL otherwise.
-  // If arguments_shadow() exist, arguments() exists, too.
-  Variable* arguments_shadow() const { return arguments_shadow_; }
-
   // Declarations list.
   ZoneList<Declaration*>* declarations() { return &decls_; }
 
 
-
   // ---------------------------------------------------------------------------
   // Variable allocation.
 
@@ -309,11 +285,15 @@
   bool AllowsLazyCompilation() const;
 
   // True if the outer context of this scope is always the global context.
-  virtual bool HasTrivialOuterContext() const;
+  bool HasTrivialOuterContext() const;
 
   // The number of contexts between this and scope; zero if this == scope.
   int ContextChainLength(Scope* scope);
 
+  // Find the first function, global, or eval scope.  This is the scope
+  // where var declarations will be hoisted to in the implementation.
+  Scope* DeclarationScope();
+
   // ---------------------------------------------------------------------------
   // Strict mode support.
   bool IsDeclared(Handle<String> name) {
@@ -339,6 +319,8 @@
 
   explicit Scope(Type type);
 
+  Isolate* const isolate_;
+
   // Scope tree.
   Scope* outer_scope_;  // the immediately enclosing outer scope, or NULL
   ZoneList<Scope*> inner_scopes_;  // the immediately enclosed inner scopes
@@ -371,8 +353,6 @@
   Variable* function_;
   // Convenience variable; function scopes only.
   Variable* arguments_;
-  // Convenience variable; function scopes only.
-  Variable* arguments_shadow_;
 
   // Illegal redeclaration.
   Expression* illegal_redecl_;
@@ -390,6 +370,10 @@
   bool outer_scope_is_eval_scope_;
   bool force_eager_compilation_;
 
+  // True if it doesn't need scope resolution (e.g., if the scope was
+  // constructed based on a serialized scope info or a catch context).
+  bool already_resolved_;
+
   // Computed as variables are declared.
   int num_var_or_const_;
 
@@ -399,7 +383,7 @@
 
   // Serialized scopes support.
   Handle<SerializedScopeInfo> scope_info_;
-  bool resolved() { return !scope_info_.is_null(); }
+  bool already_resolved() { return already_resolved_; }
 
   // Create a non-local variable with a given name.
   // These variables are looked up dynamically at runtime.
@@ -435,8 +419,16 @@
   void AllocateVariablesRecursively();
 
  private:
+  // Construct a function scope based on the scope info.
   Scope(Scope* inner_scope, Handle<SerializedScopeInfo> scope_info);
 
+  // Construct a catch scope with a binding for the name.
+  Scope(Scope* inner_scope, Handle<String> catch_variable_name);
+
+  inline Slot* NewSlot(Variable* var, Slot::Type type, int index) {
+    return new(isolate_->zone()) Slot(isolate_, var, type, index);
+  }
+
   void AddInnerScope(Scope* inner_scope) {
     if (inner_scope != NULL) {
       inner_scopes_.Add(inner_scope);
@@ -449,59 +441,6 @@
                    Handle<SerializedScopeInfo> scope_info);
 };
 
-
-// Scope used during pre-parsing.
-class DummyScope : public Scope {
- public:
-  DummyScope()
-      : Scope(GLOBAL_SCOPE),
-        nesting_level_(1),  // Allows us to Leave the initial scope.
-        inside_with_level_(kNotInsideWith) {
-    outer_scope_ = this;
-    scope_inside_with_ = false;
-  }
-
-  virtual void Initialize(bool inside_with) {
-    nesting_level_++;
-    if (inside_with && inside_with_level_ == kNotInsideWith) {
-      inside_with_level_ = nesting_level_;
-    }
-    ASSERT(inside_with_level_ <= nesting_level_);
-  }
-
-  virtual void Leave() {
-    nesting_level_--;
-    ASSERT(nesting_level_ >= 0);
-    if (nesting_level_ < inside_with_level_) {
-      inside_with_level_ = kNotInsideWith;
-    }
-    ASSERT(inside_with_level_ <= nesting_level_);
-  }
-
-  virtual Variable* Lookup(Handle<String> name)  { return NULL; }
-
-  virtual VariableProxy* NewUnresolved(Handle<String> name,
-                                       bool inside_with,
-                                       int position = RelocInfo::kNoPosition) {
-    return NULL;
-  }
-
-  virtual Variable* NewTemporary(Handle<String> name)  { return NULL; }
-
-  virtual bool HasTrivialOuterContext() const {
-    return (nesting_level_ == 0 || inside_with_level_ <= 0);
-  }
-
- private:
-  static const int kNotInsideWith = -1;
-  // Number of surrounding scopes of the current scope.
-  int nesting_level_;
-  // Nesting level of outermost scope that is contained in a with statement,
-  // or kNotInsideWith if there are no with's around the current scope.
-  int inside_with_level_;
-};
-
-
 } }  // namespace v8::internal
 
 #endif  // V8_SCOPES_H_
diff --git a/src/serialize.cc b/src/serialize.cc
index a64fba3..8cde580 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -284,7 +284,6 @@
   const char* AddressNames[] = {
 #define C(name) "Isolate::" #name,
     ISOLATE_ADDRESS_LIST(C)
-    ISOLATE_ADDRESS_LIST_PROF(C)
     NULL
 #undef C
   };
@@ -1017,10 +1016,11 @@
 
       case kNativesStringResource: {
         int index = source_->Get();
-        Vector<const char> source_vector = Natives::GetScriptSource(index);
+        Vector<const char> source_vector = Natives::GetRawScriptSource(index);
         NativesExternalStringResource* resource =
-            new NativesExternalStringResource(
-                isolate->bootstrapper(), source_vector.start());
+            new NativesExternalStringResource(isolate->bootstrapper(),
+                                              source_vector.start(),
+                                              source_vector.length());
         *current++ = reinterpret_cast<Object*>(resource);
         break;
       }
diff --git a/src/spaces-inl.h b/src/spaces-inl.h
index f5f6654..0eb827d 100644
--- a/src/spaces-inl.h
+++ b/src/spaces-inl.h
@@ -379,35 +379,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void MemoryAllocator::Protect(Address start, size_t size) {
-  OS::Protect(start, size);
-}
-
-
-void MemoryAllocator::Unprotect(Address start,
-                                size_t size,
-                                Executability executable) {
-  OS::Unprotect(start, size, executable);
-}
-
-
-void MemoryAllocator::ProtectChunkFromPage(Page* page) {
-  int id = GetChunkId(page);
-  OS::Protect(chunks_[id].address(), chunks_[id].size());
-}
-
-
-void MemoryAllocator::UnprotectChunkFromPage(Page* page) {
-  int id = GetChunkId(page);
-  OS::Unprotect(chunks_[id].address(), chunks_[id].size(),
-                chunks_[id].owner()->executable() == EXECUTABLE);
-}
-
-#endif
-
-
 // --------------------------------------------------------------------------
 // PagedSpace
 
diff --git a/src/spaces.cc b/src/spaces.cc
index b494d24..0f80496 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -402,7 +402,9 @@
                                     size_t length,
                                     Executability executable) {
 #ifdef DEBUG
-  ZapBlock(reinterpret_cast<Address>(mem), length);
+  // Do not try to zap the guard page.
+  size_t guard_size = (executable == EXECUTABLE) ? Page::kPageSize : 0;
+  ZapBlock(reinterpret_cast<Address>(mem) + guard_size, length - guard_size);
 #endif
   if (isolate_->code_range()->contains(static_cast<Address>(mem))) {
     isolate_->code_range()->FreeRawMemory(mem, length);
@@ -504,14 +506,28 @@
   LOG(isolate_, NewEvent("PagedChunk", chunk, chunk_size));
 
   *allocated_pages = PagesInChunk(static_cast<Address>(chunk), chunk_size);
+
   // We may 'lose' a page due to alignment.
   ASSERT(*allocated_pages >= kPagesPerChunk - 1);
-  if (*allocated_pages == 0) {
-    FreeRawMemory(chunk, chunk_size, owner->executable());
+
+  size_t guard_size = (owner->executable() == EXECUTABLE) ? Page::kPageSize : 0;
+
+  // Check that we got at least one page that we can use.
+  if (*allocated_pages <= ((guard_size != 0) ? 1 : 0)) {
+    FreeRawMemory(chunk,
+                  chunk_size,
+                  owner->executable());
     LOG(isolate_, DeleteEvent("PagedChunk", chunk));
     return Page::FromAddress(NULL);
   }
 
+  if (guard_size != 0) {
+    OS::Guard(chunk, guard_size);
+    chunk_size -= guard_size;
+    chunk = static_cast<Address>(chunk) + guard_size;
+    --*allocated_pages;
+  }
+
   int chunk_id = Pop();
   chunks_[chunk_id].init(static_cast<Address>(chunk), chunk_size, owner);
 
@@ -681,7 +697,8 @@
     LOG(isolate_, DeleteEvent("PagedChunk", c.address()));
     ObjectSpace space = static_cast<ObjectSpace>(1 << c.owner_identity());
     size_t size = c.size();
-    FreeRawMemory(c.address(), size, c.executable());
+    size_t guard_size = (c.executable() == EXECUTABLE) ? Page::kPageSize : 0;
+    FreeRawMemory(c.address() - guard_size, size + guard_size, c.executable());
     PerformAllocationCallback(space, kAllocationActionFree, size);
   }
   c.init(NULL, 0, NULL);
@@ -868,30 +885,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void PagedSpace::Protect() {
-  Page* page = first_page_;
-  while (page->is_valid()) {
-    Isolate::Current()->memory_allocator()->ProtectChunkFromPage(page);
-    page = Isolate::Current()->memory_allocator()->
-        FindLastPageInSameChunk(page)->next_page();
-  }
-}
-
-
-void PagedSpace::Unprotect() {
-  Page* page = first_page_;
-  while (page->is_valid()) {
-    Isolate::Current()->memory_allocator()->UnprotectChunkFromPage(page);
-    page = Isolate::Current()->memory_allocator()->
-        FindLastPageInSameChunk(page)->next_page();
-  }
-}
-
-#endif
-
-
 void PagedSpace::MarkAllPagesClean() {
   PageIterator it(this, PageIterator::ALL_PAGES);
   while (it.has_next()) {
@@ -1196,7 +1189,6 @@
   ASSERT(IsPowerOf2(maximum_semispace_capacity));
 
   // Allocate and setup the histogram arrays if necessary.
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
   promoted_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
 
@@ -1204,7 +1196,6 @@
                        promoted_histogram_[name].set_name(#name);
   INSTANCE_TYPE_LIST(SET_NAME)
 #undef SET_NAME
-#endif
 
   ASSERT(size == 2 * heap()->ReservedSemiSpaceSize());
   ASSERT(IsAddressAligned(start, size, 0));
@@ -1236,7 +1227,6 @@
 
 
 void NewSpace::TearDown() {
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   if (allocated_histogram_) {
     DeleteArray(allocated_histogram_);
     allocated_histogram_ = NULL;
@@ -1245,7 +1235,6 @@
     DeleteArray(promoted_histogram_);
     promoted_histogram_ = NULL;
   }
-#endif
 
   start_ = NULL;
   allocation_info_.top = NULL;
@@ -1258,24 +1247,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void NewSpace::Protect() {
-  heap()->isolate()->memory_allocator()->Protect(ToSpaceLow(), Capacity());
-  heap()->isolate()->memory_allocator()->Protect(FromSpaceLow(), Capacity());
-}
-
-
-void NewSpace::Unprotect() {
-  heap()->isolate()->memory_allocator()->Unprotect(ToSpaceLow(), Capacity(),
-                                                   to_space_.executable());
-  heap()->isolate()->memory_allocator()->Unprotect(FromSpaceLow(), Capacity(),
-                                                   from_space_.executable());
-}
-
-#endif
-
-
 void NewSpace::Flip() {
   SemiSpace tmp = from_space_;
   from_space_ = to_space_;
@@ -1638,7 +1609,6 @@
 
 
 // Support for statistics gathering for --heap-stats and --log-gc.
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 void NewSpace::ClearHistograms() {
   for (int i = 0; i <= LAST_TYPE; i++) {
     allocated_histogram_[i].clear();
@@ -1648,9 +1618,7 @@
 
 // Because the copying collector does not touch garbage objects, we iterate
 // the new space before a collection to get a histogram of allocated objects.
-// This only happens (1) when compiled with DEBUG and the --heap-stats flag is
-// set, or when compiled with ENABLE_LOGGING_AND_PROFILING and the --log-gc
-// flag is set.
+// This only happens when --log-gc flag is set.
 void NewSpace::CollectStatistics() {
   ClearHistograms();
   SemiSpaceIterator it(this);
@@ -1659,7 +1627,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static void DoReportStatistics(Isolate* isolate,
                                HistogramInfo* info, const char* description) {
   LOG(isolate, HeapSampleBeginEvent("NewSpace", description));
@@ -1686,7 +1653,6 @@
   }
   LOG(isolate, HeapSampleEndEvent("NewSpace", description));
 }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 
 void NewSpace::ReportStatistics() {
@@ -1709,13 +1675,11 @@
   }
 #endif  // DEBUG
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_gc) {
     Isolate* isolate = ISOLATE;
     DoReportStatistics(isolate, allocated_histogram_, "allocated");
     DoReportStatistics(isolate, promoted_histogram_, "promoted");
   }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 }
 
 
@@ -1733,7 +1697,6 @@
   promoted_histogram_[type].increment_number(1);
   promoted_histogram_[type].increment_bytes(obj->Size());
 }
-#endif  // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 
 
 // -----------------------------------------------------------------------------
@@ -2726,9 +2689,10 @@
                                         Executability executable) {
   size_t requested = ChunkSizeFor(size_in_bytes);
   size_t size;
+  size_t guard_size = (executable == EXECUTABLE) ? Page::kPageSize : 0;
   Isolate* isolate = Isolate::Current();
   void* mem = isolate->memory_allocator()->AllocateRawMemory(
-      requested, &size, executable);
+      requested + guard_size, &size, executable);
   if (mem == NULL) return NULL;
 
   // The start of the chunk may be overlayed with a page so we have to
@@ -2736,13 +2700,19 @@
   ASSERT((size & Page::kPageFlagMask) == 0);
 
   LOG(isolate, NewEvent("LargeObjectChunk", mem, size));
-  if (size < requested) {
+  if (size < requested + guard_size) {
     isolate->memory_allocator()->FreeRawMemory(
         mem, size, executable);
     LOG(isolate, DeleteEvent("LargeObjectChunk", mem));
     return NULL;
   }
 
+  if (guard_size != 0) {
+    OS::Guard(mem, guard_size);
+    size -= guard_size;
+    mem = static_cast<Address>(mem) + guard_size;
+  }
+
   ObjectSpace space = (executable == EXECUTABLE)
       ? kObjectSpaceCodeSpace
       : kObjectSpaceLoSpace;
@@ -2796,9 +2766,11 @@
     ObjectSpace space = kObjectSpaceLoSpace;
     if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace;
     size_t size = chunk->size();
-    heap()->isolate()->memory_allocator()->FreeRawMemory(chunk->address(),
-                                                         size,
-                                                         executable);
+    size_t guard_size = (executable == EXECUTABLE) ? Page::kPageSize : 0;
+    heap()->isolate()->memory_allocator()->FreeRawMemory(
+        chunk->address() - guard_size,
+        size + guard_size,
+        executable);
     heap()->isolate()->memory_allocator()->PerformAllocationCallback(
         space, kAllocationActionFree, size);
   }
@@ -2809,31 +2781,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void LargeObjectSpace::Protect() {
-  LargeObjectChunk* chunk = first_chunk_;
-  while (chunk != NULL) {
-    heap()->isolate()->memory_allocator()->Protect(chunk->address(),
-                                                   chunk->size());
-    chunk = chunk->next();
-  }
-}
-
-
-void LargeObjectSpace::Unprotect() {
-  LargeObjectChunk* chunk = first_chunk_;
-  while (chunk != NULL) {
-    bool is_code = chunk->GetObject()->IsCode();
-    heap()->isolate()->memory_allocator()->Unprotect(chunk->address(),
-        chunk->size(), is_code ? EXECUTABLE : NOT_EXECUTABLE);
-    chunk = chunk->next();
-  }
-}
-
-#endif
-
-
 MaybeObject* LargeObjectSpace::AllocateRawInternal(int requested_size,
                                                    int object_size,
                                                    Executability executable) {
@@ -3020,10 +2967,15 @@
       objects_size_ -= object->Size();
       page_count_--;
       ObjectSpace space = kObjectSpaceLoSpace;
-      if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace;
-      heap()->isolate()->memory_allocator()->FreeRawMemory(chunk_address,
-                                                           chunk_size,
-                                                           executable);
+      size_t guard_size = 0;
+      if (executable == EXECUTABLE) {
+        space = kObjectSpaceCodeSpace;
+        guard_size = Page::kPageSize;
+      }
+      heap()->isolate()->memory_allocator()->FreeRawMemory(
+          chunk_address - guard_size,
+          chunk_size + guard_size,
+          executable);
       heap()->isolate()->memory_allocator()->PerformAllocationCallback(
           space, kAllocationActionFree, size_);
       LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", chunk_address));
@@ -3070,7 +3022,7 @@
     // strings), fixed arrays, and byte arrays in large object space.
     ASSERT(object->IsCode() || object->IsSeqString() ||
            object->IsExternalString() || object->IsFixedArray() ||
-           object->IsByteArray());
+           object->IsFixedDoubleArray() || object->IsByteArray());
 
     // The object itself should look OK.
     object->Verify();
diff --git a/src/spaces.h b/src/spaces.h
index 4024387..ac5d998 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -380,12 +380,6 @@
   // (e.g. see LargeObjectSpace).
   virtual intptr_t SizeOfObjects() { return Size(); }
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  virtual void Protect() = 0;
-  virtual void Unprotect() = 0;
-#endif
-
 #ifdef DEBUG
   virtual void Print() = 0;
 #endif
@@ -641,17 +635,6 @@
                                   Page** last_page,
                                   Page** last_page_in_use);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect a block of memory by marking it read-only/writable.
-  inline void Protect(Address start, size_t size);
-  inline void Unprotect(Address start, size_t size,
-                        Executability executable);
-
-  // Protect/unprotect a chunk given a page in the chunk.
-  inline void ProtectChunkFromPage(Page* page);
-  inline void UnprotectChunkFromPage(Page* page);
-#endif
-
 #ifdef DEBUG
   // Reports statistic info of the space.
   void ReportStatistics();
@@ -664,13 +647,11 @@
 #ifdef V8_TARGET_ARCH_X64
   static const int kPagesPerChunk = 32;
   // On 64 bit the chunk table consists of 4 levels of 4096-entry tables.
-  static const int kPagesPerChunkLog2 = 5;
   static const int kChunkTableLevels = 4;
   static const int kChunkTableBitsPerLevel = 12;
 #else
   static const int kPagesPerChunk = 16;
   // On 32 bit the chunk table consists of 2 levels of 256-entry tables.
-  static const int kPagesPerChunkLog2 = 4;
   static const int kChunkTableLevels = 2;
   static const int kChunkTableBitsPerLevel = 8;
 #endif
@@ -679,7 +660,6 @@
   MemoryAllocator();
 
   static const int kChunkSize = kPagesPerChunk * Page::kPageSize;
-  static const int kChunkSizeLog2 = kPagesPerChunkLog2 + kPageSizeBits;
 
   // Maximum space size in bytes.
   intptr_t capacity_;
@@ -1157,12 +1137,6 @@
   // Ensures that the capacity is at least 'capacity'. Returns false on failure.
   bool EnsureCapacity(int capacity);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  void Protect();
-  void Unprotect();
-#endif
-
 #ifdef DEBUG
   // Print meta info and objects in this space.
   virtual void Print();
@@ -1270,7 +1244,6 @@
 };
 
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 class NumberAndSizeInfo BASE_EMBEDDED {
  public:
   NumberAndSizeInfo() : number_(0), bytes_(0) {}
@@ -1293,9 +1266,7 @@
 
 
 // HistogramInfo class for recording a single "bar" of a histogram.  This
-// class is used for collecting statistics to print to stdout (when compiled
-// with DEBUG) or to the log file (when compiled with
-// ENABLE_LOGGING_AND_PROFILING).
+// class is used for collecting statistics to print to the log file.
 class HistogramInfo: public NumberAndSizeInfo {
  public:
   HistogramInfo() : NumberAndSizeInfo() {}
@@ -1306,7 +1277,6 @@
  private:
   const char* name_;
 };
-#endif
 
 
 // -----------------------------------------------------------------------------
@@ -1392,12 +1362,6 @@
   bool Commit();
   bool Uncommit();
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  virtual void Protect() {}
-  virtual void Unprotect() {}
-#endif
-
 #ifdef DEBUG
   virtual void Print();
   virtual void Verify();
@@ -1628,12 +1592,6 @@
   template <typename StringType>
   inline void ShrinkStringAtAllocationBoundary(String* string, int len);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  virtual void Protect();
-  virtual void Unprotect();
-#endif
-
 #ifdef DEBUG
   // Verify the active semispace.
   virtual void Verify();
@@ -1641,7 +1599,6 @@
   virtual void Print() { to_space_.Print(); }
 #endif
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   // Iterates the active semispace to collect statistics.
   void CollectStatistics();
   // Reports previously collected statistics of the active semispace.
@@ -1654,7 +1611,6 @@
   // to space during a scavenge GC.
   void RecordAllocation(HeapObject* obj);
   void RecordPromotion(HeapObject* obj);
-#endif
 
   // Return whether the operation succeded.
   bool CommitFromSpaceIfNeeded() {
@@ -1683,10 +1639,8 @@
   AllocationInfo allocation_info_;
   AllocationInfo mc_forwarding_info_;
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   HistogramInfo* allocated_histogram_;
   HistogramInfo* promoted_histogram_;
-#endif
 
   // Implementation of AllocateRaw and MCAllocateRaw.
   MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(
@@ -2296,12 +2250,6 @@
   // may use some memory, leaving less for large objects.
   virtual bool ReserveSpace(int bytes);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  void Protect();
-  void Unprotect();
-#endif
-
 #ifdef DEBUG
   virtual void Verify();
   virtual void Print();
diff --git a/src/string-stream.cc b/src/string-stream.cc
index aea1420..9002593 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -30,6 +30,8 @@
 #include "factory.h"
 #include "string-stream.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/string.js b/src/string.js
index f24862c..600b131 100644
--- a/src/string.js
+++ b/src/string.js
@@ -251,7 +251,9 @@
 
   // Compute the string to replace with.
   if (IS_FUNCTION(replace)) {
-    builder.add(%_CallFunction(%GetGlobalReceiver(),
+    var receiver =
+        %_IsNativeOrStrictMode(replace) ? void 0 : %GetGlobalReceiver();
+    builder.add(%_CallFunction(receiver,
                                search,
                                start,
                                subject,
@@ -418,7 +420,8 @@
   if (NUMBER_OF_CAPTURES(lastMatchInfo) == 2) {
     var match_start = 0;
     var override = new InternalArray(null, 0, subject);
-    var receiver = %GetGlobalReceiver();
+    var receiver =
+        %_IsNativeOrStrictMode(replace) ? void 0 : %GetGlobalReceiver();
     while (i < len) {
       var elem = res[i];
       if (%_IsSmi(elem)) {
@@ -475,8 +478,10 @@
     // No captures, only the match, which is always valid.
     var s = SubString(subject, index, endOfMatch);
     // Don't call directly to avoid exposing the built-in global object.
+    var receiver =
+        %_IsNativeOrStrictMode(replace) ? void 0 : %GetGlobalReceiver();
     replacement =
-        %_CallFunction(%GetGlobalReceiver(), s, index, subject, replace);
+        %_CallFunction(receiver, s, index, subject, replace);
   } else {
     var parameters = new InternalArray(m + 2);
     for (var j = 0; j < m; j++) {
diff --git a/src/strtod.cc b/src/strtod.cc
index cedbff9..568531e 100644
--- a/src/strtod.cc
+++ b/src/strtod.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -26,10 +26,10 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <stdarg.h>
-#include <limits.h>
+#include <math.h>
 
-#include "v8.h"
-
+#include "platform.h"
+#include "utils.h"
 #include "strtod.h"
 #include "bignum.h"
 #include "cached-powers.h"
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 8c6d84c..79cd7a0 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -29,6 +29,7 @@
 
 #include "api.h"
 #include "arguments.h"
+#include "code-stubs.h"
 #include "gdb-jit.h"
 #include "ic-inl.h"
 #include "stub-cache.h"
@@ -485,86 +486,7 @@
 }
 
 
-namespace {
-
-ExternalArrayType ElementsKindToExternalArrayType(JSObject::ElementsKind kind) {
-  switch (kind) {
-    case JSObject::EXTERNAL_BYTE_ELEMENTS:
-      return kExternalByteArray;
-    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
-      return kExternalUnsignedByteArray;
-    case JSObject::EXTERNAL_SHORT_ELEMENTS:
-      return kExternalShortArray;
-    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-      return kExternalUnsignedShortArray;
-    case JSObject::EXTERNAL_INT_ELEMENTS:
-      return kExternalIntArray;
-    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
-      return kExternalUnsignedIntArray;
-    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
-      return kExternalFloatArray;
-    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
-      return kExternalDoubleArray;
-    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
-      return kExternalPixelArray;
-    default:
-      UNREACHABLE();
-      return static_cast<ExternalArrayType>(0);
-  }
-}
-
-}  // anonymous namespace
-
-
-MaybeObject* StubCache::ComputeKeyedLoadOrStoreExternalArray(
-    JSObject* receiver,
-    bool is_store,
-    StrictModeFlag strict_mode) {
-  Code::Flags flags =
-      Code::ComputeMonomorphicFlags(
-          is_store ? Code::KEYED_STORE_IC :
-                     Code::KEYED_LOAD_IC,
-          NORMAL,
-          strict_mode);
-  ExternalArrayType array_type =
-      ElementsKindToExternalArrayType(receiver->GetElementsKind());
-  String* name = is_store
-      ? isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol()
-      : isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol();
-  Object* maybe_code = receiver->map()->FindInCodeCache(name, flags);
-  if (!maybe_code->IsUndefined()) return Code::cast(maybe_code);
-
-  MaybeObject* maybe_new_code = NULL;
-  if (is_store) {
-    ExternalArrayStoreStubCompiler compiler(strict_mode);
-    maybe_new_code = compiler.CompileStore(receiver, array_type);
-  } else {
-    ExternalArrayLoadStubCompiler compiler(strict_mode);
-    maybe_new_code = compiler.CompileLoad(receiver, array_type);
-  }
-  Code* code;
-  if (!maybe_new_code->To(&code)) return maybe_new_code;
-  code->set_external_array_type(array_type);
-  if (is_store) {
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_STORE_IC_TAG,
-                            Code::cast(code), 0));
-  } else {
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG,
-                            Code::cast(code), 0));
-  }
-  ASSERT(code->IsCode());
-  Object* result;
-  { MaybeObject* maybe_result =
-        receiver->UpdateMapCodeCache(name, Code::cast(code));
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
-  return code;
-}
-
-
-MaybeObject* StubCache::ComputeKeyedLoadOrStoreFastElement(
+MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement(
     JSObject* receiver,
     bool is_store,
     StrictModeFlag strict_mode) {
@@ -575,18 +497,19 @@
           NORMAL,
           strict_mode);
   String* name = is_store
-      ? isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol()
-      : isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol();
+      ? isolate()->heap()->KeyedStoreElementMonomorphic_symbol()
+      : isolate()->heap()->KeyedLoadElementMonomorphic_symbol();
   Object* maybe_code = receiver->map()->FindInCodeCache(name, flags);
   if (!maybe_code->IsUndefined()) return Code::cast(maybe_code);
 
   MaybeObject* maybe_new_code = NULL;
+  Map* receiver_map = receiver->map();
   if (is_store) {
     KeyedStoreStubCompiler compiler(strict_mode);
-    maybe_new_code = compiler.CompileStoreFastElement(receiver->map());
+    maybe_new_code = compiler.CompileStoreElement(receiver_map);
   } else {
     KeyedLoadStubCompiler compiler;
-    maybe_new_code = compiler.CompileLoadFastElement(receiver->map());
+    maybe_new_code = compiler.CompileLoadElement(receiver_map);
   }
   Code* code;
   if (!maybe_new_code->To(&code)) return maybe_new_code;
@@ -1117,6 +1040,26 @@
 }
 
 
+MaybeObject* StubCache::ComputeCallArguments(int argc,
+                                             InLoopFlag in_loop,
+                                             Code::Kind kind) {
+  ASSERT(kind == Code::KEYED_CALL_IC);
+  Code::Flags flags = Code::ComputeFlags(kind,
+                                         in_loop,
+                                         MEGAMORPHIC,
+                                         Code::kNoExtraICState,
+                                         NORMAL,
+                                         argc);
+  Object* probe;
+  { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
+    if (!maybe_probe->ToObject(&probe)) return maybe_probe;
+  }
+  if (!probe->IsUndefined()) return probe;
+  StubCompiler compiler;
+  return FillCache(isolate_, compiler.CompileCallArguments(flags));
+}
+
+
 MaybeObject* StubCache::ComputeCallMegamorphic(
     int argc,
     InLoopFlag in_loop,
@@ -1447,8 +1390,7 @@
   JSObject* recv = JSObject::cast(args[0]);
   String* name = String::cast(args[1]);
   Object* value = args[2];
-  StrictModeFlag strict_mode =
-      static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
+  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
   ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
   ASSERT(recv->HasNamedInterceptor());
   PropertyAttributes attr = NONE;
@@ -1460,8 +1402,8 @@
 
 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
   JSObject* receiver = JSObject::cast(args[0]);
-  ASSERT(Smi::cast(args[1])->value() >= 0);
-  uint32_t index = Smi::cast(args[1])->value();
+  ASSERT(args.smi_at(1) >= 0);
+  uint32_t index = args.smi_at(1);
   return receiver->GetElementWithInterceptor(receiver, index);
 }
 
@@ -1573,6 +1515,26 @@
 }
 
 
+MaybeObject* StubCompiler::CompileCallArguments(Code::Flags flags) {
+  HandleScope scope(isolate());
+  int argc = Code::ExtractArgumentsCountFromFlags(flags);
+  KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
+  Code::Kind kind = Code::ExtractKindFromFlags(flags);
+  Object* result;
+  { MaybeObject* maybe_result =
+        GetCodeWithFlags(flags, "CompileCallArguments");
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+  }
+  Code* code = Code::cast(result);
+  USE(code);
+  PROFILE(isolate(),
+          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
+                          code, code->arguments_count()));
+  GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code)));
+  return result;
+}
+
+
 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) {
   HandleScope scope(isolate());
   int argc = Code::ExtractArgumentsCountFromFlags(flags);
@@ -1760,6 +1722,12 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
+    MacroAssembler* masm) {
+  KeyedStoreIC::GenerateSlow(masm);
+}
+
+
 CallStubCompiler::CallStubCompiler(int argc,
                                    InLoopFlag in_loop,
                                    Code::Kind kind,
@@ -1923,38 +1891,4 @@
 }
 
 
-MaybeObject* ExternalArrayLoadStubCompiler::GetCode() {
-  Object* result;
-  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
-                                                    NORMAL,
-                                                    strict_mode_);
-  { MaybeObject* maybe_result = GetCodeWithFlags(flags,
-                                                 "ExternalArrayLoadStub");
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
-  Code* code = Code::cast(result);
-  USE(code);
-  PROFILE(isolate(),
-          CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayLoadStub"));
-  return result;
-}
-
-
-MaybeObject* ExternalArrayStoreStubCompiler::GetCode() {
-  Object* result;
-  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC,
-                                                    NORMAL,
-                                                    strict_mode_);
-  { MaybeObject* maybe_result = GetCodeWithFlags(flags,
-                                                 "ExternalArrayStoreStub");
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
-  Code* code = Code::cast(result);
-  USE(code);
-  PROFILE(isolate(),
-          CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStoreStub"));
-  return result;
-}
-
-
 } }  // namespace v8::internal
diff --git a/src/stub-cache.h b/src/stub-cache.h
index a1243c2..ffe4241 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -183,15 +183,11 @@
       Map* transition,
       StrictModeFlag strict_mode);
 
-  MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreExternalArray(
+  MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreElement(
       JSObject* receiver,
       bool is_store,
       StrictModeFlag strict_mode);
 
-  MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreFastElement(
-      JSObject* receiver,
-      bool is_store,
-      StrictModeFlag strict_mode);
   // ---
 
   MUST_USE_RESULT MaybeObject* ComputeCallField(
@@ -265,6 +261,10 @@
                                                  Code::Kind kind,
                                                  Code::ExtraICState state);
 
+  MUST_USE_RESULT MaybeObject* ComputeCallArguments(int argc,
+                                                    InLoopFlag in_loop,
+                                                    Code::Kind kind);
+
   MUST_USE_RESULT MaybeObject* ComputeCallMegamorphic(int argc,
                                                       InLoopFlag in_loop,
                                                       Code::Kind kind,
@@ -429,6 +429,7 @@
   MUST_USE_RESULT MaybeObject* CompileCallPreMonomorphic(Code::Flags flags);
   MUST_USE_RESULT MaybeObject* CompileCallNormal(Code::Flags flags);
   MUST_USE_RESULT MaybeObject* CompileCallMegamorphic(Code::Flags flags);
+  MUST_USE_RESULT MaybeObject* CompileCallArguments(Code::Flags flags);
   MUST_USE_RESULT MaybeObject* CompileCallMiss(Code::Flags flags);
 #ifdef ENABLE_DEBUGGER_SUPPORT
   MUST_USE_RESULT MaybeObject* CompileCallDebugBreak(Code::Flags flags);
@@ -650,17 +651,21 @@
   MUST_USE_RESULT MaybeObject* CompileLoadStringLength(String* name);
   MUST_USE_RESULT MaybeObject* CompileLoadFunctionPrototype(String* name);
 
-  MUST_USE_RESULT MaybeObject* CompileLoadFastElement(Map* receiver_map);
+  MUST_USE_RESULT MaybeObject* CompileLoadElement(Map* receiver_map);
 
   MUST_USE_RESULT MaybeObject* CompileLoadMegamorphic(
       MapList* receiver_maps,
       CodeList* handler_ics);
 
   static void GenerateLoadExternalArray(MacroAssembler* masm,
-                                        ExternalArrayType array_type);
+                                        JSObject::ElementsKind elements_kind);
 
   static void GenerateLoadFastElement(MacroAssembler* masm);
 
+  static void GenerateLoadFastDoubleElement(MacroAssembler* masm);
+
+  static void GenerateLoadDictionaryElement(MacroAssembler* masm);
+
  private:
   MaybeObject* GetCode(PropertyType type,
                        String* name,
@@ -705,7 +710,7 @@
                                                  Map* transition,
                                                  String* name);
 
-  MUST_USE_RESULT MaybeObject* CompileStoreFastElement(Map* receiver_map);
+  MUST_USE_RESULT MaybeObject* CompileStoreElement(Map* receiver_map);
 
   MUST_USE_RESULT MaybeObject* CompileStoreMegamorphic(
       MapList* receiver_maps,
@@ -714,8 +719,13 @@
   static void GenerateStoreFastElement(MacroAssembler* masm,
                                        bool is_js_array);
 
+  static void GenerateStoreFastDoubleElement(MacroAssembler* masm,
+                                             bool is_js_array);
+
   static void GenerateStoreExternalArray(MacroAssembler* masm,
-                                         ExternalArrayType array_type);
+                                         JSObject::ElementsKind elements_kind);
+
+  static void GenerateStoreDictionaryElement(MacroAssembler* masm);
 
  private:
   MaybeObject* GetCode(PropertyType type,
@@ -894,35 +904,6 @@
   CallHandlerInfo* api_call_info_;
 };
 
-class ExternalArrayLoadStubCompiler: public StubCompiler {
- public:
-  explicit ExternalArrayLoadStubCompiler(StrictModeFlag strict_mode)
-    : strict_mode_(strict_mode) { }
-
-  MUST_USE_RESULT MaybeObject* CompileLoad(
-      JSObject* receiver, ExternalArrayType array_type);
-
- private:
-  MaybeObject* GetCode();
-
-  StrictModeFlag strict_mode_;
-};
-
-
-class ExternalArrayStoreStubCompiler: public StubCompiler {
- public:
-  explicit ExternalArrayStoreStubCompiler(StrictModeFlag strict_mode)
-      : strict_mode_(strict_mode) {}
-
-  MUST_USE_RESULT MaybeObject* CompileStore(
-      JSObject* receiver, ExternalArrayType array_type);
-
- private:
-  MaybeObject* GetCode();
-
-  StrictModeFlag strict_mode_;
-};
-
 
 } }  // namespace v8::internal
 
diff --git a/src/third_party/valgrind/valgrind.h b/src/third_party/valgrind/valgrind.h
index a94dc58..7a3ee2f 100644
--- a/src/third_party/valgrind/valgrind.h
+++ b/src/third_party/valgrind/valgrind.h
@@ -12,7 +12,7 @@
    This file is part of Valgrind, a dynamic binary instrumentation
    framework.
 
-   Copyright (C) 2000-2007 Julian Seward.  All rights reserved.
+   Copyright (C) 2000-2010 Julian Seward.  All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
@@ -73,6 +73,25 @@
 #ifndef __VALGRIND_H
 #define __VALGRIND_H
 
+
+/* ------------------------------------------------------------------ */
+/* VERSION NUMBER OF VALGRIND                                         */
+/* ------------------------------------------------------------------ */
+
+/* Specify Valgrind's version number, so that user code can
+   conditionally compile based on our version number.  Note that these
+   were introduced at version 3.6 and so do not exist in version 3.5
+   or earlier.  The recommended way to use them to check for "version
+   X.Y or later" is (eg)
+
+#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__)   \
+    && (__VALGRIND_MAJOR__ > 3                                   \
+        || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
+*/
+#define __VALGRIND_MAJOR__    3
+#define __VALGRIND_MINOR__    6
+
+
 #include <stdarg.h>
 #include <stdint.h>
 
@@ -85,34 +104,44 @@
    identifying architectures, which are different to the ones we use
    within the rest of Valgrind.  Note, __powerpc__ is active for both
    32 and 64-bit PPC, whereas __powerpc64__ is only active for the
-   latter (on Linux, that is). */
+   latter (on Linux, that is).
+
+   Misc note: how to find out what's predefined in gcc by default:
+   gcc -Wp,-dM somefile.c
+*/
+#undef PLAT_x86_darwin
+#undef PLAT_amd64_darwin
+#undef PLAT_x86_win32
 #undef PLAT_x86_linux
 #undef PLAT_amd64_linux
 #undef PLAT_ppc32_linux
 #undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
+#undef PLAT_arm_linux
+#undef PLAT_s390x_linux
 
-#if !defined(_AIX) && defined(__i386__)
+
+#if defined(__APPLE__) && defined(__i386__)
+#  define PLAT_x86_darwin 1
+#elif defined(__APPLE__) && defined(__x86_64__)
+#  define PLAT_amd64_darwin 1
+#elif defined(__MINGW32__) || defined(__CYGWIN32__) \
+      || (defined(_WIN32) && defined(_M_IX86))
+#  define PLAT_x86_win32 1
+#elif defined(__linux__) && defined(__i386__)
 #  define PLAT_x86_linux 1
-#elif !defined(_AIX) && defined(__x86_64__)
+#elif defined(__linux__) && defined(__x86_64__)
 #  define PLAT_amd64_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
 #  define PLAT_ppc32_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
 #  define PLAT_ppc64_linux 1
-#elif defined(_AIX) && defined(__64BIT__)
-#  define PLAT_ppc64_aix5 1
-#elif defined(_AIX) && !defined(__64BIT__)
-#  define PLAT_ppc32_aix5 1
-#endif
-
-
+#elif defined(__linux__) && defined(__arm__)
+#  define PLAT_arm_linux 1
+#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
+#  define PLAT_s390x_linux 1
+#else
 /* If we're not compiling for our target platform, don't generate
    any inline asms.  */
-#if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \
-    && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \
-    && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5)
 #  if !defined(NVALGRIND)
 #    define NVALGRIND 1
 #  endif
@@ -124,17 +153,31 @@
 /* in here of use to end-users -- skip to the next section.           */
 /* ------------------------------------------------------------------ */
 
+/*
+ * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
+ * request. Accepts both pointers and integers as arguments.
+ *
+ * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
+ * client request and whose value equals the client request result. Accepts
+ * both pointers and integers as arguments.
+ */
+
+#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
+                                   _zzq_request, _zzq_arg1, _zzq_arg2,  \
+                                   _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
+  { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),      \
+                        (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
+                        (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); }
+
 #if defined(NVALGRIND)
 
 /* Define NVALGRIND to completely remove the Valgrind magic sequence
    from the compiled code (analogous to NDEBUG's effects on
    assert()) */
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-   {                                                              \
-      (_zzq_rlval) = (_zzq_default);                              \
-   }
+      (_zzq_default)
 
 #else  /* ! NVALGRIND */
 
@@ -173,9 +216,10 @@
    inline asm stuff to be useful.
 */
 
-/* ------------------------- x86-linux ------------------------- */
+/* ------------------------- x86-{linux,darwin} ---------------- */
 
-#if defined(PLAT_x86_linux)
+#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
+    ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
 
 typedef
    struct { 
@@ -187,10 +231,11 @@
                      "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
                      "roll $29, %%edi ; roll $19, %%edi\n\t"
 
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  { volatile unsigned int _zzq_args[6];                           \
+  __extension__                                                   \
+  ({volatile unsigned int _zzq_args[6];                           \
     volatile unsigned int _zzq_result;                            \
     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
@@ -205,8 +250,8 @@
                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
                      : "cc", "memory"                             \
                     );                                            \
-    _zzq_rlval = _zzq_result;                                     \
-  }
+    _zzq_result;                                                  \
+  })
 
 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
@@ -225,11 +270,77 @@
                      __SPECIAL_INSTRUCTION_PREAMBLE               \
                      /* call-noredir *%EAX */                     \
                      "xchgl %%edx,%%edx\n\t"
-#endif /* PLAT_x86_linux */
+#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
 
-/* ------------------------ amd64-linux ------------------------ */
+/* ------------------------- x86-Win32 ------------------------- */
 
-#if defined(PLAT_amd64_linux)
+#if defined(PLAT_x86_win32) && !defined(__GNUC__)
+
+typedef
+   struct { 
+      unsigned int nraddr; /* where's the code? */
+   }
+   OrigFn;
+
+#if defined(_MSC_VER)
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
+                     __asm rol edi, 3  __asm rol edi, 13          \
+                     __asm rol edi, 29 __asm rol edi, 19
+
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
+        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
+    valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
+        (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
+        (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
+        (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
+
+static __inline uintptr_t
+valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
+                                uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
+                                uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
+                                uintptr_t _zzq_arg5)
+{
+    volatile uintptr_t _zzq_args[6];
+    volatile unsigned int _zzq_result;
+    _zzq_args[0] = (uintptr_t)(_zzq_request);
+    _zzq_args[1] = (uintptr_t)(_zzq_arg1);
+    _zzq_args[2] = (uintptr_t)(_zzq_arg2);
+    _zzq_args[3] = (uintptr_t)(_zzq_arg3);
+    _zzq_args[4] = (uintptr_t)(_zzq_arg4);
+    _zzq_args[5] = (uintptr_t)(_zzq_arg5);
+    __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
+            __SPECIAL_INSTRUCTION_PREAMBLE
+            /* %EDX = client_request ( %EAX ) */
+            __asm xchg ebx,ebx
+            __asm mov _zzq_result, edx
+    }
+    return _zzq_result;
+}
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
+  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
+    volatile unsigned int __addr;                                 \
+    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
+            /* %EAX = guest_NRADDR */                             \
+            __asm xchg ecx,ecx                                    \
+            __asm mov __addr, eax                                 \
+    }                                                             \
+    _zzq_orig->nraddr = __addr;                                   \
+  }
+
+#define VALGRIND_CALL_NOREDIR_EAX ERROR
+
+#else
+#error Unsupported compiler.
+#endif
+
+#endif /* PLAT_x86_win32 */
+
+/* ------------------------ amd64-{linux,darwin} --------------- */
+
+#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
 
 typedef
    struct { 
@@ -241,10 +352,11 @@
                      "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
                      "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
 
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  { volatile uint64_t _zzq_args[6];                 \
+    __extension__                                                 \
+    ({ volatile uint64_t _zzq_args[6];              \
     volatile uint64_t _zzq_result;                  \
     _zzq_args[0] = (uint64_t)(_zzq_request);        \
     _zzq_args[1] = (uint64_t)(_zzq_arg1);           \
@@ -259,8 +371,8 @@
                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
                      : "cc", "memory"                             \
                     );                                            \
-    _zzq_rlval = _zzq_result;                                     \
-  }
+    _zzq_result;                                                  \
+    })
 
 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
@@ -279,7 +391,7 @@
                      __SPECIAL_INSTRUCTION_PREAMBLE               \
                      /* call-noredir *%RAX */                     \
                      "xchgq %%rdx,%%rdx\n\t"
-#endif /* PLAT_amd64_linux */
+#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
 
 /* ------------------------ ppc32-linux ------------------------ */
 
@@ -295,11 +407,12 @@
                      "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
                      "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
 
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                   \
-  {          unsigned int  _zzq_args[6];                          \
+    __extension__                                                 \
+  ({         unsigned int  _zzq_args[6];                          \
              unsigned int  _zzq_result;                           \
              unsigned int* _zzq_ptr;                              \
     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
@@ -318,8 +431,8 @@
                      : "=b" (_zzq_result)                         \
                      : "b" (_zzq_default), "b" (_zzq_ptr)         \
                      : "cc", "memory", "r3", "r4");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
+    _zzq_result;                                                  \
+    })
 
 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
@@ -356,11 +469,12 @@
                      "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
                      "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
 
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                   \
-  {          uint64_t  _zzq_args[6];                \
+  __extension__                                                   \
+  ({         uint64_t  _zzq_args[6];                \
     register uint64_t  _zzq_result __asm__("r3");   \
     register uint64_t* _zzq_ptr __asm__("r4");      \
     _zzq_args[0] = (uint64_t)(_zzq_request);        \
@@ -376,8 +490,8 @@
                      : "=r" (_zzq_result)                         \
                      : "0" (_zzq_default), "r" (_zzq_ptr)         \
                      : "cc", "memory");                           \
-    _zzq_rlval = _zzq_result;                                     \
-  }
+    _zzq_result;                                                  \
+  })
 
 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
@@ -407,149 +521,135 @@
 
 #endif /* PLAT_ppc64_linux */
 
-/* ------------------------ ppc32-aix5 ------------------------- */
+/* ------------------------- arm-linux ------------------------- */
 
-#if defined(PLAT_ppc32_aix5)
+#if defined(PLAT_arm_linux)
 
 typedef
    struct { 
       unsigned int nraddr; /* where's the code? */
-      unsigned int r2;  /* what tocptr do we need? */
    }
    OrigFn;
 
 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
-                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
+            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
+            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
 
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
                                                                   \
-  {          unsigned int  _zzq_args[7];                          \
-    register unsigned int  _zzq_result;                           \
-    register unsigned int* _zzq_ptr;                              \
+  __extension__                                                   \
+  ({volatile unsigned int  _zzq_args[6];                          \
+    volatile unsigned int  _zzq_result;                           \
     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    _zzq_args[6] = (unsigned int)(_zzq_default);                  \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 4,%1\n\t"                                \
-                     "lwz 3, 24(4)\n\t"                           \
+    __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
+                     "mov r4, %2\n\t" /*ptr*/                     \
                      __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_ptr)                             \
-                     : "r3", "r4", "cc", "memory");               \
-    _zzq_rlval = _zzq_result;                                     \
-  }
+                     /* R3 = client_request ( R4 ) */             \
+                     "orr r10, r10, r10\n\t"                      \
+                     "mov %0, r3"     /*result*/                  \
+                     : "=r" (_zzq_result)                         \
+                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
+                     : "cc","memory", "r3", "r4");                \
+    _zzq_result;                                                  \
+  })
 
 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register unsigned int __addr;                                 \
+    unsigned int __addr;                                          \
     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
+                     /* R3 = guest_NRADDR */                      \
+                     "orr r11, r11, r11\n\t"                      \
+                     "mov %0, r3"                                 \
+                     : "=r" (__addr)                              \
                      :                                            \
-                     : "r3", "cc", "memory"                       \
+                     : "cc", "memory", "r3"                       \
                     );                                            \
     _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
   }
 
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
+#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
                      __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
+                     /* branch-and-link-to-noredir *%R4 */        \
+                     "orr r12, r12, r12\n\t"
 
-#endif /* PLAT_ppc32_aix5 */
+#endif /* PLAT_arm_linux */
 
-/* ------------------------ ppc64-aix5 ------------------------- */
+/* ------------------------ s390x-linux ------------------------ */
 
-#if defined(PLAT_ppc64_aix5)
+#if defined(PLAT_s390x_linux)
 
 typedef
-   struct { 
-      uint64_t nraddr; /* where's the code? */
-      uint64_t r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
-                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST(                               \
-        _zzq_rlval, _zzq_default, _zzq_request,                   \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  {          uint64_t  _zzq_args[7];                \
-    register uint64_t  _zzq_result;                 \
-    register uint64_t* _zzq_ptr;                    \
-    _zzq_args[0] = (unsigned int long long)(_zzq_request);        \
-    _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \
-    _zzq_args[6] = (unsigned int long long)(_zzq_default);        \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 4,%1\n\t"                                \
-                     "ld 3, 48(4)\n\t"                            \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_ptr)                             \
-                     : "r3", "r4", "cc", "memory");               \
-    _zzq_rlval = _zzq_result;                                     \
+  struct {
+     uint64_t nraddr; /* where's the code? */
   }
+  OrigFn;
 
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    register uint64_t __addr;                       \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "r3", "cc", "memory"                       \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
+/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
+ * code. This detection is implemented in platform specific toIR.c
+ * (e.g. VEX/priv/guest_s390_decoder.c).
+ */
+#define __SPECIAL_INSTRUCTION_PREAMBLE                           \
+                     "lr 15,15\n\t"                              \
+                     "lr 1,1\n\t"                                \
+                     "lr 2,2\n\t"                                \
+                     "lr 3,3\n\t"
 
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
+#define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
+#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
+#define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
 
-#endif /* PLAT_ppc64_aix5 */
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
+       _zzq_default, _zzq_request,                               \
+       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
+  __extension__                                                  \
+ ({volatile uint64_t _zzq_args[6];                 \
+   volatile uint64_t _zzq_result;                  \
+   _zzq_args[0] = (uint64_t)(_zzq_request);        \
+   _zzq_args[1] = (uint64_t)(_zzq_arg1);           \
+   _zzq_args[2] = (uint64_t)(_zzq_arg2);           \
+   _zzq_args[3] = (uint64_t)(_zzq_arg3);           \
+   _zzq_args[4] = (uint64_t)(_zzq_arg4);           \
+   _zzq_args[5] = (uint64_t)(_zzq_arg5);           \
+   __asm__ volatile(/* r2 = args */                              \
+                    "lgr 2,%1\n\t"                               \
+                    /* r3 = default */                           \
+                    "lgr 3,%2\n\t"                               \
+                    __SPECIAL_INSTRUCTION_PREAMBLE               \
+                    __CLIENT_REQUEST_CODE                        \
+                    /* results = r3 */                           \
+                    "lgr %0, 3\n\t"                              \
+                    : "=d" (_zzq_result)                         \
+                    : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
+                    : "cc", "2", "3", "memory"                   \
+                   );                                            \
+   _zzq_result;                                                  \
+ })
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
+   volatile uint64_t __addr;                       \
+   __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
+                    __GET_NR_CONTEXT_CODE                        \
+                    "lgr %0, 3\n\t"                              \
+                    : "=a" (__addr)                              \
+                    :                                            \
+                    : "cc", "3", "memory"                        \
+                   );                                            \
+   _zzq_orig->nraddr = __addr;                                   \
+ }
+
+#define VALGRIND_CALL_NOREDIR_R1                                 \
+                    __SPECIAL_INSTRUCTION_PREAMBLE               \
+                    __CALL_NO_REDIR_CODE
+
+#endif /* PLAT_s390x_linux */
 
 /* Insert assembly code for other platforms here... */
 
@@ -582,11 +682,15 @@
 /* Use these to write the name of your wrapper.  NOTE: duplicates
    VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
 
+/* Use an extra level of macroisation so as to ensure the soname/fnname
+   args are fully macro-expanded before pasting them together. */
+#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
+
 #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
-   _vgwZU_##soname##_##fnname
+   VG_CONCAT4(_vgwZU_,soname,_,fnname)
 
 #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
-   _vgwZZ_##soname##_##fnname
+   VG_CONCAT4(_vgwZZ_,soname,_,fnname)
 
 /* Use this macro from within a wrapper function to collect the
    context (address and possibly other info) of the original function.
@@ -613,9 +717,25 @@
    do { volatile unsigned long _junk;                             \
         CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
 
-/* ------------------------- x86-linux ------------------------- */
+#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
+   do { volatile unsigned long _junk;                             \
+        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
 
-#if defined(PLAT_x86_linux)
+#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
+   do { volatile unsigned long _junk;                             \
+        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
+
+#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
+   do { volatile unsigned long _junk;                             \
+        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
+
+#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
+   do { volatile unsigned long _junk;                             \
+        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
+
+/* ------------------------- x86-{linux,darwin} ---------------- */
+
+#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
 
 /* These regs are trashed by the hidden call.  No need to mention eax
    as gcc can already see that, plus causes gcc to bomb. */
@@ -648,10 +768,11 @@
       _argvec[0] = (unsigned long)_orig.nraddr;                   \
       _argvec[1] = (unsigned long)(arg1);                         \
       __asm__ volatile(                                           \
+         "subl $12, %%esp\n\t"                                    \
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $4, %%esp\n"                                       \
+         "addl $16, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -668,11 +789,12 @@
       _argvec[1] = (unsigned long)(arg1);                         \
       _argvec[2] = (unsigned long)(arg2);                         \
       __asm__ volatile(                                           \
+         "subl $8, %%esp\n\t"                                     \
          "pushl 8(%%eax)\n\t"                                     \
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $8, %%esp\n"                                       \
+         "addl $16, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -690,12 +812,13 @@
       _argvec[2] = (unsigned long)(arg2);                         \
       _argvec[3] = (unsigned long)(arg3);                         \
       __asm__ volatile(                                           \
+         "subl $4, %%esp\n\t"                                     \
          "pushl 12(%%eax)\n\t"                                    \
          "pushl 8(%%eax)\n\t"                                     \
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $12, %%esp\n"                                      \
+         "addl $16, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -740,6 +863,7 @@
       _argvec[4] = (unsigned long)(arg4);                         \
       _argvec[5] = (unsigned long)(arg5);                         \
       __asm__ volatile(                                           \
+         "subl $12, %%esp\n\t"                                    \
          "pushl 20(%%eax)\n\t"                                    \
          "pushl 16(%%eax)\n\t"                                    \
          "pushl 12(%%eax)\n\t"                                    \
@@ -747,7 +871,7 @@
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $20, %%esp\n"                                      \
+         "addl $32, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -768,6 +892,7 @@
       _argvec[5] = (unsigned long)(arg5);                         \
       _argvec[6] = (unsigned long)(arg6);                         \
       __asm__ volatile(                                           \
+         "subl $8, %%esp\n\t"                                     \
          "pushl 24(%%eax)\n\t"                                    \
          "pushl 20(%%eax)\n\t"                                    \
          "pushl 16(%%eax)\n\t"                                    \
@@ -776,7 +901,7 @@
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $24, %%esp\n"                                      \
+         "addl $32, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -799,6 +924,7 @@
       _argvec[6] = (unsigned long)(arg6);                         \
       _argvec[7] = (unsigned long)(arg7);                         \
       __asm__ volatile(                                           \
+         "subl $4, %%esp\n\t"                                     \
          "pushl 28(%%eax)\n\t"                                    \
          "pushl 24(%%eax)\n\t"                                    \
          "pushl 20(%%eax)\n\t"                                    \
@@ -808,7 +934,7 @@
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $28, %%esp\n"                                      \
+         "addl $32, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -867,6 +993,7 @@
       _argvec[8] = (unsigned long)(arg8);                         \
       _argvec[9] = (unsigned long)(arg9);                         \
       __asm__ volatile(                                           \
+         "subl $12, %%esp\n\t"                                    \
          "pushl 36(%%eax)\n\t"                                    \
          "pushl 32(%%eax)\n\t"                                    \
          "pushl 28(%%eax)\n\t"                                    \
@@ -878,7 +1005,7 @@
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $36, %%esp\n"                                      \
+         "addl $48, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -904,6 +1031,7 @@
       _argvec[9] = (unsigned long)(arg9);                         \
       _argvec[10] = (unsigned long)(arg10);                       \
       __asm__ volatile(                                           \
+         "subl $8, %%esp\n\t"                                     \
          "pushl 40(%%eax)\n\t"                                    \
          "pushl 36(%%eax)\n\t"                                    \
          "pushl 32(%%eax)\n\t"                                    \
@@ -916,7 +1044,7 @@
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $40, %%esp\n"                                      \
+         "addl $48, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -944,6 +1072,7 @@
       _argvec[10] = (unsigned long)(arg10);                       \
       _argvec[11] = (unsigned long)(arg11);                       \
       __asm__ volatile(                                           \
+         "subl $4, %%esp\n\t"                                     \
          "pushl 44(%%eax)\n\t"                                    \
          "pushl 40(%%eax)\n\t"                                    \
          "pushl 36(%%eax)\n\t"                                    \
@@ -957,7 +1086,7 @@
          "pushl 4(%%eax)\n\t"                                     \
          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
          VALGRIND_CALL_NOREDIR_EAX                                \
-         "addl $44, %%esp\n"                                      \
+         "addl $48, %%esp\n"                                      \
          : /*out*/   "=a" (_res)                                  \
          : /*in*/    "a" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
@@ -1008,11 +1137,11 @@
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
 
-#endif /* PLAT_x86_linux */
+#endif /* PLAT_x86_linux || PLAT_x86_darwin */
 
-/* ------------------------ amd64-linux ------------------------ */
+/* ------------------------ amd64-{linux,darwin} --------------- */
 
-#if defined(PLAT_amd64_linux)
+#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
 
 /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
 
@@ -1020,6 +1149,78 @@
 #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
                             "rdi", "r8", "r9", "r10", "r11"
 
+/* This is all pretty complex.  It's so as to make stack unwinding
+   work reliably.  See bug 243270.  The basic problem is the sub and
+   add of 128 of %rsp in all of the following macros.  If gcc believes
+   the CFA is in %rsp, then unwinding may fail, because what's at the
+   CFA is not what gcc "expected" when it constructs the CFIs for the
+   places where the macros are instantiated.
+
+   But we can't just add a CFI annotation to increase the CFA offset
+   by 128, to match the sub of 128 from %rsp, because we don't know
+   whether gcc has chosen %rsp as the CFA at that point, or whether it
+   has chosen some other register (eg, %rbp).  In the latter case,
+   adding a CFI annotation to change the CFA offset is simply wrong.
+
+   So the solution is to get hold of the CFA using
+   __builtin_dwarf_cfa(), put it in a known register, and add a
+   CFI annotation to say what the register is.  We choose %rbp for
+   this (perhaps perversely), because:
+
+   (1) %rbp is already subject to unwinding.  If a new register was
+       chosen then the unwinder would have to unwind it in all stack
+       traces, which is expensive, and
+
+   (2) %rbp is already subject to precise exception updates in the
+       JIT.  If a new register was chosen, we'd have to have precise
+       exceptions for it too, which reduces performance of the
+       generated code.
+
+   However .. one extra complication.  We can't just whack the result
+   of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
+   list of trashed registers at the end of the inline assembly
+   fragments; gcc won't allow %rbp to appear in that list.  Hence
+   instead we need to stash %rbp in %r15 for the duration of the asm,
+   and say that %r15 is trashed instead.  gcc seems happy to go with
+   that.
+
+   Oh .. and this all needs to be conditionalised so that it is
+   unchanged from before this commit, when compiled with older gccs
+   that don't support __builtin_dwarf_cfa.  Furthermore, since
+   this header file is freestanding, it has to be independent of
+   config.h, and so the following conditionalisation cannot depend on
+   configure time checks.
+
+   Although it's not clear from
+   'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
+   this expression excludes Darwin.
+   .cfi directives in Darwin assembly appear to be completely
+   different and I haven't investigated how they work.
+
+   For even more entertainment value, note we have to use the
+   completely undocumented __builtin_dwarf_cfa(), which appears to
+   really compute the CFA, whereas __builtin_frame_address(0) claims
+   to but actually doesn't.  See
+   https://bugs.kde.org/show_bug.cgi?id=243270#c47
+*/
+#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
+#  define __FRAME_POINTER                                         \
+      ,"r"(__builtin_dwarf_cfa())
+#  define VALGRIND_CFI_PROLOGUE                                   \
+      "movq %%rbp, %%r15\n\t"                                     \
+      "movq %2, %%rbp\n\t"                                        \
+      ".cfi_remember_state\n\t"                                   \
+      ".cfi_def_cfa rbp, 0\n\t"
+#  define VALGRIND_CFI_EPILOGUE                                   \
+      "movq %%r15, %%rbp\n\t"                                     \
+      ".cfi_restore_state\n\t"
+#else
+#  define __FRAME_POINTER
+#  define VALGRIND_CFI_PROLOGUE
+#  define VALGRIND_CFI_EPILOGUE
+#endif
+
+
 /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
    long) == 8. */
 
@@ -1039,7 +1240,7 @@
    redzone, for the duration of the hidden call, to make it safe.
 
    Probably the same problem afflicts the other redzone-style ABIs too
-   (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
+   (ppc64-linux); but for those, the stack is
    self describing (none of this CFI nonsense) so at least messing
    with the stack pointer doesn't give a danger of non-unwindable
    stack. */
@@ -1051,13 +1252,15 @@
       volatile unsigned long _res;                                \
       _argvec[0] = (unsigned long)_orig.nraddr;                   \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1070,14 +1273,16 @@
       _argvec[0] = (unsigned long)_orig.nraddr;                   \
       _argvec[1] = (unsigned long)(arg1);                         \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "movq 8(%%rax), %%rdi\n\t"                               \
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1091,15 +1296,17 @@
       _argvec[1] = (unsigned long)(arg1);                         \
       _argvec[2] = (unsigned long)(arg2);                         \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "movq 16(%%rax), %%rsi\n\t"                              \
          "movq 8(%%rax), %%rdi\n\t"                               \
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1114,6 +1321,7 @@
       _argvec[2] = (unsigned long)(arg2);                         \
       _argvec[3] = (unsigned long)(arg3);                         \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "movq 24(%%rax), %%rdx\n\t"                              \
          "movq 16(%%rax), %%rsi\n\t"                              \
@@ -1121,9 +1329,10 @@
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1139,6 +1348,7 @@
       _argvec[3] = (unsigned long)(arg3);                         \
       _argvec[4] = (unsigned long)(arg4);                         \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "movq 32(%%rax), %%rcx\n\t"                              \
          "movq 24(%%rax), %%rdx\n\t"                              \
@@ -1147,9 +1357,10 @@
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1166,6 +1377,7 @@
       _argvec[4] = (unsigned long)(arg4);                         \
       _argvec[5] = (unsigned long)(arg5);                         \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "movq 40(%%rax), %%r8\n\t"                               \
          "movq 32(%%rax), %%rcx\n\t"                              \
@@ -1175,9 +1387,10 @@
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1195,6 +1408,7 @@
       _argvec[5] = (unsigned long)(arg5);                         \
       _argvec[6] = (unsigned long)(arg6);                         \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "movq 48(%%rax), %%r9\n\t"                               \
          "movq 40(%%rax), %%r8\n\t"                               \
@@ -1203,11 +1417,12 @@
          "movq 16(%%rax), %%rsi\n\t"                              \
          "movq 8(%%rax), %%rdi\n\t"                               \
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
-         "addq $128,%%rsp\n\t"                                    \
          VALGRIND_CALL_NOREDIR_RAX                                \
+         "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1227,7 +1442,8 @@
       _argvec[6] = (unsigned long)(arg6);                         \
       _argvec[7] = (unsigned long)(arg7);                         \
       __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_PROLOGUE                                    \
+         "subq $136,%%rsp\n\t"                                    \
          "pushq 56(%%rax)\n\t"                                    \
          "movq 48(%%rax), %%r9\n\t"                               \
          "movq 40(%%rax), %%r8\n\t"                               \
@@ -1238,10 +1454,11 @@
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $8, %%rsp\n"                                       \
-         "addq $128,%%rsp\n\t"                                    \
+         "addq $136,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1262,6 +1479,7 @@
       _argvec[7] = (unsigned long)(arg7);                         \
       _argvec[8] = (unsigned long)(arg8);                         \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "pushq 64(%%rax)\n\t"                                    \
          "pushq 56(%%rax)\n\t"                                    \
@@ -1275,9 +1493,10 @@
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $16, %%rsp\n"                                      \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1299,7 +1518,8 @@
       _argvec[8] = (unsigned long)(arg8);                         \
       _argvec[9] = (unsigned long)(arg9);                         \
       __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_PROLOGUE                                    \
+         "subq $136,%%rsp\n\t"                                    \
          "pushq 72(%%rax)\n\t"                                    \
          "pushq 64(%%rax)\n\t"                                    \
          "pushq 56(%%rax)\n\t"                                    \
@@ -1312,10 +1532,11 @@
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $24, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
+         "addq $136,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1338,6 +1559,7 @@
       _argvec[9] = (unsigned long)(arg9);                         \
       _argvec[10] = (unsigned long)(arg10);                       \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "pushq 80(%%rax)\n\t"                                    \
          "pushq 72(%%rax)\n\t"                                    \
@@ -1353,9 +1575,10 @@
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $32, %%rsp\n"                                      \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1379,7 +1602,8 @@
       _argvec[10] = (unsigned long)(arg10);                       \
       _argvec[11] = (unsigned long)(arg11);                       \
       __asm__ volatile(                                           \
-         "subq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_PROLOGUE                                    \
+         "subq $136,%%rsp\n\t"                                    \
          "pushq 88(%%rax)\n\t"                                    \
          "pushq 80(%%rax)\n\t"                                    \
          "pushq 72(%%rax)\n\t"                                    \
@@ -1394,10 +1618,11 @@
          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $40, %%rsp\n"                                      \
-         "addq $128,%%rsp\n\t"                                    \
+         "addq $136,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -1422,6 +1647,7 @@
       _argvec[11] = (unsigned long)(arg11);                       \
       _argvec[12] = (unsigned long)(arg12);                       \
       __asm__ volatile(                                           \
+         VALGRIND_CFI_PROLOGUE                                    \
          "subq $128,%%rsp\n\t"                                    \
          "pushq 96(%%rax)\n\t"                                    \
          "pushq 88(%%rax)\n\t"                                    \
@@ -1439,14 +1665,15 @@
          VALGRIND_CALL_NOREDIR_RAX                                \
          "addq $48, %%rsp\n"                                      \
          "addq $128,%%rsp\n\t"                                    \
+         VALGRIND_CFI_EPILOGUE                                    \
          : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
 
-#endif /* PLAT_amd64_linux */
+#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
 
 /* ------------------------ ppc32-linux ------------------------ */
 
@@ -2439,54 +2666,28 @@
 
 #endif /* PLAT_ppc64_linux */
 
-/* ------------------------ ppc32-aix5 ------------------------- */
+/* ------------------------- arm-linux ------------------------- */
 
-#if defined(PLAT_ppc32_aix5)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
+#if defined(PLAT_arm_linux)
 
 /* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
+#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
 
-/* Expand the stack frame, copying enough info that unwinding
-   still works.  Trashes r3. */
-
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
-         "addi 1,1,-" #_n_fr "\n\t"                               \
-         "lwz  3," #_n_fr "(1)\n\t"                               \
-         "stw  3,0(1)\n\t"
-
-#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
-         "addi 1,1," #_n_fr "\n\t"
-
-/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
+/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
    long) == 4. */
 
 #define CALL_FN_W_v(lval, orig)                                   \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
+      volatile unsigned long _argvec[1];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "mov %0, r0\n"                                           \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2495,27 +2696,18 @@
 #define CALL_FN_W_W(lval, orig, arg1)                             \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
+      volatile unsigned long _argvec[2];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "mov %0, r0\n"                                           \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "0" (&_argvec[0])                            \
+         : /*trash*/ "cc", "memory",  __CALLER_SAVED_REGS         \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
@@ -2523,28 +2715,19 @@
 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
+      volatile unsigned long _argvec[3];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "mov %0, r0\n"                                           \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2553,30 +2736,21 @@
 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
+      volatile unsigned long _argvec[4];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "mov %0, r0\n"                                           \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2585,32 +2759,23 @@
 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
+      volatile unsigned long _argvec[5];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2619,34 +2784,27 @@
 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
+      volatile unsigned long _argvec[6];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t" /* arg2->r4 */                       \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "push {r0} \n\t"                                         \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #4 \n\t"                                    \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2655,36 +2813,29 @@
 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
+      volatile unsigned long _argvec[7];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
+      _argvec[6] = (unsigned long)(arg6);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "ldr r1, [%1, #24] \n\t"                                 \
+         "push {r0, r1} \n\t"                                     \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #8 \n\t"                                    \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2694,38 +2845,31 @@
                                  arg7)                            \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
+      volatile unsigned long _argvec[8];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
+      _argvec[6] = (unsigned long)(arg6);                         \
+      _argvec[7] = (unsigned long)(arg7);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "ldr r1, [%1, #24] \n\t"                                 \
+         "ldr r2, [%1, #28] \n\t"                                 \
+         "push {r0, r1, r2} \n\t"                                 \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #12 \n\t"                                   \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2735,40 +2879,33 @@
                                  arg7,arg8)                       \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
+      volatile unsigned long _argvec[9];                          \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
+      _argvec[6] = (unsigned long)(arg6);                         \
+      _argvec[7] = (unsigned long)(arg7);                         \
+      _argvec[8] = (unsigned long)(arg8);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "ldr r1, [%1, #24] \n\t"                                 \
+         "ldr r2, [%1, #28] \n\t"                                 \
+         "ldr r3, [%1, #32] \n\t"                                 \
+         "push {r0, r1, r2, r3} \n\t"                             \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #16 \n\t"                                   \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2778,47 +2915,35 @@
                                  arg7,arg8,arg9)                  \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
+      volatile unsigned long _argvec[10];                         \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
+      _argvec[6] = (unsigned long)(arg6);                         \
+      _argvec[7] = (unsigned long)(arg7);                         \
+      _argvec[8] = (unsigned long)(arg8);                         \
+      _argvec[9] = (unsigned long)(arg9);                         \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(64)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "ldr r1, [%1, #24] \n\t"                                 \
+         "ldr r2, [%1, #28] \n\t"                                 \
+         "ldr r3, [%1, #32] \n\t"                                 \
+         "ldr r4, [%1, #36] \n\t"                                 \
+         "push {r0, r1, r2, r3, r4} \n\t"                         \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #20 \n\t"                                   \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
@@ -2828,738 +2953,612 @@
                                   arg7,arg8,arg9,arg10)           \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
+      volatile unsigned long _argvec[11];                         \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
+      _argvec[6] = (unsigned long)(arg6);                         \
+      _argvec[7] = (unsigned long)(arg7);                         \
+      _argvec[8] = (unsigned long)(arg8);                         \
+      _argvec[9] = (unsigned long)(arg9);                         \
+      _argvec[10] = (unsigned long)(arg10);                       \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(64)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #40] \n\t"                                 \
+         "push {r0} \n\t"                                         \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "ldr r1, [%1, #24] \n\t"                                 \
+         "ldr r2, [%1, #28] \n\t"                                 \
+         "ldr r3, [%1, #32] \n\t"                                 \
+         "ldr r4, [%1, #36] \n\t"                                 \
+         "push {r0, r1, r2, r3, r4} \n\t"                         \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #24 \n\t"                                   \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
 
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
+                                  arg6,arg7,arg8,arg9,arg10,      \
+                                  arg11)                          \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
+      volatile unsigned long _argvec[12];                         \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
+      _argvec[6] = (unsigned long)(arg6);                         \
+      _argvec[7] = (unsigned long)(arg7);                         \
+      _argvec[8] = (unsigned long)(arg8);                         \
+      _argvec[9] = (unsigned long)(arg9);                         \
+      _argvec[10] = (unsigned long)(arg10);                       \
+      _argvec[11] = (unsigned long)(arg11);                       \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,64(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(72)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #40] \n\t"                                 \
+         "ldr r1, [%1, #44] \n\t"                                 \
+         "push {r0, r1} \n\t"                                     \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "ldr r1, [%1, #24] \n\t"                                 \
+         "ldr r2, [%1, #28] \n\t"                                 \
+         "ldr r3, [%1, #32] \n\t"                                 \
+         "ldr r4, [%1, #36] \n\t"                                 \
+         "push {r0, r1, r2, r3, r4} \n\t"                         \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #28 \n\t"                                   \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
+         : /*in*/    "0" (&_argvec[0])                            \
+         : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS           \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
 
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
+                                  arg6,arg7,arg8,arg9,arg10,      \
+                                  arg11,arg12)                    \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
+      volatile unsigned long _argvec[13];                         \
       volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
+      _argvec[0] = (unsigned long)_orig.nraddr;                   \
+      _argvec[1] = (unsigned long)(arg1);                         \
+      _argvec[2] = (unsigned long)(arg2);                         \
+      _argvec[3] = (unsigned long)(arg3);                         \
+      _argvec[4] = (unsigned long)(arg4);                         \
+      _argvec[5] = (unsigned long)(arg5);                         \
+      _argvec[6] = (unsigned long)(arg6);                         \
+      _argvec[7] = (unsigned long)(arg7);                         \
+      _argvec[8] = (unsigned long)(arg8);                         \
+      _argvec[9] = (unsigned long)(arg9);                         \
+      _argvec[10] = (unsigned long)(arg10);                       \
+      _argvec[11] = (unsigned long)(arg11);                       \
+      _argvec[12] = (unsigned long)(arg12);                       \
       __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
-         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
-         /* arg12 */                                              \
-         "lwz 3,48(11)\n\t"                                       \
-         "stw 3,68(1)\n\t"                                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,64(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,60(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,56(1)\n\t"                                        \
-         /* args1-8 */                                            \
-         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
-         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
-         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
-         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
-         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
-         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
-         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
-         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
-         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(72)                                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
+         "ldr r0, [%1, #40] \n\t"                                 \
+         "ldr r1, [%1, #44] \n\t"                                 \
+         "ldr r2, [%1, #48] \n\t"                                 \
+         "push {r0, r1, r2} \n\t"                                 \
+         "ldr r0, [%1, #20] \n\t"                                 \
+         "ldr r1, [%1, #24] \n\t"                                 \
+         "ldr r2, [%1, #28] \n\t"                                 \
+         "ldr r3, [%1, #32] \n\t"                                 \
+         "ldr r4, [%1, #36] \n\t"                                 \
+         "push {r0, r1, r2, r3, r4} \n\t"                         \
+         "ldr r0, [%1, #4] \n\t"                                  \
+         "ldr r1, [%1, #8] \n\t"                                  \
+         "ldr r2, [%1, #12] \n\t"                                 \
+         "ldr r3, [%1, #16] \n\t"                                 \
+         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
+         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
+         "add sp, sp, #32 \n\t"                                   \
+         "mov %0, r0"                                             \
          : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
+         : /*in*/    "0" (&_argvec[0])                            \
          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
       );                                                          \
       lval = (__typeof__(lval)) _res;                             \
    } while (0)
 
-#endif /* PLAT_ppc32_aix5 */
+#endif /* PLAT_arm_linux */
 
-/* ------------------------ ppc64-aix5 ------------------------- */
+/* ------------------------- s390x-linux ------------------------- */
 
-#if defined(PLAT_ppc64_aix5)
+#if defined(PLAT_s390x_linux)
 
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
+/* Similar workaround as amd64 (see above), but we use r11 as frame
+   pointer and save the old r11 in r7. r11 might be used for
+   argvec, therefore we copy argvec in r1 since r1 is clobbered
+   after the call anyway.  */
+#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
+#  define __FRAME_POINTER                                         \
+      ,"d"(__builtin_dwarf_cfa())
+#  define VALGRIND_CFI_PROLOGUE                                   \
+      ".cfi_remember_state\n\t"                                   \
+      "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
+      "lgr 7,11\n\t"                                              \
+      "lgr 11,%2\n\t"                                             \
+      ".cfi_def_cfa r11, 0\n\t"
+#  define VALGRIND_CFI_EPILOGUE                                   \
+      "lgr 11, 7\n\t"                                             \
+      ".cfi_restore_state\n\t"
+#else
+#  define __FRAME_POINTER
+#  define VALGRIND_CFI_PROLOGUE                                   \
+      "lgr 1,%1\n\t"
+#  define VALGRIND_CFI_EPILOGUE
+#endif
 
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
 
-/* Expand the stack frame, copying enough info that unwinding
-   still works.  Trashes r3. */
 
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
-         "addi 1,1,-" #_n_fr "\n\t"                               \
-         "ld   3," #_n_fr "(1)\n\t"                               \
-         "std  3,0(1)\n\t"
 
-#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
-         "addi 1,1," #_n_fr "\n\t"
+/* These regs are trashed by the hidden call. Note that we overwrite
+   r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
+   function a proper return address. All others are ABI defined call
+   clobbers. */
+#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
+                           "f0","f1","f2","f3","f4","f5","f6","f7"
 
-/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
-   long) == 8. */
 
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_v(lval, orig)                                  \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long  _argvec[1];                        \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-160\n\t"                                      \
+         "lg 1, 0(1)\n\t"  /* target->r1 */                      \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,160\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+/* The call abi has the arguments in r2-r6 and stack */
+#define CALL_FN_W_W(lval, orig, arg1)                            \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[2];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-160\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,160\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[3];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-160\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,160\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[4];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-160\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,160\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[5];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-160\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,160\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[6];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-160\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,160\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
+                     arg6)                                       \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[7];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      _argvec[6] = (unsigned long)arg6;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-168\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "mvc 160(8,15), 48(1)\n\t"                              \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,168\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
+                     arg6, arg7)                                 \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[8];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      _argvec[6] = (unsigned long)arg6;                          \
+      _argvec[7] = (unsigned long)arg7;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-176\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "mvc 160(8,15), 48(1)\n\t"                              \
+         "mvc 168(8,15), 56(1)\n\t"                              \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,176\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
+                     arg6, arg7 ,arg8)                           \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[9];                         \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      _argvec[6] = (unsigned long)arg6;                          \
+      _argvec[7] = (unsigned long)arg7;                          \
+      _argvec[8] = (unsigned long)arg8;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-184\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "mvc 160(8,15), 48(1)\n\t"                              \
+         "mvc 168(8,15), 56(1)\n\t"                              \
+         "mvc 176(8,15), 64(1)\n\t"                              \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,184\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(128)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
+                     arg6, arg7 ,arg8, arg9)                     \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[10];                        \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      _argvec[6] = (unsigned long)arg6;                          \
+      _argvec[7] = (unsigned long)arg7;                          \
+      _argvec[8] = (unsigned long)arg8;                          \
+      _argvec[9] = (unsigned long)arg9;                          \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-192\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "mvc 160(8,15), 48(1)\n\t"                              \
+         "mvc 168(8,15), 56(1)\n\t"                              \
+         "mvc 176(8,15), 64(1)\n\t"                              \
+         "mvc 184(8,15), 72(1)\n\t"                              \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,192\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(128)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
+                     arg6, arg7 ,arg8, arg9, arg10)              \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[11];                        \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      _argvec[6] = (unsigned long)arg6;                          \
+      _argvec[7] = (unsigned long)arg7;                          \
+      _argvec[8] = (unsigned long)arg8;                          \
+      _argvec[9] = (unsigned long)arg9;                          \
+      _argvec[10] = (unsigned long)arg10;                        \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-200\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "mvc 160(8,15), 48(1)\n\t"                              \
+         "mvc 168(8,15), 56(1)\n\t"                              \
+         "mvc 176(8,15), 64(1)\n\t"                              \
+         "mvc 184(8,15), 72(1)\n\t"                              \
+         "mvc 192(8,15), 80(1)\n\t"                              \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,200\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(144)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
+                     arg6, arg7 ,arg8, arg9, arg10, arg11)       \
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[12];                        \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      _argvec[6] = (unsigned long)arg6;                          \
+      _argvec[7] = (unsigned long)arg7;                          \
+      _argvec[8] = (unsigned long)arg8;                          \
+      _argvec[9] = (unsigned long)arg9;                          \
+      _argvec[10] = (unsigned long)arg10;                        \
+      _argvec[11] = (unsigned long)arg11;                        \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-208\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "mvc 160(8,15), 48(1)\n\t"                              \
+         "mvc 168(8,15), 56(1)\n\t"                              \
+         "mvc 176(8,15), 64(1)\n\t"                              \
+         "mvc 184(8,15), 72(1)\n\t"                              \
+         "mvc 192(8,15), 80(1)\n\t"                              \
+         "mvc 200(8,15), 88(1)\n\t"                              \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,208\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         "mr 11,%1\n\t"                                           \
-         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
-         "std  2,-16(11)\n\t" /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
-         /* arg12 */                                              \
-         "ld  3,96(11)\n\t"                                       \
-         "std 3,136(1)\n\t"                                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
-         VG_CONTRACT_FRAME_BY(144)                                \
-         VG_CONTRACT_FRAME_BY(512)                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
+#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
+                     arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
+   do {                                                          \
+      volatile OrigFn        _orig = (orig);                     \
+      volatile unsigned long _argvec[13];                        \
+      volatile unsigned long _res;                               \
+      _argvec[0] = (unsigned long)_orig.nraddr;                  \
+      _argvec[1] = (unsigned long)arg1;                          \
+      _argvec[2] = (unsigned long)arg2;                          \
+      _argvec[3] = (unsigned long)arg3;                          \
+      _argvec[4] = (unsigned long)arg4;                          \
+      _argvec[5] = (unsigned long)arg5;                          \
+      _argvec[6] = (unsigned long)arg6;                          \
+      _argvec[7] = (unsigned long)arg7;                          \
+      _argvec[8] = (unsigned long)arg8;                          \
+      _argvec[9] = (unsigned long)arg9;                          \
+      _argvec[10] = (unsigned long)arg10;                        \
+      _argvec[11] = (unsigned long)arg11;                        \
+      _argvec[12] = (unsigned long)arg12;                        \
+      __asm__ volatile(                                          \
+         VALGRIND_CFI_PROLOGUE                                   \
+         "aghi 15,-216\n\t"                                      \
+         "lg 2, 8(1)\n\t"                                        \
+         "lg 3,16(1)\n\t"                                        \
+         "lg 4,24(1)\n\t"                                        \
+         "lg 5,32(1)\n\t"                                        \
+         "lg 6,40(1)\n\t"                                        \
+         "mvc 160(8,15), 48(1)\n\t"                              \
+         "mvc 168(8,15), 56(1)\n\t"                              \
+         "mvc 176(8,15), 64(1)\n\t"                              \
+         "mvc 184(8,15), 72(1)\n\t"                              \
+         "mvc 192(8,15), 80(1)\n\t"                              \
+         "mvc 200(8,15), 88(1)\n\t"                              \
+         "mvc 208(8,15), 96(1)\n\t"                              \
+         "lg 1, 0(1)\n\t"                                        \
+         VALGRIND_CALL_NOREDIR_R1                                \
+         "lgr %0, 2\n\t"                                         \
+         "aghi 15,216\n\t"                                       \
+         VALGRIND_CFI_EPILOGUE                                   \
+         : /*out*/   "=d" (_res)                                 \
+         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
+         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
+      );                                                         \
+      lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-#endif /* PLAT_ppc64_aix5 */
+
+#endif /* PLAT_s390x_linux */
 
 
 /* ------------------------------------------------------------------ */
@@ -3605,9 +3604,14 @@
              errors. */
           VG_USERREQ__COUNT_ERRORS = 0x1201,
 
+          /* Allows a string (gdb monitor command) to be passed to the tool
+             Used for interaction with vgdb/gdb */
+          VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
+
           /* These are useful and can be interpreted by any tool that
              tracks malloc() et al, by using vg_replace_malloc.c. */
           VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
+          VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
           VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
           /* Memory pool support. */
           VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
@@ -3620,30 +3624,43 @@
           VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
 
           /* Allow printfs to valgrind log. */
+          /* The first two pass the va_list argument by value, which
+             assumes it is the same size as or smaller than a UWord,
+             which generally isn't the case.  Hence are deprecated.
+             The second two pass the vargs by reference and so are
+             immune to this problem. */
+          /* both :: char* fmt, va_list vargs (DEPRECATED) */
           VG_USERREQ__PRINTF           = 0x1401,
           VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
+          /* both :: char* fmt, va_list* vargs */
+          VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
+          VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
 
           /* Stack support. */
           VG_USERREQ__STACK_REGISTER   = 0x1501,
           VG_USERREQ__STACK_DEREGISTER = 0x1502,
-          VG_USERREQ__STACK_CHANGE     = 0x1503
+          VG_USERREQ__STACK_CHANGE     = 0x1503,
+
+          /* Wine support */
+          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
+
+          /* Querying of debug info. */
+          VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701
    } Vg_ClientRequest;
 
 #if !defined(__GNUC__)
 #  define __extension__ /* */
 #endif
 
+
 /* Returns the number of Valgrinds this code is running under.  That
    is, 0 if running natively, 1 if running under Valgrind, 2 if
    running under Valgrind which is running under another Valgrind,
    etc. */
-#define RUNNING_ON_VALGRIND  __extension__                        \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */,          \
-                               VG_USERREQ__RUNNING_ON_VALGRIND,   \
-                               0, 0, 0, 0, 0);                    \
-    _qzz_res;                                                     \
-   })
+#define RUNNING_ON_VALGRIND                                           \
+    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
+                                    VG_USERREQ__RUNNING_ON_VALGRIND,  \
+                                    0, 0, 0, 0, 0)                    \
 
 
 /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
@@ -3651,56 +3668,93 @@
    since it provides a way to make sure valgrind will retranslate the
    invalidated area.  Returns no value. */
 #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
                                VG_USERREQ__DISCARD_TRANSLATIONS,  \
-                               _qzz_addr, _qzz_len, 0, 0, 0);     \
-   }
+                               _qzz_addr, _qzz_len, 0, 0, 0)
 
 
 /* These requests are for getting Valgrind itself to print something.
-   Possibly with a backtrace.  This is a really ugly hack. */
+   Possibly with a backtrace.  This is a really ugly hack.  The return value
+   is the number of characters printed, excluding the "**<pid>** " part at the
+   start and the backtrace (if present). */
 
-#if defined(NVALGRIND)
-
-#  define VALGRIND_PRINTF(...)
-#  define VALGRIND_PRINTF_BACKTRACE(...)
-
-#else /* NVALGRIND */
-
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
 /* Modern GCC will optimize the static routine out if unused,
    and unused attribute will shut down warnings about it.  */
 static int VALGRIND_PRINTF(const char *format, ...)
    __attribute__((format(__printf__, 1, 2), __unused__));
+#endif
 static int
+#if defined(_MSC_VER)
+__inline
+#endif
 VALGRIND_PRINTF(const char *format, ...)
 {
+#if defined(NVALGRIND)
+   return 0;
+#else /* NVALGRIND */
+#if defined(_MSC_VER)
+   uintptr_t _qzz_res;
+#else
    unsigned long _qzz_res;
+#endif
    va_list vargs;
    va_start(vargs, format);
-   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
-                              (unsigned long)format, (unsigned long)vargs, 
+#if defined(_MSC_VER)
+   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
+                              VG_USERREQ__PRINTF_VALIST_BY_REF,
+                              (uintptr_t)format,
+                              (uintptr_t)&vargs,
                               0, 0, 0);
+#else
+   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
+                              VG_USERREQ__PRINTF_VALIST_BY_REF,
+                              (unsigned long)format,
+                              (unsigned long)&vargs, 
+                              0, 0, 0);
+#endif
    va_end(vargs);
    return (int)_qzz_res;
+#endif /* NVALGRIND */
 }
 
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
 static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
    __attribute__((format(__printf__, 1, 2), __unused__));
+#endif
 static int
+#if defined(_MSC_VER)
+__inline
+#endif
 VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
 {
+#if defined(NVALGRIND)
+   return 0;
+#else /* NVALGRIND */
+#if defined(_MSC_VER)
+   uintptr_t _qzz_res;
+#else
    unsigned long _qzz_res;
+#endif
    va_list vargs;
    va_start(vargs, format);
-   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
-                              (unsigned long)format, (unsigned long)vargs, 
+#if defined(_MSC_VER)
+   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
+                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
+                              (uintptr_t)format,
+                              (uintptr_t)&vargs,
                               0, 0, 0);
+#else
+   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
+                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
+                              (unsigned long)format,
+                              (unsigned long)&vargs, 
+                              0, 0, 0);
+#endif
    va_end(vargs);
    return (int)_qzz_res;
-}
-
 #endif /* NVALGRIND */
+}
 
 
 /* These requests allow control to move from the simulated CPU to the
@@ -3727,199 +3781,253 @@
    with a lot in the past.
 */
 #define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL0,          \
-                               _qyy_fn,                           \
-                               0, 0, 0, 0);                       \
-    _qyy_res;                                                     \
-   })
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
+                                    VG_USERREQ__CLIENT_CALL0,     \
+                                    _qyy_fn,                      \
+                                    0, 0, 0, 0)
 
-#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL1,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, 0, 0, 0);               \
-    _qyy_res;                                                     \
-   })
+#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
+                                    VG_USERREQ__CLIENT_CALL1,          \
+                                    _qyy_fn,                           \
+                                    _qyy_arg1, 0, 0, 0)
 
-#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL2,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, _qyy_arg2, 0, 0);       \
-    _qyy_res;                                                     \
-   })
+#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
+                                    VG_USERREQ__CLIENT_CALL2,          \
+                                    _qyy_fn,                           \
+                                    _qyy_arg1, _qyy_arg2, 0, 0)
 
 #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
-   __extension__                                                  \
-   ({unsigned long _qyy_res;                                      \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
-                               VG_USERREQ__CLIENT_CALL3,          \
-                               _qyy_fn,                           \
-                               _qyy_arg1, _qyy_arg2,              \
-                               _qyy_arg3, 0);                     \
-    _qyy_res;                                                     \
-   })
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
+                                    VG_USERREQ__CLIENT_CALL3,           \
+                                    _qyy_fn,                            \
+                                    _qyy_arg1, _qyy_arg2,               \
+                                    _qyy_arg3, 0)
 
 
 /* Counts the number of errors that have been recorded by a tool.  Nb:
    the tool must record the errors with VG_(maybe_record_error)() or
    VG_(unique_error)() for them to be counted. */
 #define VALGRIND_COUNT_ERRORS                                     \
-   __extension__                                                  \
-   ({unsigned int _qyy_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
+    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
+                               0 /* default return */,            \
                                VG_USERREQ__COUNT_ERRORS,          \
-                               0, 0, 0, 0, 0);                    \
-    _qyy_res;                                                     \
-   })
+                               0, 0, 0, 0, 0)
 
-/* Mark a block of memory as having been allocated by a malloc()-like
-   function.  `addr' is the start of the usable block (ie. after any
-   redzone) `rzB' is redzone size if the allocator can apply redzones;
-   use '0' if not.  Adding redzones makes it more likely Valgrind will spot
-   block overruns.  `is_zeroed' indicates if the memory is zeroed, as it is
-   for calloc().  Put it immediately after the point where a block is
-   allocated. 
+/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
+   when heap blocks are allocated in order to give accurate results.  This
+   happens automatically for the standard allocator functions such as
+   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
+   delete[], etc.
+
+   But if your program uses a custom allocator, this doesn't automatically
+   happen, and Valgrind will not do as well.  For example, if you allocate
+   superblocks with mmap() and then allocates chunks of the superblocks, all
+   Valgrind's observations will be at the mmap() level and it won't know that
+   the chunks should be considered separate entities.  In Memcheck's case,
+   that means you probably won't get heap block overrun detection (because
+   there won't be redzones marked as unaddressable) and you definitely won't
+   get any leak detection.
+
+   The following client requests allow a custom allocator to be annotated so
+   that it can be handled accurately by Valgrind.
+
+   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
+   by a malloc()-like function.  For Memcheck (an illustrative case), this
+   does two things:
+
+   - It records that the block has been allocated.  This means any addresses
+     within the block mentioned in error messages will be
+     identified as belonging to the block.  It also means that if the block
+     isn't freed it will be detected by the leak checker.
+
+   - It marks the block as being addressable and undefined (if 'is_zeroed' is
+     not set), or addressable and defined (if 'is_zeroed' is set).  This
+     controls how accesses to the block by the program are handled.
    
-   If you're using Memcheck: If you're allocating memory via superblocks,
-   and then handing out small chunks of each superblock, if you don't have
-   redzones on your small blocks, it's worth marking the superblock with
-   VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are
-   detected.  But if you can put redzones on, it's probably better to not do
-   this, so that messages for small overruns are described in terms of the
-   small block rather than the superblock (but if you have a big overrun
-   that skips over a redzone, you could miss an error this way).  See
-   memcheck/tests/custom_alloc.c for an example.
+   'addr' is the start of the usable block (ie. after any
+   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
+   can apply redzones -- these are blocks of padding at the start and end of
+   each block.  Adding redzones is recommended as it makes it much more likely
+   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
+   zeroed (or filled with another predictable value), as is the case for
+   calloc().
+   
+   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
+   heap block -- that will be used by the client program -- is allocated.
+   It's best to put it at the outermost level of the allocator if possible;
+   for example, if you have a function my_alloc() which calls
+   internal_alloc(), and the client request is put inside internal_alloc(),
+   stack traces relating to the heap block will contain entries for both
+   my_alloc() and internal_alloc(), which is probably not what you want.
 
-   WARNING: if your allocator uses malloc() or 'new' to allocate
-   superblocks, rather than mmap() or brk(), this will not work properly --
-   you'll likely get assertion failures during leak detection.  This is
-   because Valgrind doesn't like seeing overlapping heap blocks.  Sorry.
+   For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
+   custom blocks from within a heap block, B, that has been allocated with
+   malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
+   -- the custom blocks will take precedence.
 
-   Nb: block must be freed via a free()-like function specified
-   with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
+   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
+   Memcheck, it does two things:
+
+   - It records that the block has been deallocated.  This assumes that the
+     block was annotated as having been allocated via
+     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
+
+   - It marks the block as being unaddressable.
+
+   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
+   heap block is deallocated.
+
+   VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
+   Memcheck, it does four things:
+
+   - It records that the size of a block has been changed.  This assumes that
+     the block was annotated as having been allocated via
+     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
+
+   - If the block shrunk, it marks the freed memory as being unaddressable.
+
+   - If the block grew, it marks the new area as undefined and defines a red
+     zone past the end of the new block.
+
+   - The V-bits of the overlap between the old and the new block are preserved.
+
+   VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
+   and before deallocation of the old block.
+
+   In many cases, these three client requests will not be enough to get your
+   allocator working well with Memcheck.  More specifically, if your allocator
+   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
+   will be necessary to mark the memory as addressable just before the zeroing
+   occurs, otherwise you'll get a lot of invalid write errors.  For example,
+   you'll need to do this if your allocator recycles freed blocks, but it
+   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
+   Alternatively, if your allocator reuses freed blocks for allocator-internal
+   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
+
+   Really, what's happening is a blurring of the lines between the client
+   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
+   memory should be considered unaddressable to the client program, but the
+   allocator knows more than the rest of the client program and so may be able
+   to safely access it.  Extra client requests are necessary for Valgrind to
+   understand the distinction between the allocator and the rest of the
+   program.
+
+   Ignored if addr == 0.
+*/
 #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__MALLOCLIKE_BLOCK,      \
-                               addr, sizeB, rzB, is_zeroed, 0);   \
-   }
+                               addr, sizeB, rzB, is_zeroed, 0)
 
-/* Mark a block of memory as having been freed by a free()-like function.
-   `rzB' is redzone size;  it must match that given to
-   VALGRIND_MALLOCLIKE_BLOCK.  Memory not freed will be detected by the leak
-   checker.  Put it immediately after the point where the block is freed. */
+/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
+   Ignored if addr == 0.
+*/
+#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
+                               VG_USERREQ__RESIZEINPLACE_BLOCK,   \
+                               addr, oldSizeB, newSizeB, rzB, 0)
+
+/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
+   Ignored if addr == 0.
+*/
 #define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__FREELIKE_BLOCK,        \
-                               addr, rzB, 0, 0, 0);               \
-   }
+                               addr, rzB, 0, 0, 0)
 
 /* Create a memory pool. */
 #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__CREATE_MEMPOOL,        \
-                               pool, rzB, is_zeroed, 0, 0);       \
-   }
+                               pool, rzB, is_zeroed, 0, 0)
 
 /* Destroy a memory pool. */
 #define VALGRIND_DESTROY_MEMPOOL(pool)                            \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__DESTROY_MEMPOOL,       \
-                               pool, 0, 0, 0, 0);                 \
-   }
+                               pool, 0, 0, 0, 0)
 
 /* Associate a piece of memory with a memory pool. */
 #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__MEMPOOL_ALLOC,         \
-                               pool, addr, size, 0, 0);           \
-   }
+                               pool, addr, size, 0, 0)
 
 /* Disassociate a piece of memory from a memory pool. */
 #define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__MEMPOOL_FREE,          \
-                               pool, addr, 0, 0, 0);              \
-   }
+                               pool, addr, 0, 0, 0)
 
 /* Disassociate any pieces outside a particular range. */
 #define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__MEMPOOL_TRIM,          \
-                               pool, addr, size, 0, 0);           \
-   }
+                               pool, addr, size, 0, 0)
 
 /* Resize and/or move a piece associated with a memory pool. */
 #define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__MOVE_MEMPOOL,          \
-                               poolA, poolB, 0, 0, 0);            \
-   }
+                               poolA, poolB, 0, 0, 0)
 
 /* Resize and/or move a piece associated with a memory pool. */
 #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__MEMPOOL_CHANGE,        \
-                               pool, addrA, addrB, size, 0);      \
-   }
+                               pool, addrA, addrB, size, 0)
 
 /* Return 1 if a mempool exists, else 0. */
 #define VALGRIND_MEMPOOL_EXISTS(pool)                             \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
                                VG_USERREQ__MEMPOOL_EXISTS,        \
-                               pool, 0, 0, 0, 0);                 \
-    _qzz_res;                                                     \
-   })
+                               pool, 0, 0, 0, 0)
 
 /* Mark a piece of memory as being a stack. Returns a stack id. */
 #define VALGRIND_STACK_REGISTER(start, end)                       \
-   ({unsigned int _qzz_res;                                       \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
                                VG_USERREQ__STACK_REGISTER,        \
-                               start, end, 0, 0, 0);              \
-    _qzz_res;                                                     \
-   })
+                               start, end, 0, 0, 0)
 
 /* Unmark the piece of memory associated with a stack id as being a
    stack. */
 #define VALGRIND_STACK_DEREGISTER(id)                             \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
                                VG_USERREQ__STACK_DEREGISTER,      \
-                               id, 0, 0, 0, 0);                   \
-   }
+                               id, 0, 0, 0, 0)
 
 /* Change the start and end address of the stack id. */
 #define VALGRIND_STACK_CHANGE(id, start, end)                     \
-   {unsigned int _qzz_res;                                        \
-    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
                                VG_USERREQ__STACK_CHANGE,          \
-                               id, start, end, 0, 0);             \
-   }
+                               id, start, end, 0, 0)
+
+/* Load PDB debug info for Wine PE image_map. */
+#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)   \
+    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                            \
+                               VG_USERREQ__LOAD_PDB_DEBUGINFO,    \
+                               fd, ptr, total_size, delta, 0)
+
+/* Map a code address to a source file name and line number.  buf64
+   must point to a 64-byte buffer in the caller's address space.  The
+   result will be dumped in there and is guaranteed to be zero
+   terminated.  If no info is found, the first byte is set to zero. */
+#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
+    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
+                               VG_USERREQ__MAP_IP_TO_SRCLOC,      \
+                               addr, buf64, 0, 0, 0)
 
 
+#undef PLAT_x86_darwin
+#undef PLAT_amd64_darwin
+#undef PLAT_x86_win32
 #undef PLAT_x86_linux
 #undef PLAT_amd64_linux
 #undef PLAT_ppc32_linux
 #undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
+#undef PLAT_arm_linux
+#undef PLAT_s390x_linux
 
 #endif   /* __VALGRIND_H */
diff --git a/src/token.h b/src/token.h
index a0afbc1..77333bc 100644
--- a/src/token.h
+++ b/src/token.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -167,8 +167,8 @@
                                                                         \
   /* Future reserved words (ECMA-262, section 7.6.1.2). */              \
   T(FUTURE_RESERVED_WORD, NULL, 0)                                      \
+  T(FUTURE_STRICT_RESERVED_WORD, NULL, 0)                               \
   K(CONST, "const", 0)                                                  \
-  K(NATIVE, "native", 0)                                                \
                                                                         \
   /* Illegal token - not able to scan. */                               \
   T(ILLEGAL, "ILLEGAL", 0)                                              \
diff --git a/src/type-info.cc b/src/type-info.cc
index 5f794bd..defb1ae 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -28,6 +28,7 @@
 #include "v8.h"
 
 #include "ast.h"
+#include "code-stubs.h"
 #include "compiler.h"
 #include "ic.h"
 #include "macro-assembler.h"
@@ -61,7 +62,7 @@
 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
                                        Handle<Context> global_context) {
   global_context_ = global_context;
-  PopulateMap(code);
+  BuildDictionary(code);
   ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue);
 }
 
@@ -74,26 +75,55 @@
 }
 
 
-bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) {
+bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
   Handle<Object> map_or_code(GetInfo(expr->id()));
   if (map_or_code->IsMap()) return true;
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
     return code->is_keyed_load_stub() &&
         code->ic_state() == MONOMORPHIC &&
+        Code::ExtractTypeFromFlags(code->flags()) == NORMAL &&
         code->FindFirstMap() != NULL;
   }
   return false;
 }
 
 
-bool TypeFeedbackOracle::StoreIsMonomorphic(Expression* expr) {
+bool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) {
+  Handle<Object> map_or_code(GetInfo(expr->id()));
+  if (map_or_code->IsCode()) {
+    Handle<Code> code = Handle<Code>::cast(map_or_code);
+    Builtins* builtins = Isolate::Current()->builtins();
+    return code->is_keyed_load_stub() &&
+        *code != builtins->builtin(Builtins::kKeyedLoadIC_Generic) &&
+        code->ic_state() == MEGAMORPHIC;
+  }
+  return false;
+}
+
+
+bool TypeFeedbackOracle::StoreIsMonomorphicNormal(Expression* expr) {
   Handle<Object> map_or_code(GetInfo(expr->id()));
   if (map_or_code->IsMap()) return true;
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
     return code->is_keyed_store_stub() &&
-        code->ic_state() == MONOMORPHIC;
+        code->ic_state() == MONOMORPHIC &&
+        Code::ExtractTypeFromFlags(code->flags()) == NORMAL;
+  }
+  return false;
+}
+
+
+bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(Expression* expr) {
+  Handle<Object> map_or_code(GetInfo(expr->id()));
+  if (map_or_code->IsCode()) {
+    Handle<Code> code = Handle<Code>::cast(map_or_code);
+    Builtins* builtins = Isolate::Current()->builtins();
+    return code->is_keyed_store_stub() &&
+        *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic) &&
+        *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic_Strict) &&
+        code->ic_state() == MEGAMORPHIC;
   }
   return false;
 }
@@ -106,7 +136,7 @@
 
 
 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
-  ASSERT(LoadIsMonomorphic(expr));
+  ASSERT(LoadIsMonomorphicNormal(expr));
   Handle<Object> map_or_code(GetInfo(expr->id()));
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
@@ -119,7 +149,7 @@
 
 
 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
-  ASSERT(StoreIsMonomorphic(expr));
+  ASSERT(StoreIsMonomorphicNormal(expr));
   Handle<Object> map_or_code(GetInfo(expr->id()));
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
@@ -171,20 +201,6 @@
   return check;
 }
 
-ExternalArrayType TypeFeedbackOracle::GetKeyedLoadExternalArrayType(
-    Property* expr) {
-  Handle<Object> stub = GetInfo(expr->id());
-  ASSERT(stub->IsCode());
-  return Code::cast(*stub)->external_array_type();
-}
-
-ExternalArrayType TypeFeedbackOracle::GetKeyedStoreExternalArrayType(
-    Expression* expr) {
-  Handle<Object> stub = GetInfo(expr->id());
-  ASSERT(stub->IsCode());
-  return Code::cast(*stub)->external_array_type();
-}
-
 Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck(
     CheckType check) {
   JSFunction* function = NULL;
@@ -224,8 +240,7 @@
   switch (state) {
     case CompareIC::UNINITIALIZED:
       // Uninitialized means never executed.
-      // TODO(fschneider): Introduce a separate value for never-executed ICs.
-      return unknown;
+      return TypeInfo::Uninitialized();
     case CompareIC::SMIS:
       return TypeInfo::Smi();
     case CompareIC::HEAP_NUMBERS:
@@ -286,8 +301,7 @@
     switch (type) {
       case BinaryOpIC::UNINITIALIZED:
         // Uninitialized means never executed.
-        // TODO(fschneider): Introduce a separate value for never-executed ICs
-        return unknown;
+        return TypeInfo::Uninitialized();
       case BinaryOpIC::SMI:
         switch (result_type) {
           case BinaryOpIC::UNINITIALIZED:
@@ -404,104 +418,130 @@
 }
 
 
-void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) {
-  ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound);
-  MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target);
-  USE(maybe_result);
-#ifdef DEBUG
-  Object* result;
-  // Dictionary has been allocated with sufficient size for all elements.
-  ASSERT(maybe_result->ToObject(&result));
-  ASSERT(*dictionary_ == result);
-#endif
+void TypeFeedbackOracle::CollectKeyedReceiverTypes(
+    unsigned ast_id,
+    ZoneMapList* types) {
+  Handle<Object> object = GetInfo(ast_id);
+  if (!object->IsCode()) return;
+  Handle<Code> code = Handle<Code>::cast(object);
+  if (code->kind() == Code::KEYED_LOAD_IC ||
+      code->kind() == Code::KEYED_STORE_IC) {
+    AssertNoAllocation no_allocation;
+    int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+    for (RelocIterator it(*code, mask); !it.done(); it.next()) {
+      RelocInfo* info = it.rinfo();
+      Object* object = info->target_object();
+      if (object->IsMap()) {
+        types->Add(Handle<Map>(Map::cast(object)));
+      }
+    }
+  }
 }
 
 
-void TypeFeedbackOracle::PopulateMap(Handle<Code> code) {
-  Isolate* isolate = Isolate::Current();
-  HandleScope scope(isolate);
-
-  const int kInitialCapacity = 16;
-  List<int> code_positions(kInitialCapacity);
-  List<unsigned> ast_ids(kInitialCapacity);
-  CollectIds(*code, &code_positions, &ast_ids);
-
-  ASSERT(dictionary_.is_null());  // Only initialize once.
-  dictionary_ = isolate->factory()->NewNumberDictionary(
-      code_positions.length());
-
-  const int length = code_positions.length();
-  ASSERT(ast_ids.length() == length);
-  for (int i = 0; i < length; i++) {
-    AssertNoAllocation no_allocation;
-    RelocInfo info(code->instruction_start() + code_positions[i],
-                   RelocInfo::CODE_TARGET, 0);
-    Code* target = Code::GetCodeFromTargetAddress(info.target_address());
-    unsigned id = ast_ids[i];
-    InlineCacheState state = target->ic_state();
-    Code::Kind kind = target->kind();
-
-    if (kind == Code::BINARY_OP_IC ||
-        kind == Code::UNARY_OP_IC ||
-        kind == Code::COMPARE_IC) {
-      SetInfo(id, target);
-    } else if (state == MONOMORPHIC) {
-      if (kind == Code::KEYED_LOAD_IC ||
-          kind == Code::KEYED_STORE_IC) {
-        SetInfo(id, target);
-      } else if (kind != Code::CALL_IC ||
-                 target->check_type() == RECEIVER_MAP_CHECK) {
-        Map* map = target->FindFirstMap();
-        if (map == NULL) {
-          SetInfo(id, target);
-        } else {
-          SetInfo(id, map);
-        }
-      } else {
-        ASSERT(target->kind() == Code::CALL_IC);
-        CheckType check = target->check_type();
-        ASSERT(check != RECEIVER_MAP_CHECK);
-        SetInfo(id,  Smi::FromInt(check));
-      }
-    } else if (state == MEGAMORPHIC) {
-      SetInfo(id, target);
-    }
-  }
+// Things are a bit tricky here: The iterator for the RelocInfos and the infos
+// themselves are not GC-safe, so we first get all infos, then we create the
+// dictionary (possibly triggering GC), and finally we relocate the collected
+// infos before we process them.
+void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) {
+  AssertNoAllocation no_allocation;
+  ZoneList<RelocInfo> infos(16);
+  HandleScope scope;
+  GetRelocInfos(code, &infos);
+  CreateDictionary(code, &infos);
+  ProcessRelocInfos(&infos);
   // Allocate handle in the parent scope.
   dictionary_ = scope.CloseAndEscape(dictionary_);
 }
 
 
-void TypeFeedbackOracle::CollectIds(Code* code,
-                                    List<int>* code_positions,
-                                    List<unsigned>* ast_ids) {
-  AssertNoAllocation no_allocation;
+void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code,
+                                       ZoneList<RelocInfo>* infos) {
   int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
-  for (RelocIterator it(code, mask); !it.done(); it.next()) {
-    RelocInfo* info = it.rinfo();
-    ASSERT(RelocInfo::IsCodeTarget(info->rmode()));
-    Code* target = Code::GetCodeFromTargetAddress(info->target_address());
-    if (target->is_inline_cache_stub()) {
-      InlineCacheState state = target->ic_state();
-      Code::Kind kind = target->kind();
-      if (kind == Code::BINARY_OP_IC) {
-        if (target->binary_op_type() ==
-            BinaryOpIC::GENERIC) {
-          continue;
-        }
-      } else if (kind == Code::COMPARE_IC) {
-        if (target->compare_state() == CompareIC::GENERIC) continue;
-      } else {
-        if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
-      }
-      code_positions->Add(
-          static_cast<int>(info->pc() - code->instruction_start()));
-      ASSERT(ast_ids->length() == 0 ||
-             (*ast_ids)[ast_ids->length()-1] !=
-             static_cast<unsigned>(info->data()));
-      ast_ids->Add(static_cast<unsigned>(info->data()));
-    }
+  for (RelocIterator it(*code, mask); !it.done(); it.next()) {
+    infos->Add(*it.rinfo());
   }
 }
 
+
+void TypeFeedbackOracle::CreateDictionary(Handle<Code> code,
+                                          ZoneList<RelocInfo>* infos) {
+  DisableAssertNoAllocation allocation_allowed;
+  byte* old_start = code->instruction_start();
+  dictionary_ = FACTORY->NewNumberDictionary(infos->length());
+  byte* new_start = code->instruction_start();
+  RelocateRelocInfos(infos, old_start, new_start);
+}
+
+
+void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos,
+                                            byte* old_start,
+                                            byte* new_start) {
+  for (int i = 0; i < infos->length(); i++) {
+    RelocInfo* info = &(*infos)[i];
+    info->set_pc(new_start + (info->pc() - old_start));
+  }
+}
+
+
+void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
+  for (int i = 0; i < infos->length(); i++) {
+    unsigned ast_id = static_cast<unsigned>((*infos)[i].data());
+    Code* target = Code::GetCodeFromTargetAddress((*infos)[i].target_address());
+    ProcessTarget(ast_id, target);
+  }
+}
+
+
+void TypeFeedbackOracle::ProcessTarget(unsigned ast_id, Code* target) {
+  switch (target->kind()) {
+    case Code::LOAD_IC:
+    case Code::STORE_IC:
+    case Code::CALL_IC:
+    case Code::KEYED_CALL_IC:
+      if (target->ic_state() == MONOMORPHIC) {
+        if (target->kind() == Code::CALL_IC &&
+            target->check_type() != RECEIVER_MAP_CHECK) {
+          SetInfo(ast_id,  Smi::FromInt(target->check_type()));
+        } else {
+          Object* map = target->FindFirstMap();
+          SetInfo(ast_id, map == NULL ? static_cast<Object*>(target) : map);
+        }
+      } else if (target->ic_state() == MEGAMORPHIC) {
+        SetInfo(ast_id, target);
+      }
+      break;
+
+    case Code::KEYED_LOAD_IC:
+    case Code::KEYED_STORE_IC:
+      if (target->ic_state() == MONOMORPHIC ||
+          target->ic_state() == MEGAMORPHIC) {
+        SetInfo(ast_id, target);
+      }
+      break;
+
+    case Code::UNARY_OP_IC:
+    case Code::BINARY_OP_IC:
+    case Code::COMPARE_IC:
+      SetInfo(ast_id, target);
+      break;
+
+    default:
+      break;
+  }
+}
+
+
+void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) {
+  ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound);
+  MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target);
+  USE(maybe_result);
+#ifdef DEBUG
+  Object* result = NULL;
+  // Dictionary has been allocated with sufficient size for all elements.
+  ASSERT(maybe_result->ToObject(&result));
+  ASSERT(*dictionary_ == result);
+#endif
+}
+
 } }  // namespace v8::internal
diff --git a/src/type-info.h b/src/type-info.h
index 828e3c7..0a8c935 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -30,12 +30,13 @@
 
 #include "allocation.h"
 #include "globals.h"
-#include "zone.h"
 #include "zone-inl.h"
 
 namespace v8 {
 namespace internal {
 
+const int kMaxKeyedPolymorphism = 4;
+
 //         Unknown
 //           |   \____________
 //           |                |
@@ -215,8 +216,10 @@
  public:
   TypeFeedbackOracle(Handle<Code> code, Handle<Context> global_context);
 
-  bool LoadIsMonomorphic(Property* expr);
-  bool StoreIsMonomorphic(Expression* expr);
+  bool LoadIsMonomorphicNormal(Property* expr);
+  bool LoadIsMegamorphicWithTypeInfo(Property* expr);
+  bool StoreIsMonomorphicNormal(Expression* expr);
+  bool StoreIsMegamorphicWithTypeInfo(Expression* expr);
   bool CallIsMonomorphic(Call* expr);
 
   Handle<Map> LoadMonomorphicReceiverType(Property* expr);
@@ -227,9 +230,8 @@
   ZoneMapList* CallReceiverTypes(Call* expr,
                                  Handle<String> name,
                                  CallKind call_kind);
-
-  ExternalArrayType GetKeyedLoadExternalArrayType(Property* expr);
-  ExternalArrayType GetKeyedStoreExternalArrayType(Expression* expr);
+  void CollectKeyedReceiverTypes(unsigned ast_id,
+                                 ZoneMapList* types);
 
   CheckType GetCallCheckType(Call* expr);
   Handle<JSObject> GetPrototypeForPrimitiveCheck(CheckType check);
@@ -251,11 +253,14 @@
 
   void SetInfo(unsigned ast_id, Object* target);
 
-  void PopulateMap(Handle<Code> code);
-
-  void CollectIds(Code* code,
-                  List<int>* code_positions,
-                  List<unsigned>* ast_ids);
+  void BuildDictionary(Handle<Code> code);
+  void GetRelocInfos(Handle<Code> code, ZoneList<RelocInfo>* infos);
+  void CreateDictionary(Handle<Code> code, ZoneList<RelocInfo>* infos);
+  void RelocateRelocInfos(ZoneList<RelocInfo>* infos,
+                          byte* old_start,
+                          byte* new_start);
+  void ProcessRelocInfos(ZoneList<RelocInfo>* infos);
+  void ProcessTarget(unsigned ast_id, Code* target);
 
   // Returns an element from the backing store. Returns undefined if
   // there is no information.
diff --git a/src/utils.cc b/src/utils.cc
index b466301..89ef4c6 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -26,211 +26,26 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <stdarg.h>
-
-#include "v8.h"
-
-#include "platform.h"
-
-#include "sys/stat.h"
+#include "../include/v8stdint.h"
+#include "checks.h"
+#include "utils.h"
 
 namespace v8 {
 namespace internal {
 
 
-void PrintF(const char* format, ...) {
-  va_list arguments;
-  va_start(arguments, format);
-  OS::VPrint(format, arguments);
-  va_end(arguments);
-}
-
-
-void PrintF(FILE* out, const char* format, ...) {
-  va_list arguments;
-  va_start(arguments, format);
-  OS::VFPrint(out, format, arguments);
-  va_end(arguments);
-}
-
-
-void Flush(FILE* out) {
-  fflush(out);
-}
-
-
-char* ReadLine(const char* prompt) {
-  char* result = NULL;
-  char line_buf[256];
-  int offset = 0;
-  bool keep_going = true;
-  fprintf(stdout, "%s", prompt);
-  fflush(stdout);
-  while (keep_going) {
-    if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
-      // fgets got an error. Just give up.
-      if (result != NULL) {
-        DeleteArray(result);
-      }
-      return NULL;
-    }
-    int len = StrLength(line_buf);
-    if (len > 1 &&
-        line_buf[len - 2] == '\\' &&
-        line_buf[len - 1] == '\n') {
-      // When we read a line that ends with a "\" we remove the escape and
-      // append the remainder.
-      line_buf[len - 2] = '\n';
-      line_buf[len - 1] = 0;
-      len -= 1;
-    } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
-      // Since we read a new line we are done reading the line. This
-      // will exit the loop after copying this buffer into the result.
-      keep_going = false;
-    }
-    if (result == NULL) {
-      // Allocate the initial result and make room for the terminating '\0'
-      result = NewArray<char>(len + 1);
-    } else {
-      // Allocate a new result with enough room for the new addition.
-      int new_len = offset + len + 1;
-      char* new_result = NewArray<char>(new_len);
-      // Copy the existing input into the new array and set the new
-      // array as the result.
-      memcpy(new_result, result, offset * kCharSize);
-      DeleteArray(result);
-      result = new_result;
-    }
-    // Copy the newly read line into the result.
-    memcpy(result + offset, line_buf, len * kCharSize);
-    offset += len;
-  }
-  ASSERT(result != NULL);
-  result[offset] = '\0';
-  return result;
-}
-
-
-char* ReadCharsFromFile(const char* filename,
-                        int* size,
-                        int extra_space,
-                        bool verbose) {
-  FILE* file = OS::FOpen(filename, "rb");
-  if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
-    if (verbose) {
-      OS::PrintError("Cannot read from file %s.\n", filename);
-    }
-    return NULL;
-  }
-
-  // Get the size of the file and rewind it.
-  *size = ftell(file);
-  rewind(file);
-
-  char* result = NewArray<char>(*size + extra_space);
-  for (int i = 0; i < *size;) {
-    int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
-    if (read <= 0) {
-      fclose(file);
-      DeleteArray(result);
-      return NULL;
-    }
-    i += read;
-  }
-  fclose(file);
-  return result;
-}
-
-
-byte* ReadBytes(const char* filename, int* size, bool verbose) {
-  char* chars = ReadCharsFromFile(filename, size, 0, verbose);
-  return reinterpret_cast<byte*>(chars);
-}
-
-
-Vector<const char> ReadFile(const char* filename,
-                            bool* exists,
-                            bool verbose) {
-  int size;
-  char* result = ReadCharsFromFile(filename, &size, 1, verbose);
-  if (!result) {
-    *exists = false;
-    return Vector<const char>::empty();
-  }
-  result[size] = '\0';
-  *exists = true;
-  return Vector<const char>(result, size);
-}
-
-
-int WriteCharsToFile(const char* str, int size, FILE* f) {
-  int total = 0;
-  while (total < size) {
-    int write = static_cast<int>(fwrite(str, 1, size - total, f));
-    if (write == 0) {
-      return total;
-    }
-    total += write;
-    str += write;
-  }
-  return total;
-}
-
-
-int AppendChars(const char* filename,
-                const char* str,
-                int size,
-                bool verbose) {
-  FILE* f = OS::FOpen(filename, "ab");
-  if (f == NULL) {
-    if (verbose) {
-      OS::PrintError("Cannot open file %s for writing.\n", filename);
-    }
-    return 0;
-  }
-  int written = WriteCharsToFile(str, size, f);
-  fclose(f);
-  return written;
-}
-
-
-int WriteChars(const char* filename,
-               const char* str,
-               int size,
-               bool verbose) {
-  FILE* f = OS::FOpen(filename, "wb");
-  if (f == NULL) {
-    if (verbose) {
-      OS::PrintError("Cannot open file %s for writing.\n", filename);
-    }
-    return 0;
-  }
-  int written = WriteCharsToFile(str, size, f);
-  fclose(f);
-  return written;
-}
-
-
-int WriteBytes(const char* filename,
-               const byte* bytes,
-               int size,
-               bool verbose) {
-  const char* str = reinterpret_cast<const char*>(bytes);
-  return WriteChars(filename, str, size, verbose);
-}
-
-
-StringBuilder::StringBuilder(int size) {
+SimpleStringBuilder::SimpleStringBuilder(int size) {
   buffer_ = Vector<char>::New(size);
   position_ = 0;
 }
 
 
-void StringBuilder::AddString(const char* s) {
+void SimpleStringBuilder::AddString(const char* s) {
   AddSubstring(s, StrLength(s));
 }
 
 
-void StringBuilder::AddSubstring(const char* s, int n) {
+void SimpleStringBuilder::AddSubstring(const char* s, int n) {
   ASSERT(!is_finalized() && position_ + n < buffer_.length());
   ASSERT(static_cast<size_t>(n) <= strlen(s));
   memcpy(&buffer_[position_], s, n * kCharSize);
@@ -238,33 +53,32 @@
 }
 
 
-void StringBuilder::AddFormatted(const char* format, ...) {
-  va_list arguments;
-  va_start(arguments, format);
-  AddFormattedList(format, arguments);
-  va_end(arguments);
-}
-
-
-void StringBuilder::AddFormattedList(const char* format, va_list list) {
-  ASSERT(!is_finalized() && position_ < buffer_.length());
-  int n = OS::VSNPrintF(buffer_ + position_, format, list);
-  if (n < 0 || n >= (buffer_.length() - position_)) {
-    position_ = buffer_.length();
-  } else {
-    position_ += n;
-  }
-}
-
-
-void StringBuilder::AddPadding(char c, int count) {
+void SimpleStringBuilder::AddPadding(char c, int count) {
   for (int i = 0; i < count; i++) {
     AddCharacter(c);
   }
 }
 
 
-char* StringBuilder::Finalize() {
+void SimpleStringBuilder::AddDecimalInteger(int32_t value) {
+  uint32_t number = static_cast<uint32_t>(value);
+  if (value < 0) {
+    AddCharacter('-');
+    number = static_cast<uint32_t>(-value);
+  }
+  int digits = 1;
+  for (uint32_t factor = 10; digits < 10; digits++, factor *= 10) {
+    if (factor > number) break;
+  }
+  position_ += digits;
+  for (int i = 1; i <= digits; i++) {
+    buffer_[position_ - i] = '0' + static_cast<char>(number % 10);
+    number /= 10;
+  }
+}
+
+
+char* SimpleStringBuilder::Finalize() {
   ASSERT(!is_finalized() && position_ < buffer_.length());
   buffer_[position_] = '\0';
   // Make sure nobody managed to add a 0-character to the
@@ -275,97 +89,4 @@
   return buffer_.start();
 }
 
-
-MemoryMappedExternalResource::MemoryMappedExternalResource(const char* filename)
-    : filename_(NULL),
-      data_(NULL),
-      length_(0),
-      remove_file_on_cleanup_(false) {
-  Init(filename);
-}
-
-
-MemoryMappedExternalResource::
-    MemoryMappedExternalResource(const char* filename,
-                                 bool remove_file_on_cleanup)
-    : filename_(NULL),
-      data_(NULL),
-      length_(0),
-      remove_file_on_cleanup_(remove_file_on_cleanup) {
-  Init(filename);
-}
-
-
-MemoryMappedExternalResource::~MemoryMappedExternalResource() {
-  // Release the resources if we had successfully acquired them:
-  if (file_ != NULL) {
-    delete file_;
-    if (remove_file_on_cleanup_) {
-      OS::Remove(filename_);
-    }
-    DeleteArray<char>(filename_);
-  }
-}
-
-
-void MemoryMappedExternalResource::Init(const char* filename) {
-  file_ = OS::MemoryMappedFile::open(filename);
-  if (file_ != NULL) {
-    filename_ = StrDup(filename);
-    data_ = reinterpret_cast<char*>(file_->memory());
-    length_ = file_->size();
-  }
-}
-
-
-bool MemoryMappedExternalResource::EnsureIsAscii(bool abort_if_failed) const {
-  bool is_ascii = true;
-
-  int line_no = 1;
-  const char* start_of_line = data_;
-  const char* end = data_ + length_;
-  for (const char* p = data_; p < end; p++) {
-    char c = *p;
-    if ((c & 0x80) != 0) {
-      // Non-ascii detected:
-      is_ascii = false;
-
-      // Report the error and abort if appropriate:
-      if (abort_if_failed) {
-        int char_no = static_cast<int>(p - start_of_line) - 1;
-
-        ASSERT(filename_ != NULL);
-        PrintF("\n\n\n"
-               "Abort: Non-Ascii character 0x%.2x in file %s line %d char %d",
-               c, filename_, line_no, char_no);
-
-        // Allow for some context up to kNumberOfLeadingContextChars chars
-        // before the offending non-ascii char to help the user see where
-        // the offending char is.
-        const int kNumberOfLeadingContextChars = 10;
-        const char* err_context = p - kNumberOfLeadingContextChars;
-        if (err_context < data_) {
-          err_context = data_;
-        }
-        // Compute the length of the error context and print it.
-        int err_context_length = static_cast<int>(p - err_context);
-        if (err_context_length != 0) {
-          PrintF(" after \"%.*s\"", err_context_length, err_context);
-        }
-        PrintF(".\n\n\n");
-        OS::Abort();
-      }
-
-      break;  // Non-ascii detected.  No need to continue scanning.
-    }
-    if (c == '\n') {
-      start_of_line = p;
-      line_no++;
-    }
-  }
-
-  return is_ascii;
-}
-
-
 } }  // namespace v8::internal
diff --git a/src/utils.h b/src/utils.h
index da7a1d9..ecdf1c7 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -52,11 +52,9 @@
 
 
 // X must be a power of 2.  Returns the number of trailing zeros.
-template <typename T>
-static inline int WhichPowerOf2(T x) {
+static inline int WhichPowerOf2(uint32_t x) {
   ASSERT(IsPowerOf2(x));
   ASSERT(x != 0);
-  if (x < 0) return 31;
   int bits = 0;
 #ifdef DEBUG
   int original_x = x;
@@ -795,6 +793,98 @@
   return BitCastHelper<Dest, Source>::cast(source);
 }
 
+
+template<typename ElementType, int NumElements>
+class EmbeddedContainer {
+ public:
+  EmbeddedContainer() : elems_() { }
+
+  int length() { return NumElements; }
+  ElementType& operator[](int i) {
+    ASSERT(i < length());
+    return elems_[i];
+  }
+
+ private:
+  ElementType elems_[NumElements];
+};
+
+
+template<typename ElementType>
+class EmbeddedContainer<ElementType, 0> {
+ public:
+  int length() { return 0; }
+  ElementType& operator[](int i) {
+    UNREACHABLE();
+    static ElementType t = 0;
+    return t;
+  }
+};
+
+
+// Helper class for building result strings in a character buffer. The
+// purpose of the class is to use safe operations that checks the
+// buffer bounds on all operations in debug mode.
+// This simple base class does not allow formatted output.
+class SimpleStringBuilder {
+ public:
+  // Create a string builder with a buffer of the given size. The
+  // buffer is allocated through NewArray<char> and must be
+  // deallocated by the caller of Finalize().
+  explicit SimpleStringBuilder(int size);
+
+  SimpleStringBuilder(char* buffer, int size)
+      : buffer_(buffer, size), position_(0) { }
+
+  ~SimpleStringBuilder() { if (!is_finalized()) Finalize(); }
+
+  int size() const { return buffer_.length(); }
+
+  // Get the current position in the builder.
+  int position() const {
+    ASSERT(!is_finalized());
+    return position_;
+  }
+
+  // Reset the position.
+  void Reset() { position_ = 0; }
+
+  // Add a single character to the builder. It is not allowed to add
+  // 0-characters; use the Finalize() method to terminate the string
+  // instead.
+  void AddCharacter(char c) {
+    ASSERT(c != '\0');
+    ASSERT(!is_finalized() && position_ < buffer_.length());
+    buffer_[position_++] = c;
+  }
+
+  // Add an entire string to the builder. Uses strlen() internally to
+  // compute the length of the input string.
+  void AddString(const char* s);
+
+  // Add the first 'n' characters of the given string 's' to the
+  // builder. The input string must have enough characters.
+  void AddSubstring(const char* s, int n);
+
+  // Add character padding to the builder. If count is non-positive,
+  // nothing is added to the builder.
+  void AddPadding(char c, int count);
+
+  // Add the decimal representation of the value.
+  void AddDecimalInteger(int value);
+
+  // Finalize the string by 0-terminating it and returning the buffer.
+  char* Finalize();
+
+ protected:
+  Vector<char> buffer_;
+  int position_;
+
+  bool is_finalized() const { return position_ < 0; }
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SimpleStringBuilder);
+};
+
 } }  // namespace v8::internal
 
 #endif  // V8_UTILS_H_
diff --git a/src/v8-counters.h b/src/v8-counters.h
index e3b16e9..2de8303 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -126,8 +126,9 @@
      V8.GCCompactorCausedByWeakHandles)                               \
   SC(gc_last_resort_from_js, V8.GCLastResortFromJS)                   \
   SC(gc_last_resort_from_handles, V8.GCLastResortFromHandles)         \
-  SC(map_slow_to_fast_elements, V8.MapSlowToFastElements)             \
-  SC(map_fast_to_slow_elements, V8.MapFastToSlowElements)             \
+  SC(map_to_fast_elements, V8.MapToFastElements)                      \
+  SC(map_to_fast_double_elements, V8.MapToFastDoubleElements)         \
+  SC(map_to_slow_elements, V8.MapToSlowElements)                      \
   SC(map_to_external_array_elements, V8.MapToExternalArrayElements)   \
   /* How is the generic keyed-load stub used? */                      \
   SC(keyed_load_generic_smi, V8.KeyedLoadGenericSmi)                  \
@@ -169,14 +170,10 @@
   SC(named_load_inline_field, V8.NamedLoadInlineFast)                 \
   SC(keyed_load_inline_generic, V8.KeyedLoadInlineGeneric)            \
   SC(keyed_load_inline_fast, V8.KeyedLoadInlineFast)                  \
-  SC(named_load_full, V8.NamedLoadFull)                               \
-  SC(keyed_load_full, V8.KeyedLoadFull)                               \
   SC(keyed_store_inline_generic, V8.KeyedStoreInlineGeneric)          \
   SC(keyed_store_inline_fast, V8.KeyedStoreInlineFast)                \
   SC(named_store_inline_generic, V8.NamedStoreInlineGeneric)          \
   SC(named_store_inline_fast, V8.NamedStoreInlineFast)                \
-  SC(keyed_store_full, V8.KeyedStoreFull)                             \
-  SC(named_store_full, V8.NamedStoreFull)                             \
   SC(keyed_store_inline_miss, V8.KeyedStoreInlineMiss)                \
   SC(named_store_global_inline, V8.NamedStoreGlobalInline)            \
   SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss)   \
diff --git a/src/v8.cc b/src/v8.cc
index 0b562fc..36f835f 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -50,6 +50,9 @@
 bool V8::has_fatal_error_ = false;
 bool V8::use_crankshaft_ = true;
 
+static Mutex* entropy_mutex = OS::CreateMutex();
+static EntropySource entropy_source;
+
 
 bool V8::Initialize(Deserializer* des) {
   InitializeOncePerProcess();
@@ -100,42 +103,45 @@
 }
 
 
-static uint32_t random_seed() {
-  if (FLAG_random_seed == 0) {
-    return random();
+static void seed_random(uint32_t* state) {
+  for (int i = 0; i < 2; ++i) {
+    if (FLAG_random_seed != 0) {
+      state[i] = FLAG_random_seed;
+    } else if (entropy_source != NULL) {
+      uint32_t val;
+      ScopedLock lock(entropy_mutex);
+      entropy_source(reinterpret_cast<unsigned char*>(&val), sizeof(uint32_t));
+      state[i] = val;
+    } else {
+      state[i] = random();
+    }
   }
-  return FLAG_random_seed;
 }
 
 
-typedef struct {
-  uint32_t hi;
-  uint32_t lo;
-} random_state;
-
-
 // Random number generator using George Marsaglia's MWC algorithm.
-static uint32_t random_base(random_state *state) {
-  // Initialize seed using the system random(). If one of the seeds
-  // should ever become zero again, or if random() returns zero, we
-  // avoid getting stuck with zero bits in hi or lo by re-initializing
-  // them on demand.
-  if (state->hi == 0) state->hi = random_seed();
-  if (state->lo == 0) state->lo = random_seed();
+static uint32_t random_base(uint32_t* state) {
+  // Initialize seed using the system random().
+  // No non-zero seed will ever become zero again.
+  if (state[0] == 0) seed_random(state);
 
-  // Mix the bits.
-  state->hi = 36969 * (state->hi & 0xFFFF) + (state->hi >> 16);
-  state->lo = 18273 * (state->lo & 0xFFFF) + (state->lo >> 16);
-  return (state->hi << 16) + (state->lo & 0xFFFF);
+  // Mix the bits.  Never replaces state[i] with 0 if it is nonzero.
+  state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16);
+  state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16);
+
+  return (state[0] << 14) + (state[1] & 0x3FFFF);
+}
+
+
+void V8::SetEntropySource(EntropySource source) {
+  entropy_source = source;
 }
 
 
 // Used by JavaScript APIs
 uint32_t V8::Random(Isolate* isolate) {
   ASSERT(isolate == Isolate::Current());
-  // TODO(isolates): move lo and hi to isolate
-  static random_state state = {0, 0};
-  return random_base(&state);
+  return random_base(isolate->random_seed());
 }
 
 
@@ -144,9 +150,7 @@
 // leaks that could be used in an exploit.
 uint32_t V8::RandomPrivate(Isolate* isolate) {
   ASSERT(isolate == Isolate::Current());
-  // TODO(isolates): move lo and hi to isolate
-  static random_state state = {0, 0};
-  return random_base(&state);
+  return random_base(isolate->private_random_seed());
 }
 
 
diff --git a/src/v8.h b/src/v8.h
index 9d98521..e565ca5 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -35,13 +35,10 @@
 #if defined(GOOGLE3)
 // Google3 special flag handling.
 #if defined(DEBUG) && defined(NDEBUG)
-// If both are defined in Google3, then we are building an optimized v8 with
-// assertions enabled.
+// 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
+// consistency.
 #undef NDEBUG
-#elif !defined(DEBUG) && !defined(NDEBUG)
-// If neither is defined in Google3, then we are building a debug v8. Mark it
-// as such.
-#define DEBUG
 #endif
 #endif  // defined(GOOGLE3)
 
@@ -94,6 +91,9 @@
   static void FatalProcessOutOfMemory(const char* location,
                                       bool take_snapshot = false);
 
+  // Allows an entropy source to be provided for use in random number
+  // generation.
+  static void SetEntropySource(EntropySource source);
   // Random number generation support. Not cryptographically safe.
   static uint32_t Random(Isolate* isolate);
   // We use random numbers internally in memory allocation and in the
diff --git a/src/v8conversions.cc b/src/v8conversions.cc
new file mode 100644
index 0000000..96056ec
--- /dev/null
+++ b/src/v8conversions.cc
@@ -0,0 +1,129 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdarg.h>
+#include <limits.h>
+
+#include "v8.h"
+
+#include "conversions-inl.h"
+#include "v8conversions.h"
+#include "dtoa.h"
+#include "factory.h"
+#include "scanner-base.h"
+#include "strtod.h"
+
+namespace v8 {
+namespace internal {
+
+namespace {
+
+// C++-style iterator adaptor for StringInputBuffer
+// (unlike C++ iterators the end-marker has different type).
+class StringInputBufferIterator {
+ public:
+  class EndMarker {};
+
+  explicit StringInputBufferIterator(StringInputBuffer* buffer);
+
+  int operator*() const;
+  void operator++();
+  bool operator==(EndMarker const&) const { return end_; }
+  bool operator!=(EndMarker const& m) const { return !end_; }
+
+ private:
+  StringInputBuffer* const buffer_;
+  int current_;
+  bool end_;
+};
+
+
+StringInputBufferIterator::StringInputBufferIterator(
+    StringInputBuffer* buffer) : buffer_(buffer) {
+  ++(*this);
+}
+
+int StringInputBufferIterator::operator*() const {
+  return current_;
+}
+
+
+void StringInputBufferIterator::operator++() {
+  end_ = !buffer_->has_more();
+  if (!end_) {
+    current_ = buffer_->GetNext();
+  }
+}
+}  // End anonymous namespace.
+
+
+double StringToDouble(UnicodeCache* unicode_cache,
+                      String* str, int flags, double empty_string_val) {
+  StringShape shape(str);
+  if (shape.IsSequentialAscii()) {
+    const char* begin = SeqAsciiString::cast(str)->GetChars();
+    const char* end = begin + str->length();
+    return InternalStringToDouble(unicode_cache, begin, end, flags,
+                                  empty_string_val);
+  } else if (shape.IsSequentialTwoByte()) {
+    const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
+    const uc16* end = begin + str->length();
+    return InternalStringToDouble(unicode_cache, begin, end, flags,
+                                  empty_string_val);
+  } else {
+    StringInputBuffer buffer(str);
+    return InternalStringToDouble(unicode_cache,
+                                  StringInputBufferIterator(&buffer),
+                                  StringInputBufferIterator::EndMarker(),
+                                  flags,
+                                  empty_string_val);
+  }
+}
+
+
+double StringToInt(UnicodeCache* unicode_cache,
+                   String* str,
+                   int radix) {
+  StringShape shape(str);
+  if (shape.IsSequentialAscii()) {
+    const char* begin = SeqAsciiString::cast(str)->GetChars();
+    const char* end = begin + str->length();
+    return InternalStringToInt(unicode_cache, begin, end, radix);
+  } else if (shape.IsSequentialTwoByte()) {
+    const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
+    const uc16* end = begin + str->length();
+    return InternalStringToInt(unicode_cache, begin, end, radix);
+  } else {
+    StringInputBuffer buffer(str);
+    return InternalStringToInt(unicode_cache,
+                               StringInputBufferIterator(&buffer),
+                               StringInputBufferIterator::EndMarker(),
+                               radix);
+  }
+}
+
+} }  // namespace v8::internal
diff --git a/test/mjsunit/override-eval-with-non-function.js b/src/v8conversions.h
similarity index 63%
copy from test/mjsunit/override-eval-with-non-function.js
copy to src/v8conversions.h
index edbcb19..1840e3a 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/src/v8conversions.h
@@ -25,12 +25,36 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+#ifndef V8_V8CONVERSIONS_H_
+#define V8_V8CONVERSIONS_H_
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+#include "conversions.h"
+
+namespace v8 {
+namespace internal {
+
+// Convert from Number object to C integer.
+static inline int32_t NumberToInt32(Object* number) {
+  if (number->IsSmi()) return Smi::cast(number)->value();
+  return DoubleToInt32(number->Number());
 }
 
-test();
+
+static inline uint32_t NumberToUint32(Object* number) {
+  if (number->IsSmi()) return Smi::cast(number)->value();
+  return DoubleToUint32(number->Number());
+}
+
+
+// Converts a string into a double value according to ECMA-262 9.3.1
+double StringToDouble(UnicodeCache* unicode_cache,
+                      String* str,
+                      int flags,
+                      double empty_string_val = 0);
+
+// Converts a string into an integer.
+double StringToInt(UnicodeCache* unicode_cache, String* str, int radix);
+
+} }  // namespace v8::internal
+
+#endif  // V8_V8CONVERSIONS_H_
diff --git a/src/v8globals.h b/src/v8globals.h
index a23ca19..f05a702 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -98,10 +98,6 @@
 const int kProcessorCacheLineSize = 64;
 
 // Constants relevant to double precision floating point numbers.
-
-// Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no
-// other bits set.
-const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51;
 // If looking only at the top 32 bits, the QNaN mask is bits 19 to 30.
 const uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32);
 
@@ -395,12 +391,11 @@
 };
 
 
-// Logging and profiling.
-// A StateTag represents a possible state of the VM.  When compiled with
-// ENABLE_VMSTATE_TRACKING, 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.
+// 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.
 
 #define STATE_TAG_LIST(V) \
   V(JS)                   \
@@ -507,6 +502,16 @@
   CALL_AS_FUNCTION
 };
 
+
+static const uint32_t kHoleNanUpper32 = 0x7FFFFFFF;
+static const uint32_t kHoleNanLower32 = 0xFFFFFFFF;
+static const uint32_t kNaNOrInfinityLowerBoundUpper32 = 0x7FF00000;
+
+const uint64_t kHoleNanInt64 =
+    (static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32;
+const uint64_t kLastNonNaNInt64 =
+    (static_cast<uint64_t>(kNaNOrInfinityLowerBoundUpper32) << 32);
+
 } }  // namespace v8::internal
 
 #endif  // V8_V8GLOBALS_H_
diff --git a/src/v8natives.js b/src/v8natives.js
index 700fe58..ff87804 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -56,7 +56,7 @@
     %FunctionSetName(f, key);
     %FunctionRemovePrototype(f);
     %SetProperty(object, key, f, attributes);
-    %SetES5Flag(f);
+    %SetNativeFlag(f);
   }
   %ToFastProperties(object);
 }
@@ -106,7 +106,7 @@
       // Truncate number.
       return string | 0;
     }
-    if (IS_UNDEFINED(radix)) radix = 0;
+    radix = radix | 0;
   } else {
     radix = TO_INT32(radix);
     if (!(radix == 0 || (2 <= radix && radix <= 36)))
@@ -132,10 +132,19 @@
 function GlobalEval(x) {
   if (!IS_STRING(x)) return x;
 
+  var receiver = this;
   var global_receiver = %GlobalReceiver(global);
-  var this_is_global_receiver = (this === global_receiver);
+
+  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+    receiver = global_receiver;
+  }
+
+  var this_is_global_receiver = (receiver === global_receiver);
   var global_is_detached = (global === global_receiver);
 
+  // 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.
   if (!this_is_global_receiver || global_is_detached) {
     throw new $EvalError('The "this" object passed to eval must ' +
                          'be the global object from which eval originated');
@@ -144,7 +153,7 @@
   var f = %CompileString(x);
   if (!IS_FUNCTION(f)) return f;
 
-  return %_CallFunction(this, f);
+  return %_CallFunction(receiver, f);
 }
 
 
@@ -246,8 +255,9 @@
 
 // Extensions for providing property getters and setters.
 function ObjectDefineGetter(name, fun) {
-  if (this == null && !IS_UNDETECTABLE(this)) {
-    throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
+  var receiver = this;
+  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+    receiver = %GlobalReceiver(global);
   }
   if (!IS_FUNCTION(fun)) {
     throw new $TypeError('Object.prototype.__defineGetter__: Expecting function');
@@ -256,21 +266,23 @@
   desc.setGet(fun);
   desc.setEnumerable(true);
   desc.setConfigurable(true);
-  DefineOwnProperty(ToObject(this), ToString(name), desc, false);
+  DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
 }
 
 
 function ObjectLookupGetter(name) {
-  if (this == null && !IS_UNDETECTABLE(this)) {
-    throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
+  var receiver = this;
+  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+    receiver = %GlobalReceiver(global);
   }
-  return %LookupAccessor(ToObject(this), ToString(name), GETTER);
+  return %LookupAccessor(ToObject(receiver), ToString(name), GETTER);
 }
 
 
 function ObjectDefineSetter(name, fun) {
-  if (this == null && !IS_UNDETECTABLE(this)) {
-    throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
+  var receiver = this;
+  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+    receiver = %GlobalReceiver(global);
   }
   if (!IS_FUNCTION(fun)) {
     throw new $TypeError(
@@ -280,21 +292,29 @@
   desc.setSet(fun);
   desc.setEnumerable(true);
   desc.setConfigurable(true);
-  DefineOwnProperty(ToObject(this), ToString(name), desc, false);
+  DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
 }
 
 
 function ObjectLookupSetter(name) {
-  if (this == null && !IS_UNDETECTABLE(this)) {
-    throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
+  var receiver = this;
+  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+    receiver = %GlobalReceiver(global);
   }
-  return %LookupAccessor(ToObject(this), ToString(name), SETTER);
+  return %LookupAccessor(ToObject(receiver), ToString(name), SETTER);
 }
 
 
 function ObjectKeys(obj) {
   if (!IS_SPEC_OBJECT(obj))
     throw MakeTypeError("obj_ctor_property_non_object", ["keys"]);
+  if (%IsJSProxy(obj)) {
+    var handler = %GetHandler(obj);
+    var keys = handler.keys;
+    if (IS_UNDEFINED(keys)) keys = DerivedKeysTrap;
+    var names = %_CallFunction(handler, keys);
+    return ToStringArray(names);
+  }
   return %LocalKeys(obj);
 }
 
@@ -302,14 +322,14 @@
 // ES5 8.10.1.
 function IsAccessorDescriptor(desc) {
   if (IS_UNDEFINED(desc)) return false;
-  return desc.hasGetter_ || desc.hasSetter_;
+  return desc.hasGetter() || desc.hasSetter();
 }
 
 
 // ES5 8.10.2.
 function IsDataDescriptor(desc) {
   if (IS_UNDEFINED(desc)) return false;
-  return desc.hasValue_ || desc.hasWritable_;
+  return desc.hasValue() || desc.hasWritable();
 }
 
 
@@ -323,6 +343,7 @@
   return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
 }
 
+
 // ES5 8.10.4
 function FromPropertyDescriptor(desc) {
   if (IS_UNDEFINED(desc)) return desc;
@@ -340,6 +361,36 @@
            configurable: desc.isConfigurable() };
 }
 
+
+// Harmony Proxies
+function FromGenericPropertyDescriptor(desc) {
+  if (IS_UNDEFINED(desc)) return desc;
+  var obj = new $Object();
+
+  if (desc.hasValue()) {
+    %IgnoreAttributesAndSetProperty(obj, "value", desc.getValue(), NONE);
+  }
+  if (desc.hasWritable()) {
+    %IgnoreAttributesAndSetProperty(obj, "writable", desc.isWritable(), NONE);
+  }
+  if (desc.hasGetter()) {
+    %IgnoreAttributesAndSetProperty(obj, "get", desc.getGet(), NONE);
+  }
+  if (desc.hasSetter()) {
+    %IgnoreAttributesAndSetProperty(obj, "set", desc.getSet(), NONE);
+  }
+  if (desc.hasEnumerable()) {
+    %IgnoreAttributesAndSetProperty(obj, "enumerable",
+                                    desc.isEnumerable(), NONE);
+  }
+  if (desc.hasConfigurable()) {
+    %IgnoreAttributesAndSetProperty(obj, "configurable",
+                                    desc.isConfigurable(), NONE);
+  }
+  return obj;
+}
+
+
 // ES5 8.10.5.
 function ToPropertyDescriptor(obj) {
   if (!IS_SPEC_OBJECT(obj)) {
@@ -386,6 +437,23 @@
 }
 
 
+// For Harmony proxies.
+function ToCompletePropertyDescriptor(obj) {
+  var desc = ToPropertyDescriptor(obj)
+  if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
+    if (!desc.hasValue()) desc.setValue(void 0);
+    if (!desc.hasWritable()) desc.setWritable(false);
+  } else {
+    // Is accessor descriptor.
+    if (!desc.hasGetter()) desc.setGet(void 0);
+    if (!desc.hasSetter()) desc.setSet(void 0);
+  }
+  if (!desc.hasEnumerable()) desc.setEnumerable(false);
+  if (!desc.hasConfigurable()) desc.setConfigurable(false);
+  return desc;
+}
+
+
 function PropertyDescriptor() {
   // Initialize here so they are all in-object and have the same map.
   // Default values from ES5 8.6.1.
@@ -533,25 +601,25 @@
 }
 
 
-// ES5 section 8.12.2.
-function GetProperty(obj, p) {
-  var prop = GetOwnProperty(obj);
-  if (!IS_UNDEFINED(prop)) return prop;
-  var proto = obj.__proto__;
-  if (IS_NULL(proto)) return void 0;
-  return GetProperty(proto, p);
-}
-
-
-// ES5 section 8.12.6
-function HasProperty(obj, p) {
-  var desc = GetProperty(obj, p);
-  return IS_UNDEFINED(desc) ? false : true;
-}
-
-
 // ES5 section 8.12.1.
 function GetOwnProperty(obj, p) {
+  if (%IsJSProxy(obj)) {
+    var handler = %GetHandler(obj);
+    var getOwnProperty = handler.getOwnPropertyDescriptor;
+    if (IS_UNDEFINED(getOwnProperty)) {
+      throw MakeTypeError("handler_trap_missing",
+                          [handler, "getOwnPropertyDescriptor"]);
+    }
+    var descriptor = %_CallFunction(handler, p, getOwnProperty);
+    if (IS_UNDEFINED(descriptor)) return descriptor;
+    var desc = ToCompletePropertyDescriptor(descriptor);
+    if (!desc.isConfigurable()) {
+      throw MakeTypeError("proxy_prop_not_configurable",
+                          [handler, "getOwnPropertyDescriptor", p, descriptor]);
+    }
+    return desc;
+  }
+
   // GetOwnProperty returns an array indexed by the constants
   // defined in macros.py.
   // If p is not a property on obj undefined is returned.
@@ -564,8 +632,33 @@
 }
 
 
+// Harmony proxies.
+function DefineProxyProperty(obj, p, attributes, should_throw) {
+  var handler = %GetHandler(obj);
+  var defineProperty = handler.defineProperty;
+  if (IS_UNDEFINED(defineProperty)) {
+    throw MakeTypeError("handler_trap_missing", [handler, "defineProperty"]);
+  }
+  var result = %_CallFunction(handler, p, attributes, defineProperty);
+  if (!ToBoolean(result)) {
+    if (should_throw) {
+      throw MakeTypeError("handler_returned_false",
+                          [handler, "defineProperty"]);
+    } else {
+      return false;
+    }
+  }
+  return true;
+}
+
+
 // ES5 8.12.9.
 function DefineOwnProperty(obj, p, desc, should_throw) {
+  if (%IsJSProxy(obj)) {
+    var attributes = FromGenericPropertyDescriptor(desc);
+    return DefineProxyProperty(obj, p, attributes, should_throw);
+  }
+
   var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p));
   // A false value here means that access checks failed.
   if (current_or_access === false) return void 0;
@@ -577,7 +670,7 @@
   // Step 3
   if (IS_UNDEFINED(current) && !extensible) {
     if (should_throw) {
-      throw MakeTypeError("define_disallowed", ["defineProperty"]);
+      throw MakeTypeError("define_disallowed", [p]);
     } else {
       return;
     }
@@ -607,7 +700,7 @@
           (desc.hasEnumerable() &&
            desc.isEnumerable() != current.isEnumerable())) {
         if (should_throw) {
-          throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+          throw MakeTypeError("redefine_disallowed", [p]);
         } else {
           return;
         }
@@ -617,7 +710,7 @@
         // Step 9a
         if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
           if (should_throw) {
-            throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+            throw MakeTypeError("redefine_disallowed", [p]);
           } else {
             return;
           }
@@ -626,7 +719,7 @@
         if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
           if (!current.isWritable() && desc.isWritable()) {
             if (should_throw) {
-              throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+              throw MakeTypeError("redefine_disallowed", [p]);
             } else {
               return;
             }
@@ -634,7 +727,7 @@
           if (!current.isWritable() && desc.hasValue() &&
               !SameValue(desc.getValue(), current.getValue())) {
             if (should_throw) {
-              throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+              throw MakeTypeError("redefine_disallowed", [p]);
             } else {
               return;
             }
@@ -644,14 +737,14 @@
         if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
           if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) {
             if (should_throw) {
-              throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+              throw MakeTypeError("redefine_disallowed", [p]);
             } else {
               return;
             }
           }
           if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) {
             if (should_throw) {
-              throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+              throw MakeTypeError("redefine_disallowed", [p]);
             } else {
               return;
             }
@@ -733,24 +826,57 @@
 function ObjectGetPrototypeOf(obj) {
   if (!IS_SPEC_OBJECT(obj))
     throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]);
-  return obj.__proto__;
+  return %GetPrototype(obj);
 }
 
 
 // ES5 section 15.2.3.3
 function ObjectGetOwnPropertyDescriptor(obj, p) {
   if (!IS_SPEC_OBJECT(obj))
-    throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyDescriptor"]);
+    throw MakeTypeError("obj_ctor_property_non_object",
+                        ["getOwnPropertyDescriptor"]);
   var desc = GetOwnProperty(obj, p);
   return FromPropertyDescriptor(desc);
 }
 
 
+// For Harmony proxies
+function ToStringArray(obj, trap) {
+  if (!IS_SPEC_OBJECT(obj)) {
+    throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]);
+  }
+  var n = ToUint32(obj.length);
+  var array = new $Array(n);
+  var names = {}
+  for (var index = 0; index < n; index++) {
+    var s = ToString(obj[index]);
+    if (s in names) {
+      throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s])
+    }
+    array[index] = s;
+    names.s = 0;
+  }
+  return array;
+}
+
+
 // ES5 section 15.2.3.4.
 function ObjectGetOwnPropertyNames(obj) {
   if (!IS_SPEC_OBJECT(obj))
     throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]);
 
+  // Special handling for proxies.
+  if (%IsJSProxy(obj)) {
+    var handler = %GetHandler(obj);
+    var getOwnPropertyNames = handler.getOwnPropertyNames;
+    if (IS_UNDEFINED(getOwnPropertyNames)) {
+      throw MakeTypeError("handler_trap_missing",
+                          [handler, "getOwnPropertyNames"]);
+    }
+    var names = %_CallFunction(handler, getOwnPropertyNames);
+    return ToStringArray(names, "getOwnPropertyNames");
+  }
+
   // Find all the indexed properties.
 
   // Get the local element names.
@@ -816,8 +942,37 @@
     throw MakeTypeError("obj_ctor_property_non_object", ["defineProperty"]);
   }
   var name = ToString(p);
-  var desc = ToPropertyDescriptor(attributes);
-  DefineOwnProperty(obj, name, desc, true);
+  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?).
+    var attributesClone = {}
+    for (var a in attributes) {
+      attributesClone[a] = attributes[a];
+    }
+    DefineProxyProperty(obj, name, attributesClone, true);
+    // The following would implement the spec as in the current proposal,
+    // but after recent comments on es-discuss, is most likely obsolete.
+    /*
+    var defineObj = FromGenericPropertyDescriptor(desc);
+    var names = ObjectGetOwnPropertyNames(attributes);
+    var standardNames =
+      {value: 0, writable: 0, get: 0, set: 0, enumerable: 0, configurable: 0};
+    for (var i = 0; i < names.length; i++) {
+      var N = names[i];
+      if (!(%HasLocalProperty(standardNames, N))) {
+        var attr = GetOwnProperty(attributes, N);
+        DefineOwnProperty(descObj, N, attr, true);
+      }
+    }
+    // This is really confusing the types, but it is what the proxies spec
+    // currently requires:
+    desc = descObj;
+    */
+  } else {
+    var desc = ToPropertyDescriptor(attributes);
+    DefineOwnProperty(obj, name, desc, true);
+  }
   return obj;
 }
 
@@ -845,19 +1000,41 @@
 }
 
 
+// Harmony proxies.
+function ProxyFix(obj) {
+  var handler = %GetHandler(obj);
+  var fix = handler.fix;
+  if (IS_UNDEFINED(fix)) {
+    throw MakeTypeError("handler_trap_missing", [handler, "fix"]);
+  }
+  var props = %_CallFunction(handler, fix);
+  if (IS_UNDEFINED(props)) {
+    throw MakeTypeError("handler_returned_undefined", [handler, "fix"]);
+  }
+  %Fix(obj);
+  ObjectDefineProperties(obj, props);
+}
+
+
 // ES5 section 15.2.3.8.
 function ObjectSeal(obj) {
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("obj_ctor_property_non_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 = GetOwnProperty(obj, name);
-    if (desc.isConfigurable()) desc.setConfigurable(false);
-    DefineOwnProperty(obj, name, desc, true);
+    if (desc.isConfigurable()) {
+      desc.setConfigurable(false);
+      DefineOwnProperty(obj, name, desc, true);
+    }
   }
-  return ObjectPreventExtension(obj);
+  %PreventExtensions(obj);
+  return obj;
 }
 
 
@@ -866,15 +1043,21 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("obj_ctor_property_non_object", ["freeze"]);
   }
+  if (%IsJSProxy(obj)) {
+    ProxyFix(obj);
+  }
   var names = ObjectGetOwnPropertyNames(obj);
   for (var i = 0; i < names.length; i++) {
     var name = names[i];
     var desc = GetOwnProperty(obj, name);
-    if (IsDataDescriptor(desc)) desc.setWritable(false);
-    if (desc.isConfigurable()) desc.setConfigurable(false);
-    DefineOwnProperty(obj, name, desc, true);
+    if (desc.isWritable() || desc.isConfigurable()) {
+      if (IsDataDescriptor(desc)) desc.setWritable(false);
+      desc.setConfigurable(false);
+      DefineOwnProperty(obj, name, desc, true);
+    }
   }
-  return ObjectPreventExtension(obj);
+  %PreventExtensions(obj);
+  return obj;
 }
 
 
@@ -883,6 +1066,9 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("obj_ctor_property_non_object", ["preventExtension"]);
   }
+  if (%IsJSProxy(obj)) {
+    ProxyFix(obj);
+  }
   %PreventExtensions(obj);
   return obj;
 }
@@ -893,6 +1079,9 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("obj_ctor_property_non_object", ["isSealed"]);
   }
+  if (%IsJSProxy(obj)) {
+    return false;
+  }
   var names = ObjectGetOwnPropertyNames(obj);
   for (var i = 0; i < names.length; i++) {
     var name = names[i];
@@ -911,6 +1100,9 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("obj_ctor_property_non_object", ["isFrozen"]);
   }
+  if (%IsJSProxy(obj)) {
+    return false;
+  }
   var names = ObjectGetOwnPropertyNames(obj);
   for (var i = 0; i < names.length; i++) {
     var name = names[i];
@@ -928,7 +1120,10 @@
 // ES5 section 15.2.3.13
 function ObjectIsExtensible(obj) {
   if (!IS_SPEC_OBJECT(obj)) {
-    throw MakeTypeError("obj_ctor_property_non_object", ["preventExtension"]);
+    throw MakeTypeError("obj_ctor_property_non_object", ["isExtensible"]);
+  }
+  if (%IsJSProxy(obj)) {
+    return true;
   }
   return %IsExtensible(obj);
 }
@@ -1199,7 +1394,9 @@
     }
   }
 
-  var name = %FunctionGetName(func);
+  var name = %FunctionNameShouldPrintAsAnonymous(func)
+      ? 'anonymous'
+      : %FunctionGetName(func);
   return 'function ' + name + source;
 }
 
@@ -1270,7 +1467,8 @@
   // Set the correct length.
   var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0;
   %FunctionSetLength(result, length);
-
+  %FunctionRemovePrototype(result);
+  %FunctionSetBound(result);
   return result;
 }
 
@@ -1293,7 +1491,7 @@
   // The call to SetNewFunctionAttributes will ensure the prototype
   // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
   var f = %CompileString(source)();
-  %FunctionSetName(f, "anonymous");
+  %FunctionMarkNameShouldPrintAsAnonymous(f);
   return %SetNewFunctionAttributes(f);
 }
 
diff --git a/src/v8threads.cc b/src/v8threads.cc
index 26169b5..c9a8bb6 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -46,7 +46,7 @@
 // current thread will be guaranteed to have the lock for a given isolate.
 Locker::Locker(v8::Isolate* isolate)
   : has_lock_(false),
-    top_level_(false),
+    top_level_(true),
     isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
   if (isolate_ == NULL) {
     isolate_ = i::Isolate::GetDefaultIsolateForLocking();
@@ -401,9 +401,10 @@
 
 
 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms)
-  : Thread(isolate, "v8:CtxtSwitcher"),
+  : Thread("v8:CtxtSwitcher"),
     keep_going_(true),
-    sleep_ms_(every_n_ms) {
+    sleep_ms_(every_n_ms),
+    isolate_(isolate) {
 }
 
 
@@ -411,7 +412,7 @@
 // ContextSwitcher thread if needed.
 void ContextSwitcher::StartPreemption(int every_n_ms) {
   Isolate* isolate = Isolate::Current();
-  ASSERT(Locker::IsLocked());
+  ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate)));
   if (isolate->context_switcher() == NULL) {
     // If the ContextSwitcher thread is not running at the moment start it now.
     isolate->set_context_switcher(new ContextSwitcher(isolate, every_n_ms));
@@ -428,7 +429,7 @@
 // must cooperatively schedule amongst them from this point on.
 void ContextSwitcher::StopPreemption() {
   Isolate* isolate = Isolate::Current();
-  ASSERT(Locker::IsLocked());
+  ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate)));
   if (isolate->context_switcher() != NULL) {
     // The ContextSwitcher thread is running. We need to stop it and release
     // its resources.
diff --git a/src/v8threads.h b/src/v8threads.h
index d8a923e..3ba823a 100644
--- a/src/v8threads.h
+++ b/src/v8threads.h
@@ -152,12 +152,15 @@
   static void PreemptionReceived();
 
  private:
-  explicit ContextSwitcher(Isolate* isolate, int every_n_ms);
+  ContextSwitcher(Isolate* isolate, int every_n_ms);
+
+  Isolate* isolate() const { return isolate_; }
 
   void Run();
 
   bool keep_going_;
   int sleep_ms_;
+  Isolate* isolate_;
 };
 
 } }  // namespace v8::internal
diff --git a/src/v8utils.cc b/src/v8utils.cc
new file mode 100644
index 0000000..bf0e05d
--- /dev/null
+++ b/src/v8utils.cc
@@ -0,0 +1,360 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdarg.h>
+
+#include "v8.h"
+
+#include "platform.h"
+
+#include "sys/stat.h"
+
+namespace v8 {
+namespace internal {
+
+
+void PrintF(const char* format, ...) {
+  va_list arguments;
+  va_start(arguments, format);
+  OS::VPrint(format, arguments);
+  va_end(arguments);
+}
+
+
+void PrintF(FILE* out, const char* format, ...) {
+  va_list arguments;
+  va_start(arguments, format);
+  OS::VFPrint(out, format, arguments);
+  va_end(arguments);
+}
+
+
+void Flush(FILE* out) {
+  fflush(out);
+}
+
+
+char* ReadLine(const char* prompt) {
+  char* result = NULL;
+  char line_buf[256];
+  int offset = 0;
+  bool keep_going = true;
+  fprintf(stdout, "%s", prompt);
+  fflush(stdout);
+  while (keep_going) {
+    if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
+      // fgets got an error. Just give up.
+      if (result != NULL) {
+        DeleteArray(result);
+      }
+      return NULL;
+    }
+    int len = StrLength(line_buf);
+    if (len > 1 &&
+        line_buf[len - 2] == '\\' &&
+        line_buf[len - 1] == '\n') {
+      // When we read a line that ends with a "\" we remove the escape and
+      // append the remainder.
+      line_buf[len - 2] = '\n';
+      line_buf[len - 1] = 0;
+      len -= 1;
+    } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
+      // Since we read a new line we are done reading the line. This
+      // will exit the loop after copying this buffer into the result.
+      keep_going = false;
+    }
+    if (result == NULL) {
+      // Allocate the initial result and make room for the terminating '\0'
+      result = NewArray<char>(len + 1);
+    } else {
+      // Allocate a new result with enough room for the new addition.
+      int new_len = offset + len + 1;
+      char* new_result = NewArray<char>(new_len);
+      // Copy the existing input into the new array and set the new
+      // array as the result.
+      memcpy(new_result, result, offset * kCharSize);
+      DeleteArray(result);
+      result = new_result;
+    }
+    // Copy the newly read line into the result.
+    memcpy(result + offset, line_buf, len * kCharSize);
+    offset += len;
+  }
+  ASSERT(result != NULL);
+  result[offset] = '\0';
+  return result;
+}
+
+
+char* ReadCharsFromFile(FILE* file,
+                        int* size,
+                        int extra_space,
+                        bool verbose,
+                        const char* filename) {
+  if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
+    if (verbose) {
+      OS::PrintError("Cannot read from file %s.\n", filename);
+    }
+    return NULL;
+  }
+
+  // Get the size of the file and rewind it.
+  *size = ftell(file);
+  rewind(file);
+
+  char* result = NewArray<char>(*size + extra_space);
+  for (int i = 0; i < *size && feof(file) == 0;) {
+    int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
+    if (read != (*size - i) && ferror(file) != 0) {
+      fclose(file);
+      DeleteArray(result);
+      return NULL;
+    }
+    i += read;
+  }
+  return result;
+}
+
+
+char* ReadCharsFromFile(const char* filename,
+                        int* size,
+                        int extra_space,
+                        bool verbose) {
+  FILE* file = OS::FOpen(filename, "rb");
+  char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
+  if (file != NULL) fclose(file);
+  return result;
+}
+
+
+byte* ReadBytes(const char* filename, int* size, bool verbose) {
+  char* chars = ReadCharsFromFile(filename, size, 0, verbose);
+  return reinterpret_cast<byte*>(chars);
+}
+
+
+static Vector<const char> SetVectorContents(char* chars,
+                                            int size,
+                                            bool* exists) {
+  if (!chars) {
+    *exists = false;
+    return Vector<const char>::empty();
+  }
+  chars[size] = '\0';
+  *exists = true;
+  return Vector<const char>(chars, size);
+}
+
+
+Vector<const char> ReadFile(const char* filename,
+                            bool* exists,
+                            bool verbose) {
+  int size;
+  char* result = ReadCharsFromFile(filename, &size, 1, verbose);
+  return SetVectorContents(result, size, exists);
+}
+
+
+Vector<const char> ReadFile(FILE* file,
+                            bool* exists,
+                            bool verbose) {
+  int size;
+  char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
+  return SetVectorContents(result, size, exists);
+}
+
+
+int WriteCharsToFile(const char* str, int size, FILE* f) {
+  int total = 0;
+  while (total < size) {
+    int write = static_cast<int>(fwrite(str, 1, size - total, f));
+    if (write == 0) {
+      return total;
+    }
+    total += write;
+    str += write;
+  }
+  return total;
+}
+
+
+int AppendChars(const char* filename,
+                const char* str,
+                int size,
+                bool verbose) {
+  FILE* f = OS::FOpen(filename, "ab");
+  if (f == NULL) {
+    if (verbose) {
+      OS::PrintError("Cannot open file %s for writing.\n", filename);
+    }
+    return 0;
+  }
+  int written = WriteCharsToFile(str, size, f);
+  fclose(f);
+  return written;
+}
+
+
+int WriteChars(const char* filename,
+               const char* str,
+               int size,
+               bool verbose) {
+  FILE* f = OS::FOpen(filename, "wb");
+  if (f == NULL) {
+    if (verbose) {
+      OS::PrintError("Cannot open file %s for writing.\n", filename);
+    }
+    return 0;
+  }
+  int written = WriteCharsToFile(str, size, f);
+  fclose(f);
+  return written;
+}
+
+
+int WriteBytes(const char* filename,
+               const byte* bytes,
+               int size,
+               bool verbose) {
+  const char* str = reinterpret_cast<const char*>(bytes);
+  return WriteChars(filename, str, size, verbose);
+}
+
+
+
+void StringBuilder::AddFormatted(const char* format, ...) {
+  va_list arguments;
+  va_start(arguments, format);
+  AddFormattedList(format, arguments);
+  va_end(arguments);
+}
+
+
+void StringBuilder::AddFormattedList(const char* format, va_list list) {
+  ASSERT(!is_finalized() && position_ < buffer_.length());
+  int n = OS::VSNPrintF(buffer_ + position_, format, list);
+  if (n < 0 || n >= (buffer_.length() - position_)) {
+    position_ = buffer_.length();
+  } else {
+    position_ += n;
+  }
+}
+
+
+MemoryMappedExternalResource::MemoryMappedExternalResource(const char* filename)
+    : filename_(NULL),
+      data_(NULL),
+      length_(0),
+      remove_file_on_cleanup_(false) {
+  Init(filename);
+}
+
+
+MemoryMappedExternalResource::
+    MemoryMappedExternalResource(const char* filename,
+                                 bool remove_file_on_cleanup)
+    : filename_(NULL),
+      data_(NULL),
+      length_(0),
+      remove_file_on_cleanup_(remove_file_on_cleanup) {
+  Init(filename);
+}
+
+
+MemoryMappedExternalResource::~MemoryMappedExternalResource() {
+  // Release the resources if we had successfully acquired them:
+  if (file_ != NULL) {
+    delete file_;
+    if (remove_file_on_cleanup_) {
+      OS::Remove(filename_);
+    }
+    DeleteArray<char>(filename_);
+  }
+}
+
+
+void MemoryMappedExternalResource::Init(const char* filename) {
+  file_ = OS::MemoryMappedFile::open(filename);
+  if (file_ != NULL) {
+    filename_ = StrDup(filename);
+    data_ = reinterpret_cast<char*>(file_->memory());
+    length_ = file_->size();
+  }
+}
+
+
+bool MemoryMappedExternalResource::EnsureIsAscii(bool abort_if_failed) const {
+  bool is_ascii = true;
+
+  int line_no = 1;
+  const char* start_of_line = data_;
+  const char* end = data_ + length_;
+  for (const char* p = data_; p < end; p++) {
+    char c = *p;
+    if ((c & 0x80) != 0) {
+      // Non-ascii detected:
+      is_ascii = false;
+
+      // Report the error and abort if appropriate:
+      if (abort_if_failed) {
+        int char_no = static_cast<int>(p - start_of_line) - 1;
+
+        ASSERT(filename_ != NULL);
+        PrintF("\n\n\n"
+               "Abort: Non-Ascii character 0x%.2x in file %s line %d char %d",
+               c, filename_, line_no, char_no);
+
+        // Allow for some context up to kNumberOfLeadingContextChars chars
+        // before the offending non-ascii char to help the user see where
+        // the offending char is.
+        const int kNumberOfLeadingContextChars = 10;
+        const char* err_context = p - kNumberOfLeadingContextChars;
+        if (err_context < data_) {
+          err_context = data_;
+        }
+        // Compute the length of the error context and print it.
+        int err_context_length = static_cast<int>(p - err_context);
+        if (err_context_length != 0) {
+          PrintF(" after \"%.*s\"", err_context_length, err_context);
+        }
+        PrintF(".\n\n\n");
+        OS::Abort();
+      }
+
+      break;  // Non-ascii detected.  No need to continue scanning.
+    }
+    if (c == '\n') {
+      start_of_line = p;
+      line_no++;
+    }
+  }
+
+  return is_ascii;
+}
+
+
+} }  // namespace v8::internal
diff --git a/src/v8utils.h b/src/v8utils.h
index 93fc1fd..aada521 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -188,73 +188,11 @@
 Vector<const char> ReadFile(const char* filename,
                             bool* exists,
                             bool verbose = true);
+Vector<const char> ReadFile(FILE* file,
+                            bool* exists,
+                            bool verbose = true);
 
 
-// Helper class for building result strings in a character buffer. The
-// purpose of the class is to use safe operations that checks the
-// buffer bounds on all operations in debug mode.
-class StringBuilder {
- public:
-  // Create a string builder with a buffer of the given size. The
-  // buffer is allocated through NewArray<char> and must be
-  // deallocated by the caller of Finalize().
-  explicit StringBuilder(int size);
-
-  StringBuilder(char* buffer, int size)
-      : buffer_(buffer, size), position_(0) { }
-
-  ~StringBuilder() { if (!is_finalized()) Finalize(); }
-
-  int size() const { return buffer_.length(); }
-
-  // Get the current position in the builder.
-  int position() const {
-    ASSERT(!is_finalized());
-    return position_;
-  }
-
-  // Reset the position.
-  void Reset() { position_ = 0; }
-
-  // Add a single character to the builder. It is not allowed to add
-  // 0-characters; use the Finalize() method to terminate the string
-  // instead.
-  void AddCharacter(char c) {
-    ASSERT(c != '\0');
-    ASSERT(!is_finalized() && position_ < buffer_.length());
-    buffer_[position_++] = c;
-  }
-
-  // Add an entire string to the builder. Uses strlen() internally to
-  // compute the length of the input string.
-  void AddString(const char* s);
-
-  // Add the first 'n' characters of the given string 's' to the
-  // builder. The input string must have enough characters.
-  void AddSubstring(const char* s, int n);
-
-  // Add formatted contents to the builder just like printf().
-  void AddFormatted(const char* format, ...);
-
-  // Add formatted contents like printf based on a va_list.
-  void AddFormattedList(const char* format, va_list list);
-
-  // Add character padding to the builder. If count is non-positive,
-  // nothing is added to the builder.
-  void AddPadding(char c, int count);
-
-  // Finalize the string by 0-terminating it and returning the buffer.
-  char* Finalize();
-
- private:
-  Vector<char> buffer_;
-  int position_;
-
-  bool is_finalized() const { return position_ < 0; }
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
-};
-
 
 // Copy from ASCII/16bit chars to ASCII/16bit chars.
 template <typename sourcechar, typename sinkchar>
@@ -313,6 +251,19 @@
   bool remove_file_on_cleanup_;
 };
 
+class StringBuilder : public SimpleStringBuilder {
+ public:
+  explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
+  StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
+
+  // Add formatted contents to the builder just like printf().
+  void AddFormatted(const char* format, ...);
+
+  // Add formatted contents like printf based on a va_list.
+  void AddFormattedList(const char* format, va_list list);
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+};
 
 } }  // namespace v8::internal
 
diff --git a/src/variables.cc b/src/variables.cc
index 0502722..67150ea 100644
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -57,32 +57,26 @@
 }
 
 
-Slot* Variable::AsSlot() const {
-  return rewrite_ == NULL ? NULL : rewrite_->AsSlot();
-}
+Slot* Variable::AsSlot() const { return rewrite_; }
 
 
 bool Variable::IsStackAllocated() const {
-  Slot* slot = AsSlot();
-  return slot != NULL && slot->IsStackAllocated();
+  return rewrite_ != NULL && rewrite_->IsStackAllocated();
 }
 
 
 bool Variable::IsParameter() const {
-  Slot* s = AsSlot();
-  return s != NULL && s->type() == Slot::PARAMETER;
+  return rewrite_ != NULL && rewrite_->type() == Slot::PARAMETER;
 }
 
 
 bool Variable::IsStackLocal() const {
-  Slot* s = AsSlot();
-  return s != NULL && s->type() == Slot::LOCAL;
+  return rewrite_ != NULL && rewrite_->type() == Slot::LOCAL;
 }
 
 
 bool Variable::IsContextSlot() const {
-  Slot* s = AsSlot();
-  return s != NULL && s->type() == Slot::CONTEXT;
+  return rewrite_ != NULL && rewrite_->type() == Slot::CONTEXT;
 }
 
 
diff --git a/src/variables.h b/src/variables.h
index b1ff0db..a9c06d1 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -81,7 +81,7 @@
   // Printing support
   static const char* Mode2String(Mode mode);
 
-  // Type testing & conversion
+  // Type testing & conversion.  Global variables are not slots.
   Property* AsProperty() const;
   Slot* AsSlot() const;
 
@@ -138,8 +138,8 @@
     local_if_not_shadowed_ = local;
   }
 
-  Expression* rewrite() const { return rewrite_; }
-  void set_rewrite(Expression* expr) { rewrite_ = expr; }
+  Slot* rewrite() const { return rewrite_; }
+  void set_rewrite(Slot* slot) { rewrite_ = slot; }
 
  private:
   Scope* scope_;
@@ -150,8 +150,7 @@
   Variable* local_if_not_shadowed_;
 
   // Code generation.
-  // rewrite_ is usually a Slot or a Property, but may be any expression.
-  Expression* rewrite_;
+  Slot* rewrite_;
 
   // Valid as a LHS? (const and this are not valid LHS, for example)
   bool is_valid_LHS_;
diff --git a/src/version.cc b/src/version.cc
index 34549fa..fcf6f88 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -33,9 +33,9 @@
 // NOTE these macros are used by the SCons build script so their names
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
-#define MINOR_VERSION     3
-#define BUILD_NUMBER      10
-#define PATCH_LEVEL       39
+#define MINOR_VERSION     4
+#define BUILD_NUMBER      14
+#define PATCH_LEVEL       35
 // 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/vm-state-inl.h b/src/vm-state-inl.h
index 1f363de..c647e56 100644
--- a/src/vm-state-inl.h
+++ b/src/vm-state-inl.h
@@ -39,7 +39,6 @@
 // logger and partially threaded through the call stack.  States are pushed by
 // VMState construction and popped by destruction.
 //
-#ifdef ENABLE_VMSTATE_TRACKING
 inline const char* StateToString(StateTag state) {
   switch (state) {
     case JS:
@@ -61,32 +60,16 @@
 
 VMState::VMState(Isolate* isolate, StateTag tag)
     : isolate_(isolate), previous_tag_(isolate->current_vm_state()) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_state_changes) {
     LOG(isolate, UncheckedStringEvent("Entering", StateToString(tag)));
     LOG(isolate, UncheckedStringEvent("From", StateToString(previous_tag_)));
   }
-#endif
 
   isolate_->SetCurrentVMState(tag);
-
-#ifdef ENABLE_HEAP_PROTECTION
-  if (FLAG_protect_heap) {
-    if (tag == EXTERNAL) {
-      // We are leaving V8.
-      ASSERT(previous_tag_ != EXTERNAL);
-      isolate_->heap()->Protect();
-    } else if (previous_tag_ = EXTERNAL) {
-      // We are entering V8.
-      isolate_->heap()->Unprotect();
-    }
-  }
-#endif
 }
 
 
 VMState::~VMState() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_state_changes) {
     LOG(isolate_,
         UncheckedStringEvent("Leaving",
@@ -94,32 +77,10 @@
     LOG(isolate_,
         UncheckedStringEvent("To", StateToString(previous_tag_)));
   }
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
-#ifdef ENABLE_HEAP_PROTECTION
-  StateTag tag = isolate_->current_vm_state();
-#endif
 
   isolate_->SetCurrentVMState(previous_tag_);
-
-#ifdef ENABLE_HEAP_PROTECTION
-  if (FLAG_protect_heap) {
-    if (tag == EXTERNAL) {
-      // We are reentering V8.
-      ASSERT(previous_tag_ != EXTERNAL);
-      isolate_->heap()->Unprotect();
-    } else if (previous_tag_ == EXTERNAL) {
-      // We are leaving V8.
-      isolate_->heap()->Protect();
-    }
-  }
-#endif  // ENABLE_HEAP_PROTECTION
 }
 
-#endif  // ENABLE_VMSTATE_TRACKING
-
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
 
 ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback)
     : isolate_(isolate), previous_callback_(isolate->external_callback()) {
@@ -130,8 +91,6 @@
   isolate_->set_external_callback(previous_callback_);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 
 } }  // namespace v8::internal
 
diff --git a/src/vm-state.h b/src/vm-state.h
index 2062340..831e2d3 100644
--- a/src/vm-state.h
+++ b/src/vm-state.h
@@ -35,7 +35,6 @@
 namespace internal {
 
 class VMState BASE_EMBEDDED {
-#ifdef ENABLE_VMSTATE_TRACKING
  public:
   inline VMState(Isolate* isolate, StateTag tag);
   inline ~VMState();
@@ -43,26 +42,16 @@
  private:
   Isolate* isolate_;
   StateTag previous_tag_;
-
-#else
- public:
-  VMState(Isolate* isolate, StateTag state) {}
-#endif
 };
 
 
 class ExternalCallbackScope BASE_EMBEDDED {
-#ifdef ENABLE_LOGGING_AND_PROFILING
  public:
   inline ExternalCallbackScope(Isolate* isolate, Address callback);
   inline ~ExternalCallbackScope();
  private:
   Isolate* isolate_;
   Address previous_callback_;
-#else
- public:
-  ExternalCallbackScope(Isolate* isolate, Address callback) {}
-#endif
 };
 
 } }  // namespace v8::internal
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 7769b03..c23eb16 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -125,7 +125,7 @@
     return names[index];
   }
 
-  static Register toRegister(int code) {
+  static Register from_code(int code) {
     Register r = { code };
     return r;
   }
@@ -640,6 +640,7 @@
   void push_imm32(int32_t imm32);
   void push(Register src);
   void push(const Operand& src);
+  void push(Handle<Object> handle);
 
   void pop(Register dst);
   void pop(const Operand& dst);
@@ -1167,7 +1168,7 @@
   // Call near relative 32-bit displacement, relative to next instruction.
   void call(Label* L);
   void call(Handle<Code> target,
-            RelocInfo::Mode rmode,
+            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
             unsigned ast_id = kNoASTId);
 
   // Calls directly to the given address using a relative offset.
@@ -1349,7 +1350,9 @@
   void Print();
 
   // Check the code size generated from label to here.
-  int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); }
+  int SizeOfCodeGeneratedSince(Label* label) {
+    return pc_offset() - label->pos();
+  }
 
   // Mark address of the ExitJSFrame code.
   void RecordJSReturn();
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index fc4581c..0763989 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -362,8 +362,9 @@
   __ JumpIfSmi(rax, &use_receiver);
 
   // If the type of the result (stored in its map) is less than
-  // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
-  __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+  // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
+  STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+  __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
   __ j(above_equal, &exit);
 
   // Throw away the result of the constructor invocation and use the
@@ -675,8 +676,8 @@
 
     // Do not transform the receiver for natives.
     // SharedFunctionInfo is already loaded into rbx.
-    __ testb(FieldOperand(rbx, SharedFunctionInfo::kES5NativeByteOffset),
-             Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
+    __ testb(FieldOperand(rbx, SharedFunctionInfo::kNativeByteOffset),
+             Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
     __ j(not_zero, &shift_arguments);
 
     // Compute the receiver in non-strict mode.
@@ -688,9 +689,8 @@
     __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
     __ j(equal, &use_global_receiver);
 
-    STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-    STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-    __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, rcx);
+    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+    __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, rcx);
     __ j(above_equal, &shift_arguments);
 
     __ bind(&convert_to_object);
@@ -847,9 +847,9 @@
   __ j(not_equal, &push_receiver);
 
   // Do not transform the receiver for natives.
-  __ testb(FieldOperand(rdx, SharedFunctionInfo::kES5NativeByteOffset),
-           Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
-  __ j(not_zero, &push_receiver);
+  __ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset),
+           Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
+  __ j(not_equal, &push_receiver);
 
   // Compute the receiver in non-strict mode.
   __ JumpIfSmi(rbx, &call_to_object, Label::kNear);
@@ -860,9 +860,8 @@
 
   // If given receiver is already a JavaScript object then there's no
   // reason for converting it.
-  STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
-  STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, rcx);
+  STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+  __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, rcx);
   __ j(above_equal, &push_receiver);
 
   // Convert the receiver to an object.
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 7075e66..1a6efcb 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -125,18 +125,17 @@
   __ movq(rcx, Operand(rsp, 1 * kPointerSize));
 
   // Setup the object header.
-  __ LoadRoot(kScratchRegister, Heap::kContextMapRootIndex);
+  __ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex);
   __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
   __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));
 
   // Setup the fixed slots.
   __ Set(rbx, 0);  // Set to NULL.
   __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
-  __ movq(Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)), rax);
-  __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rbx);
+  __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rsi);
   __ movq(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)), rbx);
 
-  // Copy the global object from the surrounding context.
+  // Copy the global object from the previous context.
   __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx);
 
@@ -152,7 +151,7 @@
 
   // Need to collect. Call into runtime system.
   __ bind(&gc);
-  __ TailCallRuntime(Runtime::kNewContext, 1, 1);
+  __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1);
 }
 
 
@@ -231,8 +230,11 @@
 }
 
 
+// The stub returns zero for false, and a non-zero value for true.
 void ToBooleanStub::Generate(MacroAssembler* masm) {
   Label false_result, true_result, not_string;
+  const Register map = rdx;
+
   __ movq(rax, Operand(rsp, 1 * kPointerSize));
 
   // undefined -> false
@@ -248,51 +250,47 @@
   // Smis: 0 -> false, all other -> true
   __ Cmp(rax, Smi::FromInt(0));
   __ j(equal, &false_result);
-  Condition is_smi = __ CheckSmi(rax);
-  __ j(is_smi, &true_result);
+  __ JumpIfSmi(rax, &true_result);
 
-  // 'null' => false.
+  // 'null' -> false.
   __ CompareRoot(rax, Heap::kNullValueRootIndex);
   __ j(equal, &false_result, Label::kNear);
 
-  // Get the map and type of the heap object.
-  // We don't use CmpObjectType because we manipulate the type field.
-  __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
-  __ movzxbq(rcx, FieldOperand(rdx, Map::kInstanceTypeOffset));
+  // Get the map of the heap object.
+  __ movq(map, FieldOperand(rax, HeapObject::kMapOffset));
 
-  // Undetectable => false.
-  __ movzxbq(rbx, FieldOperand(rdx, Map::kBitFieldOffset));
-  __ and_(rbx, Immediate(1 << Map::kIsUndetectable));
+  // Undetectable -> false.
+  __ testb(FieldOperand(map, Map::kBitFieldOffset),
+           Immediate(1 << Map::kIsUndetectable));
   __ j(not_zero, &false_result, Label::kNear);
 
-  // JavaScript object => true.
-  __ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE));
+  // JavaScript object -> true.
+  __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
   __ j(above_equal, &true_result, Label::kNear);
 
-  // String value => false iff empty.
-  __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
+  // String value -> false iff empty.
+  __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
   __ j(above_equal, &not_string, Label::kNear);
-  __ movq(rdx, FieldOperand(rax, String::kLengthOffset));
-  __ SmiTest(rdx);
+  __ cmpq(FieldOperand(rax, String::kLengthOffset), Immediate(0));
   __ j(zero, &false_result, Label::kNear);
   __ jmp(&true_result, Label::kNear);
 
   __ bind(&not_string);
-  __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
-  __ j(not_equal, &true_result, Label::kNear);
-  // HeapNumber => false iff +0, -0, or NaN.
+  // HeapNumber -> false iff +0, -0, or NaN.
   // These three cases set the zero flag when compared to zero using ucomisd.
+  __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
+  __ j(not_equal, &true_result, Label::kNear);
   __ xorps(xmm0, xmm0);
   __ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
   __ j(zero, &false_result, Label::kNear);
   // Fall through to |true_result|.
 
-  // Return 1/0 for true/false in rax.
+  // Return 1/0 for true/false in tos_.
   __ bind(&true_result);
-  __ Set(rax, 1);
+  __ Set(tos_, 1);
   __ ret(1 * kPointerSize);
   __ bind(&false_result);
-  __ Set(rax, 0);
+  __ Set(tos_, 0);
   __ ret(1 * kPointerSize);
 }
 
@@ -406,12 +404,6 @@
 }
 
 
-Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info) {
-  UnaryOpStub stub(key, type_info);
-  return stub.GetCode();
-}
-
-
 void UnaryOpStub::Generate(MacroAssembler* masm) {
   switch (operand_type_) {
     case UnaryOpIC::UNINITIALIZED:
@@ -432,12 +424,10 @@
 
 void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
   __ pop(rcx);  // Save return address.
-  __ push(rax);
-  // Left and right arguments are now on top.
-  // Push this stub's key. Although the operation and the type info are
-  // encoded into the key, the encoding is opaque, so push them too.
-  __ Push(Smi::FromInt(MinorKey()));
+
+  __ push(rax);  // the operand
   __ Push(Smi::FromInt(op_));
+  __ Push(Smi::FromInt(mode_));
   __ Push(Smi::FromInt(operand_type_));
 
   __ push(rcx);  // Push return address.
@@ -445,10 +435,7 @@
   // Patch the caller to an appropriate specialized stub and return the
   // operation result to the caller of the stub.
   __ TailCallExternalReference(
-      ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
-                        masm->isolate()),
-      4,
-      1);
+      ExternalReference(IC_Utility(IC::kUnaryOp_Patch), masm->isolate()), 4, 1);
 }
 
 
@@ -655,33 +642,17 @@
 }
 
 
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
-}
-
-
-Handle<Code> GetBinaryOpStub(int key,
-                             BinaryOpIC::TypeInfo type_info,
-                             BinaryOpIC::TypeInfo result_type_info) {
-  BinaryOpStub stub(key, type_info, result_type_info);
-  return stub.GetCode();
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -742,12 +713,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -756,13 +722,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -1959,49 +1922,288 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+  // Stack layout:
+  //  rsp[0] : return address
+  //  rsp[8] : number of parameters (tagged)
+  //  rsp[16] : receiver displacement
+  //  rsp[24] : function
+  // Registers used over the whole function:
+  //  rbx: the mapped parameter count (untagged)
+  //  rax: the allocated object (tagged).
+
+  Factory* factory = masm->isolate()->factory();
+
+  __ SmiToInteger64(rbx, Operand(rsp, 1 * kPointerSize));
+  // rbx = parameter count (untagged)
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label runtime;
+  Label adaptor_frame, try_allocate;
+  __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
+  __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
+  __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+  __ j(equal, &adaptor_frame);
+
+  // No adaptor, parameter count = argument count.
+  __ movq(rcx, rbx);
+  __ jmp(&try_allocate, Label::kNear);
+
+  // We have an adaptor frame. Patch the parameters pointer.
+  __ bind(&adaptor_frame);
+  __ SmiToInteger64(rcx,
+                    Operand(rdx,
+                            ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
+                      StandardFrameConstants::kCallerSPOffset));
+  __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+
+  // rbx = parameter count (untagged)
+  // rcx = argument count (untagged)
+  // Compute the mapped parameter count = min(rbx, rcx) in rbx.
+  __ cmpq(rbx, rcx);
+  __ j(less_equal, &try_allocate, Label::kNear);
+  __ movq(rbx, rcx);
+
+  __ 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;
+  Label no_parameter_map;
+  __ testq(rbx, rbx);
+  __ j(zero, &no_parameter_map, Label::kNear);
+  __ lea(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize));
+  __ bind(&no_parameter_map);
+
+  // 2. Backing store.
+  __ lea(r8, Operand(r8, rcx, times_pointer_size, FixedArray::kHeaderSize));
+
+  // 3. Arguments object.
+  __ addq(r8, Immediate(Heap::kArgumentsObjectSize));
+
+  // Do the allocation of all three objects in one go.
+  __ AllocateInNewSpace(r8, rax, rdx, rdi, &runtime, TAG_OBJECT);
+
+  // rax = address of new object(s) (tagged)
+  // rcx = argument count (untagged)
+  // Get the arguments boilerplate from the current (global) context into rdi.
+  Label has_mapped_parameters, copy;
+  __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
+  __ testq(rbx, rbx);
+  __ j(not_zero, &has_mapped_parameters, Label::kNear);
+
+  const int kIndex = Context::ARGUMENTS_BOILERPLATE_INDEX;
+  __ movq(rdi, Operand(rdi, Context::SlotOffset(kIndex)));
+  __ jmp(&copy, Label::kNear);
+
+  const int kAliasedIndex = Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX;
+  __ bind(&has_mapped_parameters);
+  __ movq(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex)));
+  __ bind(&copy);
+
+  // rax = address of new object (tagged)
+  // rbx = mapped parameter count (untagged)
+  // rcx = argument count (untagged)
+  // rdi = address of boilerplate object (tagged)
+  // Copy the JS object part.
+  for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
+    __ movq(rdx, FieldOperand(rdi, i));
+    __ movq(FieldOperand(rax, i), rdx);
+  }
+
+  // Setup the callee in-object property.
+  STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
+  __ movq(rdx, Operand(rsp, 3 * kPointerSize));
+  __ movq(FieldOperand(rax, JSObject::kHeaderSize +
+                       Heap::kArgumentsCalleeIndex * kPointerSize),
+          rdx);
+
+  // Use the length (smi tagged) and set that as an in-object property too.
+  // Note: rcx is tagged from here on.
+  STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
+  __ Integer32ToSmi(rcx, rcx);
+  __ movq(FieldOperand(rax, JSObject::kHeaderSize +
+                       Heap::kArgumentsLengthIndex * kPointerSize),
+          rcx);
+
+  // Setup the elements pointer in the allocated arguments object.
+  // If we allocated a parameter map, edi will point there, otherwise to the
+  // backing store.
+  __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize));
+  __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
+
+  // rax = address of new object (tagged)
+  // rbx = mapped parameter count (untagged)
+  // rcx = argument count (tagged)
+  // rdi = address of parameter map or backing store (tagged)
+
+  // Initialize parameter map. If there are no mapped arguments, we're done.
+  Label skip_parameter_map;
+  __ testq(rbx, rbx);
+  __ j(zero, &skip_parameter_map);
+
+  __ LoadRoot(kScratchRegister, Heap::kNonStrictArgumentsElementsMapRootIndex);
+  // rbx contains the untagged argument count. Add 2 and tag to write.
+  __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
+  __ Integer64PlusConstantToSmi(r9, rbx, 2);
+  __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), r9);
+  __ movq(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi);
+  __ lea(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
+  __ movq(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9);
+
+  // 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;
+
+  // Load tagged parameter count into r9.
+  __ movq(r9, Operand(rsp, 1 * kPointerSize));
+  __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
+  __ addq(r8, Operand(rsp, 3 * kPointerSize));
+  __ subq(r8, r9);
+  __ Move(r11, factory->the_hole_value());
+  __ movq(rdx, rdi);
+  __ SmiToInteger64(kScratchRegister, r9);
+  __ lea(rdi, Operand(rdi, kScratchRegister,
+                      times_pointer_size,
+                      kParameterMapHeaderSize));
+  // r9 = loop variable (tagged)
+  // r8 = mapping index (tagged)
+  // r11 = the hole value
+  // rdx = address of parameter map (tagged)
+  // rdi = address of backing store (tagged)
+  __ jmp(&parameters_test, Label::kNear);
+
+  __ bind(&parameters_loop);
+  __ SmiSubConstant(r9, r9, Smi::FromInt(1));
+  __ SmiToInteger64(kScratchRegister, r9);
+  __ movq(FieldOperand(rdx, kScratchRegister,
+                       times_pointer_size,
+                       kParameterMapHeaderSize),
+          r8);
+  __ movq(FieldOperand(rdi, kScratchRegister,
+                       times_pointer_size,
+                       FixedArray::kHeaderSize),
+          r11);
+  __ SmiAddConstant(r8, r8, Smi::FromInt(1));
+  __ bind(&parameters_test);
+  __ SmiTest(r9);
+  __ j(not_zero, &parameters_loop, Label::kNear);
+
+  __ bind(&skip_parameter_map);
+
+  // rcx = argument count (tagged)
+  // rdi = address of backing store (tagged)
+  // Copy arguments header and remaining slots (if there are any).
+  __ Move(FieldOperand(rdi, FixedArray::kMapOffset),
+          factory->fixed_array_map());
+  __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
+
+  Label arguments_loop, arguments_test;
+  __ movq(r8, rbx);
+  __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+  // Untag rcx and r8 for the loop below.
+  __ SmiToInteger64(rcx, rcx);
+  __ SmiToInteger64(r8, r8);
+  __ lea(kScratchRegister, Operand(r8, times_pointer_size, 0));
+  __ subq(rdx, kScratchRegister);
+  __ jmp(&arguments_test, Label::kNear);
+
+  __ bind(&arguments_loop);
+  __ subq(rdx, Immediate(kPointerSize));
+  __ movq(r9, Operand(rdx, 0));
+  __ movq(FieldOperand(rdi, r8,
+                       times_pointer_size,
+                       FixedArray::kHeaderSize),
+          r9);
+  __ addq(r8, Immediate(1));
+
+  __ bind(&arguments_test);
+  __ cmpq(r8, rcx);
+  __ j(less, &arguments_loop, Label::kNear);
+
+  // Return and remove the on-stack parameters.
+  __ ret(3 * kPointerSize);
+
+  // Do the runtime call to allocate the arguments object.
+  // rcx = argument count (untagged)
+  __ bind(&runtime);
+  __ Integer32ToSmi(rcx, rcx);
+  __ movq(Operand(rsp, 1 * kPointerSize), rcx);  // Patch argument count.
+  __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
+  // esp[0] : return address
+  // esp[8] : number of parameters
+  // esp[16] : receiver displacement
+  // esp[24] : function
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label runtime;
+  __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
+  __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
+  __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+  __ j(not_equal, &runtime);
+
+  // Patch the arguments.length and the parameters pointer.
+  __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+  __ SmiToInteger64(rcx, rcx);
+  __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
+              StandardFrameConstants::kCallerSPOffset));
+  __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
   // rsp[0] : return address
   // rsp[8] : number of parameters
   // rsp[16] : receiver displacement
   // rsp[24] : function
 
-  // The displacement is used for skipping the return address and the
-  // frame pointer on the stack. It is the offset of the last
-  // parameter (if any) relative to the frame pointer.
-  static const int kDisplacement = 2 * kPointerSize;
-
   // Check if the calling frame is an arguments adaptor frame.
   Label adaptor_frame, try_allocate, runtime;
   __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
-  __ Cmp(Operand(rdx, StandardFrameConstants::kContextOffset),
-         Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+  __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
+  __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ j(equal, &adaptor_frame);
 
   // Get the length from the frame.
-  __ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize));
+  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+  __ SmiToInteger64(rcx, rcx);
   __ jmp(&try_allocate);
 
   // Patch the arguments.length and the parameters pointer.
   __ bind(&adaptor_frame);
-  __ SmiToInteger32(rcx,
-                    Operand(rdx,
-                            ArgumentsAdaptorFrameConstants::kLengthOffset));
-  // Space on stack must already hold a smi.
-  __ Integer32ToSmiField(Operand(rsp, 1 * kPointerSize), rcx);
-  // Do not clobber the length index for the indexing operation since
-  // it is used compute the size for allocation later.
-  __ lea(rdx, Operand(rdx, rcx, times_pointer_size, kDisplacement));
+  __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+  __ SmiToInteger64(rcx, rcx);
+  __ lea(rdx, Operand(rdx, rcx, times_pointer_size,
+                      StandardFrameConstants::kCallerSPOffset));
   __ movq(Operand(rsp, 2 * kPointerSize), rdx);
 
   // Try the new space allocation. Start out with computing the size of
   // the arguments object and the elements array.
   Label add_arguments_object;
   __ bind(&try_allocate);
-  __ testl(rcx, rcx);
-  __ j(zero, &add_arguments_object);
-  __ leal(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize));
+  __ testq(rcx, rcx);
+  __ j(zero, &add_arguments_object, Label::kNear);
+  __ lea(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize));
   __ bind(&add_arguments_object);
-  __ addl(rcx, Immediate(GetArgumentsObjectSize()));
+  __ addq(rcx, Immediate(Heap::kArgumentsObjectSizeStrict));
 
   // Do the allocation of both objects in one go.
   __ AllocateInNewSpace(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
@@ -2009,59 +2211,51 @@
   // Get the arguments boilerplate from the current (global) context.
   __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
   __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
-  __ movq(rdi, Operand(rdi,
-                       Context::SlotOffset(GetArgumentsBoilerplateIndex())));
+  const int offset =
+      Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
+  __ movq(rdi, Operand(rdi, offset));
 
   // Copy the JS object part.
-  STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize);
-  __ movq(kScratchRegister, FieldOperand(rdi, 0 * kPointerSize));
-  __ movq(rdx, FieldOperand(rdi, 1 * kPointerSize));
-  __ movq(rbx, FieldOperand(rdi, 2 * kPointerSize));
-  __ movq(FieldOperand(rax, 0 * kPointerSize), kScratchRegister);
-  __ movq(FieldOperand(rax, 1 * kPointerSize), rdx);
-  __ movq(FieldOperand(rax, 2 * kPointerSize), rbx);
-
-  if (type_ == NEW_NON_STRICT) {
-    // Setup the callee in-object property.
-    ASSERT(Heap::kArgumentsCalleeIndex == 1);
-    __ movq(kScratchRegister, Operand(rsp, 3 * kPointerSize));
-    __ movq(FieldOperand(rax, JSObject::kHeaderSize +
-                              Heap::kArgumentsCalleeIndex * kPointerSize),
-            kScratchRegister);
+  for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
+    __ movq(rbx, FieldOperand(rdi, i));
+    __ movq(FieldOperand(rax, i), rbx);
   }
 
   // Get the length (smi tagged) and set that as an in-object property too.
-  ASSERT(Heap::kArgumentsLengthIndex == 0);
+  STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
   __ movq(rcx, Operand(rsp, 1 * kPointerSize));
   __ movq(FieldOperand(rax, JSObject::kHeaderSize +
-                            Heap::kArgumentsLengthIndex * kPointerSize),
+                       Heap::kArgumentsLengthIndex * kPointerSize),
           rcx);
 
   // If there are no actual arguments, we're done.
   Label done;
-  __ SmiTest(rcx);
+  __ testq(rcx, rcx);
   __ j(zero, &done);
 
-  // Get the parameters pointer from the stack and untag the length.
+  // Get the parameters pointer from the stack.
   __ movq(rdx, Operand(rsp, 2 * kPointerSize));
 
   // Setup the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ lea(rdi, Operand(rax, GetArgumentsObjectSize()));
+  __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSizeStrict));
   __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
   __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
   __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
+
+
   __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
-  __ SmiToInteger32(rcx, rcx);  // Untag length for the loop below.
+  // Untag the length for the loop below.
+  __ SmiToInteger64(rcx, rcx);
 
   // Copy the fixed array slots.
   Label loop;
   __ bind(&loop);
-  __ movq(kScratchRegister, Operand(rdx, -1 * kPointerSize));  // Skip receiver.
-  __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), kScratchRegister);
+  __ movq(rbx, Operand(rdx, -1 * kPointerSize));  // Skip receiver.
+  __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), rbx);
   __ addq(rdi, Immediate(kPointerSize));
   __ subq(rdx, Immediate(kPointerSize));
-  __ decl(rcx);
+  __ decq(rcx);
   __ j(not_zero, &loop);
 
   // Return and remove the on-stack parameters.
@@ -2070,7 +2264,7 @@
 
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
+  __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
 }
 
 
@@ -2335,6 +2529,7 @@
 #else
   // Already there in AMD64 calling convention.
   ASSERT(arg1.is(rdi));
+  USE(arg1);
 #endif
 
   // Locate the code entry and call it.
@@ -2711,8 +2906,8 @@
              factory->heap_number_map());
       __ j(equal, &heap_number, Label::kNear);
       if (cc_ != equal) {
-        // Call runtime on identical JSObjects.  Otherwise return equal.
-        __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+        // Call runtime on identical objects.  Otherwise return equal.
+        __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
         __ j(above_equal, &not_identical, Label::kNear);
       }
       __ Set(rax, EQUAL);
@@ -2768,9 +2963,9 @@
       // There is no test for undetectability in strict equality.
 
       // If the first object is a JS object, we have done pointer comparison.
-      STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+      STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
       Label first_non_object;
-      __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+      __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
       __ j(below, &first_non_object, Label::kNear);
       // Return non-zero (eax (not rax) is not zero)
       Label return_not_equal;
@@ -2783,7 +2978,7 @@
       __ CmpInstanceType(rcx, ODDBALL_TYPE);
       __ j(equal, &return_not_equal);
 
-      __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
+      __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx);
       __ j(above_equal, &return_not_equal);
 
       // Check for oddballs: true, false, null, undefined.
@@ -2879,9 +3074,9 @@
     __ lea(rcx, Operand(rax, rdx, times_1, 0));
     __ testb(rcx, Immediate(kSmiTagMask));
     __ j(not_zero, &not_both_objects, Label::kNear);
-    __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
+    __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rbx);
     __ j(below, &not_both_objects, Label::kNear);
-    __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
+    __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx);
     __ j(below, &not_both_objects, Label::kNear);
     __ testb(FieldOperand(rbx, Map::kBitFieldOffset),
              Immediate(1 << Map::kIsUndetectable));
@@ -3004,6 +3199,7 @@
   __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
   Handle<Code> adaptor =
       Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline();
+  __ SetCallKind(rcx, CALL_AS_METHOD);
   __ Jump(adaptor, RelocInfo::CODE_TARGET);
 }
 
@@ -3240,9 +3436,7 @@
 
 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   Label invoke, exit;
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Label not_outermost_js, not_outermost_js_2;
-#endif
   {  // NOLINT. Scope block confuses linter.
     MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
     // Setup frame.
@@ -3287,7 +3481,6 @@
     __ push(c_entry_fp_operand);
   }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If this is the outermost JS call, set js_entry_sp value.
   ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
   __ Load(rax, js_entry_sp);
@@ -3301,7 +3494,6 @@
   __ bind(&not_outermost_js);
   __ Push(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME));
   __ bind(&cont);
-#endif
 
   // Call a faked try-block that does the invoke.
   __ call(&invoke);
@@ -3345,7 +3537,6 @@
   __ PopTryHandler();
 
   __ bind(&exit);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Check if the current stack frame is marked as the outermost JS frame.
   __ pop(rbx);
   __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME));
@@ -3353,7 +3544,6 @@
   __ movq(kScratchRegister, js_entry_sp);
   __ movq(Operand(kScratchRegister, 0), Immediate(0));
   __ bind(&not_outermost_js_2);
-#endif
 
   // Restore the top frame descriptor from the stack.
   { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
@@ -3417,9 +3607,9 @@
   __ JumpIfSmi(rax, &slow);
 
   // Check that the left hand is a JS object. Leave its map in rax.
-  __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax);
+  __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax);
   __ j(below, &slow);
-  __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE);
+  __ CmpInstanceType(rax, LAST_SPEC_OBJECT_TYPE);
   __ j(above, &slow);
 
   // Get the prototype of the function.
@@ -3444,9 +3634,9 @@
 
   // Check that the function prototype is a JS object.
   __ JumpIfSmi(rbx, &slow);
-  __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister);
+  __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
   __ j(below, &slow);
-  __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
+  __ CmpInstanceType(kScratchRegister, LAST_SPEC_OBJECT_TYPE);
   __ j(above, &slow);
 
   // Register mapping:
@@ -3562,15 +3752,8 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case less: cc_name = "LT"; break;
@@ -3581,35 +3764,12 @@
     case not_equal: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == equal || cc_ == not_equal)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s",
-               cc_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == equal || cc_ == not_equal;
+  stream->Add("CompareStub_%s", cc_name);
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
@@ -3815,15 +3975,12 @@
 
   // Make sure that both arguments are strings if not known in advance.
   if (flags_ == NO_STRING_ADD_FLAGS) {
-    Condition is_smi;
-    is_smi = masm->CheckSmi(rax);
-    __ j(is_smi, &string_add_runtime);
+    __ JumpIfSmi(rax, &string_add_runtime);
     __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, r8);
     __ j(above_equal, &string_add_runtime);
 
     // First argument is a a string, test second.
-    is_smi = masm->CheckSmi(rdx);
-    __ j(is_smi, &string_add_runtime);
+    __ JumpIfSmi(rdx, &string_add_runtime);
     __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, r9);
     __ j(above_equal, &string_add_runtime);
   } else {
diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h
index 2774403..4058118 100644
--- a/src/x64/code-stubs-x64.h
+++ b/src/x64/code-stubs-x64.h
@@ -59,34 +59,14 @@
 };
 
 
-class ToBooleanStub: public CodeStub {
- public:
-  ToBooleanStub() { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  Major MajorKey() { return ToBoolean; }
-  int MinorKey() { return 0; }
-};
-
-
 class UnaryOpStub: public CodeStub {
  public:
-  UnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
+  UnaryOpStub(Token::Value op,
+              UnaryOverwriteMode mode,
+              UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(UnaryOpIC::UNINITIALIZED),
-        name_(NULL) {
-  }
-
-  UnaryOpStub(
-      int key,
-      UnaryOpIC::TypeInfo operand_type)
-      : op_(OpBits::decode(key)),
-        mode_(ModeBits::decode(key)),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -96,20 +76,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("UnaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -169,8 +136,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
 
@@ -181,8 +147,7 @@
       : op_(OpBits::decode(key)),
         mode_(ModeBits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -197,20 +162,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 15 bits RRRTTTOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
@@ -430,14 +382,6 @@
   int MinorKey() { return 0; }
 
   void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "NumberToStringStub"; }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("NumberToStringStub\n");
-  }
-#endif
 };
 
 
@@ -481,13 +425,6 @@
       StringDictionary::kHeaderSize +
       StringDictionary::kElementsStartIndex * kPointerSize;
 
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("StringDictionaryLookupStub\n");
-  }
-#endif
-
   Major MajorKey() { return StringDictionaryNegativeLookup; }
 
   int MinorKey() {
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index f8f2d6e..507bbd4 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -132,6 +132,7 @@
 
   CodeDesc desc;
   masm.GetCode(&desc);
+  OS::ProtectCode(buffer, actual_size);
   // Call the function from C++ through this pointer.
   return FUNCTION_CAST<ModuloFunction>(buffer);
 }
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 94c7850..a0648ce 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -58,9 +58,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static bool RecordPositions(MacroAssembler* masm,
                               int pos,
diff --git a/src/x64/cpu-x64.cc b/src/x64/cpu-x64.cc
index e637ba1..ae5045f 100644
--- a/src/x64/cpu-x64.cc
+++ b/src/x64/cpu-x64.cc
@@ -67,7 +67,8 @@
   // solution is to run valgrind with --smc-check=all, but this comes at a big
   // performance cost.  We can notify valgrind to invalidate its cache.
 #ifdef VALGRIND_DISCARD_TRANSLATIONS
-  VALGRIND_DISCARD_TRANSLATIONS(start, size);
+  unsigned res = VALGRIND_DISCARD_TRANSLATIONS(start, size);
+  USE(res);
 #endif
 }
 
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index abac2b6..2a31f28 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -128,7 +128,9 @@
   Address instruction_start = function->code()->instruction_start();
   Address jump_table_address =
       instruction_start + function->code()->safepoint_table_offset();
+#ifdef DEBUG
   Address previous_pc = instruction_start;
+#endif
 
   SafepointTableDeoptimiztionEntryIterator deoptimizations(function->code());
   Address entry_pc = NULL;
@@ -157,12 +159,16 @@
       CodePatcher patcher(call_address, Assembler::kCallInstructionLength);
       patcher.masm()->Call(GetDeoptimizationEntry(deoptimization_index, LAZY),
                            RelocInfo::NONE);
+#ifdef DEBUG
       previous_pc = call_end_address;
+#endif
     } else {
       // Not room enough for a long Call instruction. Write a short call
       // instruction to a long jump placed elsewhere in the code.
+#ifdef DEBUG
       Address short_call_end_address =
           call_address + MacroAssembler::kShortCallInstructionLength;
+#endif
       ASSERT(next_pc >= short_call_end_address);
 
       // Write jump in jump-table.
@@ -177,7 +183,9 @@
       CodePatcher call_patcher(call_address,
                                MacroAssembler::kShortCallInstructionLength);
       call_patcher.masm()->call(jump_table_address);
+#ifdef DEBUG
       previous_pc = short_call_end_address;
+#endif
     }
 
     // Continue with next deoptimization entry.
@@ -316,7 +324,7 @@
   USE(height_in_bytes);
 
   unsigned fixed_size = ComputeFixedSize(function_);
-  unsigned input_frame_size = static_cast<unsigned>(input_->GetFrameSize());
+  unsigned input_frame_size = input_->GetFrameSize();
   ASSERT(fixed_size + height_in_bytes == input_frame_size);
 
   unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize;
@@ -340,6 +348,9 @@
   output_ = new FrameDescription*[1];
   output_[0] = new(output_frame_size) FrameDescription(
       output_frame_size, function_);
+#ifdef DEBUG
+  output_[0]->SetKind(Code::OPTIMIZED_FUNCTION);
+#endif
 
   // Clear the incoming parameters in the optimized frame to avoid
   // confusing the garbage collector.
@@ -448,12 +459,15 @@
   // The 'fixed' part of the frame consists of the incoming parameters and
   // the part described by JavaScriptFrameConstants.
   unsigned fixed_frame_size = ComputeFixedSize(function);
-  unsigned input_frame_size = static_cast<unsigned>(input_->GetFrameSize());
+  unsigned input_frame_size = input_->GetFrameSize();
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
   FrameDescription* output_frame =
       new(output_frame_size) FrameDescription(output_frame_size, function);
+#ifdef DEBUG
+  output_frame->SetKind(Code::FUNCTION);
+#endif
 
   bool is_bottommost = (0 == frame_index);
   bool is_topmost = (output_count_ - 1 == frame_index);
@@ -584,7 +598,7 @@
   output_frame->SetState(Smi::FromInt(state));
 
   // Set the continuation for the topmost frame.
-  if (is_topmost) {
+  if (is_topmost && bailout_type_ != DEBUGGER) {
     Code* continuation = (bailout_type_ == EAGER)
         ? isolate_->builtins()->builtin(Builtins::kNotifyDeoptimized)
         : isolate_->builtins()->builtin(Builtins::kNotifyLazyDeoptimized);
@@ -596,6 +610,26 @@
 }
 
 
+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 rbp and rsp are set to the correct values though.
+  for (int i = 0; i < Register::kNumRegisters; i++) {
+    input_->SetRegister(i, i * 4);
+  }
+  input_->SetRegister(rsp.code(), reinterpret_cast<intptr_t>(frame->sp()));
+  input_->SetRegister(rbp.code(), reinterpret_cast<intptr_t>(frame->fp()));
+  for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; 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, Memory::uint64_at(tos + i));
+  }
+}
+
+
 #define __ masm()->
 
 void Deoptimizer::EntryGenerator::Generate() {
@@ -617,7 +651,7 @@
   // We push all registers onto the stack, even though we do not need
   // to restore all later.
   for (int i = 0; i < kNumberOfRegisters; i++) {
-    Register r = Register::toRegister(i);
+    Register r = Register::from_code(i);
     __ push(r);
   }
 
@@ -775,12 +809,12 @@
 
   // Restore the registers from the stack.
   for (int i = kNumberOfRegisters - 1; i >= 0 ; i--) {
-    Register r = Register::toRegister(i);
+    Register r = Register::from_code(i);
     // Do not restore rsp, simply pop the value into the next register
     // and overwrite this afterwards.
     if (r.is(rsp)) {
       ASSERT(i > 0);
-      r = Register::toRegister(i - 1);
+      r = Register::from_code(i - 1);
     }
     __ pop(r);
   }
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index 7bb2e61..14c95bc 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -1062,11 +1062,12 @@
         AppendToBuffer("movq ");
         current += PrintRightXMMOperand(current);
         AppendToBuffer(", %s", NameOfXMMRegister(regop));
+      } else if (opcode == 0x50) {
+        AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop));
+        current += PrintRightXMMOperand(current);
       } else {
         const char* mnemonic = "?";
-        if (opcode == 0x50) {
-          mnemonic = "movmskpd";
-        } else  if (opcode == 0x54) {
+        if (opcode == 0x54) {
           mnemonic = "andpd";
         } else  if (opcode == 0x56) {
           mnemonic = "orpd";
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 57baf77..23c2bf8 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -78,16 +78,18 @@
   }
 
   void EmitPatchInfo() {
-    int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
-    ASSERT(is_int8(delta_to_patch_site));
-    __ testl(rax, Immediate(delta_to_patch_site));
+    if (patch_site_.is_bound()) {
+      int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
+      ASSERT(is_int8(delta_to_patch_site));
+      __ testl(rax, Immediate(delta_to_patch_site));
 #ifdef DEBUG
-    info_emitted_ = true;
+      info_emitted_ = true;
 #endif
+    } else {
+      __ nop();  // Signals no inlined code.
+    }
   }
 
-  bool is_bound() const { return patch_site_.is_bound(); }
-
  private:
   // jc will be patched with jz, jnc will become jnz.
   void EmitJump(Condition cc, Label* target, Label::Distance near_jump) {
@@ -121,6 +123,7 @@
 void FullCodeGenerator::Generate(CompilationInfo* info) {
   ASSERT(info_ == NULL);
   info_ = info;
+  scope_ = info->scope();
   SetFunctionPosition(function());
   Comment cmnt(masm_, "[ function compiled by full code generator");
 
@@ -131,16 +134,16 @@
   }
 #endif
 
-  // Strict mode functions need to replace the receiver with undefined
-  // when called as functions (without an explicit receiver
-  // object). rcx is zero for method calls and non-zero for function
-  // calls.
-  if (info->is_strict_mode()) {
+  // Strict mode functions and builtins need to replace the receiver
+  // with undefined when called as functions (without an explicit
+  // receiver object). rcx is zero for method calls and non-zero for
+  // function calls.
+  if (info->is_strict_mode() || info->is_native()) {
     Label ok;
     __ testq(rcx, rcx);
     __ j(zero, &ok, Label::kNear);
     // +1 for return address.
-    int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
+    int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize;
     __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
     __ movq(Operand(rsp, receiver_offset), kScratchRegister);
     __ bind(&ok);
@@ -152,7 +155,7 @@
   __ push(rdi);  // Callee's JS Function.
 
   { Comment cmnt(masm_, "[ Allocate locals");
-    int locals_count = scope()->num_stack_slots();
+    int locals_count = info->scope()->num_stack_slots();
     if (locals_count == 1) {
       __ PushRoot(Heap::kUndefinedValueRootIndex);
     } else if (locals_count > 1) {
@@ -166,7 +169,7 @@
   bool function_in_register = true;
 
   // Possibly allocate a local context.
-  int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   if (heap_slots > 0) {
     Comment cmnt(masm_, "[ Allocate local context");
     // Argument to NewContext is the function, which is still in rdi.
@@ -175,7 +178,7 @@
       FastNewContextStub stub(heap_slots);
       __ CallStub(&stub);
     } else {
-      __ CallRuntime(Runtime::kNewContext, 1);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
     }
     function_in_register = false;
     // Context is returned in both rax and rsi.  It replaces the context
@@ -183,7 +186,7 @@
     __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
 
     // Copy any necessary parameters into the context.
-    int num_parameters = scope()->num_parameters();
+    int num_parameters = info->scope()->num_parameters();
     for (int i = 0; i < num_parameters; i++) {
       Slot* slot = scope()->parameter(i)->AsSlot();
       if (slot != NULL && slot->type() == Slot::CONTEXT) {
@@ -215,26 +218,21 @@
       __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
     }
     // The receiver is just before the parameters on the caller's stack.
-    int offset = scope()->num_parameters() * kPointerSize;
+    int num_parameters = info->scope()->num_parameters();
+    int offset = num_parameters * kPointerSize;
     __ lea(rdx,
            Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset));
     __ push(rdx);
-    __ Push(Smi::FromInt(scope()->num_parameters()));
+    __ Push(Smi::FromInt(num_parameters));
     // Arguments to ArgumentsAccessStub:
     //   function, receiver address, parameter count.
     // The stub will rewrite receiver and parameter count if the previous
     // stack frame was an arguments adapter frame.
     ArgumentsAccessStub stub(
         is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT
-                         : ArgumentsAccessStub::NEW_NON_STRICT);
+                         : ArgumentsAccessStub::NEW_NON_STRICT_SLOW);
     __ CallStub(&stub);
 
-    Variable* arguments_shadow = scope()->arguments_shadow();
-    if (arguments_shadow != NULL) {
-      // Store new arguments object in both "arguments" and ".arguments" slots.
-      __ movq(rcx, rax);
-      Move(arguments_shadow->AsSlot(), rcx, rbx, rdx);
-    }
     Move(arguments->AsSlot(), rax, rbx, rdx);
   }
 
@@ -338,7 +336,7 @@
     __ movq(rsp, rbp);
     __ pop(rbp);
 
-    int arguments_bytes = (scope()->num_parameters() + 1) * kPointerSize;
+    int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize;
     __ Ret(arguments_bytes, rcx);
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
@@ -377,7 +375,7 @@
 void FullCodeGenerator::TestContext::Plug(Slot* slot) const {
   codegen()->Move(result_register(), slot);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -410,7 +408,7 @@
     if (true_label_ != fall_through_) __ jmp(true_label_);
   } else {
     __ LoadRoot(result_register(), index);
-    codegen()->DoTest(true_label_, false_label_, fall_through_);
+    codegen()->DoTest(this);
   }
 }
 
@@ -455,7 +453,7 @@
   } else {
     // For simplicity we always test the accumulator register.
     __ Move(result_register(), lit);
-    codegen()->DoTest(true_label_, false_label_, fall_through_);
+    codegen()->DoTest(this);
   }
 }
 
@@ -491,7 +489,7 @@
   __ Drop(count);
   __ Move(result_register(), reg);
   codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
-  codegen()->DoTest(true_label_, false_label_, fall_through_);
+  codegen()->DoTest(this);
 }
 
 
@@ -566,13 +564,14 @@
 }
 
 
-void FullCodeGenerator::DoTest(Label* if_true,
+void FullCodeGenerator::DoTest(Expression* condition,
+                               Label* if_true,
                                Label* if_false,
                                Label* fall_through) {
-  ToBooleanStub stub;
+  ToBooleanStub stub(result_register());
   __ push(result_register());
   __ CallStub(&stub);
-  __ testq(rax, rax);
+  __ testq(result_register(), result_register());
   // The stub returns nonzero for true.
   Split(not_zero, if_true, if_false, fall_through);
 }
@@ -685,13 +684,16 @@
         // We bypass the general EmitSlotSearch because we know more about
         // this specific context.
 
-        // The variable in the decl always resides in the current context.
+        // The variable in the decl always resides in the current function
+        // context.
         ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
         if (FLAG_debug_code) {
-          // Check if we have the correct context pointer.
-          __ movq(rbx, ContextOperand(rsi, Context::FCONTEXT_INDEX));
-          __ cmpq(rbx, rsi);
-          __ Check(equal, "Unexpected declaration in current context.");
+          // Check that we're not inside a with or catch context.
+          __ movq(rbx, FieldOperand(rsi, HeapObject::kMapOffset));
+          __ CompareRoot(rbx, Heap::kWithContextMapRootIndex);
+          __ Check(not_equal, "Declaration in with context.");
+          __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex);
+          __ Check(not_equal, "Declaration in catch context.");
         }
         if (mode == Variable::CONST) {
           __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
@@ -739,7 +741,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
       __ push(rax);
       VisitForAccumulatorValue(function);
@@ -751,7 +753,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ call(ic);
     }
   }
 }
@@ -824,7 +826,8 @@
     // Record position before stub call for type feedback.
     SetSourcePosition(clause->position());
     Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
-    EmitCallIC(ic, &patch_site, clause->CompareId());
+    __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
+    patch_site.EmitPatchInfo();
 
     __ testq(rax, rax);
     __ j(not_equal, &next_test);
@@ -878,7 +881,7 @@
   // Convert the object to a JS object.
   Label convert, done_convert;
   __ JumpIfSmi(rax, &convert);
-  __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+  __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
   __ j(above_equal, &done_convert);
   __ bind(&convert);
   __ push(rax);
@@ -1068,7 +1071,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1089,8 +1092,7 @@
         __ j(not_equal, slow);
       }
       // Load next context in chain.
-      __ movq(temp, ContextOperand(context, Context::CLOSURE_INDEX));
-      __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset));
+      __ movq(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering rsi.
       context = temp;
     }
@@ -1118,8 +1120,7 @@
     __ cmpq(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
     __ j(not_equal, slow);
     // Load next context in chain.
-    __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX));
-    __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset));
+    __ movq(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
     __ jmp(&next);
     __ bind(&fast);
   }
@@ -1132,7 +1133,7 @@
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
-  EmitCallIC(ic, mode, AstNode::kNoNumber);
+  __ call(ic, mode);
 }
 
 
@@ -1151,8 +1152,7 @@
                 Immediate(0));
         __ j(not_equal, slow);
       }
-      __ movq(temp, ContextOperand(context, Context::CLOSURE_INDEX));
-      __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset));
+      __ movq(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
       // Walk the rest of the chain without clobbering rsi.
       context = temp;
     }
@@ -1213,7 +1213,7 @@
           __ Move(rax, key_literal->handle());
           Handle<Code> ic =
               isolate()->builtins()->KeyedLoadIC_Initialize();
-          EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
+          __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
           __ jmp(done);
         }
       }
@@ -1222,21 +1222,24 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
-  // Four cases: non-this global variables, lookup slots, all other
-  // types of slots, and parameters that rewrite to explicit property
-  // accesses on the arguments object.
-  Slot* slot = var->AsSlot();
-  Property* property = var->AsProperty();
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
 
-  if (var->is_global() && !var->is_this()) {
+  // Three cases: non-this global variables, lookup slots, and all other
+  // types of slots.
+  Slot* slot = var->AsSlot();
+  ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
+
+  if (slot == NULL) {
     Comment cmnt(masm_, "Global variable");
     // Use inline caching. Variable name is passed in rcx and the global
     // object on the stack.
     __ Move(rcx, var->name());
     __ movq(rax, GlobalObjectOperand());
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
     context()->Plug(rax);
 
   } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
@@ -1255,7 +1258,7 @@
 
     context()->Plug(rax);
 
-  } else if (slot != NULL) {
+  } else {
     Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
                             ? "Context slot"
                             : "Stack slot");
@@ -1273,34 +1276,6 @@
     } else {
       context()->Plug(slot);
     }
-
-  } else {
-    Comment cmnt(masm_, "Rewritten parameter");
-    ASSERT_NOT_NULL(property);
-    // Rewritten parameter accesses are of the form "slot[literal]".
-
-    // Assert that the object is in a slot.
-    Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
-    ASSERT_NOT_NULL(object_var);
-    Slot* object_slot = object_var->AsSlot();
-    ASSERT_NOT_NULL(object_slot);
-
-    // Load the object.
-    MemOperand object_loc = EmitSlotSearch(object_slot, rax);
-    __ movq(rdx, object_loc);
-
-    // Assert that the key is a smi.
-    Literal* key_literal = property->key()->AsLiteral();
-    ASSERT_NOT_NULL(key_literal);
-    ASSERT(key_literal->handle()->IsSmi());
-
-    // Load the key.
-    __ Move(rax, key_literal->handle());
-
-    // Do a keyed property load.
-    Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
-    context()->Plug(rax);
   }
 }
 
@@ -1412,7 +1387,7 @@
             Handle<Code> ic = is_strict_mode()
                 ? isolate()->builtins()->StoreIC_Initialize_Strict()
                 : isolate()->builtins()->StoreIC_Initialize();
-            EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id());
+            __ call(ic, RelocInfo::CODE_TARGET, key->id());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           } else {
             VisitForEffect(value);
@@ -1533,7 +1508,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
@@ -1559,29 +1534,13 @@
       break;
     case KEYED_PROPERTY: {
       if (expr->is_compound()) {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          MemOperand slot_operand =
-              EmitSlotSearch(obj_proxy->var()->AsSlot(), rcx);
-          __ push(slot_operand);
-          __ Move(rax, property->key()->AsLiteral()->handle());
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForAccumulatorValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForAccumulatorValue(property->key());
         __ movq(rdx, Operand(rsp, 0));
         __ push(rax);
       } else {
-        if (property->is_arguments_access()) {
-          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
-          MemOperand slot_operand =
-              EmitSlotSearch(obj_proxy->var()->AsSlot(), rcx);
-          __ push(slot_operand);
-          __ Push(property->key()->AsLiteral()->handle());
-        } else {
-          VisitForStackValue(property->obj());
-          VisitForStackValue(property->key());
-        }
+        VisitForStackValue(property->obj());
+        VisitForStackValue(property->key());
       }
       break;
     }
@@ -1593,7 +1552,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -1657,14 +1616,14 @@
   Literal* key = prop->key()->AsLiteral();
   __ Move(rcx, key->handle());
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+  __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
 }
 
 
@@ -1686,7 +1645,8 @@
   __ bind(&stub_call);
   __ movq(rax, rcx);
   BinaryOpStub stub(op, mode);
-  EmitCallIC(stub.GetCode(), &patch_site, expr->id());
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   __ jmp(&done, Label::kNear);
 
   __ bind(&smi_case);
@@ -1733,8 +1693,9 @@
                                      OverwriteMode mode) {
   __ pop(rdx);
   BinaryOpStub stub(op, mode);
-  // NULL signals no inlined smi code.
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code.
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  patch_site.EmitPatchInfo();
   context()->Plug(rax);
 }
 
@@ -1748,7 +1709,7 @@
   }
 
   // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
@@ -1774,30 +1735,20 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ call(ic);
       break;
     }
     case KEYED_PROPERTY: {
       __ push(rax);  // Preserve value.
-      if (prop->is_synthetic()) {
-        ASSERT(prop->obj()->AsVariableProxy() != NULL);
-        ASSERT(prop->key()->AsLiteral() != NULL);
-        { AccumulatorValueContext for_object(this);
-          EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
-        }
-        __ movq(rdx, rax);
-        __ Move(rcx, prop->key()->AsLiteral()->handle());
-      } else {
-        VisitForStackValue(prop->obj());
-        VisitForAccumulatorValue(prop->key());
-        __ movq(rcx, rax);
-        __ pop(rdx);
-      }
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
+      __ movq(rcx, rax);
+      __ pop(rdx);
       __ pop(rax);  // Restore value.
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+      __ call(ic);
       break;
     }
   }
@@ -1808,8 +1759,6 @@
 
 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
                                                Token::Value op) {
-  // Left-hand sides that rewrite to explicit property accesses do not reach
-  // here.
   ASSERT(var != NULL);
   ASSERT(var->is_global() || var->AsSlot() != NULL);
 
@@ -1823,7 +1772,7 @@
     Handle<Code> ic = is_strict_mode()
         ? isolate()->builtins()->StoreIC_Initialize_Strict()
         : isolate()->builtins()->StoreIC_Initialize();
-    EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
+    __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
 
   } else if (op == Token::INIT_CONST) {
     // Like var declarations, const declarations are hoisted to function
@@ -1843,17 +1792,7 @@
         __ j(not_equal, &skip);
         __ movq(Operand(rbp, SlotOffset(slot)), rax);
         break;
-      case Slot::CONTEXT: {
-        __ movq(rcx, ContextOperand(rsi, Context::FCONTEXT_INDEX));
-        __ movq(rdx, ContextOperand(rcx, slot->index()));
-        __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
-        __ j(not_equal, &skip);
-        __ movq(ContextOperand(rcx, slot->index()), rax);
-        int offset = Context::SlotOffset(slot->index());
-        __ movq(rdx, rax);  // Preserve the stored value in eax.
-        __ RecordWrite(rcx, offset, rdx, rbx);
-        break;
-      }
+      case Slot::CONTEXT:
       case Slot::LOOKUP:
         __ push(rax);
         __ push(rsi);
@@ -1926,7 +1865,7 @@
   Handle<Code> ic = is_strict_mode()
       ? isolate()->builtins()->StoreIC_Initialize_Strict()
       : isolate()->builtins()->StoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -1966,7 +1905,7 @@
   Handle<Code> ic = is_strict_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2018,7 +1957,7 @@
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic =
       ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
-  EmitCallIC(ic, mode, expr->id());
+  __ call(ic, mode, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2052,7 +1991,7 @@
   Handle<Code> ic =
       ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
   __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize));  // Key.
-  EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2092,7 +2031,7 @@
   }
 
   // Push the receiver of the enclosing function and do runtime call.
-  __ push(Operand(rbp, (2 + scope()->num_parameters()) * kPointerSize));
+  __ push(Operand(rbp, (2 + info_->scope()->num_parameters()) * kPointerSize));
 
   // Push the strict mode flag.
   __ Push(Smi::FromInt(strict_mode_flag()));
@@ -2206,9 +2145,9 @@
       __ bind(&done);
       // Push function.
       __ push(rax);
-      // Push global receiver.
-      __ movq(rbx, GlobalObjectOperand());
-      __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ PushRoot(Heap::kTheHoleValueRootIndex);
       __ bind(&call);
     }
 
@@ -2229,7 +2168,7 @@
     } else {
       // Call to a keyed property.
       // For a synthetic property use keyed load IC followed by function call,
-      // for a regular property use keyed EmitCallIC.
+      // for a regular property use EmitKeyedCallWithIC.
       if (prop->is_synthetic()) {
         // Do not visit the object and key subexpressions (they are shared
         // by all occurrences of the same rewritten parameter).
@@ -2247,7 +2186,7 @@
         SetSourcePosition(prop->position());
 
         Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-        EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
+        __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
         // Push result (function).
         __ push(rax);
         // Push Global receiver.
@@ -2373,9 +2312,9 @@
            Immediate(1 << Map::kIsUndetectable));
   __ j(not_zero, if_false);
   __ movzxbq(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
-  __ cmpq(rbx, Immediate(FIRST_JS_OBJECT_TYPE));
+  __ cmpq(rbx, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
   __ j(below, if_false);
-  __ cmpq(rbx, Immediate(LAST_JS_OBJECT_TYPE));
+  __ cmpq(rbx, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(below_equal, if_true, if_false, fall_through);
 
@@ -2396,7 +2335,7 @@
                          &if_true, &if_false, &fall_through);
 
   __ JumpIfSmi(rax, if_false);
-  __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
+  __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rbx);
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
   Split(above_equal, if_true, if_false, fall_through);
 
@@ -2634,7 +2573,7 @@
   // parameter count in rax.
   VisitForAccumulatorValue(args->at(0));
   __ movq(rdx, rax);
-  __ Move(rax, Smi::FromInt(scope()->num_parameters()));
+  __ Move(rax, Smi::FromInt(info_->scope()->num_parameters()));
   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
   __ CallStub(&stub);
   context()->Plug(rax);
@@ -2646,7 +2585,7 @@
 
   Label exit;
   // Get the number of formal parameters.
-  __ Move(rax, Smi::FromInt(scope()->num_parameters()));
+  __ Move(rax, Smi::FromInt(info_->scope()->num_parameters()));
 
   // Check if the calling frame is an arguments adaptor frame.
   __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
@@ -2675,16 +2614,18 @@
 
   // Check that the object is a JS object but take special care of JS
   // functions to make sure they have 'Function' as their class.
-  __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax);  // Map is now in rax.
+  __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax);
+  // Map is now in rax.
   __ j(below, &null);
 
-  // As long as JS_FUNCTION_TYPE is the last instance type and it is
-  // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
-  // LAST_JS_OBJECT_TYPE.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
-  __ CmpInstanceType(rax, JS_FUNCTION_TYPE);
-  __ j(equal, &function);
+  // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
+  // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
+  STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+  STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+                LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
+  __ CmpInstanceType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
+  __ j(above_equal, &function);
 
   // Check if the constructor in the map is a function.
   __ movq(rax, FieldOperand(rax, Map::kConstructorOffset));
@@ -2727,13 +2668,11 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
   // Finally, we're expected to leave a value on the top of the stack.
   __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
   context()->Plug(rax);
@@ -3331,9 +3270,7 @@
   __ j(not_equal, &bailout);
 
   // Check that the array has fast elements.
-  __ testb(FieldOperand(scratch, Map::kBitField2Offset),
-           Immediate(1 << Map::kHasFastElements));
-  __ j(zero, &bailout);
+  __ CheckFastElements(scratch, &bailout);
 
   // Array has fast elements, so its length must be a smi.
   // If the array has length zero, return the empty string.
@@ -3579,6 +3516,39 @@
 }
 
 
+void FullCodeGenerator::EmitIsNativeOrStrictMode(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 1);
+
+  // Load the function into rax.
+  VisitForAccumulatorValue(args->at(0));
+
+  // Prepare for the test.
+  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);
+
+  // Test for strict mode function.
+  __ movq(rdx, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset));
+  __ testb(FieldOperand(rdx, SharedFunctionInfo::kStrictModeByteOffset),
+           Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
+  __ j(not_equal, if_true);
+
+  // Test for native function.
+  __ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset),
+           Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
+  __ j(not_equal, if_true);
+
+  // Not native or strict-mode function.
+  __ jmp(if_false);
+
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+  context()->Plug(if_true, if_false);
+}
+
+
 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   Handle<String> name = expr->name();
   if (name->length() > 0 && name->Get(0) == '_') {
@@ -3609,7 +3579,7 @@
     RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
     Handle<Code> ic =
         ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
-    EmitCallIC(ic, mode, expr->id());
+    __ call(ic, mode, expr->id());
     // Restore context register.
     __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
   } else {
@@ -3712,8 +3682,7 @@
       Comment cmt(masm_, "[ UnaryOperation (ADD)");
       VisitForAccumulatorValue(expr->expression());
       Label no_conversion;
-      Condition is_smi = masm_->CheckSmi(result_register());
-      __ j(is_smi, &no_conversion);
+      __ JumpIfSmi(result_register(), &no_conversion);
       ToNumberStub convert_stub;
       __ CallStub(&convert_stub);
       __ bind(&no_conversion);
@@ -3747,7 +3716,7 @@
   // accumulator register rax.
   VisitForAccumulatorValue(expr->expression());
   SetSourcePosition(expr->position());
-  EmitCallIC(stub.GetCode(), NULL, expr->id());
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
   context()->Plug(rax);
 }
 
@@ -3764,7 +3733,7 @@
   }
 
   // Expression can only be a property, a global or a (parameter or local)
-  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
+  // slot.
   enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
   LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
@@ -3779,7 +3748,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
@@ -3790,16 +3759,8 @@
       __ push(rax);  // Copy of receiver, needed for later store.
       EmitNamedPropertyLoad(prop);
     } else {
-      if (prop->is_arguments_access()) {
-        VariableProxy* obj_proxy = prop->obj()->AsVariableProxy();
-        MemOperand slot_operand =
-            EmitSlotSearch(obj_proxy->var()->AsSlot(), rcx);
-        __ push(slot_operand);
-        __ Move(rax, prop->key()->AsLiteral()->handle());
-      } else {
-        VisitForStackValue(prop->obj());
-        VisitForAccumulatorValue(prop->key());
-      }
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
       __ movq(rdx, Operand(rsp, 0));  // Leave receiver on stack
       __ push(rax);  // Copy of key, needed for later store.
       EmitKeyedPropertyLoad(prop);
@@ -3816,9 +3777,7 @@
 
   // Call ToNumber only if operand is not a smi.
   Label no_conversion;
-  Condition is_smi;
-  is_smi = masm_->CheckSmi(rax);
-  __ j(is_smi, &no_conversion, Label::kNear);
+  __ JumpIfSmi(rax, &no_conversion, Label::kNear);
   ToNumberStub convert_stub;
   __ CallStub(&convert_stub);
   __ bind(&no_conversion);
@@ -3878,7 +3837,8 @@
     __ movq(rdx, rax);
     __ Move(rax, Smi::FromInt(1));
   }
-  EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
+  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+  patch_site.EmitPatchInfo();
   __ bind(&done);
 
   // Store the value returned in rax.
@@ -3911,7 +3871,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->StoreIC_Initialize_Strict()
           : isolate()->builtins()->StoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -3928,7 +3888,7 @@
       Handle<Code> ic = is_strict_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
           : isolate()->builtins()->KeyedStoreIC_Initialize();
-      EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
+      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -3955,7 +3915,7 @@
     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
-    EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
+    __ call(ic);
     PrepareForBailout(expr, TOS_REG);
     context()->Plug(rax);
   } else if (proxy != NULL &&
@@ -3978,30 +3938,18 @@
     context()->Plug(rax);
   } else {
     // This expression cannot throw a reference error at the top level.
-    context()->HandleExpression(expr);
+    VisitInCurrentContext(expr);
   }
 }
 
 
-bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
-                                          Expression* left,
-                                          Expression* right,
-                                          Label* if_true,
-                                          Label* if_false,
-                                          Label* fall_through) {
-  if (op != Token::EQ && op != Token::EQ_STRICT) return false;
-
-  // Check for the pattern: typeof <expression> == <string literal>.
-  Literal* right_literal = right->AsLiteral();
-  if (right_literal == NULL) return false;
-  Handle<Object> right_literal_value = right_literal->handle();
-  if (!right_literal_value->IsString()) return false;
-  UnaryOperation* left_unary = left->AsUnaryOperation();
-  if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
-  Handle<String> check = Handle<String>::cast(right_literal_value);
-
+void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
+                                                 Handle<String> check,
+                                                 Label* if_true,
+                                                 Label* if_false,
+                                                 Label* fall_through) {
   { AccumulatorValueContext context(this);
-    VisitForTypeofValue(left_unary->expression());
+    VisitForTypeofValue(expr);
   }
   PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
 
@@ -4034,16 +3982,17 @@
     Split(not_zero, if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->function_symbol())) {
     __ JumpIfSmi(rax, if_false);
-    __ CmpObjectType(rax, FIRST_FUNCTION_CLASS_TYPE, rdx);
+    STATIC_ASSERT(LAST_CALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE);
+    __ CmpObjectType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, rdx);
     Split(above_equal, if_true, if_false, fall_through);
   } else if (check->Equals(isolate()->heap()->object_symbol())) {
     __ JumpIfSmi(rax, if_false);
     __ CompareRoot(rax, Heap::kNullValueRootIndex);
     __ j(equal, if_true);
-    __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdx);
+    __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx);
     __ j(below, if_false);
-    __ CmpInstanceType(rdx, FIRST_FUNCTION_CLASS_TYPE);
-    __ j(above_equal, if_false);
+    __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ j(above, if_false);
     // Check for undetectable objects => false.
     __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
              Immediate(1 << Map::kIsUndetectable));
@@ -4051,8 +4000,18 @@
   } else {
     if (if_false != fall_through) __ jmp(if_false);
   }
+}
 
-  return true;
+
+void FullCodeGenerator::EmitLiteralCompareUndefined(Expression* expr,
+                                                    Label* if_true,
+                                                    Label* if_false,
+                                                    Label* fall_through) {
+  VisitForAccumulatorValue(expr);
+  PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
+
+  __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
+  Split(equal, if_true, if_false, fall_through);
 }
 
 
@@ -4071,14 +4030,12 @@
 
   // First we try a fast inlined version of the compare when one of
   // the operands is a literal.
-  Token::Value op = expr->op();
-  Expression* left = expr->left();
-  Expression* right = expr->right();
-  if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) {
+  if (TryLiteralCompare(expr, if_true, if_false, fall_through)) {
     context()->Plug(if_true, if_false);
     return;
   }
 
+  Token::Value op = expr->op();
   VisitForStackValue(expr->left());
   switch (op) {
     case Token::IN:
@@ -4103,11 +4060,8 @@
     default: {
       VisitForAccumulatorValue(expr->right());
       Condition cc = no_condition;
-      bool strict = false;
       switch (op) {
         case Token::EQ_STRICT:
-          strict = true;
-          // Fall through.
         case Token::EQ:
           cc = equal;
           __ pop(rdx);
@@ -4153,7 +4107,8 @@
       // Record position and call the compare IC.
       SetSourcePosition(expr->position());
       Handle<Code> ic = CompareIC::GetUninitialized(op);
-      EmitCallIC(ic, &patch_site, expr->id());
+      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+      patch_site.EmitPatchInfo();
 
       PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
       __ testq(rax, rax);
@@ -4185,8 +4140,7 @@
     __ j(equal, if_true);
     __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
     __ j(equal, if_true);
-    Condition is_smi = masm_->CheckSmi(rax);
-    __ j(is_smi, if_false);
+    __ JumpIfSmi(rax, if_false);
     // It can be an undetectable object.
     __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
     __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
@@ -4213,59 +4167,6 @@
 }
 
 
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   RelocInfo::Mode mode,
-                                   unsigned ast_id) {
-  ASSERT(mode == RelocInfo::CODE_TARGET ||
-         mode == RelocInfo::CODE_TARGET_CONTEXT);
-  Counters* counters = isolate()->counters();
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(counters->named_load_full(), 1);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(counters->keyed_load_full(), 1);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(counters->named_store_full(), 1);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(counters->keyed_store_full(), 1);
-    default:
-      break;
-  }
-  __ call(ic, mode, ast_id);
-}
-
-
-void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
-                                   JumpPatchSite* patch_site,
-                                   unsigned ast_id) {
-  Counters* counters = isolate()->counters();
-  switch (ic->kind()) {
-    case Code::LOAD_IC:
-      __ IncrementCounter(counters->named_load_full(), 1);
-      break;
-    case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(counters->keyed_load_full(), 1);
-      break;
-    case Code::STORE_IC:
-      __ IncrementCounter(counters->named_store_full(), 1);
-      break;
-    case Code::KEYED_STORE_IC:
-      __ IncrementCounter(counters->keyed_store_full(), 1);
-    default:
-      break;
-  }
-  __ call(ic, RelocInfo::CODE_TARGET, ast_id);
-  if (patch_site != NULL && patch_site->is_bound()) {
-    patch_site->EmitPatchInfo();
-  } else {
-    __ nop();  // Signals no inlined code.
-  }
-}
-
-
 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
   ASSERT(IsAligned(frame_offset, kPointerSize));
   __ movq(Operand(rbp, frame_offset), value);
@@ -4277,6 +4178,26 @@
 }
 
 
+void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
+  Scope* declaration_scope = scope()->DeclarationScope();
+  if (declaration_scope->is_global_scope()) {
+    // Contexts nested in the global context have a canonical empty function
+    // as their closure, not the anonymous closure containing the global
+    // code.  Pass a smi sentinel and let the runtime look up the empty
+    // function.
+    __ Push(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.
+    __ push(ContextOperand(rsi, Context::CLOSURE_INDEX));
+  } else {
+    ASSERT(declaration_scope->is_function_scope());
+    __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+  }
+}
+
+
 // ----------------------------------------------------------------------------
 // Non-local control flow support.
 
@@ -4285,11 +4206,11 @@
   ASSERT(!result_register().is(rdx));
   ASSERT(!result_register().is(rcx));
   // Cook return address on top of stack (smi encoded Code* delta)
-  __ movq(rdx, Operand(rsp, 0));
+  __ pop(rdx);
   __ Move(rcx, masm_->CodeObject());
   __ subq(rdx, rcx);
   __ Integer32ToSmi(rdx, rdx);
-  __ movq(Operand(rsp, 0), rdx);
+  __ push(rdx);
   // Store result register while executing finally block.
   __ push(result_register());
 }
@@ -4298,16 +4219,13 @@
 void FullCodeGenerator::ExitFinallyBlock() {
   ASSERT(!result_register().is(rdx));
   ASSERT(!result_register().is(rcx));
-  // Restore result register from stack.
   __ pop(result_register());
   // Uncook return address.
-  __ movq(rdx, Operand(rsp, 0));
+  __ pop(rdx);
   __ SmiToInteger32(rdx, rdx);
   __ Move(rcx, masm_->CodeObject());
   __ addq(rdx, rcx);
-  __ movq(Operand(rsp, 0), rdx);
-  // And return.
-  __ ret(0);
+  __ jmp(rdx);
 }
 
 
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index cec8894..339d2c1 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -76,11 +76,11 @@
   // Check that the receiver is a valid JS object.
   __ movq(r1, FieldOperand(receiver, HeapObject::kMapOffset));
   __ movb(r0, FieldOperand(r1, Map::kInstanceTypeOffset));
-  __ cmpb(r0, Immediate(FIRST_JS_OBJECT_TYPE));
+  __ cmpb(r0, Immediate(FIRST_SPEC_OBJECT_TYPE));
   __ j(below, miss);
 
   // If this assert fails, we have to check upper bound too.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
 
   GenerateGlobalInstanceTypeCheck(masm, r0, miss);
 
@@ -225,110 +225,6 @@
 }
 
 
-static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
-                                         Label* miss,
-                                         Register elements,
-                                         Register key,
-                                         Register r0,
-                                         Register r1,
-                                         Register r2,
-                                         Register result) {
-  // 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.
-  //
-  // Scratch registers:
-  //
-  // r0 - holds the untagged key on entry and holds the hash once computed.
-  //
-  // r1 - used to hold the capacity mask of the dictionary
-  //
-  // r2 - used for the index into the dictionary.
-  //
-  // 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.
-
-  Label done;
-
-  // Compute the hash code from the untagged key.  This must be kept in sync
-  // with ComputeIntegerHash in utils.h.
-  //
-  // hash = ~hash + (hash << 15);
-  __ movl(r1, r0);
-  __ notl(r0);
-  __ shll(r1, Immediate(15));
-  __ addl(r0, r1);
-  // hash = hash ^ (hash >> 12);
-  __ movl(r1, r0);
-  __ shrl(r1, Immediate(12));
-  __ xorl(r0, r1);
-  // hash = hash + (hash << 2);
-  __ leal(r0, Operand(r0, r0, times_4, 0));
-  // hash = hash ^ (hash >> 4);
-  __ movl(r1, r0);
-  __ shrl(r1, Immediate(4));
-  __ xorl(r0, r1);
-  // hash = hash * 2057;
-  __ imull(r0, r0, Immediate(2057));
-  // hash = hash ^ (hash >> 16);
-  __ movl(r1, r0);
-  __ shrl(r1, Immediate(16));
-  __ xorl(r0, r1);
-
-  // Compute capacity mask.
-  __ SmiToInteger32(r1,
-                    FieldOperand(elements, NumberDictionary::kCapacityOffset));
-  __ decl(r1);
-
-  // Generate an unrolled loop that performs a few probes before giving up.
-  const int kProbes = 4;
-  for (int i = 0; i < kProbes; i++) {
-    // Use r2 for index calculations and keep the hash intact in r0.
-    __ movq(r2, r0);
-    // Compute the masked index: (hash + i + i * i) & mask.
-    if (i > 0) {
-      __ addl(r2, Immediate(NumberDictionary::GetProbeOffset(i)));
-    }
-    __ and_(r2, r1);
-
-    // Scale the index by multiplying by the entry size.
-    ASSERT(NumberDictionary::kEntrySize == 3);
-    __ lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3
-
-    // Check if the key matches.
-    __ cmpq(key, FieldOperand(elements,
-                              r2,
-                              times_pointer_size,
-                              NumberDictionary::kElementsStartOffset));
-    if (i != (kProbes - 1)) {
-      __ j(equal, &done);
-    } else {
-      __ j(not_equal, miss);
-    }
-  }
-
-  __ bind(&done);
-  // Check that the value is a normal propety.
-  const int kDetailsOffset =
-      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
-  ASSERT_EQ(NORMAL, 0);
-  __ Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
-          Smi::FromInt(PropertyDetails::TypeField::mask()));
-  __ j(not_zero, miss);
-
-  // Get the value at the masked, scaled index.
-  const int kValueOffset =
-      NumberDictionary::kElementsStartOffset + kPointerSize;
-  __ movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
-}
-
-
 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : receiver
@@ -508,11 +404,8 @@
   GenerateKeyedLoadReceiverCheck(
       masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow);
 
-  // Check the "has fast elements" bit in the receiver's map which is
-  // now in rcx.
-  __ testb(FieldOperand(rcx, Map::kBitField2Offset),
-           Immediate(1 << Map::kHasFastElements));
-  __ j(zero, &check_number_dictionary);
+  // Check the receiver's map to see if it has fast elements.
+  __ CheckFastElements(rcx, &check_number_dictionary);
 
   GenerateFastArrayLoad(masm,
                         rdx,
@@ -538,7 +431,7 @@
   __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
                  Heap::kHashTableMapRootIndex);
   __ j(not_equal, &slow);
-  GenerateNumberDictionaryLoad(masm, &slow, rcx, rax, rbx, r9, rdi, rax);
+  __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax);
   __ ret(0);
 
   __ bind(&slow);
@@ -730,9 +623,13 @@
 
   __ CmpInstanceType(rbx, JS_ARRAY_TYPE);
   __ j(equal, &array);
-  // Check that the object is some kind of JS object.
-  __ CmpInstanceType(rbx, FIRST_JS_OBJECT_TYPE);
+  // Check that the object is some kind of JSObject.
+  __ CmpInstanceType(rbx, FIRST_JS_RECEIVER_TYPE);
   __ j(below, &slow);
+  __ CmpInstanceType(rbx, JS_PROXY_TYPE);
+  __ j(equal, &slow);
+  __ CmpInstanceType(rbx, JS_FUNCTION_PROXY_TYPE);
+  __ j(equal, &slow);
 
   // Object case: Check key against length in the elements array.
   // rax: value
@@ -1098,7 +995,7 @@
   __ j(not_equal, &slow_load);
   __ SmiToInteger32(rbx, rcx);
   // ebx: untagged index
-  GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi);
+  __ LoadFromNumberDictionary(&slow_load, rax, rcx, rbx, r9, rdi, rdi);
   __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
   __ jmp(&do_call);
 
@@ -1197,6 +1094,171 @@
 }
 
 
+static Operand 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 elements
+  // 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.
+  __ CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, scratch1);
+  __ j(below, slow_case);
+
+  // Check that the key is a positive smi.
+  Condition check = masm->CheckNonNegativeSmi(key);
+  __ j(NegateCondition(check), slow_case);
+
+  // Load the elements into scratch1 and check its map. If not, jump
+  // to the unmapped lookup with the parameter map in scratch1.
+  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  __ movq(scratch1, FieldOperand(object, JSObject::kElementsOffset));
+  __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK);
+
+  // Check if element is in the range of mapped arguments.
+  __ movq(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset));
+  __ SmiSubConstant(scratch2, scratch2, Smi::FromInt(2));
+  __ cmpq(key, scratch2);
+  __ j(greater_equal, unmapped_case);
+
+  // Load element index and check whether it is the hole.
+  const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize;
+  __ SmiToInteger64(scratch3, key);
+  __ movq(scratch2, FieldOperand(scratch1,
+                                 scratch3,
+                                 times_pointer_size,
+                                 kHeaderSize));
+  __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex);
+  __ j(equal, 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).
+  __ movq(scratch1, FieldOperand(scratch1, FixedArray::kHeaderSize));
+  __ SmiToInteger64(scratch3, scratch2);
+  return FieldOperand(scratch1,
+                      scratch3,
+                      times_pointer_size,
+                      Context::kHeaderSize);
+}
+
+
+static Operand 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;
+  __ movq(backing_store, FieldOperand(parameter_map, kBackingStoreOffset));
+  Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map());
+  __ CheckMap(backing_store, fixed_array_map, slow_case, DONT_DO_SMI_CHECK);
+  __ movq(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset));
+  __ cmpq(key, scratch);
+  __ j(greater_equal, slow_case);
+  __ SmiToInteger64(scratch, key);
+  return FieldOperand(backing_store,
+                      scratch,
+                      times_pointer_size,
+                      FixedArray::kHeaderSize);
+}
+
+
+void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label slow, notin;
+  Operand mapped_location =
+      GenerateMappedArgumentsLookup(
+          masm, rdx, rax, rbx, rcx, rdi, &notin, &slow);
+  __ movq(rax, mapped_location);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in rbx.
+  Operand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow);
+  __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
+  __ j(equal, &slow);
+  __ movq(rax, unmapped_location);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
+void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax     : value
+  //  -- rcx     : key
+  //  -- rdx     : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label slow, notin;
+  Operand mapped_location = GenerateMappedArgumentsLookup(
+      masm, rdx, rcx, rbx, rdi, r8, &notin, &slow);
+  __ movq(mapped_location, rax);
+  __ lea(r9, mapped_location);
+  __ movq(r8, rax);
+  __ RecordWrite(rbx, r9, r8);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in rbx.
+  Operand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rdi, &slow);
+  __ movq(unmapped_location, rax);
+  __ lea(r9, unmapped_location);
+  __ movq(r8, rax);
+  __ RecordWrite(rbx, r9, r8);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm, false);
+}
+
+
+void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
+                                             int argc) {
+  // ----------- S t a t e -------------
+  // rcx                      : function name
+  // rsp[0]                   : return address
+  // rsp[8]                   : argument argc
+  // rsp[16]                  : argument argc - 1
+  // ...
+  // rsp[argc * 8]            : argument 1
+  // rsp[(argc + 1) * 8]      : argument 0 = receiver
+  // -----------------------------------
+  Label slow, notin;
+  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+  Operand mapped_location = GenerateMappedArgumentsLookup(
+      masm, rdx, rcx, rbx, rax, r8, &notin, &slow);
+  __ movq(rdi, mapped_location);
+  GenerateFunctionTailCall(masm, argc, &slow);
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in rbx.
+  Operand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rax, &slow);
+  __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
+  __ j(equal, &slow);
+  __ movq(rdi, unmapped_location);
+  GenerateFunctionTailCall(masm, argc, &slow);
+  __ bind(&slow);
+  GenerateMiss(masm, argc);
+}
+
+
 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : receiver
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 9fa11fa..e505058 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -144,7 +144,7 @@
   // when called as functions (without an explicit receiver
   // object). rcx is zero for method calls and non-zero for function
   // calls.
-  if (info_->is_strict_mode()) {
+  if (info_->is_strict_mode() || info_->is_native()) {
     Label ok;
     __ testq(rcx, rcx);
     __ j(zero, &ok, Label::kNear);
@@ -197,7 +197,7 @@
       FastNewContextStub stub(heap_slots);
       __ CallStub(&stub);
     } else {
-      __ CallRuntime(Runtime::kNewContext, 1);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
     }
     RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
     // Context is returned in both rax and rsi.  It replaces the context
@@ -275,11 +275,25 @@
 
 bool LCodeGen::GenerateDeferredCode() {
   ASSERT(is_generating());
-  for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
-    LDeferredCode* code = deferred_[i];
-    __ bind(code->entry());
-    code->Generate();
-    __ jmp(code->exit());
+  if (deferred_.length() > 0) {
+    for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
+      LDeferredCode* code = deferred_[i];
+      __ bind(code->entry());
+      code->Generate();
+      __ jmp(code->exit());
+    }
+
+    // Pad code to ensure that the last piece of deferred code have
+    // room for lazy bailout.
+    while ((masm()->pc_offset() - LastSafepointEnd())
+           < Deoptimizer::patch_size()) {
+      int padding = masm()->pc_offset() - LastSafepointEnd();
+      if (padding > 9) {
+        __ nop(9);
+      } else {
+        __ nop(padding);
+      }
+    }
   }
 
   // Deferred code is the last part of the instruction sequence. Mark
@@ -692,7 +706,7 @@
 
 
 void LCodeGen::RecordPosition(int position) {
-  if (!FLAG_debug_info || position == RelocInfo::kNoPosition) return;
+  if (position == RelocInfo::kNoPosition) return;
   masm()->positions_recorder()->RecordPosition(position);
 }
 
@@ -1216,6 +1230,20 @@
 }
 
 
+void LCodeGen::DoElementsKind(LElementsKind* instr) {
+  Register result = ToRegister(instr->result());
+  Register input = ToRegister(instr->InputAt(0));
+
+  // Load map into |result|.
+  __ movq(result, FieldOperand(input, HeapObject::kMapOffset));
+  // Load the map's "bit field 2" into |result|. We only need the first byte.
+  __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset));
+  // Retrieve elements_kind from bit field 2.
+  __ and_(result, Immediate(Map::kElementsKindMask));
+  __ shr(result, Immediate(Map::kElementsKindShift));
+}
+
+
 void LCodeGen::DoValueOf(LValueOf* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register result = ToRegister(instr->result());
@@ -1350,7 +1378,7 @@
   int true_block = chunk_->LookupDestination(instr->true_block_id());
   int false_block = chunk_->LookupDestination(instr->false_block_id());
 
-  Representation r = instr->hydrogen()->representation();
+  Representation r = instr->hydrogen()->value()->representation();
   if (r.IsInteger32()) {
     Register reg = ToRegister(instr->InputAt(0));
     __ testl(reg, reg);
@@ -1363,7 +1391,7 @@
   } else {
     ASSERT(r.IsTagged());
     Register reg = ToRegister(instr->InputAt(0));
-    HType type = instr->hydrogen()->type();
+    HType type = instr->hydrogen()->value()->type();
     if (type.IsBoolean()) {
       __ CompareRoot(reg, Heap::kTrueValueRootIndex);
       EmitBranch(true_block, false_block, equal);
@@ -1400,7 +1428,7 @@
       // The conversion stub doesn't cause garbage collections so it's
       // safe to not record a safepoint after the call.
       __ bind(&call_stub);
-      ToBooleanStub stub;
+      ToBooleanStub stub(rax);
       __ Pushad();
       __ push(reg);
       __ CallStub(&stub);
@@ -1412,44 +1440,17 @@
 }
 
 
-void LCodeGen::EmitGoto(int block, LDeferredCode* deferred_stack_check) {
+void LCodeGen::EmitGoto(int block) {
   block = chunk_->LookupDestination(block);
   int next_block = GetNextEmittedBlock(current_block_);
   if (block != next_block) {
-    // Perform stack overflow check if this goto needs it before jumping.
-    if (deferred_stack_check != NULL) {
-      __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
-      __ j(above_equal, chunk_->GetAssemblyLabel(block));
-      __ jmp(deferred_stack_check->entry());
-      deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block));
-    } else {
-      __ jmp(chunk_->GetAssemblyLabel(block));
-    }
+    __ jmp(chunk_->GetAssemblyLabel(block));
   }
 }
 
 
-void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
-  PushSafepointRegistersScope scope(this);
-  CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr);
-}
-
-
 void LCodeGen::DoGoto(LGoto* instr) {
-  class DeferredStackCheck: public LDeferredCode {
-   public:
-    DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
-   private:
-    LGoto* instr_;
-  };
-
-  DeferredStackCheck* deferred = NULL;
-  if (instr->include_stack_check()) {
-    deferred = new DeferredStackCheck(this, instr);
-  }
-  EmitGoto(instr->block_id(), deferred);
+  EmitGoto(instr->block_id());
 }
 
 
@@ -1497,32 +1498,6 @@
 }
 
 
-void LCodeGen::DoCmpID(LCmpID* instr) {
-  LOperand* left = instr->InputAt(0);
-  LOperand* right = instr->InputAt(1);
-  LOperand* result = instr->result();
-
-  Label unordered;
-  if (instr->is_double()) {
-    // Don't base result on EFLAGS when a NaN is involved. Instead
-    // jump to the unordered case, which produces a false value.
-    __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
-    __ j(parity_even, &unordered, Label::kNear);
-  } else {
-    EmitCmpI(left, right);
-  }
-
-  Label done;
-  Condition cc = TokenToCondition(instr->op(), instr->is_double());
-  __ LoadRoot(ToRegister(result), Heap::kTrueValueRootIndex);
-  __ j(cc, &done, Label::kNear);
-
-  __ bind(&unordered);
-  __ LoadRoot(ToRegister(result), Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
@@ -1543,23 +1518,7 @@
 }
 
 
-void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
-  Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  Register result = ToRegister(instr->result());
-
-  Label different, done;
-  __ cmpq(left, right);
-  __ j(not_equal, &different, Label::kNear);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ jmp(&done, Label::kNear);
-  __ bind(&different);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
-void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
+void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
   Register left = ToRegister(instr->InputAt(0));
   Register right = ToRegister(instr->InputAt(1));
   int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1570,75 +1529,16 @@
 }
 
 
-void LCodeGen::DoCmpSymbolEq(LCmpSymbolEq* instr) {
+void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
   Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  Register result = ToRegister(instr->result());
-
-  Label done;
-  __ cmpq(left, right);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ j(not_equal, &done, Label::kNear);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ bind(&done);
-}
-
-
-void LCodeGen::DoCmpSymbolEqAndBranch(LCmpSymbolEqAndBranch* instr) {
-  Register left = ToRegister(instr->InputAt(0));
-  Register right = ToRegister(instr->InputAt(1));
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
   int true_block = chunk_->LookupDestination(instr->true_block_id());
+  int false_block = chunk_->LookupDestination(instr->false_block_id());
 
-  __ cmpq(left, right);
+  __ cmpq(left, Immediate(instr->hydrogen()->right()));
   EmitBranch(true_block, false_block, equal);
 }
 
 
-void LCodeGen::DoIsNull(LIsNull* instr) {
-  Register reg = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  // If the expression is known to be a smi, then it's
-  // definitely not null. Materialize false.
-  // Consider adding other type and representation tests too.
-  if (instr->hydrogen()->value()->type().IsSmi()) {
-    __ LoadRoot(result, Heap::kFalseValueRootIndex);
-    return;
-  }
-
-  __ CompareRoot(reg, Heap::kNullValueRootIndex);
-  if (instr->is_strict()) {
-    ASSERT(Heap::kTrueValueRootIndex >= 0);
-    __ movl(result, Immediate(Heap::kTrueValueRootIndex));
-    Label load;
-    __ j(equal, &load, Label::kNear);
-    __ Set(result, Heap::kFalseValueRootIndex);
-    __ bind(&load);
-    __ LoadRootIndexed(result, result, 0);
-  } else {
-    Label false_value, true_value, done;
-    __ j(equal, &true_value, Label::kNear);
-    __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
-    __ j(equal, &true_value, Label::kNear);
-    __ JumpIfSmi(reg, &false_value, Label::kNear);
-    // Check for undetectable objects by looking in the bit field in
-    // the map. The object has already been smi checked.
-    Register scratch = result;
-    __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
-    __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
-             Immediate(1 << Map::kIsUndetectable));
-    __ j(not_zero, &true_value, Label::kNear);
-    __ bind(&false_value);
-    __ LoadRoot(result, Heap::kFalseValueRootIndex);
-    __ jmp(&done, Label::kNear);
-    __ bind(&true_value);
-    __ LoadRoot(result, Heap::kTrueValueRootIndex);
-    __ bind(&done);
-  }
-}
-
-
 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
   Register reg = ToRegister(instr->InputAt(0));
 
@@ -1694,32 +1594,13 @@
 
   __ movzxbl(kScratchRegister,
              FieldOperand(kScratchRegister, Map::kInstanceTypeOffset));
-  __ cmpb(kScratchRegister, Immediate(FIRST_JS_OBJECT_TYPE));
+  __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
   __ j(below, is_not_object);
-  __ cmpb(kScratchRegister, Immediate(LAST_JS_OBJECT_TYPE));
+  __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
   return below_equal;
 }
 
 
-void LCodeGen::DoIsObject(LIsObject* instr) {
-  Register reg = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  Label is_false, is_true, done;
-
-  Condition true_cond = EmitIsObject(reg, &is_false, &is_true);
-  __ j(true_cond, &is_true);
-
-  __ bind(&is_false);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ jmp(&done);
-
-  __ bind(&is_true);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
   Register reg = ToRegister(instr->InputAt(0));
 
@@ -1734,22 +1615,6 @@
 }
 
 
-void LCodeGen::DoIsSmi(LIsSmi* instr) {
-  LOperand* input_operand = instr->InputAt(0);
-  Register result = ToRegister(instr->result());
-  if (input_operand->IsRegister()) {
-    Register input = ToRegister(input_operand);
-    __ CheckSmiToIndicator(result, input);
-  } else {
-    Operand input = ToOperand(instr->InputAt(0));
-    __ CheckSmiToIndicator(result, input);
-  }
-  // result is zero if input is a smi, and one otherwise.
-  ASSERT(Heap::kFalseValueRootIndex == Heap::kTrueValueRootIndex + 1);
-  __ LoadRootIndexed(result, result, Heap::kTrueValueRootIndex);
-}
-
-
 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
   int true_block = chunk_->LookupDestination(instr->true_block_id());
   int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1766,25 +1631,6 @@
 }
 
 
-void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  Label false_label, done;
-  __ JumpIfSmi(input, &false_label);
-  __ movq(result, FieldOperand(input, HeapObject::kMapOffset));
-  __ testb(FieldOperand(result, Map::kBitFieldOffset),
-           Immediate(1 << Map::kIsUndetectable));
-  __ j(zero, &false_label);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ jmp(&done);
-  __ bind(&false_label);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register temp = ToRegister(instr->TempAt(0));
@@ -1800,7 +1646,7 @@
 }
 
 
-static InstanceType TestType(HHasInstanceType* instr) {
+static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
   InstanceType from = instr->from();
   InstanceType to = instr->to();
   if (from == FIRST_TYPE) return to;
@@ -1809,7 +1655,7 @@
 }
 
 
-static Condition BranchCondition(HHasInstanceType* instr) {
+static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
   InstanceType from = instr->from();
   InstanceType to = instr->to();
   if (from == to) return equal;
@@ -1820,25 +1666,6 @@
 }
 
 
-void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  __ testl(input, Immediate(kSmiTagMask));
-  Label done, is_false;
-  __ j(zero, &is_false);
-  __ CmpObjectType(input, TestType(instr->hydrogen()), result);
-  __ j(NegateCondition(BranchCondition(instr->hydrogen())),
-       &is_false, Label::kNear);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ jmp(&done, Label::kNear);
-  __ bind(&is_false);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
 
@@ -1868,21 +1695,6 @@
 }
 
 
-void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-
-  ASSERT(instr->hydrogen()->value()->representation().IsTagged());
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ testl(FieldOperand(input, String::kHashFieldOffset),
-           Immediate(String::kContainsCachedArrayIndexMask));
-  Label done;
-  __ j(zero, &done, Label::kNear);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoHasCachedArrayIndexAndBranch(
     LHasCachedArrayIndexAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
@@ -1904,26 +1716,27 @@
                                Register input,
                                Register temp) {
   __ JumpIfSmi(input, is_false);
-  __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, temp);
+  __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp);
   __ j(below, is_false);
 
   // Map is now in temp.
   // Functions have class 'Function'.
-  __ CmpInstanceType(temp, JS_FUNCTION_TYPE);
+  __ CmpInstanceType(temp, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
   if (class_name->IsEqualTo(CStrVector("Function"))) {
-    __ j(equal, is_true);
+    __ j(above_equal, is_true);
   } else {
-    __ j(equal, is_false);
+    __ j(above_equal, is_false);
   }
 
   // Check if the constructor in the map is a function.
   __ movq(temp, FieldOperand(temp, Map::kConstructorOffset));
 
-  // As long as JS_FUNCTION_TYPE is the last instance type and it is
-  // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
-  // LAST_JS_OBJECT_TYPE.
-  ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
-  ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
+  // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last type and
+  // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+  // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
+  STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+  STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+                LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
 
   // Objects with a non-function constructor have class 'Object'.
   __ CmpObjectType(temp, JS_FUNCTION_TYPE, kScratchRegister);
@@ -1950,29 +1763,6 @@
 }
 
 
-void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  ASSERT(input.is(result));
-  Register temp = ToRegister(instr->TempAt(0));
-  Handle<String> class_name = instr->hydrogen()->class_name();
-  Label done;
-  Label is_true, is_false;
-
-  EmitClassOfTest(&is_true, &is_false, class_name, input, temp);
-
-  __ j(not_equal, &is_false);
-
-  __ bind(&is_true);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-  __ jmp(&done, Label::kNear);
-
-  __ bind(&is_false);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
   Register input = ToRegister(instr->InputAt(0));
   Register temp = ToRegister(instr->TempAt(0));
@@ -2016,19 +1806,6 @@
 }
 
 
-void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
-  int true_block = chunk_->LookupDestination(instr->true_block_id());
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
-
-  InstanceofStub stub(InstanceofStub::kNoFlags);
-  __ push(ToRegister(instr->InputAt(0)));
-  __ push(ToRegister(instr->InputAt(1)));
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-  __ testq(rax, rax);
-  EmitBranch(true_block, false_block, zero);
-}
-
-
 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
   class DeferredInstanceOfKnownGlobal: public LDeferredCode {
    public:
@@ -2106,7 +1883,6 @@
     __ push(ToRegister(instr->InputAt(0)));
     __ Push(instr->function());
 
-    Register temp = ToRegister(instr->TempAt(0));
     static const int kAdditionalDelta = 10;
     int delta =
         masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
@@ -2160,25 +1936,6 @@
 }
 
 
-void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) {
-  Token::Value op = instr->op();
-  int true_block = chunk_->LookupDestination(instr->true_block_id());
-  int false_block = chunk_->LookupDestination(instr->false_block_id());
-
-  Handle<Code> ic = CompareIC::GetUninitialized(op);
-  CallCode(ic, RelocInfo::CODE_TARGET, instr);
-
-  // The compare stub expects compare condition and the input operands
-  // reversed for GT and LTE.
-  Condition condition = TokenToCondition(op, false);
-  if (op == Token::GT || op == Token::LTE) {
-    condition = ReverseCondition(condition);
-  }
-  __ testq(rax, rax);
-  EmitBranch(true_block, false_block, condition);
-}
-
-
 void LCodeGen::DoReturn(LReturn* instr) {
   if (FLAG_trace) {
     // Preserve the return value on the stack and rely on the runtime
@@ -2412,7 +2169,7 @@
   Register input = ToRegister(instr->InputAt(0));
   __ movq(result, FieldOperand(input, JSObject::kElementsOffset));
   if (FLAG_debug_code) {
-    Label done;
+    Label done, ok, fail;
     __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
                    Heap::kFixedArrayMapRootIndex);
     __ j(equal, &done, Label::kNear);
@@ -2422,11 +2179,19 @@
     Register temp((result.is(rax)) ? rbx : rax);
     __ push(temp);
     __ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
-    __ movzxbq(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
-    __ subq(temp, Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
-    __ cmpq(temp, Immediate(kExternalArrayTypeCount));
+    __ movzxbq(temp, FieldOperand(temp, Map::kBitField2Offset));
+    __ and_(temp, Immediate(Map::kElementsKindMask));
+    __ shr(temp, Immediate(Map::kElementsKindShift));
+    __ cmpl(temp, Immediate(JSObject::FAST_ELEMENTS));
+    __ j(equal, &ok, Label::kNear);
+    __ cmpl(temp, Immediate(JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND));
+    __ j(less, &fail, Label::kNear);
+    __ cmpl(temp, Immediate(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND));
+    __ j(less_equal, &ok, Label::kNear);
+    __ bind(&fail);
+    __ Abort("Check for fast or external elements failed");
+    __ bind(&ok);
     __ pop(temp);
-    __ Check(below, "Check for fast elements failed.");
     __ bind(&done);
   }
 }
@@ -2479,55 +2244,82 @@
 }
 
 
-Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer,
-                                            LOperand* key,
-                                            ExternalArrayType array_type) {
+void LCodeGen::DoLoadKeyedFastDoubleElement(
+    LLoadKeyedFastDoubleElement* instr) {
+  XMMRegister result(ToDoubleRegister(instr->result()));
+
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
+        sizeof(kHoleNanLower32);
+    Operand hole_check_operand = BuildFastArrayOperand(
+        instr->elements(),
+        instr->key(),
+        JSObject::FAST_DOUBLE_ELEMENTS,
+        offset);
+    __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
+    DeoptimizeIf(equal, instr->environment());
+  }
+
+  Operand double_load_operand = BuildFastArrayOperand(
+      instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
+      FixedDoubleArray::kHeaderSize - kHeapObjectTag);
+  __ movsd(result, double_load_operand);
+}
+
+
+Operand LCodeGen::BuildFastArrayOperand(
+    LOperand* external_pointer,
+    LOperand* key,
+    JSObject::ElementsKind elements_kind,
+    uint32_t offset) {
   Register external_pointer_reg = ToRegister(external_pointer);
-  int shift_size = ExternalArrayTypeToShiftSize(array_type);
+  int shift_size = ElementsKindToShiftSize(elements_kind);
   if (key->IsConstantOperand()) {
     int constant_value = ToInteger32(LConstantOperand::cast(key));
     if (constant_value & 0xF0000000) {
       Abort("array index constant value too big");
     }
-    return Operand(external_pointer_reg, constant_value * (1 << shift_size));
+    return Operand(external_pointer_reg,
+                   constant_value * (1 << shift_size) + offset);
   } else {
     ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
-    return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0);
+    return Operand(external_pointer_reg, ToRegister(key),
+                   scale_factor, offset);
   }
 }
 
 
 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
     LLoadKeyedSpecializedArrayElement* instr) {
-  ExternalArrayType array_type = instr->array_type();
-  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
-                                            instr->key(), array_type));
-  if (array_type == kExternalFloatArray) {
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
+  Operand operand(BuildFastArrayOperand(instr->external_pointer(),
+                                        instr->key(), elements_kind, 0));
+  if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
     XMMRegister result(ToDoubleRegister(instr->result()));
     __ movss(result, operand);
     __ cvtss2sd(result, result);
-  } else if (array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     __ movsd(ToDoubleRegister(instr->result()), operand);
   } else {
     Register result(ToRegister(instr->result()));
-    switch (array_type) {
-      case kExternalByteArray:
+    switch (elements_kind) {
+      case JSObject::EXTERNAL_BYTE_ELEMENTS:
         __ movsxbq(result, operand);
         break;
-      case kExternalUnsignedByteArray:
-      case kExternalPixelArray:
+      case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+      case JSObject::EXTERNAL_PIXEL_ELEMENTS:
         __ movzxbq(result, operand);
         break;
-      case kExternalShortArray:
+      case JSObject::EXTERNAL_SHORT_ELEMENTS:
         __ movsxwq(result, operand);
         break;
-      case kExternalUnsignedShortArray:
+      case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
         __ movzxwq(result, operand);
         break;
-      case kExternalIntArray:
+      case JSObject::EXTERNAL_INT_ELEMENTS:
         __ movsxlq(result, operand);
         break;
-      case kExternalUnsignedIntArray:
+      case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
         __ movl(result, operand);
         __ testl(result, result);
         // TODO(danno): we could be more clever here, perhaps having a special
@@ -2535,8 +2327,12 @@
         // happens, and generate code that returns a double rather than int.
         DeoptimizeIf(negative, instr->environment());
         break;
-      case kExternalFloatArray:
-      case kExternalDoubleArray:
+      case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+      case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+      case JSObject::FAST_ELEMENTS:
+      case JSObject::FAST_DOUBLE_ELEMENTS:
+      case JSObject::DICTIONARY_ELEMENTS:
+      case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -2611,12 +2407,27 @@
   ASSERT(function.is(rdi));  // Required by InvokeFunction.
   ASSERT(ToRegister(instr->result()).is(rax));
 
-  // TODO(1412): This is not correct if the called function is a
-  // strict mode function or a native.
-  //
-  // If the receiver is null or undefined, we have to pass the global object
-  // as a receiver.
+  // 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, receiver_ok;
+
+  // Do not transform the receiver to object for strict mode
+  // functions.
+  __ movq(kScratchRegister,
+          FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
+  __ testb(FieldOperand(kScratchRegister,
+                        SharedFunctionInfo::kStrictModeByteOffset),
+           Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
+  __ j(not_equal, &receiver_ok, Label::kNear);
+
+  // Do not transform the receiver to object for builtins.
+  __ testb(FieldOperand(kScratchRegister,
+                        SharedFunctionInfo::kNativeByteOffset),
+           Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
+  __ j(not_equal, &receiver_ok, Label::kNear);
+
+  // Normal function. Replace undefined or null with global receiver.
   __ CompareRoot(receiver, Heap::kNullValueRootIndex);
   __ j(equal, &global_object, Label::kNear);
   __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex);
@@ -2625,7 +2436,7 @@
   // The receiver should be a JS object.
   Condition is_smi = __ CheckSmi(receiver);
   DeoptimizeIf(is_smi, instr->environment());
-  __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, kScratchRegister);
+  __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
   DeoptimizeIf(below, instr->environment());
   __ jmp(&receiver_ok, Label::kNear);
 
@@ -2681,6 +2492,12 @@
 }
 
 
+void LCodeGen::DoThisFunction(LThisFunction* instr) {
+  Register result = ToRegister(instr->result());
+  __ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+}
+
+
 void LCodeGen::DoContext(LContext* instr) {
   Register result = ToRegister(instr->result());
   __ movq(result, rsi);
@@ -2691,8 +2508,7 @@
   Register context = ToRegister(instr->context());
   Register result = ToRegister(instr->result());
   __ movq(result,
-          Operand(context, Context::SlotOffset(Context::CLOSURE_INDEX)));
-  __ movq(result, FieldOperand(result, JSFunction::kContextOffset));
+          Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
 }
 
 
@@ -3202,33 +3018,37 @@
 
 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
     LStoreKeyedSpecializedArrayElement* instr) {
-  ExternalArrayType array_type = instr->array_type();
-  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
-                                            instr->key(), array_type));
-  if (array_type == kExternalFloatArray) {
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
+  Operand operand(BuildFastArrayOperand(instr->external_pointer(),
+                                        instr->key(), elements_kind, 0));
+  if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
     XMMRegister value(ToDoubleRegister(instr->value()));
     __ cvtsd2ss(value, value);
     __ movss(operand, value);
-  } else if (array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     __ movsd(operand, ToDoubleRegister(instr->value()));
   } else {
     Register value(ToRegister(instr->value()));
-    switch (array_type) {
-      case kExternalPixelArray:
-      case kExternalByteArray:
-      case kExternalUnsignedByteArray:
+    switch (elements_kind) {
+      case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+      case JSObject::EXTERNAL_BYTE_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
         __ movb(operand, value);
         break;
-      case kExternalShortArray:
-      case kExternalUnsignedShortArray:
+      case JSObject::EXTERNAL_SHORT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
         __ movw(operand, value);
         break;
-      case kExternalIntArray:
-      case kExternalUnsignedIntArray:
+      case JSObject::EXTERNAL_INT_ELEMENTS:
+      case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
         __ movl(operand, value);
         break;
-      case kExternalFloatArray:
-      case kExternalDoubleArray:
+      case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+      case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+      case JSObject::FAST_ELEMENTS:
+      case JSObject::FAST_DOUBLE_ELEMENTS:
+      case JSObject::DICTIONARY_ELEMENTS:
+      case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -3277,6 +3097,27 @@
 }
 
 
+void LCodeGen::DoStoreKeyedFastDoubleElement(
+    LStoreKeyedFastDoubleElement* instr) {
+  XMMRegister value = ToDoubleRegister(instr->value());
+  Label have_value;
+
+  __ ucomisd(value, value);
+  __ j(parity_odd, &have_value);  // NaN.
+
+  ExternalReference canonical_nan_reference =
+      ExternalReference::address_of_canonical_non_hole_nan();
+  __ Set(kScratchRegister, BitCast<uint64_t>(
+      FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
+  __ movq(value, kScratchRegister);
+
+  __ bind(&have_value);
+  Operand double_store_operand = BuildFastArrayOperand(
+      instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
+      FixedDoubleArray::kHeaderSize - kHeapObjectTag);
+  __ movsd(double_store_operand, value);
+}
+
 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
   ASSERT(ToRegister(instr->object()).is(rdx));
   ASSERT(ToRegister(instr->key()).is(rcx));
@@ -4035,29 +3876,6 @@
 }
 
 
-void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  Label true_label;
-  Label false_label;
-  Label done;
-
-  Condition final_branch_condition = EmitTypeofIs(&true_label,
-                                                  &false_label,
-                                                  input,
-                                                  instr->type_literal());
-  __ j(final_branch_condition, &true_label);
-  __ bind(&false_label);
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ jmp(&done, Label::kNear);
-
-  __ bind(&true_label);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
   ASSERT(!operand->IsDoubleRegister());
   if (operand->IsConstantOperand()) {
@@ -4124,17 +3942,17 @@
 
   } else if (type_name->Equals(heap()->function_symbol())) {
     __ JumpIfSmi(input, false_label);
-    __ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input);
+    __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input);
     final_branch_condition = above_equal;
 
   } else if (type_name->Equals(heap()->object_symbol())) {
     __ JumpIfSmi(input, false_label);
     __ CompareRoot(input, Heap::kNullValueRootIndex);
     __ j(equal, true_label);
-    __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
+    __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
     __ j(below, false_label);
-    __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
-    __ j(above_equal, false_label);
+    __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ j(above, false_label);
     // Check for undetectable objects => false.
     __ testb(FieldOperand(input, Map::kBitFieldOffset),
              Immediate(1 << Map::kIsUndetectable));
@@ -4149,25 +3967,6 @@
 }
 
 
-void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
-  Register result = ToRegister(instr->result());
-  Label true_label;
-  Label done;
-
-  EmitIsConstructCall(result);
-  __ j(equal, &true_label, Label::kNear);
-
-  __ LoadRoot(result, Heap::kFalseValueRootIndex);
-  __ jmp(&done, Label::kNear);
-
-  __ bind(&true_label);
-  __ LoadRoot(result, Heap::kTrueValueRootIndex);
-
-
-  __ bind(&done);
-}
-
-
 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
   Register temp = ToRegister(instr->TempAt(0));
   int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -4248,15 +4047,48 @@
 }
 
 
-void LCodeGen::DoStackCheck(LStackCheck* instr) {
-  // Perform stack overflow check.
-  Label done;
-  __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
-  __ j(above_equal, &done, Label::kNear);
+void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
+  {
+    PushSafepointRegistersScope scope(this);
+    __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+    __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
+    RegisterLazyDeoptimization(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
+  }
 
-  StackCheckStub stub;
-  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-  __ bind(&done);
+  // The gap code includes the restoring of the safepoint registers.
+  int pc = masm()->pc_offset();
+  safepoints_.SetPcAfterGap(pc);
+}
+
+
+void LCodeGen::DoStackCheck(LStackCheck* instr) {
+  class DeferredStackCheck: public LDeferredCode {
+   public:
+    DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
+        : LDeferredCode(codegen), instr_(instr) { }
+    virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
+   private:
+    LStackCheck* instr_;
+  };
+
+  if (instr->hydrogen()->is_function_entry()) {
+    // Perform stack overflow check.
+    Label done;
+    __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
+    __ j(above_equal, &done, Label::kNear);
+    StackCheckStub stub;
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+    __ bind(&done);
+  } else {
+    ASSERT(instr->hydrogen()->is_backwards_branch());
+    // Perform stack overflow check if this goto needs it before jumping.
+    DeferredStackCheck* deferred_stack_check =
+        new DeferredStackCheck(this, instr);
+    __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
+    __ j(below, deferred_stack_check->entry());
+    __ bind(instr->done_label());
+    deferred_stack_check->SetExit(instr->done_label());
+  }
 }
 
 
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index 7c9f2a0..d7c72b5 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -94,7 +94,7 @@
   void DoDeferredNumberTagD(LNumberTagD* instr);
   void DoDeferredTaggedToI(LTaggedToI* instr);
   void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
-  void DoDeferredStackCheck(LGoto* instr);
+  void DoDeferredStackCheck(LStackCheck* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
@@ -215,9 +215,11 @@
 
   Register ToRegister(int index) const;
   XMMRegister ToDoubleRegister(int index) const;
-  Operand BuildExternalArrayOperand(LOperand* external_pointer,
-                                    LOperand* key,
-                                    ExternalArrayType array_type);
+  Operand BuildFastArrayOperand(
+      LOperand* external_pointer,
+      LOperand* key,
+      JSObject::ElementsKind elements_kind,
+      uint32_t offset);
 
   // Specific math operations - used from DoUnaryMathOperation.
   void EmitIntegerMathAbs(LUnaryMathOperation* instr);
@@ -246,7 +248,7 @@
   }
 
   static Condition TokenToCondition(Token::Value op, bool is_unsigned);
-  void EmitGoto(int block, LDeferredCode* deferred_stack_check = NULL);
+  void EmitGoto(int block);
   void EmitBranch(int left_block, int right_block, Condition cc);
   void EmitCmpI(LOperand* left, LOperand* right);
   void EmitNumberUntagD(Register input,
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 569fa3e..00b906d 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -78,13 +78,13 @@
   ASSERT(Output() == NULL ||
          LUnallocated::cast(Output())->HasFixedPolicy() ||
          !LUnallocated::cast(Output())->HasRegisterPolicy());
-  for (UseIterator it(this); it.HasNext(); it.Advance()) {
-    LUnallocated* operand = LUnallocated::cast(it.Next());
+  for (UseIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
     ASSERT(operand->HasFixedPolicy() ||
            operand->IsUsedAtStart());
   }
-  for (TempIterator it(this); it.HasNext(); it.Advance()) {
-    LUnallocated* operand = LUnallocated::cast(it.Next());
+  for (TempIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
     ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
   }
 }
@@ -113,21 +113,18 @@
 template<int R, int I, int T>
 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
   stream->Add("= ");
-  inputs_.PrintOperandsTo(stream);
+  for (int i = 0; i < inputs_.length(); i++) {
+    if (i > 0) stream->Add(" ");
+    inputs_[i]->PrintTo(stream);
+  }
 }
 
 
 template<int R, int I, int T>
 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
-  results_.PrintOperandsTo(stream);
-}
-
-
-template<typename T, int N>
-void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
-  for (int i = 0; i < N; i++) {
+  for (int i = 0; i < results_.length(); i++) {
     if (i > 0) stream->Add(" ");
-    elems_[i]->PrintTo(stream);
+    results_[i]->PrintTo(stream);
   }
 }
 
@@ -270,12 +267,6 @@
 }
 
 
-void LTypeofIs::PrintDataTo(StringStream* stream) {
-  InputAt(0)->PrintTo(stream);
-  stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
-}
-
-
 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
   stream->Add("if typeof ");
   InputAt(0)->PrintTo(stream);
@@ -345,13 +336,6 @@
 }
 
 
-void LClassOfTest::PrintDataTo(StringStream* stream) {
-  stream->Add("= class_of_test(");
-  InputAt(0)->PrintTo(stream);
-  stream->Add(", \"%o\")", *hydrogen()->class_name());
-}
-
-
 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
   arguments()->PrintTo(stream);
 
@@ -393,8 +377,7 @@
     LLabel* label = LLabel::cast(first_instr);
     if (last_instr->IsGoto()) {
       LGoto* goto_instr = LGoto::cast(last_instr);
-      if (!goto_instr->include_stack_check() &&
-          label->IsRedundant() &&
+      if (label->IsRedundant() &&
           !label->is_loop_header()) {
         bool can_eliminate = true;
         for (int i = first + 1; i < last && can_eliminate; ++i) {
@@ -445,6 +428,15 @@
 }
 
 
+void LStoreKeyedFastDoubleElement::PrintDataTo(StringStream* stream) {
+  elements()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  stream->Add("] <- ");
+  value()->PrintTo(stream);
+}
+
+
 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add("[");
@@ -713,7 +705,9 @@
 
 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
   HEnvironment* hydrogen_env = current_block_->last_environment();
-  instr->set_environment(CreateEnvironment(hydrogen_env));
+  int argument_index_accumulator = 0;
+  instr->set_environment(CreateEnvironment(hydrogen_env,
+                                           &argument_index_accumulator));
   return instr;
 }
 
@@ -803,6 +797,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
+  return AssignEnvironment(new LDeoptimize);
+}
+
+
 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
   return AssignEnvironment(new LDeoptimize);
 }
@@ -843,11 +842,11 @@
   }
 
   ASSERT(instr->representation().IsInteger32());
-  ASSERT(instr->OperandAt(0)->representation().IsInteger32());
-  ASSERT(instr->OperandAt(1)->representation().IsInteger32());
-  LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
+  ASSERT(instr->left()->representation().IsInteger32());
+  ASSERT(instr->right()->representation().IsInteger32());
+  LOperand* left = UseRegisterAtStart(instr->left());
 
-  HValue* right_value = instr->OperandAt(1);
+  HValue* right_value = instr->right();
   LOperand* right = NULL;
   int constant_value = 0;
   if (right_value->IsConstant()) {
@@ -984,28 +983,20 @@
     if (FLAG_stress_environments && !instr->HasEnvironment()) {
       instr = AssignEnvironment(instr);
     }
-    if (current->IsTest() && !instr->IsGoto()) {
-      ASSERT(instr->IsControl());
-      HTest* test = HTest::cast(current);
-      instr->set_hydrogen_value(test->value());
-      HBasicBlock* first = test->FirstSuccessor();
-      HBasicBlock* second = test->SecondSuccessor();
-      ASSERT(first != NULL && second != NULL);
-      instr->SetBranchTargets(first->block_id(), second->block_id());
-    } else {
-      instr->set_hydrogen_value(current);
-    }
-
+    instr->set_hydrogen_value(current);
     chunk_->AddInstruction(instr, current_block_);
   }
   current_instruction_ = old_current;
 }
 
 
-LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
+LEnvironment* LChunkBuilder::CreateEnvironment(
+    HEnvironment* hydrogen_env,
+    int* argument_index_accumulator) {
   if (hydrogen_env == NULL) return NULL;
 
-  LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
+  LEnvironment* outer =
+      CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
   int ast_id = hydrogen_env->ast_id();
   ASSERT(ast_id != AstNode::kNoNumber);
   int value_count = hydrogen_env->length();
@@ -1015,7 +1006,6 @@
                                           argument_count_,
                                           value_count,
                                           outer);
-  int argument_index = 0;
   for (int i = 0; i < value_count; ++i) {
     if (hydrogen_env->is_special_index(i)) continue;
 
@@ -1024,7 +1014,7 @@
     if (value->IsArgumentsObject()) {
       op = NULL;
     } else if (value->IsPushArgument()) {
-      op = new LArgument(argument_index++);
+      op = new LArgument((*argument_index_accumulator)++);
     } else {
       op = UseAny(value);
     }
@@ -1036,104 +1026,21 @@
 
 
 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
-  LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(),
-                            instr->include_stack_check());
-  return (instr->include_stack_check())
-      ? AssignPointerMap(result)
-      : result;
+  return new LGoto(instr->FirstSuccessor()->block_id());
 }
 
 
-LInstruction* LChunkBuilder::DoTest(HTest* instr) {
+LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
   HValue* v = instr->value();
-  if (!v->EmitAtUses()) {
-    return new LBranch(UseRegisterAtStart(v));
-  } else if (v->IsClassOfTest()) {
-    HClassOfTest* compare = HClassOfTest::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
-                                     TempRegister());
-  } else if (v->IsCompare()) {
-    HCompare* compare = HCompare::cast(v);
-    Token::Value op = compare->token();
-    HValue* left = compare->left();
-    HValue* right = compare->right();
-    Representation r = compare->GetInputRepresentation();
-    if (r.IsInteger32()) {
-      ASSERT(left->representation().IsInteger32());
-      ASSERT(right->representation().IsInteger32());
-      return new LCmpIDAndBranch(UseRegisterAtStart(left),
-                                 UseOrConstantAtStart(right));
-    } else if (r.IsDouble()) {
-      ASSERT(left->representation().IsDouble());
-      ASSERT(right->representation().IsDouble());
-      return new LCmpIDAndBranch(UseRegisterAtStart(left),
-                                 UseRegisterAtStart(right));
-    } else {
-      ASSERT(left->representation().IsTagged());
-      ASSERT(right->representation().IsTagged());
-      bool reversed = op == Token::GT || op == Token::LTE;
-      LOperand* left_operand = UseFixed(left, reversed ? rax : rdx);
-      LOperand* right_operand = UseFixed(right, reversed ? rdx : rax);
-      LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, right_operand);
-      return MarkAsCall(result, instr);
-    }
-  } else if (v->IsIsSmi()) {
-    HIsSmi* compare = HIsSmi::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsSmiAndBranch(Use(compare->value()));
-  } else if (v->IsIsUndetectable()) {
-    HIsUndetectable* compare = HIsUndetectable::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()),
-                                        TempRegister());
-  } else if (v->IsHasInstanceType()) {
-    HHasInstanceType* compare = HHasInstanceType::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()));
-  } else if (v->IsHasCachedArrayIndex()) {
-    HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LHasCachedArrayIndexAndBranch(
-        UseRegisterAtStart(compare->value()));
-  } else if (v->IsIsNull()) {
-    HIsNull* compare = HIsNull::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    // We only need a temp register for non-strict compare.
-    LOperand* temp = compare->is_strict() ? NULL : TempRegister();
-    return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), temp);
-  } else if (v->IsIsObject()) {
-    HIsObject* compare = HIsObject::cast(v);
-    ASSERT(compare->value()->representation().IsTagged());
-    return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()));
-  } else if (v->IsCompareJSObjectEq()) {
-    HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
-    return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
-                                       UseRegisterAtStart(compare->right()));
-  } else if (v->IsCompareSymbolEq()) {
-    HCompareSymbolEq* compare = HCompareSymbolEq::cast(v);
-    return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()),
-                                     UseRegisterAtStart(compare->right()));
-  } else if (v->IsInstanceOf()) {
-    HInstanceOf* instance_of = HInstanceOf::cast(v);
-    LInstanceOfAndBranch* result =
-        new LInstanceOfAndBranch(UseFixed(instance_of->left(), rax),
-                                 UseFixed(instance_of->right(), rdx));
-    return MarkAsCall(result, instr);
-  } else if (v->IsTypeofIs()) {
-    HTypeofIs* typeof_is = HTypeofIs::cast(v);
-    return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
-  } else if (v->IsIsConstructCall()) {
-    return new LIsConstructCallAndBranch(TempRegister());
-  } else if (v->IsConstant()) {
+  if (v->EmitAtUses()) {
+    ASSERT(v->IsConstant());
+    ASSERT(!v->representation().IsDouble());
     HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
     return new LGoto(successor->block_id());
-  } else {
-    Abort("Undefined compare before branch");
-    return NULL;
   }
+  return new LBranch(UseRegisterAtStart(v));
 }
 
 
@@ -1165,7 +1072,7 @@
 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
     HInstanceOfKnownGlobal* instr) {
   LInstanceOfKnownGlobal* result =
-      new LInstanceOfKnownGlobal(UseFixed(instr->value(), rax),
+      new LInstanceOfKnownGlobal(UseFixed(instr->left(), rax),
                                  FixedTemp(rdi));
   return MarkAsCall(DefineFixed(result, rax), instr);
 }
@@ -1191,6 +1098,11 @@
 }
 
 
+LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
+  return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction);
+}
+
+
 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
   return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext);
 }
@@ -1481,88 +1393,83 @@
 }
 
 
-LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
+LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
   Token::Value op = instr->token();
+  ASSERT(instr->left()->representation().IsTagged());
+  ASSERT(instr->right()->representation().IsTagged());
+  bool reversed = (op == Token::GT || op == Token::LTE);
+  LOperand* left = UseFixed(instr->left(), reversed ? rax : rdx);
+  LOperand* right = UseFixed(instr->right(), reversed ? rdx : rax);
+  LCmpT* result = new LCmpT(left, right);
+  return MarkAsCall(DefineFixed(result, rax), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCompareIDAndBranch(
+    HCompareIDAndBranch* instr) {
   Representation r = instr->GetInputRepresentation();
   if (r.IsInteger32()) {
     ASSERT(instr->left()->representation().IsInteger32());
     ASSERT(instr->right()->representation().IsInteger32());
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseOrConstantAtStart(instr->right());
-    return DefineAsRegister(new LCmpID(left, right));
-  } else if (r.IsDouble()) {
+    return new LCmpIDAndBranch(left, right);
+  } else {
+    ASSERT(r.IsDouble());
     ASSERT(instr->left()->representation().IsDouble());
     ASSERT(instr->right()->representation().IsDouble());
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseRegisterAtStart(instr->right());
-    return DefineAsRegister(new LCmpID(left, right));
-  } else {
-    ASSERT(instr->left()->representation().IsTagged());
-    ASSERT(instr->right()->representation().IsTagged());
-    bool reversed = (op == Token::GT || op == Token::LTE);
-    LOperand* left = UseFixed(instr->left(), reversed ? rax : rdx);
-    LOperand* right = UseFixed(instr->right(), reversed ? rdx : rax);
-    LCmpT* result = new LCmpT(left, right);
-    return MarkAsCall(DefineFixed(result, rax), instr);
+    return new LCmpIDAndBranch(left, right);
   }
 }
 
 
-LInstruction* LChunkBuilder::DoCompareJSObjectEq(
-    HCompareJSObjectEq* instr) {
+LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
+    HCompareObjectEqAndBranch* instr) {
   LOperand* left = UseRegisterAtStart(instr->left());
   LOperand* right = UseRegisterAtStart(instr->right());
-  LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right);
-  return DefineAsRegister(result);
+  return new LCmpObjectEqAndBranch(left, right);
 }
 
 
-LInstruction* LChunkBuilder::DoCompareSymbolEq(
-    HCompareSymbolEq* instr) {
-  LOperand* left = UseRegisterAtStart(instr->left());
-  LOperand* right = UseRegisterAtStart(instr->right());
-  LCmpSymbolEq* result = new LCmpSymbolEq(left, right);
-  return DefineAsRegister(result);
+LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
+    HCompareConstantEqAndBranch* instr) {
+  return new LCmpConstantEqAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
+LInstruction* LChunkBuilder::DoIsNullAndBranch(HIsNullAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LIsNull(value));
+  LOperand* temp = instr->is_strict() ? NULL : TempRegister();
+  return new LIsNullAndBranch(UseRegisterAtStart(instr->value()), temp);
 }
 
 
-LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
+LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegister(instr->value());
-
-  return DefineAsRegister(new LIsObject(value));
+  return new LIsObjectAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) {
+LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseAtStart(instr->value());
-
-  return DefineAsRegister(new LIsSmi(value));
+  return new LIsSmiAndBranch(Use(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) {
+LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
+    HIsUndetectableAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LIsUndetectable(value));
+  return new LIsUndetectableAndBranch(UseRegisterAtStart(instr->value()),
+                                      TempRegister());
 }
 
 
-LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
+LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
+    HHasInstanceTypeAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegisterAtStart(instr->value());
-
-  return DefineAsRegister(new LHasInstanceType(value));
+  return new LHasInstanceTypeAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
@@ -1575,17 +1482,17 @@
 }
 
 
-LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
-    HHasCachedArrayIndex* instr) {
+LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
+    HHasCachedArrayIndexAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
-  LOperand* value = UseRegister(instr->value());
-  return DefineAsRegister(new LHasCachedArrayIndex(value));
+  return new LHasCachedArrayIndexAndBranch(UseRegisterAtStart(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
-  Abort("Unimplemented: %s", "DoClassOfTest");
-  return NULL;
+LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
+    HClassOfTestAndBranch* instr) {
+  return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
+                                   TempRegister());
 }
 
 
@@ -1608,6 +1515,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
+  LOperand* object = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LElementsKind(object));
+}
+
+
 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
   LOperand* object = UseRegister(instr->value());
   LValueOf* result = new LValueOf(object);
@@ -1634,6 +1547,11 @@
 }
 
 
+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.
@@ -1655,8 +1573,8 @@
       LOperand* value = UseRegister(instr->value());
       bool needs_check = !instr->value()->type().IsSmi();
       if (needs_check) {
-        LOperand* xmm_temp = instr->CanTruncateToInt32() ? NULL
-                                                         : FixedTemp(xmm1);
+        bool truncating = instr->CanTruncateToInt32();
+        LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
         LTaggedToI* res = new LTaggedToI(value, xmm_temp);
         return AssignEnvironment(DefineSameAsFirst(res));
       } else {
@@ -1757,6 +1675,32 @@
 }
 
 
+LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
+  HValue* value = instr->value();
+  Representation input_rep = value->representation();
+  LOperand* reg = UseRegister(value);
+  if (input_rep.IsDouble()) {
+    return AssignEnvironment(DefineAsRegister(new LDoubleToI(reg)));
+  } else if (input_rep.IsInteger32()) {
+    // Canonicalization should already have removed the hydrogen instruction in
+    // this case, since it is a noop.
+    UNREACHABLE();
+    return NULL;
+  } else {
+    ASSERT(input_rep.IsTagged());
+    LOperand* reg = UseRegister(value);
+    // Register allocator doesn't (yet) support allocation of double
+    // temps. Reserve xmm1 explicitly.
+    LOperand* xmm_temp =
+        CpuFeatures::IsSupported(SSE3)
+        ? NULL
+        : FixedTemp(xmm1);
+    return AssignEnvironment(
+        DefineSameAsFirst(new LTaggedToI(reg, xmm_temp)));
+  }
+}
+
+
 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
   return new LReturn(UseFixed(instr->value(), rax));
 }
@@ -1891,15 +1835,29 @@
 }
 
 
+LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
+    HLoadKeyedFastDoubleElement* instr) {
+  ASSERT(instr->representation().IsDouble());
+  ASSERT(instr->key()->representation().IsInteger32());
+  LOperand* elements = UseRegisterAtStart(instr->elements());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+  LLoadKeyedFastDoubleElement* result =
+      new LLoadKeyedFastDoubleElement(elements, key);
+  return AssignEnvironment(DefineAsRegister(result));
+}
+
+
 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
     HLoadKeyedSpecializedArrayElement* instr) {
-  ExternalArrayType array_type = instr->array_type();
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
   Representation representation(instr->representation());
   ASSERT(
-      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
-                                        array_type != kExternalDoubleArray)) ||
-      (representation.IsDouble() && (array_type == kExternalFloatArray ||
-                                     array_type == kExternalDoubleArray)));
+      (representation.IsInteger32() &&
+       (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
+      (representation.IsDouble() &&
+       ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
+       (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->key()->representation().IsInteger32());
   LOperand* external_pointer = UseRegister(instr->external_pointer());
   LOperand* key = UseRegisterOrConstant(instr->key());
@@ -1908,7 +1866,7 @@
   LInstruction* load_instr = DefineAsRegister(result);
   // An unsigned int array load might overflow and cause a deopt, make sure it
   // has an environment.
-  return (array_type == kExternalUnsignedIntArray) ?
+  return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ?
       AssignEnvironment(load_instr) : load_instr;
 }
 
@@ -1941,21 +1899,38 @@
 }
 
 
+LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
+    HStoreKeyedFastDoubleElement* instr) {
+  ASSERT(instr->value()->representation().IsDouble());
+  ASSERT(instr->elements()->representation().IsTagged());
+  ASSERT(instr->key()->representation().IsInteger32());
+
+  LOperand* elements = UseRegisterAtStart(instr->elements());
+  LOperand* val = UseTempRegister(instr->value());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+
+  return new LStoreKeyedFastDoubleElement(elements, key, val);
+}
+
+
 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
     HStoreKeyedSpecializedArrayElement* instr) {
   Representation representation(instr->value()->representation());
-  ExternalArrayType array_type = instr->array_type();
+  JSObject::ElementsKind elements_kind = instr->elements_kind();
   ASSERT(
-      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
-                                        array_type != kExternalDoubleArray)) ||
-      (representation.IsDouble() && (array_type == kExternalFloatArray ||
-                                     array_type == kExternalDoubleArray)));
+      (representation.IsInteger32() &&
+       (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) ||
+      (representation.IsDouble() &&
+       ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) ||
+       (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->external_pointer()->representation().IsExternal());
   ASSERT(instr->key()->representation().IsInteger32());
 
   LOperand* external_pointer = UseRegister(instr->external_pointer());
-  bool val_is_temp_register = array_type == kExternalPixelArray ||
-      array_type == kExternalFloatArray;
+  bool val_is_temp_register =
+      elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS ||
+      elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS;
   LOperand* val = val_is_temp_register
       ? UseTempRegister(instr->value())
       : UseRegister(instr->value());
@@ -2126,13 +2101,14 @@
 }
 
 
-LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
-  return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
+LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
+  return new LTypeofIsAndBranch(UseTempRegister(instr->value()));
 }
 
 
-LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
-  return DefineAsRegister(new LIsConstructCall);
+LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
+    HIsConstructCallAndBranch* instr) {
+  return new LIsConstructCallAndBranch(TempRegister());
 }
 
 
@@ -2168,7 +2144,12 @@
 
 
 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
-  return MarkAsCall(new LStackCheck, instr);
+  if (instr->is_function_entry()) {
+    return MarkAsCall(new LStackCheck, instr);
+  } else {
+    ASSERT(instr->is_backwards_branch());
+    return AssignEnvironment(AssignPointerMap(new LStackCheck));
+  }
 }
 
 
@@ -2177,7 +2158,6 @@
   HConstant* undefined = graph()->GetConstantUndefined();
   HEnvironment* inner = outer->CopyForInlining(instr->closure(),
                                                instr->function(),
-                                               HEnvironment::LITHIUM,
                                                undefined,
                                                instr->call_kind());
   current_block_->UpdateEnvironment(inner);
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 1493836..18a036f 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -32,6 +32,7 @@
 #include "lithium-allocator.h"
 #include "lithium.h"
 #include "safepoint-table.h"
+#include "utils.h"
 
 namespace v8 {
 namespace internal {
@@ -76,17 +77,12 @@
   V(ClampDToUint8)                              \
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
-  V(ClassOfTest)                                \
   V(ClassOfTestAndBranch)                       \
-  V(CmpID)                                      \
+  V(CmpConstantEqAndBranch)                     \
   V(CmpIDAndBranch)                             \
-  V(CmpJSObjectEq)                              \
-  V(CmpJSObjectEqAndBranch)                     \
+  V(CmpObjectEqAndBranch)                       \
   V(CmpMapAndBranch)                            \
-  V(CmpSymbolEq)                                \
-  V(CmpSymbolEqAndBranch)                       \
   V(CmpT)                                       \
-  V(CmpTAndBranch)                              \
   V(ConstantD)                                  \
   V(ConstantI)                                  \
   V(ConstantT)                                  \
@@ -95,6 +91,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(ElementsKind)                               \
   V(ExternalArrayLength)                        \
   V(FixedArrayLength)                           \
   V(FunctionLiteral)                            \
@@ -102,26 +99,18 @@
   V(GlobalObject)                               \
   V(GlobalReceiver)                             \
   V(Goto)                                       \
-  V(HasCachedArrayIndex)                        \
   V(HasCachedArrayIndexAndBranch)               \
-  V(HasInstanceType)                            \
   V(HasInstanceTypeAndBranch)                   \
   V(In)                                         \
   V(InstanceOf)                                 \
-  V(InstanceOfAndBranch)                        \
   V(InstanceOfKnownGlobal)                      \
   V(InstructionGap)                             \
   V(Integer32ToDouble)                          \
   V(InvokeFunction)                             \
-  V(IsConstructCall)                            \
   V(IsConstructCallAndBranch)                   \
-  V(IsNull)                                     \
   V(IsNullAndBranch)                            \
-  V(IsObject)                                   \
   V(IsObjectAndBranch)                          \
-  V(IsSmi)                                      \
   V(IsSmiAndBranch)                             \
-  V(IsUndetectable)                             \
   V(IsUndetectableAndBranch)                    \
   V(JSArrayLength)                              \
   V(Label)                                      \
@@ -132,6 +121,7 @@
   V(LoadFunctionPrototype)                      \
   V(LoadGlobalCell)                             \
   V(LoadGlobalGeneric)                          \
+  V(LoadKeyedFastDoubleElement)                 \
   V(LoadKeyedFastElement)                       \
   V(LoadKeyedGeneric)                           \
   V(LoadKeyedSpecializedArrayElement)           \
@@ -158,6 +148,7 @@
   V(StoreContextSlot)                           \
   V(StoreGlobalCell)                            \
   V(StoreGlobalGeneric)                         \
+  V(StoreKeyedFastDoubleElement)                \
   V(StoreKeyedFastElement)                      \
   V(StoreKeyedGeneric)                          \
   V(StoreKeyedSpecializedArrayElement)          \
@@ -169,10 +160,10 @@
   V(StringLength)                               \
   V(SubI)                                       \
   V(TaggedToI)                                  \
+  V(ThisFunction)                               \
   V(Throw)                                      \
   V(ToFastProperties)                           \
   V(Typeof)                                     \
-  V(TypeofIs)                                   \
   V(TypeofIsAndBranch)                          \
   V(UnaryMathOperation)                         \
   V(UnknownOSRValue)                            \
@@ -232,7 +223,6 @@
   virtual bool IsGap() const { return false; }
 
   virtual bool IsControl() const { return false; }
-  virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
 
   void set_environment(LEnvironment* env) { environment_ = env; }
   LEnvironment* environment() const { return environment_; }
@@ -287,37 +277,6 @@
 };
 
 
-template<typename ElementType, int NumElements>
-class OperandContainer {
- public:
-  OperandContainer() {
-    for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
-  }
-  int length() { return NumElements; }
-  ElementType& operator[](int i) {
-    ASSERT(i < length());
-    return elems_[i];
-  }
-  void PrintOperandsTo(StringStream* stream);
-
- private:
-  ElementType elems_[NumElements];
-};
-
-
-template<typename ElementType>
-class OperandContainer<ElementType, 0> {
- public:
-  int length() { return 0; }
-  void PrintOperandsTo(StringStream* stream) { }
-  ElementType& operator[](int i) {
-    UNREACHABLE();
-    static ElementType t = 0;
-    return t;
-  }
-};
-
-
 // R = number of result operands (0 or 1).
 // I = number of input operands.
 // T = number of temporary operands.
@@ -340,9 +299,9 @@
   virtual void PrintOutputOperandTo(StringStream* stream);
 
  protected:
-  OperandContainer<LOperand*, R> results_;
-  OperandContainer<LOperand*, I> inputs_;
-  OperandContainer<LOperand*, T> temps_;
+  EmbeddedContainer<LOperand*, R> results_;
+  EmbeddedContainer<LOperand*, I> inputs_;
+  EmbeddedContainer<LOperand*, T> temps_;
 };
 
 
@@ -402,19 +361,16 @@
 
 class LGoto: public LTemplateInstruction<0, 0, 0> {
  public:
-  LGoto(int block_id, bool include_stack_check = false)
-    : block_id_(block_id), include_stack_check_(include_stack_check) { }
+  explicit LGoto(int block_id) : block_id_(block_id) { }
 
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
   virtual void PrintDataTo(StringStream* stream);
   virtual bool IsControl() const { return true; }
 
   int block_id() const { return block_id_; }
-  bool include_stack_check() const { return include_stack_check_; }
 
  private:
   int block_id_;
-  bool include_stack_check_;
 };
 
 
@@ -490,16 +446,15 @@
  public:
   virtual bool IsControl() const { return true; }
 
-  int true_block_id() const { return true_block_id_; }
-  int false_block_id() const { return false_block_id_; }
-  void SetBranchTargets(int true_block_id, int false_block_id) {
-    true_block_id_ = true_block_id;
-    false_block_id_ = false_block_id;
-  }
+  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
+  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
+  int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); }
+  int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); }
 
  private:
-  int true_block_id_;
-  int false_block_id_;
+  HControlInstruction* hydrogen() {
+    return HControlInstruction::cast(this->hydrogen_value());
+  }
 };
 
 
@@ -598,23 +553,6 @@
 };
 
 
-class LCmpID: public LTemplateInstruction<1, 2, 0> {
- public:
-  LCmpID(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
-
-  Token::Value op() const { return hydrogen()->token(); }
-  bool is_double() const {
-    return hydrogen()->GetInputRepresentation().IsDouble();
-  }
-};
-
-
 class LCmpIDAndBranch: public LControlInstruction<2, 0> {
  public:
   LCmpIDAndBranch(LOperand* left, LOperand* right) {
@@ -623,7 +561,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
+  DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
 
   Token::Value op() const { return hydrogen()->token(); }
   bool is_double() const {
@@ -648,61 +586,27 @@
 };
 
 
-class LCmpJSObjectEq: public LTemplateInstruction<1, 2, 0> {
+class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
  public:
-  LCmpJSObjectEq(LOperand* left, LOperand* right) {
+  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
     inputs_[0] = left;
     inputs_[1] = right;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
+  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
+                               "cmp-object-eq-and-branch")
 };
 
 
-class LCmpJSObjectEqAndBranch: public LControlInstruction<2, 0> {
+class LCmpConstantEqAndBranch: public LControlInstruction<1, 0> {
  public:
-  LCmpJSObjectEqAndBranch(LOperand* left, LOperand* right) {
+  explicit LCmpConstantEqAndBranch(LOperand* left) {
     inputs_[0] = left;
-    inputs_[1] = right;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
-                               "cmp-jsobject-eq-and-branch")
-};
-
-
-class LCmpSymbolEq: public LTemplateInstruction<1, 2, 0> {
- public:
-  LCmpSymbolEq(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpSymbolEq, "cmp-symbol-eq")
-};
-
-
-class LCmpSymbolEqAndBranch: public LControlInstruction<2, 0> {
- public:
-  LCmpSymbolEqAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpSymbolEqAndBranch, "cmp-symbol-eq-and-branch")
-};
-
-
-class LIsNull: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsNull(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
-  DECLARE_HYDROGEN_ACCESSOR(IsNull)
-
-  bool is_strict() const { return hydrogen()->is_strict(); }
+  DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
+                               "cmp-constant-eq-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
 };
 
 
@@ -714,7 +618,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(IsNull)
+  DECLARE_HYDROGEN_ACCESSOR(IsNullAndBranch)
 
   bool is_strict() const { return hydrogen()->is_strict(); }
 
@@ -722,16 +626,6 @@
 };
 
 
-class LIsObject: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsObject(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
-};
-
-
 class LIsObjectAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LIsObjectAndBranch(LOperand* value) {
@@ -739,22 +633,12 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LIsSmi: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsSmi(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
-  DECLARE_HYDROGEN_ACCESSOR(IsSmi)
-};
-
-
 class LIsSmiAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LIsSmiAndBranch(LOperand* value) {
@@ -762,22 +646,12 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LIsUndetectable: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LIsUndetectable(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(IsUndetectable, "is-undetectable")
-  DECLARE_HYDROGEN_ACCESSOR(IsUndetectable)
-};
-
-
 class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
  public:
   explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
@@ -787,22 +661,12 @@
 
   DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
                                "is-undetectable-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
 
 
-class LHasInstanceType: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LHasInstanceType(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
-  DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
-};
-
-
 class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LHasInstanceTypeAndBranch(LOperand* value) {
@@ -811,7 +675,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
                                "has-instance-type-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
+  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -828,17 +692,6 @@
 };
 
 
-class LHasCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LHasCachedArrayIndex(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
-  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
-};
-
-
 class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
@@ -847,19 +700,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
                                "has-cached-array-index-and-branch")
-  virtual void PrintDataTo(StringStream* stream);
-};
-
-
-class LClassOfTest: public LTemplateInstruction<1, 1, 1> {
- public:
-  LClassOfTest(LOperand* value, LOperand* temp) {
-    inputs_[0] = value;
-    temps_[0] = temp;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
-  DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
+  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -874,7 +715,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
                                "class-of-test-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
+  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -888,21 +729,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
-
-  Token::Value op() const { return hydrogen()->token(); }
-};
-
-
-class LCmpTAndBranch: public LControlInstruction<2, 0> {
- public:
-  LCmpTAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(Compare)
+  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
 
   Token::Value op() const { return hydrogen()->token(); }
 };
@@ -933,17 +760,6 @@
 };
 
 
-class LInstanceOfAndBranch: public LControlInstruction<2, 0> {
- public:
-  LInstanceOfAndBranch(LOperand* left, LOperand* right) {
-    inputs_[0] = left;
-    inputs_[1] = right;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
-};
-
-
 class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
  public:
   LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
@@ -1059,7 +875,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
-  DECLARE_HYDROGEN_ACCESSOR(Value)
+  DECLARE_HYDROGEN_ACCESSOR(Branch)
 
   virtual void PrintDataTo(StringStream* stream);
 };
@@ -1119,6 +935,17 @@
 };
 
 
+class LElementsKind: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LElementsKind(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
+  DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
+};
+
+
 class LValueOf: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LValueOf(LOperand* value) {
@@ -1309,6 +1136,22 @@
 };
 
 
+class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
+ public:
+  LLoadKeyedFastDoubleElement(LOperand* elements, LOperand* key) {
+    inputs_[0] = elements;
+    inputs_[1] = key;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
+                               "load-keyed-fast-double-element")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
+
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+};
+
+
 class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
  public:
   LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
@@ -1323,8 +1166,8 @@
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
-  ExternalArrayType array_type() const {
-    return hydrogen()->array_type();
+  JSObject::ElementsKind elements_kind() const {
+    return hydrogen()->elements_kind();
   }
 };
 
@@ -1441,6 +1284,11 @@
 };
 
 
+class LThisFunction: public LTemplateInstruction<1, 0, 0> {
+  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
+};
+
+
 class LContext: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(Context, "context")
@@ -1634,7 +1482,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -1649,7 +1497,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -1755,6 +1603,28 @@
 };
 
 
+class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
+ public:
+  LStoreKeyedFastDoubleElement(LOperand* elements,
+                               LOperand* key,
+                               LOperand* val) {
+    inputs_[0] = elements;
+    inputs_[1] = key;
+    inputs_[2] = val;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
+                               "store-keyed-fast-double-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  LOperand* value() { return inputs_[2]; }
+};
+
+
 class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
  public:
   LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
@@ -1772,8 +1642,8 @@
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
-  ExternalArrayType array_type() const {
-    return hydrogen()->array_type();
+  JSObject::ElementsKind elements_kind() const {
+    return hydrogen()->elements_kind();
   }
 };
 
@@ -2013,21 +1883,6 @@
 };
 
 
-class LTypeofIs: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LTypeofIs(LOperand* value) {
-    inputs_[0] = value;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
-  DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
-
-  Handle<String> type_literal() { return hydrogen()->type_literal(); }
-
-  virtual void PrintDataTo(StringStream* stream);
-};
-
-
 class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
  public:
   explicit LTypeofIsAndBranch(LOperand* value) {
@@ -2035,7 +1890,7 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
-  DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
+  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
@@ -2043,13 +1898,6 @@
 };
 
 
-class LIsConstructCall: public LTemplateInstruction<1, 0, 0> {
- public:
-  DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is-construct-call")
-  DECLARE_HYDROGEN_ACCESSOR(IsConstructCall)
-};
-
-
 class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
  public:
   explicit LIsConstructCallAndBranch(LOperand* temp) {
@@ -2058,6 +1906,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
                                "is-construct-call-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsConstructCallAndBranch)
 };
 
 
@@ -2101,6 +1950,12 @@
 class LStackCheck: public LTemplateInstruction<0, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
+  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
+
+  Label* done_label() { return &done_label_; }
+
+ private:
+  Label done_label_;
 };
 
 
@@ -2298,7 +2153,8 @@
       LInstruction* instr, int ast_id);
   void ClearInstructionPendingDeoptimizationEnvironment();
 
-  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
+  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
+                                  int* argument_index_accumulator);
 
   void VisitInstruction(HInstruction* current);
 
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 2d28579..2b15553 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -385,6 +385,9 @@
                 Heap::kFixedArrayMapRootIndex);
     j(equal, &ok, Label::kNear);
     CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
+                Heap::kFixedDoubleArrayMapRootIndex);
+    j(equal, &ok, Label::kNear);
+    CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
                 Heap::kFixedCOWArrayMapRootIndex);
     j(equal, &ok, Label::kNear);
     Abort("JSObject with fast elements map has slow elements");
@@ -2558,6 +2561,16 @@
 }
 
 
+void MacroAssembler::CheckFastElements(Register map,
+                                       Label* fail,
+                                       Label::Distance distance) {
+  STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0);
+  cmpb(FieldOperand(map, Map::kBitField2Offset),
+       Immediate(Map::kMaximumBitField2FastElementValue));
+  j(above, fail, distance);
+}
+
+
 void MacroAssembler::CheckMap(Register obj,
                               Handle<Map> map,
                               Label* fail,
@@ -3194,6 +3207,109 @@
 }
 
 
+void MacroAssembler::LoadFromNumberDictionary(Label* miss,
+                                              Register elements,
+                                              Register key,
+                                              Register r0,
+                                              Register r1,
+                                              Register r2,
+                                              Register result) {
+  // 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.
+  //
+  // Scratch registers:
+  //
+  // r0 - holds the untagged key on entry and holds the hash once computed.
+  //
+  // r1 - used to hold the capacity mask of the dictionary
+  //
+  // r2 - used for the index into the dictionary.
+  //
+  // 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.
+
+  Label done;
+
+  // Compute the hash code from the untagged key.  This must be kept in sync
+  // with ComputeIntegerHash in utils.h.
+  //
+  // hash = ~hash + (hash << 15);
+  movl(r1, r0);
+  notl(r0);
+  shll(r1, Immediate(15));
+  addl(r0, r1);
+  // hash = hash ^ (hash >> 12);
+  movl(r1, r0);
+  shrl(r1, Immediate(12));
+  xorl(r0, r1);
+  // hash = hash + (hash << 2);
+  leal(r0, Operand(r0, r0, times_4, 0));
+  // hash = hash ^ (hash >> 4);
+  movl(r1, r0);
+  shrl(r1, Immediate(4));
+  xorl(r0, r1);
+  // hash = hash * 2057;
+  imull(r0, r0, Immediate(2057));
+  // hash = hash ^ (hash >> 16);
+  movl(r1, r0);
+  shrl(r1, Immediate(16));
+  xorl(r0, r1);
+
+  // Compute capacity mask.
+  SmiToInteger32(r1,
+                 FieldOperand(elements, NumberDictionary::kCapacityOffset));
+  decl(r1);
+
+  // Generate an unrolled loop that performs a few probes before giving up.
+  const int kProbes = 4;
+  for (int i = 0; i < kProbes; i++) {
+    // Use r2 for index calculations and keep the hash intact in r0.
+    movq(r2, r0);
+    // Compute the masked index: (hash + i + i * i) & mask.
+    if (i > 0) {
+      addl(r2, Immediate(NumberDictionary::GetProbeOffset(i)));
+    }
+    and_(r2, r1);
+
+    // Scale the index by multiplying by the entry size.
+    ASSERT(NumberDictionary::kEntrySize == 3);
+    lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3
+
+    // Check if the key matches.
+    cmpq(key, FieldOperand(elements,
+                           r2,
+                           times_pointer_size,
+                           NumberDictionary::kElementsStartOffset));
+    if (i != (kProbes - 1)) {
+      j(equal, &done);
+    } else {
+      j(not_equal, miss);
+    }
+  }
+
+  bind(&done);
+  // Check that the value is a normal propety.
+  const int kDetailsOffset =
+      NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+  ASSERT_EQ(NORMAL, 0);
+  Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
+       Smi::FromInt(PropertyDetails::TypeField::mask()));
+  j(not_zero, miss);
+
+  // Get the value at the masked, scaled index.
+  const int kValueOffset =
+      NumberDictionary::kElementsStartOffset + kPointerSize;
+  movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
+}
+
+
 void MacroAssembler::LoadAllocationTopHelper(Register result,
                                              Register scratch,
                                              AllocationFlags flags) {
@@ -3607,15 +3723,10 @@
 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.
-    movq(dst, Operand(rsi, Context::SlotOffset(Context::CLOSURE_INDEX)));
-    // Load the function context (which is the incoming, outer context).
-    movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
+    movq(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     for (int i = 1; i < context_chain_length; i++) {
-      movq(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX)));
-      movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
+      movq(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
     }
-    // The context may be an intermediate context, not a function context.
-    movq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
   } else {
     // Slot is in the current function context.  Move it into the
     // destination register in case we store into it (the write barrier
@@ -3623,14 +3734,14 @@
     movq(dst, rsi);
   }
 
-  // We should not have found a 'with' context by walking the context chain
-  // (i.e., the static scope chain and runtime context chain do not agree).
-  // A variable occurring in such a scope should have slot type LOOKUP and
-  // not CONTEXT.
+  // We should not have found a with context by walking the context
+  // chain (i.e., the static scope chain and runtime context chain do
+  // not agree).  A variable occurring in such a scope should have
+  // slot type LOOKUP and not CONTEXT.
   if (emit_debug_code()) {
-    cmpq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
-    Check(equal, "Yo dawg, I heard you liked function contexts "
-                 "so I put function contexts in all your contexts");
+    CompareRoot(FieldOperand(dst, HeapObject::kMapOffset),
+                Heap::kWithContextMapRootIndex);
+    Check(not_equal, "Variable resolved to with context.");
   }
 }
 
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 16f6d8d..47ce01b 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -754,6 +754,12 @@
   // Always use unsigned comparisons: above and below, not less and greater.
   void CmpInstanceType(Register map, 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,
+                         Label* fail,
+                         Label::Distance distance = Label::kFar);
+
   // 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)
@@ -840,6 +846,15 @@
                               Label* miss);
 
 
+  void LoadFromNumberDictionary(Label* miss,
+                                Register elements,
+                                Register key,
+                                Register r0,
+                                Register r1,
+                                Register r2,
+                                Register result);
+
+
   // ---------------------------------------------------------------------------
   // Allocation support
 
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 2ea17f0..395466e 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -661,7 +661,6 @@
     }
     __ movq(rbx, ExternalReference::re_word_character_map());
     ASSERT_EQ(0, word_character_map[0]);  // Character '\0' is not a word char.
-    ExternalReference word_map = ExternalReference::re_word_character_map();
     __ testb(Operand(rbx, current_character(), times_1, 0),
              current_character());
     BranchOrBacktrack(zero, on_no_match);
@@ -676,7 +675,6 @@
     }
     __ movq(rbx, ExternalReference::re_word_character_map());
     ASSERT_EQ(0, word_character_map[0]);  // Character '\0' is not a word char.
-    ExternalReference word_map = ExternalReference::re_word_character_map();
     __ testb(Operand(rbx, current_character(), times_1, 0),
              current_character());
     BranchOrBacktrack(not_zero, on_no_match);
diff --git a/src/x64/regexp-macro-assembler-x64.h b/src/x64/regexp-macro-assembler-x64.h
index 02b510f..7102225 100644
--- a/src/x64/regexp-macro-assembler-x64.h
+++ b/src/x64/regexp-macro-assembler-x64.h
@@ -28,6 +28,12 @@
 #ifndef V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
 #define V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
 
+#include "x64/assembler-x64.h"
+#include "x64/assembler-x64-inl.h"
+#include "macro-assembler.h"
+#include "code.h"
+#include "x64/macro-assembler-x64.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index dae4a55..b8e5f22 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -105,7 +105,7 @@
   __ j(not_zero, miss_label);
 
   // Check that receiver is a JSObject.
-  __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE);
+  __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
   __ j(below, miss_label);
 
   // Load properties array.
@@ -1089,9 +1089,8 @@
   __ JumpIfSmi(receiver, miss);
 
   // Check that the maps haven't changed.
-  Register reg =
-      CheckPrototypes(object, receiver, holder,
-                      scratch1, scratch2, scratch3, name, miss);
+  CheckPrototypes(object, receiver, holder,
+                  scratch1, scratch2, scratch3, name, miss);
 
   // Return the constant value.
   __ Move(rax, Handle<Object>(value));
@@ -2530,18 +2529,18 @@
 }
 
 
-MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement(
-    Map* receiver_map) {
+MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rcx    : key
   //  -- rdx    : receiver
   //  -- rsp[0] : return address
   // -----------------------------------
+  Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
   bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
   MaybeObject* maybe_stub =
-      KeyedStoreFastElementStub(is_js_array).TryGetCode();
-  Code* stub;
+      KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(rdx,
                  Handle<Map>(receiver_map),
@@ -2990,14 +2989,15 @@
 }
 
 
-MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) {
+MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
   // ----------- S t a t e -------------
   //  -- rax    : key
   //  -- rdx    : receiver
   //  -- rsp[0] : return address
   // -----------------------------------
-  MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode();
   Code* stub;
+  JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
+  MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
   if (!maybe_stub->To(&stub)) return maybe_stub;
   __ DispatchMap(rdx,
                  Handle<Map>(receiver_map),
@@ -3176,60 +3176,58 @@
 }
 
 
-MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
-    JSObject*receiver, ExternalArrayType array_type) {
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : key
   //  -- rdx    : receiver
   //  -- rsp[0] : return address
   // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedLoadExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(rdx,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
+  Label slow, miss_force_generic;
 
-  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
 
-  // Return the generated code.
-  return GetCode();
-}
+  __ JumpIfNotSmi(rax, &miss_force_generic);
+  __ SmiToInteger32(rbx, rax);
+  __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
 
-MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
-    JSObject* receiver, ExternalArrayType array_type) {
+  // Check whether the elements is a number dictionary.
+  // rdx: receiver
+  // rax: key
+  // rbx: key as untagged int32
+  // rcx: elements
+  __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax);
+  __ ret(0);
+
+  __ bind(&slow);
   // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : key
+  //  -- rax    : key
   //  -- rdx    : receiver
-  //  -- rsp[0] : return address
+  //  -- rsp[0]  : return address
   // -----------------------------------
-  MaybeObject* maybe_stub =
-      KeyedStoreExternalArrayStub(array_type).TryGetCode();
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
-  __ DispatchMap(rdx,
-                 Handle<Map>(receiver->map()),
-                 Handle<Code>(stub),
-                 DO_SMI_CHECK);
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ jmp(slow_ic, RelocInfo::CODE_TARGET);
 
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
-
-  return GetCode();
+  __ bind(&miss_force_generic);
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Handle<Code> miss_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ jmp(miss_ic, RelocInfo::CODE_TARGET);
 }
 
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ----------- S t a t e -------------
   //  -- rax    : key
   //  -- rdx    : receiver
@@ -3256,30 +3254,30 @@
   // rbx: elements array
   __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
   // rbx: base pointer of external storage
-  switch (array_type) {
-    case kExternalByteArray:
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
       __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0));
       break;
-    case kExternalPixelArray:
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0));
       break;
-    case kExternalShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
       __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0));
       break;
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0));
       break;
-    case kExternalIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
       __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0));
       break;
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       __ movl(rcx, Operand(rbx, rcx, times_4, 0));
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0));
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       __ movsd(xmm0, Operand(rbx, rcx, times_8, 0));
       break;
     default:
@@ -3295,7 +3293,7 @@
   // xmm0: value as double.
 
   ASSERT(kSmiValueSize == 32);
-  if (array_type == kExternalUnsignedIntArray) {
+  if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
     // For the UnsignedInt array type, we need to see whether
     // the value can be represented in a Smi. If not, we need to convert
     // it to a HeapNumber.
@@ -3319,8 +3317,8 @@
     __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0);
     __ movq(rax, rcx);
     __ ret(0);
-  } else if (array_type == kExternalFloatArray ||
-             array_type == kExternalDoubleArray) {
+  } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+             elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
     // For the floating-point array type, we need to always allocate a
     // HeapNumber.
     __ AllocateHeapNumber(rcx, rbx, &slow);
@@ -3363,7 +3361,7 @@
 
 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
     MacroAssembler* masm,
-    ExternalArrayType array_type) {
+    JSObject::ElementsKind elements_kind) {
   // ----------- S t a t e -------------
   //  -- rax     : value
   //  -- rcx     : key
@@ -3393,7 +3391,7 @@
   // rbx: elements array
   // rdi: untagged key
   Label check_heap_number;
-  if (array_type == kExternalPixelArray) {
+  if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     // Float to pixel conversion is only implemented in the runtime for now.
     __ JumpIfNotSmi(rax, &slow);
   } else {
@@ -3403,8 +3401,8 @@
   __ SmiToInteger32(rdx, rax);
   __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
   // rbx: base pointer of external storage
-  switch (array_type) {
-    case kExternalPixelArray:
+  switch (elements_kind) {
+    case JSObject::EXTERNAL_PIXEL_ELEMENTS:
       {  // Clamp the value to [0..255].
         Label done;
         __ testl(rdx, Immediate(0xFFFFFF00));
@@ -3415,36 +3413,39 @@
       }
       __ movb(Operand(rbx, rdi, times_1, 0), rdx);
       break;
-    case kExternalByteArray:
-    case kExternalUnsignedByteArray:
+    case JSObject::EXTERNAL_BYTE_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
       __ movb(Operand(rbx, rdi, times_1, 0), rdx);
       break;
-    case kExternalShortArray:
-    case kExternalUnsignedShortArray:
+    case JSObject::EXTERNAL_SHORT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       __ movw(Operand(rbx, rdi, times_2, 0), rdx);
       break;
-    case kExternalIntArray:
-    case kExternalUnsignedIntArray:
+    case JSObject::EXTERNAL_INT_ELEMENTS:
+    case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
       __ movl(Operand(rbx, rdi, times_4, 0), rdx);
       break;
-    case kExternalFloatArray:
+    case JSObject::EXTERNAL_FLOAT_ELEMENTS:
       // Need to perform int-to-float conversion.
       __ cvtlsi2ss(xmm0, rdx);
       __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
       break;
-    case kExternalDoubleArray:
+    case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
       // Need to perform int-to-float conversion.
       __ cvtlsi2sd(xmm0, rdx);
       __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
       break;
-    default:
+    case JSObject::FAST_ELEMENTS:
+    case JSObject::FAST_DOUBLE_ELEMENTS:
+    case JSObject::DICTIONARY_ELEMENTS:
+    case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       break;
   }
   __ ret(0);
 
   // TODO(danno): handle heap number -> pixel array conversion
-  if (array_type != kExternalPixelArray) {
+  if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
     __ bind(&check_heap_number);
     // rax: value
     // rcx: key (a smi)
@@ -3463,11 +3464,11 @@
     // rdi: untagged index
     // rbx: base pointer of external storage
     // top of FPU stack: value
-    if (array_type == kExternalFloatArray) {
+    if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
       __ cvtsd2ss(xmm0, xmm0);
       __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
       __ ret(0);
-    } else if (array_type == kExternalDoubleArray) {
+    } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
       __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
       __ ret(0);
     } else {
@@ -3480,26 +3481,31 @@
       // rdx: value (converted to an untagged integer)
       // rdi: untagged index
       // rbx: base pointer of external storage
-      switch (array_type) {
-        case kExternalByteArray:
-        case kExternalUnsignedByteArray:
+      switch (elements_kind) {
+        case JSObject::EXTERNAL_BYTE_ELEMENTS:
+        case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
           __ cvttsd2si(rdx, xmm0);
           __ movb(Operand(rbx, rdi, times_1, 0), rdx);
           break;
-        case kExternalShortArray:
-        case kExternalUnsignedShortArray:
+        case JSObject::EXTERNAL_SHORT_ELEMENTS:
+        case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
           __ cvttsd2si(rdx, xmm0);
           __ movw(Operand(rbx, rdi, times_2, 0), rdx);
           break;
-        case kExternalIntArray:
-        case kExternalUnsignedIntArray: {
+        case JSObject::EXTERNAL_INT_ELEMENTS:
+        case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
           // Convert to int64, so that NaN and infinities become
           // 0x8000000000000000, which is zero mod 2^32.
           __ cvttsd2siq(rdx, xmm0);
           __ movl(Operand(rbx, rdi, times_4, 0), rdx);
           break;
-        }
-        default:
+        case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+        case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+        case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+        case JSObject::FAST_ELEMENTS:
+        case JSObject::FAST_DOUBLE_ELEMENTS:
+        case JSObject::DICTIONARY_ELEMENTS:
+        case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
           UNREACHABLE();
           break;
       }
@@ -3577,6 +3583,57 @@
 }
 
 
+void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
+    MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss_force_generic, slow_allocate_heapnumber;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(rax, &miss_force_generic);
+
+  // Get the elements array.
+  __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
+  __ AssertFastElements(rcx);
+
+  // Check that the key is within bounds.
+  __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset));
+  __ j(above_equal, &miss_force_generic);
+
+  // Check for the hole
+  __ SmiToInteger32(kScratchRegister, rax);
+  uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
+  __ cmpl(FieldOperand(rcx, kScratchRegister, times_8, offset),
+          Immediate(kHoleNanUpper32));
+  __ j(equal, &miss_force_generic);
+
+  // Always allocate a heap number for the result.
+  __ movsd(xmm0, FieldOperand(rcx, kScratchRegister, times_8,
+                              FixedDoubleArray::kHeaderSize));
+  __ AllocateHeapNumber(rcx, rbx, &slow_allocate_heapnumber);
+  // Set the value.
+  __ movq(rax, rcx);
+  __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0);
+  __ ret(0);
+
+  __ bind(&slow_allocate_heapnumber);
+  Handle<Code> slow_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Slow();
+  __ jmp(slow_ic, RelocInfo::CODE_TARGET);
+
+  __ bind(&miss_force_generic);
+  Handle<Code> miss_ic =
+      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
+  __ jmp(miss_ic, RelocInfo::CODE_TARGET);
+}
+
+
 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm,
                                                       bool is_js_array) {
   // ----------- S t a t e -------------
@@ -3627,6 +3684,90 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
+    MacroAssembler* masm,
+    bool is_js_array) {
+  // ----------- S t a t e -------------
+  //  -- rax    : value
+  //  -- rcx    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss_force_generic, smi_value, is_nan, maybe_nan;
+  Label have_double_value, not_nan;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(rcx, &miss_force_generic);
+
+  // Get the elements array.
+  __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset));
+  __ AssertFastElements(rdi);
+
+  // Check that the key is within bounds.
+  if (is_js_array) {
+    __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset));
+  } else {
+    __ SmiCompare(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset));
+  }
+  __ j(above_equal, &miss_force_generic);
+
+  // Handle smi values specially
+  __ JumpIfSmi(rax, &smi_value, Label::kNear);
+
+  __ CheckMap(rax,
+              masm->isolate()->factory()->heap_number_map(),
+              &miss_force_generic,
+              DONT_DO_SMI_CHECK);
+
+  // Double value, canonicalize NaN.
+  uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32);
+  __ cmpl(FieldOperand(rax, offset),
+          Immediate(kNaNOrInfinityLowerBoundUpper32));
+  __ j(greater_equal, &maybe_nan, Label::kNear);
+
+  __ bind(&not_nan);
+  __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
+  __ bind(&have_double_value);
+  __ SmiToInteger32(rcx, rcx);
+  __ movsd(FieldOperand(rdi, rcx, times_8, FixedDoubleArray::kHeaderSize),
+           xmm0);
+  __ ret(0);
+
+  __ bind(&maybe_nan);
+  // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
+  // it's an Infinity, and the non-NaN code path applies.
+  __ j(greater, &is_nan, Label::kNear);
+  __ cmpl(FieldOperand(rax, HeapNumber::kValueOffset), Immediate(0));
+  __ j(zero, &not_nan);
+  __ bind(&is_nan);
+  // Convert all NaNs to the same canonical NaN value when they are stored in
+  // the double array.
+  __ Set(kScratchRegister, BitCast<uint64_t>(
+      FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
+  __ movq(xmm0, kScratchRegister);
+  __ jmp(&have_double_value, Label::kNear);
+
+  __ bind(&smi_value);
+  // Value is a smi. convert to a double and store.
+  __ SmiToInteger32(rax, rax);
+  __ push(rax);
+  __ fild_s(Operand(rsp, 0));
+  __ pop(rax);
+  __ SmiToInteger32(rcx, rcx);
+  __ fstp_d(FieldOperand(rdi, rcx, times_8, FixedDoubleArray::kHeaderSize));
+  __ ret(0);
+
+  // Handle store cache miss, replacing the ic with the generic stub.
+  __ bind(&miss_force_generic);
+  Handle<Code> ic_force_generic =
+      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
+  __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/zone.h b/src/zone.h
index a5e437f..abb53ad 100644
--- a/src/zone.h
+++ b/src/zone.h
@@ -74,6 +74,8 @@
 
   inline void adjust_segment_bytes_allocated(int delta);
 
+  inline Isolate* isolate() { return isolate_; }
+
   static unsigned allocation_size_;
 
  private:
@@ -164,7 +166,7 @@
 class ZoneListAllocationPolicy {
  public:
   // Allocate 'size' bytes of memory in the zone.
-  INLINE(static void* New(int size));
+  static void* New(int size);
 
   // De-allocation attempts are silently ignored.
   static void Delete(void* p) { }
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index 0197178..b0a7166 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -29,7 +29,21 @@
 from os.path import join, dirname, abspath
 root_dir = dirname(File('SConstruct').rfile().abspath)
 sys.path.append(join(root_dir, 'tools'))
-Import('context object_files')
+import js2c
+Import('context object_files tools')
+
+
+# Needed for test-log. Paths are relative to the cctest dir.
+JS_FILES_FOR_TESTS = [
+  '../../../tools/splaytree.js',
+  '../../../tools/codemap.js',
+  '../../../tools/csvparser.js',
+  '../../../tools/consarray.js',
+  '../../../tools/profile.js',
+  '../../../tools/profile_view.js',
+  '../../../tools/logreader.js',
+  'log-eq-of-logging-and-traversal.js',
+]
 
 
 SOURCES = {
@@ -65,7 +79,6 @@
     'test-liveedit.cc',
     'test-lock.cc',
     'test-lockers.cc',
-    'test-log-utils.cc',
     'test-log.cc',
     'test-mark-compact.cc',
     'test-parsing.cc',
@@ -107,12 +120,22 @@
 
 def Build():
   cctest_files = context.GetRelevantSources(SOURCES)
-  env = Environment()
+  env = Environment(tools=tools)
   env.Replace(**context.flags['cctest'])
   context.ApplyEnvOverrides(env)
+  env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C)
+
+  # Combine the JavaScript library files into a single C++ file and
+  # compile it.
+  js_files = [s for s in JS_FILES_FOR_TESTS]
+  js_files_src = env.JS2C(
+    ['js-files-for-cctest.cc'], js_files, **{'TYPE': 'TEST', 'COMPRESSION': 'off'})
+  js_files_obj = context.ConfigureObject(env, js_files_src, CPPPATH=['.'])
+
   # There seems to be a glitch in the way scons decides where to put
   # PDB files when compiling using MSVC so we specify it manually.
   # This should not affect any other platforms.
+  object_files.append(js_files_obj)
   return env.Program('cctest', ['cctest.cc', cctest_files, object_files],
       PDB='cctest.exe.pdb')
 
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index f13f91e..9cbcb9c 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -1,4 +1,4 @@
-# Copyright 2010 the V8 project authors. All rights reserved.
+# Copyright 2011 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
@@ -26,47 +26,23 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 {
-  'target_defaults': {
-    'conditions': [
-      ['OS!="mac"', {
-        # TODO(sgjesse): This is currently copied from v8.gyp, should probably
-        # be refactored.
-        'conditions': [
-          ['v8_target_arch=="arm"', {
-            'defines': [
-              'V8_TARGET_ARCH_ARM',
-            ],
-          }],
-          ['v8_target_arch=="ia32"', {
-            'defines': [
-              'V8_TARGET_ARCH_IA32',
-            ],
-          }],
-          ['v8_target_arch=="mips"', {
-            'defines': [
-              'V8_TARGET_ARCH_MIPS',
-            ],
-          }],
-          ['v8_target_arch=="x64"', {
-            'defines': [
-              'V8_TARGET_ARCH_X64',
-            ],
-          }],
-        ],
-      }],
-    ],
+  'variables': {
+    'generated_file': '<(SHARED_INTERMEDIATE_DIR)/resources.cc',
   },
+  'includes': [ '../../build/v8-features.gypi' ],
   'targets': [
     {
       'target_name': 'cctest',
       'type': 'executable',
       'dependencies': [
         '../../tools/gyp/v8.gyp:v8',
+        'resources',
       ],
       'include_dirs': [
         '../../src',
       ],
       'sources': [
+        '<(generated_file)',
         'cctest.cc',
         'gay-fixed.cc',
         'gay-precision.cc',
@@ -100,7 +76,6 @@
         'test-lock.cc',
         'test-lockers.cc',
         'test-log.cc',
-        'test-log-utils.cc',
         'test-mark-compact.cc',
         'test-parsing.cc',
         'test-profile-generator.cc',
@@ -161,5 +136,41 @@
         }],
       ],
     },
+    {
+      'target_name': 'resources',
+      'type': 'none',
+      'variables': {
+        'file_list': [
+           '../../tools/splaytree.js',
+           '../../tools/codemap.js',
+           '../../tools/csvparser.js',
+           '../../tools/consarray.js',
+           '../../tools/profile.js',
+           '../../tools/profile_view.js',
+           '../../tools/logreader.js',
+           'log-eq-of-logging-and-traversal.js',
+        ],
+      },
+      'actions': [
+        {
+          'action_name': 'js2c',
+          'inputs': [
+            '../../tools/js2c.py',
+            '<@(file_list)',
+          ],
+          'outputs': [
+            '<(generated_file)',
+          ],
+          'action': [
+            'python',
+            '../../tools/js2c.py',
+            '<@(_outputs)',
+            'TEST',  # type
+            'off',  # compression
+            '<@(file_list)',
+          ],
+        }
+      ],
+    },
   ],
 }
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index e4052d6..b0b8eb7 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -87,8 +87,8 @@
 class ApiTestFuzzer: public v8::internal::Thread {
  public:
   void CallTest();
-  explicit ApiTestFuzzer(v8::internal::Isolate* isolate, int num)
-      : Thread(isolate, "ApiTestFuzzer"),
+  explicit ApiTestFuzzer(int num)
+      : Thread("ApiTestFuzzer"),
         test_number_(num),
         gate_(v8::internal::OS::CreateSemaphore(0)),
         active_(true) {
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 01a8222..6e7824f 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -30,9 +30,6 @@
 test-api/Bug*: FAIL
 
 ##############################################################################
-# BUG(281): This test fails on some Linuxes.
-test-debug/DebuggerAgent: PASS, (PASS || FAIL) if $system == linux
-
 # BUG(382): Weird test. Can't guarantee that it never times out.
 test-api/ApplyInterruption: PASS || TIMEOUT
 
@@ -42,14 +39,6 @@
 test-serialize/DependentTestThatAlwaysFails: FAIL
 
 ##############################################################################
-# BUG(1354): Bad function name inference
-test-func-name-inference/FactoryHashmapConditional: FAIL
-test-func-name-inference/FactoryHashmapVariable: FAIL
-test-func-name-inference/FactoryHashmap: FAIL
-test-func-name-inference/MultipleAssignments: FAIL
-test-func-name-inference/PassedAsConstructorParameter: FAIL
-
-##############################################################################
 [ $arch == arm ]
 
 # We cannot assume that we can throw OutOfMemory exceptions in all situations.
@@ -62,6 +51,7 @@
 test-log/ProfLazyMode: SKIP
 
 # BUG(945): Socket connect fails on ARM
+test-debug/DebuggerAgent: SKIP
 test-debug/DebuggerAgentProtocolOverflowHeader: SKIP
 test-sockets/Socket: SKIP
 
diff --git a/test/cctest/log-eq-of-logging-and-traversal.js b/test/cctest/log-eq-of-logging-and-traversal.js
new file mode 100644
index 0000000..cd52da5
--- /dev/null
+++ b/test/cctest/log-eq-of-logging-and-traversal.js
@@ -0,0 +1,193 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This is a supplementary file for test-log/EquivalenceOfLoggingAndTraversal.
+
+function parseState(s) {
+  switch (s) {
+  case "": return Profile.CodeState.COMPILED;
+  case "~": return Profile.CodeState.OPTIMIZABLE;
+  case "*": return Profile.CodeState.OPTIMIZED;
+  }
+  throw new Error("unknown code state: " + s);
+}
+
+function LogProcessor() {
+  LogReader.call(this, {
+      'code-creation': {
+          parsers: [null, parseInt, parseInt, null, 'var-args'],
+          processor: this.processCodeCreation },
+      'code-move': { parsers: [parseInt, parseInt],
+          processor: this.processCodeMove },
+      'code-delete': { parsers: [parseInt],
+          processor: this.processCodeDelete },
+      'sfi-move': { parsers: [parseInt, parseInt],
+          processor: this.processFunctionMove },
+      'shared-library': null,
+      'profiler': null,
+      'tick': null });
+  this.profile = new Profile();
+
+}
+LogProcessor.prototype.__proto__ = LogReader.prototype;
+
+LogProcessor.prototype.processCodeCreation = function(
+    type, start, size, name, maybe_func) {
+  if (type != "LazyCompile" && type != "Script" && type != "Function") return;
+  // Discard types to avoid discrepancies in "LazyCompile" vs. "Function".
+  type = "";
+  if (maybe_func.length) {
+    var funcAddr = parseInt(maybe_func[0]);
+    var state = parseState(maybe_func[1]);
+    this.profile.addFuncCode(type, name, start, size, funcAddr, state);
+  } else {
+    this.profile.addCode(type, name, start, size);
+  }
+};
+
+LogProcessor.prototype.processCodeMove = function(from, to) {
+  this.profile.moveCode(from, to);
+};
+
+LogProcessor.prototype.processCodeDelete = function(start) {
+  this.profile.deleteCode(start);
+};
+
+LogProcessor.prototype.processFunctionMove = function(from, to) {
+  this.profile.moveFunc(from, to);
+};
+
+function RunTest() {
+  // _log must be provided externally.
+  var log_lines = _log.split("\n");
+  var line, pos = 0, log_lines_length = log_lines.length;
+  if (log_lines_length < 2)
+    return "log_lines_length < 2";
+  var logging_processor = new LogProcessor();
+  for ( ; pos < log_lines_length; ++pos) {
+    line = log_lines[pos];
+    if (line === "test-logging-done,\"\"") {
+      ++pos;
+      break;
+    }
+    logging_processor.processLogLine(line);
+  }
+  logging_processor.profile.cleanUpFuncEntries();
+  var logging_entries =
+    logging_processor.profile.codeMap_.getAllDynamicEntriesWithAddresses();
+  if (logging_entries.length === 0)
+    return "logging_entries.length === 0";
+  var traversal_processor = new LogProcessor();
+  for ( ; pos < log_lines_length; ++pos) {
+    line = log_lines[pos];
+    if (line === "test-traversal-done,\"\"") break;
+    traversal_processor.processLogLine(line);
+  }
+  var traversal_entries =
+    traversal_processor.profile.codeMap_.getAllDynamicEntriesWithAddresses();
+  if (traversal_entries.length === 0)
+    return "traversal_entries.length === 0";
+
+  function addressComparator(entryA, entryB) {
+    return entryA[0] < entryB[0] ? -1 : (entryA[0] > entryB[0] ? 1 : 0);
+  }
+
+  logging_entries.sort(addressComparator);
+  traversal_entries.sort(addressComparator);
+
+  function entityNamesEqual(entityA, entityB) {
+    if ("getRawName" in entityB &&
+        entityNamesEqual.builtins.indexOf(entityB.getRawName()) !== -1) {
+      return true;
+    }
+    if (entityNamesEqual.builtins.indexOf(entityB.getName()) !== -1) return true;
+    return entityA.getName() === entityB.getName();
+  }
+  entityNamesEqual.builtins =
+    ["Boolean", "Function", "Number", "Object",
+     "Script", "String", "RegExp", "Date", "Error"];
+
+  function entitiesEqual(entityA, entityB) {
+    if (entityA === null && entityB !== null) return true;
+    if (entityA !== null && entityB === null) return false;
+    return entityA.size === entityB.size && entityNamesEqual(entityA, entityB);
+  }
+
+  var l_pos = 0, t_pos = 0;
+  var l_len = logging_entries.length, t_len = traversal_entries.length;
+  var comparison = [];
+  var equal = true;
+  // Do a merge-like comparison of entries. At the same address we expect to
+  // find the same entries. We skip builtins during log parsing, but compiled
+  // functions traversal may erroneously recognize them as functions, so we are
+  // expecting more functions in traversal vs. logging.
+  while (l_pos < l_len && t_pos < t_len) {
+    var entryA = logging_entries[l_pos];
+    var entryB = traversal_entries[t_pos];
+    var cmp = addressComparator(entryA, entryB);
+    var entityA = entryA[1], entityB = entryB[1];
+    var address = entryA[0];
+    if (cmp < 0) {
+      ++l_pos;
+      entityB = null;
+    } else if (cmp > 0) {
+      ++t_pos;
+      entityA = null;
+      address = entryB[0];
+    } else {
+      ++l_pos;
+      ++t_pos;
+    }
+    var entities_equal = entitiesEqual(entityA, entityB);
+    if (!entities_equal) equal = false;
+    comparison.push([entities_equal, address, entityA, entityB]);
+  }
+  if (l_pos < l_len) equal = false;
+  while (l_pos < l_len) {
+    var entryA = logging_entries[l_pos++];
+    comparison.push([false, entryA[0], entryA[1], null]);
+  }
+  return [equal, comparison];
+}
+
+var result = RunTest();
+if (typeof result !== "string") {
+  var out = [];
+  if (!result[0]) {
+    var comparison = result[1];
+    for (var i = 0, l = comparison.length; i < l; ++i) {
+      var c = comparison[i];
+      out.push((c[0] ? "  " : "* ") +
+               c[1].toString(16) + " " +
+               (c[2] ? c[2] : "---") + " " +
+               (c[3] ? c[3] : "---"));
+    }
+  }
+  result[0] ? true : out.join("\n");
+} else {
+  result;
+}
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1121210..5d197be 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1026,6 +1026,90 @@
 }
 
 
+THREADED_TEST(IsNativeError) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::Handle<Value> syntax_error = CompileRun(
+      "var out = 0; try { eval(\"#\"); } catch(x) { out = x; } out; ");
+  CHECK(syntax_error->IsNativeError());
+  v8::Handle<Value> not_error = CompileRun("{a:42}");
+  CHECK(!not_error->IsNativeError());
+  v8::Handle<Value> not_object = CompileRun("42");
+  CHECK(!not_object->IsNativeError());
+}
+
+
+THREADED_TEST(StringObject) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::Handle<Value> boxed_string = CompileRun("new String(\"test\")");
+  CHECK(boxed_string->IsStringObject());
+  v8::Handle<Value> unboxed_string = CompileRun("\"test\"");
+  CHECK(!unboxed_string->IsStringObject());
+  v8::Handle<Value> boxed_not_string = CompileRun("new Number(42)");
+  CHECK(!boxed_not_string->IsStringObject());
+  v8::Handle<Value> not_object = CompileRun("0");
+  CHECK(!not_object->IsStringObject());
+  v8::Handle<v8::StringObject> as_boxed = boxed_string.As<v8::StringObject>();
+  CHECK(!as_boxed.IsEmpty());
+  Local<v8::String> the_string = as_boxed->StringValue();
+  CHECK(!the_string.IsEmpty());
+  ExpectObject("\"test\"", the_string);
+  v8::Handle<v8::Value> new_boxed_string = v8::StringObject::New(the_string);
+  CHECK(new_boxed_string->IsStringObject());
+  as_boxed = new_boxed_string.As<v8::StringObject>();
+  the_string = as_boxed->StringValue();
+  CHECK(!the_string.IsEmpty());
+  ExpectObject("\"test\"", the_string);
+}
+
+
+THREADED_TEST(NumberObject) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::Handle<Value> boxed_number = CompileRun("new Number(42)");
+  CHECK(boxed_number->IsNumberObject());
+  v8::Handle<Value> unboxed_number = CompileRun("42");
+  CHECK(!unboxed_number->IsNumberObject());
+  v8::Handle<Value> boxed_not_number = CompileRun("new Boolean(false)");
+  CHECK(!boxed_not_number->IsNumberObject());
+  v8::Handle<v8::NumberObject> as_boxed = boxed_number.As<v8::NumberObject>();
+  CHECK(!as_boxed.IsEmpty());
+  double the_number = as_boxed->NumberValue();
+  CHECK_EQ(42.0, the_number);
+  v8::Handle<v8::Value> new_boxed_number = v8::NumberObject::New(43);
+  CHECK(new_boxed_number->IsNumberObject());
+  as_boxed = new_boxed_number.As<v8::NumberObject>();
+  the_number = as_boxed->NumberValue();
+  CHECK_EQ(43.0, the_number);
+}
+
+
+THREADED_TEST(BooleanObject) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::Handle<Value> boxed_boolean = CompileRun("new Boolean(true)");
+  CHECK(boxed_boolean->IsBooleanObject());
+  v8::Handle<Value> unboxed_boolean = CompileRun("true");
+  CHECK(!unboxed_boolean->IsBooleanObject());
+  v8::Handle<Value> boxed_not_boolean = CompileRun("new Number(42)");
+  CHECK(!boxed_not_boolean->IsBooleanObject());
+  v8::Handle<v8::BooleanObject> as_boxed =
+      boxed_boolean.As<v8::BooleanObject>();
+  CHECK(!as_boxed.IsEmpty());
+  bool the_boolean = as_boxed->BooleanValue();
+  CHECK_EQ(true, the_boolean);
+  v8::Handle<v8::Value> boxed_true = v8::BooleanObject::New(true);
+  v8::Handle<v8::Value> boxed_false = v8::BooleanObject::New(false);
+  CHECK(boxed_true->IsBooleanObject());
+  CHECK(boxed_false->IsBooleanObject());
+  as_boxed = boxed_true.As<v8::BooleanObject>();
+  CHECK_EQ(true, as_boxed->BooleanValue());
+  as_boxed = boxed_false.As<v8::BooleanObject>();
+  CHECK_EQ(false, as_boxed->BooleanValue());
+}
+
+
 THREADED_TEST(Number) {
   v8::HandleScope scope;
   LocalContext env;
@@ -1729,6 +1813,34 @@
 }
 
 
+THREADED_TEST(Regress97784) {
+  // Regression test for crbug.com/97784
+  // Messing with the Object.prototype should not have effect on
+  // hidden properties.
+  v8::HandleScope scope;
+  LocalContext env;
+
+  v8::Local<v8::Object> obj = v8::Object::New();
+  v8::Local<v8::String> key = v8_str("hidden");
+
+  CompileRun(
+      "set_called = false;"
+      "Object.defineProperty("
+      "    Object.prototype,"
+      "    'hidden',"
+      "    {get: function() { return 45; },"
+      "     set: function() { set_called = true; }})");
+
+  CHECK(obj->GetHiddenValue(key).IsEmpty());
+  // Make sure that the getter and setter from Object.prototype is not invoked.
+  // If it did we would have full access to the hidden properties in
+  // the accessor.
+  CHECK(obj->SetHiddenValue(key, v8::Integer::New(42)));
+  ExpectFalse("set_called");
+  CHECK_EQ(42, obj->GetHiddenValue(key)->Int32Value());
+}
+
+
 static bool interceptor_for_hidden_properties_called;
 static v8::Handle<Value> InterceptorForHiddenProperties(
     Local<String> name, const AccessorInfo& info) {
@@ -2048,10 +2160,15 @@
 THREADED_TEST(PropertyAttributes) {
   v8::HandleScope scope;
   LocalContext context;
+  // none
+  Local<String> prop = v8_str("none");
+  context->Global()->Set(prop, v8_num(7));
+  CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(prop));
   // read-only
-  Local<String> prop = v8_str("read_only");
+  prop = v8_str("read_only");
   context->Global()->Set(prop, v8_num(7), v8::ReadOnly);
   CHECK_EQ(7, context->Global()->Get(prop)->Int32Value());
+  CHECK_EQ(v8::ReadOnly, context->Global()->GetPropertyAttributes(prop));
   Script::Compile(v8_str("read_only = 9"))->Run();
   CHECK_EQ(7, context->Global()->Get(prop)->Int32Value());
   context->Global()->Set(prop, v8_num(10));
@@ -2062,6 +2179,25 @@
   CHECK_EQ(13, context->Global()->Get(prop)->Int32Value());
   Script::Compile(v8_str("delete dont_delete"))->Run();
   CHECK_EQ(13, context->Global()->Get(prop)->Int32Value());
+  CHECK_EQ(v8::DontDelete, context->Global()->GetPropertyAttributes(prop));
+  // dont-enum
+  prop = v8_str("dont_enum");
+  context->Global()->Set(prop, v8_num(28), v8::DontEnum);
+  CHECK_EQ(v8::DontEnum, context->Global()->GetPropertyAttributes(prop));
+  // absent
+  prop = v8_str("absent");
+  CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(prop));
+  Local<Value> fake_prop = v8_num(1);
+  CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(fake_prop));
+  // exception
+  TryCatch try_catch;
+  Local<Value> exception =
+      CompileRun("({ toString: function() { throw 'exception';} })");
+  CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(exception));
+  CHECK(try_catch.HasCaught());
+  String::AsciiValue exception_value(try_catch.Exception());
+  CHECK_EQ("exception", *exception_value);
+  try_catch.Reset();
 }
 
 
@@ -3039,8 +3175,7 @@
   result = script_define->Run();
   CHECK(try_catch.HasCaught());
   String::AsciiValue exception_value(try_catch.Exception());
-  CHECK_EQ(*exception_value,
-           "TypeError: Cannot redefine property: defineProperty");
+  CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
 }
 
 THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
@@ -3085,8 +3220,7 @@
   result = script_define->Run();
   CHECK(try_catch.HasCaught());
   String::AsciiValue exception_value(try_catch.Exception());
-  CHECK_EQ(*exception_value,
-           "TypeError: Cannot redefine property: defineProperty");
+  CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
 }
 
 
@@ -3204,8 +3338,7 @@
         "{get: function() { return 'func'; }})");
     CHECK(try_catch.HasCaught());
     String::AsciiValue exception_value(try_catch.Exception());
-    CHECK_EQ(*exception_value,
-            "TypeError: Cannot redefine property: defineProperty");
+    CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
   }
   {
     v8::TryCatch try_catch;
@@ -3213,8 +3346,7 @@
         "{get: function() { return 'func'; }})");
     CHECK(try_catch.HasCaught());
     String::AsciiValue exception_value(try_catch.Exception());
-    CHECK_EQ(*exception_value,
-            "TypeError: Cannot redefine property: defineProperty");
+    CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
   }
 }
 
@@ -3866,6 +3998,49 @@
 }
 
 
+THREADED_TEST(VoidLiteral) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  Local<v8::FunctionTemplate> desc =
+      v8::FunctionTemplate::New(0, v8::Handle<Value>());
+  desc->InstanceTemplate()->MarkAsUndetectable();  // undetectable
+
+  Local<v8::Object> obj = desc->GetFunction()->NewInstance();
+  env->Global()->Set(v8_str("undetectable"), obj);
+
+  ExpectBoolean("undefined == void 0", true);
+  ExpectBoolean("undetectable == void 0", true);
+  ExpectBoolean("null == void 0", true);
+  ExpectBoolean("undefined === void 0", true);
+  ExpectBoolean("undetectable === void 0", false);
+  ExpectBoolean("null === void 0", false);
+
+  ExpectBoolean("void 0 == undefined", true);
+  ExpectBoolean("void 0 == undetectable", true);
+  ExpectBoolean("void 0 == null", true);
+  ExpectBoolean("void 0 === undefined", true);
+  ExpectBoolean("void 0 === undetectable", false);
+  ExpectBoolean("void 0 === null", false);
+
+  ExpectString("(function() {"
+               "  try {"
+               "    return x === void 0;"
+               "  } catch(e) {"
+               "    return e.toString();"
+               "  }"
+               "})()",
+               "ReferenceError: x is not defined");
+  ExpectString("(function() {"
+               "  try {"
+               "    return void 0 === x;"
+               "  } catch(e) {"
+               "    return e.toString();"
+               "  }"
+               "})()",
+               "ReferenceError: x is not defined");
+}
+
 
 THREADED_TEST(ExtensibleOnUndetectable) {
   v8::HandleScope scope;
@@ -4161,6 +4336,69 @@
 }
 
 
+class NativeFunctionExtension : public Extension {
+ public:
+  NativeFunctionExtension(const char* name,
+                          const char* source,
+                          v8::InvocationCallback fun = &Echo)
+      : Extension(name, source),
+        function_(fun) { }
+
+  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
+      v8::Handle<v8::String> name) {
+    return v8::FunctionTemplate::New(function_);
+  }
+
+  static v8::Handle<v8::Value> Echo(const v8::Arguments& args) {
+    if (args.Length() >= 1) return (args[0]);
+    return v8::Undefined();
+  }
+ private:
+  v8::InvocationCallback function_;
+};
+
+
+THREADED_TEST(NativeFunctionDeclaration) {
+  v8::HandleScope handle_scope;
+  const char* name = "nativedecl";
+  v8::RegisterExtension(new NativeFunctionExtension(name,
+                                                    "native function foo();"));
+  const char* extension_names[] = { name };
+  v8::ExtensionConfiguration extensions(1, extension_names);
+  v8::Handle<Context> context = Context::New(&extensions);
+  Context::Scope lock(context);
+  v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run();
+  CHECK_EQ(result, v8::Integer::New(42));
+}
+
+
+THREADED_TEST(NativeFunctionDeclarationError) {
+  v8::HandleScope handle_scope;
+  const char* name = "nativedeclerr";
+  // Syntax error in extension code.
+  v8::RegisterExtension(new NativeFunctionExtension(name,
+                                                    "native\nfunction foo();"));
+  const char* extension_names[] = { name };
+  v8::ExtensionConfiguration extensions(1, extension_names);
+  v8::Handle<Context> context = Context::New(&extensions);
+  ASSERT(context.IsEmpty());
+}
+
+THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
+  v8::HandleScope handle_scope;
+  const char* name = "nativedeclerresc";
+  // Syntax error in extension code - escape code in "native" means that
+  // it's not treated as a keyword.
+  v8::RegisterExtension(new NativeFunctionExtension(
+      name,
+      "nativ\\u0065 function foo();"));
+  const char* extension_names[] = { name };
+  v8::ExtensionConfiguration extensions(1, extension_names);
+  v8::Handle<Context> context = Context::New(&extensions);
+  ASSERT(context.IsEmpty());
+}
+
+
 static void CheckDependencies(const char* name, const char* expected) {
   v8::HandleScope handle_scope;
   v8::ExtensionConfiguration config(1, &name);
@@ -6664,7 +6902,7 @@
   context->Global()->Set(v8_str("__proto__"), o);
 
   Local<Value> value =
-      Script::Compile(v8_str("propertyIsEnumerable(0)"))->Run();
+      Script::Compile(v8_str("this.propertyIsEnumerable(0)"))->Run();
   CHECK(value->IsBoolean());
   CHECK(!value->BooleanValue());
 
@@ -6783,6 +7021,56 @@
 }
 
 
+THREADED_TEST(SetPrototypeProperties) {
+  v8::HandleScope handle_scope;
+  LocalContext context;
+
+  Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+  t1->SetPrototypeAttributes(v8::DontDelete);
+  context->Global()->Set(v8_str("func1"), t1->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func1, 'prototype');"
+      "  return (descriptor['writable'] == true) &&"
+      "         (descriptor['enumerable'] == true) &&"
+      "         (descriptor['configurable'] == false);"
+      "})()")->BooleanValue());
+
+  Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+  t2->SetPrototypeAttributes(v8::DontEnum);
+  context->Global()->Set(v8_str("func2"), t2->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func2, 'prototype');"
+      "  return (descriptor['writable'] == true) &&"
+      "         (descriptor['enumerable'] == false) &&"
+      "         (descriptor['configurable'] == true);"
+      "})()")->BooleanValue());
+
+  Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+  t3->SetPrototypeAttributes(v8::ReadOnly);
+  context->Global()->Set(v8_str("func3"), t3->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func3, 'prototype');"
+      "  return (descriptor['writable'] == false) &&"
+      "         (descriptor['enumerable'] == true) &&"
+      "         (descriptor['configurable'] == true);"
+      "})()")->BooleanValue());
+
+  Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
+  t4->SetPrototypeAttributes(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
+  context->Global()->Set(v8_str("func4"), t4->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func4, 'prototype');"
+      "  return (descriptor['writable'] == false) &&"
+      "         (descriptor['enumerable'] == false) &&"
+      "         (descriptor['configurable'] == false);"
+      "})()")->BooleanValue());
+}
+
+
 THREADED_TEST(SetPrototypeThrows) {
   v8::HandleScope handle_scope;
   LocalContext context;
@@ -9342,8 +9630,7 @@
   int end = (count * (part + 1) / (LAST_PART + 1)) - 1;
   active_tests_ = tests_being_run_ = end - start + 1;
   for (int i = 0; i < tests_being_run_; i++) {
-    RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer(
-        i::Isolate::Current(), i + start);
+    RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer(i + start);
   }
   for (int i = 0; i < active_tests_; i++) {
     RegisterThreadedTest::nth(i)->fuzzer_->Start();
@@ -9576,6 +9863,7 @@
   // the first garbage collection but some of the maps have already
   // been marked at that point.  Therefore some of the maps are not
   // collected until the second garbage collection.
+  HEAP->global_context_map();
   HEAP->CollectAllGarbage(false);
   HEAP->CollectAllGarbage(false);
   int count = GetGlobalObjectsCount();
@@ -9914,6 +10202,19 @@
 }
 
 
+void CheckOwnProperties(v8::Handle<v8::Value> val,
+                        int elmc,
+                        const char* elmv[]) {
+  v8::Handle<v8::Object> obj = val.As<v8::Object>();
+  v8::Handle<v8::Array> props = obj->GetOwnPropertyNames();
+  CHECK_EQ(elmc, props->Length());
+  for (int i = 0; i < elmc; i++) {
+    v8::String::Utf8Value elm(props->Get(v8::Integer::New(i)));
+    CHECK_EQ(elmv[i], *elm);
+  }
+}
+
+
 THREADED_TEST(PropertyEnumeration) {
   v8::HandleScope scope;
   LocalContext context;
@@ -9931,15 +10232,21 @@
   int elmc0 = 0;
   const char** elmv0 = NULL;
   CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
+  CheckOwnProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
   int elmc1 = 2;
   const char* elmv1[] = {"a", "b"};
   CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
+  CheckOwnProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
   int elmc2 = 3;
   const char* elmv2[] = {"0", "1", "2"};
   CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
+  CheckOwnProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
   int elmc3 = 4;
   const char* elmv3[] = {"w", "z", "x", "y"};
   CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3);
+  int elmc4 = 2;
+  const char* elmv4[] = {"w", "z"};
+  CheckOwnProperties(elms->Get(v8::Integer::New(3)), elmc4, elmv4);
 }
 
 THREADED_TEST(PropertyEnumeration2) {
@@ -10341,17 +10648,16 @@
            *exception_value);
 
   try_catch.Reset();
+
   // Overwrite function bar's start position with 200.  The function entry
-  // will not be found when searching for it by position.
+  // will not be found when searching for it by position and we should fall
+  // back on eager compilation.
   sd = v8::ScriptData::PreCompile(script, i::StrLength(script));
   sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
   sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] =
       200;
   compiled_script = Script::New(source, NULL, sd);
-  CHECK(try_catch.HasCaught());
-  String::AsciiValue second_exception_value(try_catch.Message()->Get());
-  CHECK_EQ("Uncaught SyntaxError: Invalid preparser data for function bar",
-           *second_exception_value);
+  CHECK(!try_catch.HasCaught());
 
   delete sd;
 }
@@ -10459,7 +10765,7 @@
     gc_during_regexp_ = 0;
     regexp_success_ = false;
     gc_success_ = false;
-    GCThread gc_thread(i::Isolate::Current(), this);
+    GCThread gc_thread(this);
     gc_thread.Start();
     v8::Locker::StartPreemption(1);
 
@@ -10472,14 +10778,15 @@
     CHECK(regexp_success_);
     CHECK(gc_success_);
   }
+
  private:
   // Number of garbage collections required.
   static const int kRequiredGCs = 5;
 
   class GCThread : public i::Thread {
    public:
-    explicit GCThread(i::Isolate* isolate, RegExpInterruptTest* test)
-        : Thread(isolate, "GCThread"), test_(test) {}
+    explicit GCThread(RegExpInterruptTest* test)
+        : Thread("GCThread"), test_(test) {}
     virtual void Run() {
       test_->CollectGarbage();
     }
@@ -10581,7 +10888,7 @@
     gc_during_apply_ = 0;
     apply_success_ = false;
     gc_success_ = false;
-    GCThread gc_thread(i::Isolate::Current(), this);
+    GCThread gc_thread(this);
     gc_thread.Start();
     v8::Locker::StartPreemption(1);
 
@@ -10594,14 +10901,15 @@
     CHECK(apply_success_);
     CHECK(gc_success_);
   }
+
  private:
   // Number of garbage collections required.
   static const int kRequiredGCs = 2;
 
   class GCThread : public i::Thread {
    public:
-    explicit GCThread(i::Isolate* isolate, ApplyInterruptTest* test)
-        : Thread(isolate, "GCThread"), test_(test) {}
+    explicit GCThread(ApplyInterruptTest* test)
+        : Thread("GCThread"), test_(test) {}
     virtual void Run() {
       test_->CollectGarbage();
     }
@@ -10875,7 +11183,7 @@
         NONE,
         i::kNonStrictMode)->ToObjectChecked();
 
-    MorphThread morph_thread(i::Isolate::Current(), this);
+    MorphThread morph_thread(this);
     morph_thread.Start();
     v8::Locker::StartPreemption(1);
     LongRunningRegExp();
@@ -10887,17 +11195,16 @@
     CHECK(regexp_success_);
     CHECK(morph_success_);
   }
- private:
 
+ private:
   // Number of string modifications required.
   static const int kRequiredModifications = 5;
   static const int kMaxModifications = 100;
 
   class MorphThread : public i::Thread {
    public:
-    explicit MorphThread(i::Isolate* isolate,
-                         RegExpStringModificationTest* test)
-        : Thread(isolate, "MorphThread"), test_(test) {}
+    explicit MorphThread(RegExpStringModificationTest* test)
+        : Thread("MorphThread"), test_(test) {}
     virtual void Run() {
       test_->MorphString();
     }
@@ -12461,9 +12768,10 @@
                     stackTrace->GetFrame(0));
     checkStackFrame(origin, "foo", 6, 3, false, false,
                     stackTrace->GetFrame(1));
-    checkStackFrame(NULL, "", 1, 1, false, false,
+    // This is the source string inside the eval which has the call to foo.
+    checkStackFrame(NULL, "", 1, 5, false, false,
                     stackTrace->GetFrame(2));
-    // The last frame is an anonymous function that has the initial call.
+    // The last frame is an anonymous function which has the initial eval call.
     checkStackFrame(origin, "", 8, 7, false, false,
                     stackTrace->GetFrame(3));
 
@@ -12482,9 +12790,10 @@
     bool is_eval = false;
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
-    checkStackFrame(NULL, "", 1, 1, is_eval, false,
+    // This is the source string inside the eval which has the call to baz.
+    checkStackFrame(NULL, "", 1, 5, is_eval, false,
                     stackTrace->GetFrame(2));
-    // The last frame is an anonymous function that has the initial call to foo.
+    // The last frame is an anonymous function which has the initial eval call.
     checkStackFrame(origin, "", 10, 1, false, false,
                     stackTrace->GetFrame(3));
 
@@ -13714,8 +14023,8 @@
 
 class IsolateThread : public v8::internal::Thread {
  public:
-  explicit IsolateThread(v8::Isolate* isolate, int fib_limit)
-      : Thread(NULL, "IsolateThread"),
+  IsolateThread(v8::Isolate* isolate, int fib_limit)
+      : Thread("IsolateThread"),
         isolate_(isolate),
         fib_limit_(fib_limit),
         result_(0) { }
@@ -13795,7 +14104,7 @@
   };
 
   explicit InitDefaultIsolateThread(TestCase testCase)
-      : Thread(NULL, "InitDefaultIsolateThread"),
+      : Thread("InitDefaultIsolateThread"),
         testCase_(testCase),
         result_(false) { }
 
@@ -14038,48 +14347,6 @@
 }
 
 
-TEST(GlobalLoadICGC) {
-  const char* function_code =
-      "function readCell() { while (true) { return cell; } }";
-
-  // Check inline load code for a don't delete cell is cleared during
-  // GC.
-  {
-    v8::HandleScope scope;
-    LocalContext context;
-    CompileRun("var cell = \"value\";");
-    ExpectBoolean("delete cell", false);
-    CompileRun(function_code);
-    ExpectString("readCell()", "value");
-    ExpectString("readCell()", "value");
-  }
-  {
-    v8::HandleScope scope;
-    LocalContext context2;
-    // Hold the code object in the second context.
-    CompileRun(function_code);
-    CheckSurvivingGlobalObjectsCount(1);
-  }
-
-  // Check inline load code for a deletable cell is cleared during GC.
-  {
-    v8::HandleScope scope;
-    LocalContext context;
-    CompileRun("cell = \"value\";");
-    CompileRun(function_code);
-    ExpectString("readCell()", "value");
-    ExpectString("readCell()", "value");
-  }
-  {
-    v8::HandleScope scope;
-    LocalContext context2;
-    // Hold the code object in the second context.
-    CompileRun(function_code);
-    CheckSurvivingGlobalObjectsCount(1);
-  }
-}
-
-
 TEST(RegExp) {
   v8::HandleScope scope;
   LocalContext context;
@@ -14507,3 +14774,159 @@
   TryCatch try_catch;
   CompileRun("f.call(2)");
 }
+
+
+// Regression test for issue 1470.
+THREADED_TEST(ReadOnlyIndexedProperties) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+  obj->Set(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+  obj->Set(v8_str("1"), v8_str("foobar"));
+  CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("1")));
+  obj->Set(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly);
+  obj->Set(v8_num(2), v8_str("foobar"));
+  CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_num(2)));
+
+  // Test non-smi case.
+  obj->Set(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+  obj->Set(v8_str("2000000000"), v8_str("foobar"));
+  CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("2000000000")));
+}
+
+
+THREADED_TEST(Regress1516) {
+  v8::HandleScope scope;
+
+  LocalContext context;
+  { v8::HandleScope temp_scope;
+    CompileRun("({'a': 0})");
+  }
+
+  int elements;
+  { i::MapCache* map_cache =
+        i::MapCache::cast(i::Isolate::Current()->context()->map_cache());
+    elements = map_cache->NumberOfElements();
+    CHECK_LE(1, elements);
+  }
+
+  i::Isolate::Current()->heap()->CollectAllGarbage(true);
+  { i::Object* raw_map_cache = i::Isolate::Current()->context()->map_cache();
+    if (raw_map_cache != i::Isolate::Current()->heap()->undefined_value()) {
+      i::MapCache* map_cache = i::MapCache::cast(raw_map_cache);
+      CHECK_GT(elements, map_cache->NumberOfElements());
+    }
+  }
+}
+
+
+static bool BlockProtoNamedSecurityTestCallback(Local<v8::Object> global,
+                                                Local<Value> name,
+                                                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) {
+    char buffer[10];
+    CHECK_EQ(10, name->ToString()->WriteUtf8(buffer));
+    return strncmp(buffer, "__proto__", 9) != 0;
+  }
+
+  return true;
+}
+
+
+THREADED_TEST(Regress93759) {
+  HandleScope scope;
+
+  // Template for object with security check.
+  Local<ObjectTemplate> no_proto_template = v8::ObjectTemplate::New();
+  // We don't do indexing, so any callback can be used for that.
+  no_proto_template->SetAccessCheckCallbacks(
+      BlockProtoNamedSecurityTestCallback,
+      IndexedSecurityTestCallback);
+
+  // Templates for objects with hidden prototypes and possibly security check.
+  Local<FunctionTemplate> hidden_proto_template = v8::FunctionTemplate::New();
+  hidden_proto_template->SetHiddenPrototype(true);
+
+  Local<FunctionTemplate> protected_hidden_proto_template =
+      v8::FunctionTemplate::New();
+  protected_hidden_proto_template->InstanceTemplate()->SetAccessCheckCallbacks(
+      BlockProtoNamedSecurityTestCallback,
+      IndexedSecurityTestCallback);
+  protected_hidden_proto_template->SetHiddenPrototype(true);
+
+  // Context for "foreign" objects used in test.
+  Persistent<Context> context = v8::Context::New();
+  context->Enter();
+
+  // Plain object, no security check.
+  Local<Object> simple_object = Object::New();
+
+  // Object with explicit security check.
+  Local<Object> protected_object =
+      no_proto_template->NewInstance();
+
+  // JSGlobalProxy object, always have security check.
+  Local<Object> proxy_object =
+      context->Global();
+
+  // Global object, the  prototype of proxy_object. No security checks.
+  Local<Object> global_object =
+      proxy_object->GetPrototype()->ToObject();
+
+  // Hidden prototype without security check.
+  Local<Object> hidden_prototype =
+      hidden_proto_template->GetFunction()->NewInstance();
+  Local<Object> object_with_hidden =
+    Object::New();
+  object_with_hidden->SetPrototype(hidden_prototype);
+
+  // Hidden prototype with security check on the hidden prototype.
+  Local<Object> protected_hidden_prototype =
+      protected_hidden_proto_template->GetFunction()->NewInstance();
+  Local<Object> object_with_protected_hidden =
+    Object::New();
+  object_with_protected_hidden->SetPrototype(protected_hidden_prototype);
+
+  context->Exit();
+
+  // Template for object for second context. Values to test are put on it as
+  // properties.
+  Local<ObjectTemplate> global_template = ObjectTemplate::New();
+  global_template->Set(v8_str("simple"), simple_object);
+  global_template->Set(v8_str("protected"), protected_object);
+  global_template->Set(v8_str("global"), global_object);
+  global_template->Set(v8_str("proxy"), proxy_object);
+  global_template->Set(v8_str("hidden"), object_with_hidden);
+  global_template->Set(v8_str("phidden"), object_with_protected_hidden);
+
+  LocalContext context2(NULL, global_template);
+
+  Local<Value> result1 = CompileRun("Object.getPrototypeOf(simple)");
+  CHECK(result1->Equals(simple_object->GetPrototype()));
+
+  Local<Value> result2 = CompileRun("Object.getPrototypeOf(protected)");
+  CHECK(result2->Equals(Undefined()));
+
+  Local<Value> result3 = CompileRun("Object.getPrototypeOf(global)");
+  CHECK(result3->Equals(global_object->GetPrototype()));
+
+  Local<Value> result4 = CompileRun("Object.getPrototypeOf(proxy)");
+  CHECK(result4->Equals(Undefined()));
+
+  Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)");
+  CHECK(result5->Equals(
+      object_with_hidden->GetPrototype()->ToObject()->GetPrototype()));
+
+  Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
+  CHECK(result6->Equals(Undefined()));
+
+  context.Dispose();
+}
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc
index 4db1fe0..8ac89f6 100644
--- a/test/cctest/test-assembler-mips.cc
+++ b/test/cctest/test-assembler-mips.cc
@@ -1220,8 +1220,6 @@
     // Restore FCSR.
     __ ctc1(a1, FCSR);
 
-#undef RUN_ROUND_TEST
-
     __ jr(ra);
     __ nop();
 
@@ -1246,66 +1244,19 @@
     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
     USE(dummy);
 
-#define GET_FPU_ERR(x) (static_cast<int>((x >> kFCSRFlagShift) & kFCSRFlagMask))
+#define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
+#define CHECK_ROUND_RESULT(type) \
+  CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \
+  CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \
+  CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
+  CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
+  CHECK_EQ(kFPUInvalidResult, t.type##_invalid_result);
 
-    CHECK_EQ(124, t.round_up_out);
-    CHECK_EQ(123, t.round_down_out);
-    CHECK_EQ(-124, t.neg_round_up_out);
-    CHECK_EQ(-123, t.neg_round_down_out);
-
-    // Inexact.
-    CHECK_EQ(kFCSRInexactFlagBit, GET_FPU_ERR(t.round_err1_out));
-    // No error.
-    CHECK_EQ(0, GET_FPU_ERR(t.round_err2_out));
-    // Invalid operation.
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.round_err3_out));
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.round_err4_out));
-    CHECK_EQ(kFPUInvalidResult, t.round_invalid_result);
-
-    CHECK_EQ(123, t.floor_up_out);
-    CHECK_EQ(123, t.floor_down_out);
-    CHECK_EQ(-124, t.neg_floor_up_out);
-    CHECK_EQ(-124, t.neg_floor_down_out);
-
-    // Inexact.
-    CHECK_EQ(kFCSRInexactFlagBit, GET_FPU_ERR(t.floor_err1_out));
-    // No error.
-    CHECK_EQ(0, GET_FPU_ERR(t.floor_err2_out));
-    // Invalid operation.
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.floor_err3_out));
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.floor_err4_out));
-    CHECK_EQ(kFPUInvalidResult, t.floor_invalid_result);
-
-    CHECK_EQ(124, t.ceil_up_out);
-    CHECK_EQ(124, t.ceil_down_out);
-    CHECK_EQ(-123, t.neg_ceil_up_out);
-    CHECK_EQ(-123, t.neg_ceil_down_out);
-
-    // Inexact.
-    CHECK_EQ(kFCSRInexactFlagBit, GET_FPU_ERR(t.ceil_err1_out));
-    // No error.
-    CHECK_EQ(0, GET_FPU_ERR(t.ceil_err2_out));
-    // Invalid operation.
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.ceil_err3_out));
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.ceil_err4_out));
-    CHECK_EQ(kFPUInvalidResult, t.ceil_invalid_result);
-
-    // In rounding mode 0 cvt should behave like round.
-    CHECK_EQ(t.round_up_out, t.cvt_up_out);
-    CHECK_EQ(t.round_down_out, t.cvt_down_out);
-    CHECK_EQ(t.neg_round_up_out, t.neg_cvt_up_out);
-    CHECK_EQ(t.neg_round_down_out, t.neg_cvt_down_out);
-
-    // Inexact.
-    CHECK_EQ(kFCSRInexactFlagBit, GET_FPU_ERR(t.cvt_err1_out));
-    // No error.
-    CHECK_EQ(0, GET_FPU_ERR(t.cvt_err2_out));
-    // Invalid operation.
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.cvt_err3_out));
-    CHECK_EQ(kFCSRInvalidOpFlagBit, GET_FPU_ERR(t.cvt_err4_out));
-    CHECK_EQ(kFPUInvalidResult, t.cvt_invalid_result);
+    CHECK_ROUND_RESULT(round);
+    CHECK_ROUND_RESULT(floor);
+    CHECK_ROUND_RESULT(ceil);
+    CHECK_ROUND_RESULT(cvt);
   }
 }
 
-
 #undef __
diff --git a/test/cctest/test-ast.cc b/test/cctest/test-ast.cc
index d1e537d..786a54a 100644
--- a/test/cctest/test-ast.cc
+++ b/test/cctest/test-ast.cc
@@ -40,7 +40,7 @@
   CHECK_EQ(0, list->length());
 
   ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
-  AstNode* node = new EmptyStatement();
+  AstNode* node = new(ZONE) EmptyStatement();
   list->Add(node);
   CHECK_EQ(1, list->length());
   CHECK_EQ(node, list->at(0));
diff --git a/test/cctest/test-circular-queue.cc b/test/cctest/test-circular-queue.cc
index 9dd4981..c4e5c4c 100644
--- a/test/cctest/test-circular-queue.cc
+++ b/test/cctest/test-circular-queue.cc
@@ -84,12 +84,11 @@
  public:
   typedef SamplingCircularQueue::Cell Record;
 
-  ProducerThread(i::Isolate* isolate,
-                 SamplingCircularQueue* scq,
+  ProducerThread(SamplingCircularQueue* scq,
                  int records_per_chunk,
                  Record value,
                  i::Semaphore* finished)
-      : Thread(isolate, "producer"),
+      : Thread("producer"),
         scq_(scq),
         records_per_chunk_(records_per_chunk),
         value_(value),
@@ -133,10 +132,9 @@
   // Check that we are using non-reserved values.
   CHECK_NE(SamplingCircularQueue::kClear, 1);
   CHECK_NE(SamplingCircularQueue::kEnd, 1);
-  i::Isolate* isolate = i::Isolate::Current();
-  ProducerThread producer1(isolate, &scq, kRecordsPerChunk, 1, semaphore);
-  ProducerThread producer2(isolate, &scq, kRecordsPerChunk, 10, semaphore);
-  ProducerThread producer3(isolate, &scq, kRecordsPerChunk, 20, semaphore);
+  ProducerThread producer1(&scq, kRecordsPerChunk, 1, semaphore);
+  ProducerThread producer2(&scq, kRecordsPerChunk, 10, semaphore);
+  ProducerThread producer3(&scq, kRecordsPerChunk, 20, semaphore);
 
   CHECK_EQ(NULL, scq.StartDequeue());
   producer1.Start();
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index beb73c5..9ff2a17 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -2,8 +2,6 @@
 //
 // Tests of profiles generator and utilities.
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 #include "cpu-profiler-inl.h"
 #include "cctest.h"
@@ -24,7 +22,7 @@
 TEST(StartStop) {
   CpuProfilesCollection profiles;
   ProfileGenerator generator(&profiles);
-  ProfilerEventsProcessor processor(i::Isolate::Current(), &generator);
+  ProfilerEventsProcessor processor(&generator);
   processor.Start();
   processor.Stop();
   processor.Join();
@@ -85,7 +83,7 @@
   CpuProfilesCollection profiles;
   profiles.StartProfiling("", 1);
   ProfileGenerator generator(&profiles);
-  ProfilerEventsProcessor processor(i::Isolate::Current(), &generator);
+  ProfilerEventsProcessor processor(&generator);
   processor.Start();
 
   // Enqueue code creation events.
@@ -146,7 +144,7 @@
   CpuProfilesCollection profiles;
   profiles.StartProfiling("", 1);
   ProfileGenerator generator(&profiles);
-  ProfilerEventsProcessor processor(i::Isolate::Current(), &generator);
+  ProfilerEventsProcessor processor(&generator);
   processor.Start();
 
   processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
@@ -236,7 +234,7 @@
   CpuProfilesCollection profiles;
   profiles.StartProfiling("", 1);
   ProfileGenerator generator(&profiles);
-  ProfilerEventsProcessor processor(i::Isolate::Current(), &generator);
+  ProfilerEventsProcessor processor(&generator);
   processor.Start();
 
   processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
@@ -401,5 +399,3 @@
   CHECK_EQ(0, CpuProfiler::GetProfilesCount());
   CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3));
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index d8c1876..73b84b7 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -649,6 +649,7 @@
 
 // Debug event handler which counts the break points which have been hit.
 int break_point_hit_count = 0;
+int break_point_hit_count_deoptimize = 0;
 static void DebugEventBreakPointHitCount(v8::DebugEvent event,
                                          v8::Handle<v8::Object> exec_state,
                                          v8::Handle<v8::Object> event_data,
@@ -725,6 +726,12 @@
         script_data->WriteAscii(last_script_data_hit);
       }
     }
+
+    // Perform a full deoptimization when the specified number of
+    // breaks have been hit.
+    if (break_point_hit_count == break_point_hit_count_deoptimize) {
+      i::Deoptimizer::DeoptimizeAll();
+    }
   } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) {
     const int argc = 1;
     v8::Handle<v8::Value> argv[argc] = { event_data };
@@ -983,12 +990,30 @@
       // Count the number of breaks.
       break_point_hit_count++;
 
+      // Collect the JavsScript stack height if the function frame_count is
+      // compiled.
+      if (!frame_count.IsEmpty()) {
+        static const int kArgc = 1;
+        v8::Handle<v8::Value> argv[kArgc] = { exec_state };
+        // Using exec_state as receiver is just to have a receiver.
+        v8::Handle<v8::Value> result =
+            frame_count->Call(exec_state, kArgc, argv);
+        last_js_stack_height = result->Int32Value();
+      }
+
       // Set the break flag again to come back here as soon as possible.
       v8::Debug::DebugBreak();
+
     } else if (terminate_after_max_break_point_hit) {
       // Terminate execution after the last break if requested.
       v8::V8::TerminateExecution();
     }
+
+    // Perform a full deoptimization when the specified number of
+    // breaks have been hit.
+    if (break_point_hit_count == break_point_hit_count_deoptimize) {
+      i::Deoptimizer::DeoptimizeAll();
+    }
   }
 }
 
@@ -4728,8 +4753,8 @@
 // placing JSON debugger commands in the queue.
 class MessageQueueDebuggerThread : public v8::internal::Thread {
  public:
-  explicit MessageQueueDebuggerThread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "MessageQueueDebuggerThread") { }
+  MessageQueueDebuggerThread()
+      : Thread("MessageQueueDebuggerThread") { }
   void Run();
 };
 
@@ -4832,8 +4857,7 @@
 
 // This thread runs the v8 engine.
 TEST(MessageQueues) {
-  MessageQueueDebuggerThread message_queue_debugger_thread(
-      i::Isolate::Current());
+  MessageQueueDebuggerThread message_queue_debugger_thread;
 
   // Create a V8 environment
   v8::HandleScope scope;
@@ -4980,15 +5004,13 @@
 
 class V8Thread : public v8::internal::Thread {
  public:
-  explicit V8Thread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "V8Thread") { }
+  V8Thread() : Thread("V8Thread") { }
   void Run();
 };
 
 class DebuggerThread : public v8::internal::Thread {
  public:
-  explicit DebuggerThread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "DebuggerThread") { }
+  DebuggerThread() : Thread("DebuggerThread") { }
   void Run();
 };
 
@@ -5032,6 +5054,7 @@
       "\n"
       "foo();\n";
 
+  v8::V8::Initialize();
   v8::HandleScope scope;
   DebugLocalContext env;
   v8::Debug::SetMessageHandler2(&ThreadedMessageHandler);
@@ -5065,8 +5088,8 @@
 
 
 TEST(ThreadedDebugging) {
-  DebuggerThread debugger_thread(i::Isolate::Current());
-  V8Thread v8_thread(i::Isolate::Current());
+  DebuggerThread debugger_thread;
+  V8Thread v8_thread;
 
   // Create a V8 environment
   threaded_debugging_barriers.Initialize();
@@ -5087,16 +5110,14 @@
 
 class BreakpointsV8Thread : public v8::internal::Thread {
  public:
-  explicit BreakpointsV8Thread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "BreakpointsV8Thread") { }
+  BreakpointsV8Thread() : Thread("BreakpointsV8Thread") { }
   void Run();
 };
 
 class BreakpointsDebuggerThread : public v8::internal::Thread {
  public:
-  explicit BreakpointsDebuggerThread(v8::internal::Isolate* isolate,
-                                     bool global_evaluate)
-      : Thread(isolate, "BreakpointsDebuggerThread"),
+  explicit BreakpointsDebuggerThread(bool global_evaluate)
+      : Thread("BreakpointsDebuggerThread"),
         global_evaluate_(global_evaluate) {}
   void Run();
 
@@ -5146,6 +5167,7 @@
   const char* source_2 = "cat(17);\n"
     "cat(19);\n";
 
+  v8::V8::Initialize();
   v8::HandleScope scope;
   DebugLocalContext env;
   v8::Debug::SetMessageHandler2(&BreakpointsMessageHandler);
@@ -5273,9 +5295,8 @@
 void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
   i::FLAG_debugger_auto_break = true;
 
-  BreakpointsDebuggerThread breakpoints_debugger_thread(i::Isolate::Current(),
-      global_evaluate);
-  BreakpointsV8Thread breakpoints_v8_thread(i::Isolate::Current());
+  BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate);
+  BreakpointsV8Thread breakpoints_v8_thread;
 
   // Create a V8 environment
   Barriers stack_allocated_breakpoints_barriers;
@@ -5657,15 +5678,13 @@
 
 class HostDispatchV8Thread : public v8::internal::Thread {
  public:
-  explicit HostDispatchV8Thread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "HostDispatchV8Thread") { }
+  HostDispatchV8Thread() : Thread("HostDispatchV8Thread") { }
   void Run();
 };
 
 class HostDispatchDebuggerThread : public v8::internal::Thread {
  public:
-  explicit HostDispatchDebuggerThread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "HostDispatchDebuggerThread") { }
+  HostDispatchDebuggerThread() : Thread("HostDispatchDebuggerThread") { }
   void Run();
 };
 
@@ -5695,6 +5714,7 @@
     "\n";
   const char* source_2 = "cat(17);\n";
 
+  v8::V8::Initialize();
   v8::HandleScope scope;
   DebugLocalContext env;
 
@@ -5737,9 +5757,8 @@
 
 
 TEST(DebuggerHostDispatch) {
-  HostDispatchDebuggerThread host_dispatch_debugger_thread(
-      i::Isolate::Current());
-  HostDispatchV8Thread host_dispatch_v8_thread(i::Isolate::Current());
+  HostDispatchDebuggerThread host_dispatch_debugger_thread;
+  HostDispatchV8Thread host_dispatch_v8_thread;
   i::FLAG_debugger_auto_break = true;
 
   // Create a V8 environment
@@ -5763,15 +5782,14 @@
 
 class DebugMessageDispatchV8Thread : public v8::internal::Thread {
  public:
-  explicit DebugMessageDispatchV8Thread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "DebugMessageDispatchV8Thread") { }
+  DebugMessageDispatchV8Thread() : Thread("DebugMessageDispatchV8Thread") { }
   void Run();
 };
 
 class DebugMessageDispatchDebuggerThread : public v8::internal::Thread {
  public:
-  explicit DebugMessageDispatchDebuggerThread(v8::internal::Isolate* isolate)
-      : Thread(isolate, "DebugMessageDispatchDebuggerThread") { }
+  DebugMessageDispatchDebuggerThread()
+      : Thread("DebugMessageDispatchDebuggerThread") { }
   void Run();
 };
 
@@ -5784,6 +5802,7 @@
 
 
 void DebugMessageDispatchV8Thread::Run() {
+  v8::V8::Initialize();
   v8::HandleScope scope;
   DebugLocalContext env;
 
@@ -5805,10 +5824,8 @@
 
 
 TEST(DebuggerDebugMessageDispatch) {
-  DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread(
-      i::Isolate::Current());
-  DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread(
-      i::Isolate::Current());
+  DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
+  DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
 
   i::FLAG_debugger_auto_break = true;
 
@@ -5847,7 +5864,6 @@
   // Test starting and stopping the agent without any client connection.
   debugger->StartAgent("test", kPort1);
   debugger->StopAgent();
-
   // Test starting the agent, connecting a client and shutting down the agent
   // with the client connected.
   ok = debugger->StartAgent("test", kPort2);
@@ -5856,6 +5872,12 @@
   i::Socket* client = i::OS::CreateSocket();
   ok = client->Connect("localhost", port2_str);
   CHECK(ok);
+  // It is important to wait for a message from the agent. Otherwise,
+  // we can close the server socket during "accept" syscall, making it failing
+  // (at least on Linux), and the test will work incorrectly.
+  char buf;
+  ok = client->Receive(&buf, 1) == 1;
+  CHECK(ok);
   debugger->StopAgent();
   delete client;
 
@@ -5873,8 +5895,8 @@
 
 class DebuggerAgentProtocolServerThread : public i::Thread {
  public:
-  explicit DebuggerAgentProtocolServerThread(i::Isolate* isolate, int port)
-      : Thread(isolate, "DebuggerAgentProtocolServerThread"),
+  explicit DebuggerAgentProtocolServerThread(int port)
+      : Thread("DebuggerAgentProtocolServerThread"),
         port_(port),
         server_(NULL),
         client_(NULL),
@@ -5939,7 +5961,7 @@
 
   // Create a socket server to receive a debugger agent message.
   DebuggerAgentProtocolServerThread* server =
-      new DebuggerAgentProtocolServerThread(i::Isolate::Current(), kPort);
+      new DebuggerAgentProtocolServerThread(kPort);
   server->Start();
   server->WaitForListening();
 
@@ -7198,29 +7220,38 @@
                                  const char** loop_bodies,
                                  const char* loop_tail) {
   // Receive 100 breaks for each test and then terminate JavaScript execution.
-  static int count = 0;
+  static const int kBreaksPerTest = 100;
 
-  for (int i = 0; loop_bodies[i] != NULL; i++) {
-    count++;
-    max_break_point_hit_count = count * 100;
-    terminate_after_max_break_point_hit = true;
+  for (int i = 0; i < 1 && loop_bodies[i] != NULL; i++) {
+    // Perform a lazy deoptimization after various numbers of breaks
+    // have been hit.
+    for (int j = 0; j < 10; j++) {
+      break_point_hit_count_deoptimize = j;
+      if (j == 10) {
+        break_point_hit_count_deoptimize = kBreaksPerTest;
+      }
 
-    EmbeddedVector<char, 1024> buffer;
-    OS::SNPrintF(buffer,
-                 "function f() {%s%s%s}",
-                 loop_head, loop_bodies[i], loop_tail);
+      break_point_hit_count = 0;
+      max_break_point_hit_count = kBreaksPerTest;
+      terminate_after_max_break_point_hit = true;
 
-    // Function with infinite loop.
-    CompileRun(buffer.start());
+      EmbeddedVector<char, 1024> buffer;
+      OS::SNPrintF(buffer,
+                   "function f() {%s%s%s}",
+                   loop_head, loop_bodies[i], loop_tail);
 
-    // Set the debug break to enter the debugger as soon as possible.
-    v8::Debug::DebugBreak();
+      // Function with infinite loop.
+      CompileRun(buffer.start());
 
-    // Call function with infinite loop.
-    CompileRun("f();");
-    CHECK_EQ(count * 100, break_point_hit_count);
+      // Set the debug break to enter the debugger as soon as possible.
+      v8::Debug::DebugBreak();
 
-    CHECK(!v8::V8::IsExecutionTerminating());
+      // Call function with infinite loop.
+      CompileRun("f();");
+      CHECK_EQ(kBreaksPerTest, break_point_hit_count);
+
+      CHECK(!v8::V8::IsExecutionTerminating());
+    }
   }
 }
 
@@ -7232,6 +7263,9 @@
   // Register a debug event listener which sets the break flag and counts.
   v8::Debug::SetDebugEventListener(DebugEventBreakMax);
 
+  // Create a function for getting the frame count when hitting the break.
+  frame_count = CompileFunction(&env, frame_count_source, "frame_count");
+
   CompileRun("var a = 1;");
   CompileRun("function g() { }");
   CompileRun("function h() { }");
diff --git a/test/cctest/test-func-name-inference.cc b/test/cctest/test-func-name-inference.cc
index e0d99ec..4d993af 100644
--- a/test/cctest/test-func-name-inference.cc
+++ b/test/cctest/test-func-name-inference.cc
@@ -288,19 +288,28 @@
   v8::HandleScope scope;
 
   v8::Handle<v8::Script> script = Compile(
-      "var fun1 = fun2 = function () { return 1; }");
+      "var fun1 = fun2 = function () { return 1; }\n"
+      "var bar1 = bar2 = bar3 = function () { return 2; }\n"
+      "foo1 = foo2 = function () { return 3; }\n"
+      "baz1 = baz2 = baz3 = function () { return 4; }");
   CheckFunctionName(script, "return 1", "fun2");
+  CheckFunctionName(script, "return 2", "bar3");
+  CheckFunctionName(script, "return 3", "foo2");
+  CheckFunctionName(script, "return 4", "baz3");
 }
 
 
-TEST(PassedAsConstructorParameter) {
+TEST(AsConstructorParameter) {
   InitializeVM();
   v8::HandleScope scope;
 
   v8::Handle<v8::Script> script = Compile(
       "function Foo() {}\n"
-      "var foo = new Foo(function() { return 1; })");
+      "var foo = new Foo(function() { return 1; })\n"
+      "var bar = new Foo(function() { return 2; }, function() { return 3; })");
   CheckFunctionName(script, "return 1", "");
+  CheckFunctionName(script, "return 2", "");
+  CheckFunctionName(script, "return 3", "");
 }
 
 
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index d686921..8675a01 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -2,388 +2,15 @@
 //
 // Tests for heap profiler
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 
 #include "cctest.h"
 #include "heap-profiler.h"
 #include "snapshot.h"
-#include "string-stream.h"
 #include "utils-inl.h"
-#include "zone-inl.h"
 #include "../include/v8-profiler.h"
 
 namespace i = v8::internal;
-using i::ClustersCoarser;
-using i::JSObjectsCluster;
-using i::JSObjectsRetainerTree;
-using i::JSObjectsClusterTree;
-using i::RetainerHeapProfile;
-
-
-namespace {
-
-class ConstructorHeapProfileTestHelper : public i::ConstructorHeapProfile {
- public:
-  ConstructorHeapProfileTestHelper()
-    : i::ConstructorHeapProfile(),
-      f_name_(FACTORY->NewStringFromAscii(i::CStrVector("F"))),
-      f_count_(0) {
-  }
-
-  void Call(const JSObjectsCluster& cluster,
-            const i::NumberAndSizeInfo& number_and_size) {
-    if (f_name_->Equals(cluster.constructor())) {
-      CHECK_EQ(f_count_, 0);
-      f_count_ = number_and_size.number();
-      CHECK_GT(f_count_, 0);
-    }
-  }
-
-  int f_count() { return f_count_; }
-
- private:
-  i::Handle<i::String> f_name_;
-  int f_count_;
-};
-
-}  // namespace
-
-
-TEST(ConstructorProfile) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  CompileRun(
-      "function F() {}  // A constructor\n"
-      "var f1 = new F();\n"
-      "var f2 = new F();\n");
-
-  ConstructorHeapProfileTestHelper cons_profile;
-  i::AssertNoAllocation no_alloc;
-  i::HeapIterator iterator;
-  for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
-    cons_profile.CollectStats(obj);
-  CHECK_EQ(0, cons_profile.f_count());
-  cons_profile.PrintStats();
-  CHECK_EQ(2, cons_profile.f_count());
-}
-
-
-static JSObjectsCluster AddHeapObjectToTree(JSObjectsRetainerTree* tree,
-                                            i::String* constructor,
-                                            int instance,
-                                            JSObjectsCluster* ref1 = NULL,
-                                            JSObjectsCluster* ref2 = NULL,
-                                            JSObjectsCluster* ref3 = NULL) {
-  JSObjectsCluster o(constructor, reinterpret_cast<i::Object*>(instance));
-  JSObjectsClusterTree* o_tree = new JSObjectsClusterTree();
-  JSObjectsClusterTree::Locator o_loc;
-  if (ref1 != NULL) o_tree->Insert(*ref1, &o_loc);
-  if (ref2 != NULL) o_tree->Insert(*ref2, &o_loc);
-  if (ref3 != NULL) o_tree->Insert(*ref3, &o_loc);
-  JSObjectsRetainerTree::Locator loc;
-  tree->Insert(o, &loc);
-  loc.set_value(o_tree);
-  return o;
-}
-
-
-static void AddSelfReferenceToTree(JSObjectsRetainerTree* tree,
-                                   JSObjectsCluster* self_ref) {
-  JSObjectsRetainerTree::Locator loc;
-  CHECK(tree->Find(*self_ref, &loc));
-  JSObjectsClusterTree::Locator o_loc;
-  CHECK_NE(NULL, loc.value());
-  loc.value()->Insert(*self_ref, &o_loc);
-}
-
-
-static inline void CheckEqualsHelper(const char* file, int line,
-                                     const char* expected_source,
-                                     const JSObjectsCluster& expected,
-                                     const char* value_source,
-                                     const JSObjectsCluster& value) {
-  if (JSObjectsCluster::Compare(expected, value) != 0) {
-    i::HeapStringAllocator allocator;
-    i::StringStream stream(&allocator);
-    stream.Add("#  Expected: ");
-    expected.DebugPrint(&stream);
-    stream.Add("\n#  Found: ");
-    value.DebugPrint(&stream);
-    V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n%s",
-             expected_source, value_source,
-             *stream.ToCString());
-  }
-}
-
-
-static inline void CheckNonEqualsHelper(const char* file, int line,
-                                     const char* expected_source,
-                                     const JSObjectsCluster& expected,
-                                     const char* value_source,
-                                     const JSObjectsCluster& value) {
-  if (JSObjectsCluster::Compare(expected, value) == 0) {
-    i::HeapStringAllocator allocator;
-    i::StringStream stream(&allocator);
-    stream.Add("# !Expected: ");
-    expected.DebugPrint(&stream);
-    stream.Add("\n#  Found: ");
-    value.DebugPrint(&stream);
-    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s",
-             expected_source, value_source,
-             *stream.ToCString());
-  }
-}
-
-
-TEST(ClustersCoarserSimple) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
-
-  JSObjectsRetainerTree tree;
-  JSObjectsCluster function(HEAP->function_class_symbol());
-  JSObjectsCluster a(*FACTORY->NewStringFromAscii(i::CStrVector("A")));
-  JSObjectsCluster b(*FACTORY->NewStringFromAscii(i::CStrVector("B")));
-
-  // o1 <- Function
-  JSObjectsCluster o1 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function);
-  // o2 <- Function
-  JSObjectsCluster o2 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function);
-  // o3 <- A, B
-  JSObjectsCluster o3 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &a, &b);
-  // o4 <- B, A
-  JSObjectsCluster o4 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x400, &b, &a);
-  // o5 <- A, B, Function
-  JSObjectsCluster o5 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x500,
-                          &a, &b, &function);
-
-  ClustersCoarser coarser;
-  coarser.Process(&tree);
-
-  CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
-  CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4));
-  CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3));
-  CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5));
-}
-
-
-TEST(ClustersCoarserMultipleConstructors) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
-
-  JSObjectsRetainerTree tree;
-  JSObjectsCluster function(HEAP->function_class_symbol());
-
-  // o1 <- Function
-  JSObjectsCluster o1 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function);
-  // a1 <- Function
-  JSObjectsCluster a1 =
-      AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x1000, &function);
-  // o2 <- Function
-  JSObjectsCluster o2 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function);
-  // a2 <- Function
-  JSObjectsCluster a2 =
-      AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x2000, &function);
-
-  ClustersCoarser coarser;
-  coarser.Process(&tree);
-
-  CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
-  CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2));
-}
-
-
-TEST(ClustersCoarserPathsTraversal) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
-
-  JSObjectsRetainerTree tree;
-
-  // On the following graph:
-  //
-  // p
-  //   <- o21 <- o11 <-
-  // q                  o
-  //   <- o22 <- o12 <-
-  // r
-  //
-  // we expect that coarser will deduce equivalences: p ~ q ~ r,
-  // o21 ~ o22, and o11 ~ o12.
-
-  JSObjectsCluster o =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100);
-  JSObjectsCluster o11 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o);
-  JSObjectsCluster o12 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o);
-  JSObjectsCluster o21 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x210, &o11);
-  JSObjectsCluster o22 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x220, &o12);
-  JSObjectsCluster p =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o21);
-  JSObjectsCluster q =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o21, &o22);
-  JSObjectsCluster r =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o22);
-
-  ClustersCoarser coarser;
-  coarser.Process(&tree);
-
-  CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
-  CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o11));
-  CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12));
-  CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22));
-  CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21));
-  CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
-  CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
-  CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
-  CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p));
-  CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p));
-}
-
-
-TEST(ClustersCoarserSelf) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
-
-  JSObjectsRetainerTree tree;
-
-  // On the following graph:
-  //
-  // p (self-referencing)
-  //          <- o1     <-
-  // q (self-referencing)   o
-  //          <- o2     <-
-  // r (self-referencing)
-  //
-  // we expect that coarser will deduce equivalences: p ~ q ~ r, o1 ~ o2;
-
-  JSObjectsCluster o =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100);
-  JSObjectsCluster o1 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o);
-  JSObjectsCluster o2 =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o);
-  JSObjectsCluster p =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o1);
-  AddSelfReferenceToTree(&tree, &p);
-  JSObjectsCluster q =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o1, &o2);
-  AddSelfReferenceToTree(&tree, &q);
-  JSObjectsCluster r =
-      AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o2);
-  AddSelfReferenceToTree(&tree, &r);
-
-  ClustersCoarser coarser;
-  coarser.Process(&tree);
-
-  CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
-  CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o1));
-  CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
-  CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
-  CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
-  CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
-  CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(p));
-}
-
-
-namespace {
-
-class RetainerProfilePrinter : public RetainerHeapProfile::Printer {
- public:
-  RetainerProfilePrinter() : stream_(&allocator_), lines_(100) {}
-
-  void PrintRetainers(const JSObjectsCluster& cluster,
-                      const i::StringStream& retainers) {
-    cluster.Print(&stream_);
-    stream_.Add("%s", *(retainers.ToCString()));
-    stream_.Put('\0');
-  }
-
-  const char* GetRetainers(const char* constructor) {
-    FillLines();
-    const size_t cons_len = strlen(constructor);
-    for (int i = 0; i < lines_.length(); ++i) {
-      if (strncmp(constructor, lines_[i], cons_len) == 0 &&
-          lines_[i][cons_len] == ',') {
-        return lines_[i] + cons_len + 1;
-      }
-    }
-    return NULL;
-  }
-
- private:
-  void FillLines() {
-    if (lines_.length() > 0) return;
-    stream_.Put('\0');
-    stream_str_ = stream_.ToCString();
-    const char* pos = *stream_str_;
-    while (pos != NULL && *pos != '\0') {
-      lines_.Add(pos);
-      pos = strchr(pos, '\0');
-      if (pos != NULL) ++pos;
-    }
-  }
-
-  i::HeapStringAllocator allocator_;
-  i::StringStream stream_;
-  i::SmartPointer<const char> stream_str_;
-  i::List<const char*> lines_;
-};
-
-}  // namespace
-
-
-TEST(RetainerProfile) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  CompileRun(
-      "function A() {}\n"
-      "function B(x) { this.x = x; }\n"
-      "function C(x) { this.x1 = x; this.x2 = x; }\n"
-      "var a = new A();\n"
-      "var b1 = new B(a), b2 = new B(a);\n"
-      "var c = new C(a);");
-
-  RetainerHeapProfile ret_profile;
-  i::AssertNoAllocation no_alloc;
-  i::HeapIterator iterator;
-  for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
-    ret_profile.CollectStats(obj);
-  ret_profile.CoarseAndAggregate();
-  RetainerProfilePrinter printer;
-  ret_profile.DebugPrintStats(&printer);
-  const char* retainers_of_a = printer.GetRetainers("A");
-  // The order of retainers is unspecified, so we check string length, and
-  // verify each retainer separately.
-  CHECK_EQ(i::StrLength("(global property);1,B;2,C;2"),
-           i::StrLength(retainers_of_a));
-  CHECK(strstr(retainers_of_a, "(global property);1") != NULL);
-  CHECK(strstr(retainers_of_a, "B;2") != NULL);
-  CHECK(strstr(retainers_of_a, "C;2") != NULL);
-  CHECK_EQ("(global property);2", printer.GetRetainers("B"));
-  CHECK_EQ("(global property);1", printer.GetRetainers("C"));
-}
-
 
 namespace {
 
@@ -416,8 +43,8 @@
   CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount());
   const v8::HeapGraphNode* global_obj =
       snapshot->GetRoot()->GetChild(0)->GetToNode();
-  CHECK_EQ("Object", const_cast<i::HeapEntry*>(
-      reinterpret_cast<const i::HeapEntry*>(global_obj))->name());
+  CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>(
+      reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6));
   return global_obj;
 }
 
@@ -726,116 +353,6 @@
 }
 
 
-static const v8::HeapGraphNode* GetChild(
-    const v8::HeapGraphNode* node,
-    v8::HeapGraphNode::Type type,
-    const char* name,
-    const v8::HeapGraphNode* after = NULL) {
-  bool ignore_child = after == NULL ? false : true;
-  for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
-    const v8::HeapGraphEdge* prop = node->GetChild(i);
-    const v8::HeapGraphNode* child = prop->GetToNode();
-    v8::String::AsciiValue child_name(child->GetName());
-    if (!ignore_child
-        && child->GetType() == type
-        && strcmp(name, *child_name) == 0)
-      return child;
-    if (after != NULL && child == after) ignore_child = false;
-  }
-  return NULL;
-}
-
-static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
-                             int element) {
-  for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
-    const v8::HeapGraphEdge* prop = node->GetRetainer(i);
-    if (prop->GetType() == v8::HeapGraphEdge::kElement
-        && element == prop->GetName()->Int32Value())
-      return true;
-  }
-  return false;
-}
-
-TEST(AggregatedHeapSnapshot) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  CompileRun(
-      "function A() {}\n"
-      "function B(x) { this.x = x; }\n"
-      "var a = new A();\n"
-      "var b = new B(a);");
-  const v8::HeapSnapshot* snapshot =
-      v8::HeapProfiler::TakeSnapshot(
-          v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
-  const v8::HeapGraphNode* strings = GetChild(snapshot->GetRoot(),
-                                              v8::HeapGraphNode::kHidden,
-                                              "STRING_TYPE");
-  CHECK_NE(NULL, strings);
-  CHECK_NE(0, strings->GetSelfSize());
-  CHECK_NE(0, strings->GetInstancesCount());
-  const v8::HeapGraphNode* maps = GetChild(snapshot->GetRoot(),
-                                           v8::HeapGraphNode::kHidden,
-                                           "MAP_TYPE");
-  CHECK_NE(NULL, maps);
-  CHECK_NE(0, maps->GetSelfSize());
-  CHECK_NE(0, maps->GetInstancesCount());
-
-  const v8::HeapGraphNode* a = GetChild(snapshot->GetRoot(),
-                                        v8::HeapGraphNode::kObject,
-                                        "A");
-  CHECK_NE(NULL, a);
-  CHECK_NE(0, a->GetSelfSize());
-  CHECK_EQ(1, a->GetInstancesCount());
-
-  const v8::HeapGraphNode* b = GetChild(snapshot->GetRoot(),
-                                        v8::HeapGraphNode::kObject,
-                                        "B");
-  CHECK_NE(NULL, b);
-  CHECK_NE(0, b->GetSelfSize());
-  CHECK_EQ(1, b->GetInstancesCount());
-
-  const v8::HeapGraphNode* glob_prop = GetChild(snapshot->GetRoot(),
-                                                v8::HeapGraphNode::kObject,
-                                                "(global property)",
-                                                b);
-  CHECK_NE(NULL, glob_prop);
-  CHECK_EQ(0, glob_prop->GetSelfSize());
-  CHECK_EQ(0, glob_prop->GetInstancesCount());
-  CHECK_NE(0, glob_prop->GetChildrenCount());
-
-  const v8::HeapGraphNode* a_from_glob_prop = GetChild(
-      glob_prop,
-      v8::HeapGraphNode::kObject,
-      "A");
-  CHECK_NE(NULL, a_from_glob_prop);
-  CHECK_EQ(0, a_from_glob_prop->GetSelfSize());
-  CHECK_EQ(0, a_from_glob_prop->GetInstancesCount());
-  CHECK_EQ(0, a_from_glob_prop->GetChildrenCount());  // Retains nothing.
-  CHECK(IsNodeRetainedAs(a_from_glob_prop, 1));  // (global propery) has 1 ref.
-
-  const v8::HeapGraphNode* b_with_children = GetChild(
-      snapshot->GetRoot(),
-      v8::HeapGraphNode::kObject,
-      "B",
-      b);
-  CHECK_NE(NULL, b_with_children);
-  CHECK_EQ(0, b_with_children->GetSelfSize());
-  CHECK_EQ(0, b_with_children->GetInstancesCount());
-  CHECK_NE(0, b_with_children->GetChildrenCount());
-
-  const v8::HeapGraphNode* a_from_b = GetChild(
-      b_with_children,
-      v8::HeapGraphNode::kObject,
-      "A");
-  CHECK_NE(NULL, a_from_b);
-  CHECK_EQ(0, a_from_b->GetSelfSize());
-  CHECK_EQ(0, a_from_b->GetInstancesCount());
-  CHECK_EQ(0, a_from_b->GetChildrenCount());  // Retains nothing.
-  CHECK(IsNodeRetainedAs(a_from_b, 1));  // B has 1 ref to A.
-}
-
-
 TEST(HeapEntryDominator) {
   // The graph looks like this:
   //
@@ -1048,21 +565,6 @@
 }
 
 
-// Must not crash in debug mode.
-TEST(AggregatedHeapSnapshotJSONSerialization) {
-  v8::HandleScope scope;
-  LocalContext env;
-
-  const v8::HeapSnapshot* snapshot =
-      v8::HeapProfiler::TakeSnapshot(
-          v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
-  TestJSONStream stream;
-  snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
-  CHECK_GT(stream.size(), 0);
-  CHECK_EQ(1, stream.eos_signaled());
-}
-
-
 TEST(HeapSnapshotGetNodeById) {
   v8::HandleScope scope;
   LocalContext env;
@@ -1322,4 +824,70 @@
   CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3));
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
+
+TEST(DocumentURL) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  CompileRun("document = { URL:\"abcdefgh\" };");
+
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("document"));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  CHECK_NE(NULL, global);
+  CHECK_EQ("Object / abcdefgh",
+           const_cast<i::HeapEntry*>(
+               reinterpret_cast<const i::HeapEntry*>(global))->name());
+}
+
+
+TEST(DocumentWithException) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  CompileRun(
+      "this.__defineGetter__(\"document\", function() { throw new Error(); })");
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("document"));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  CHECK_NE(NULL, global);
+  CHECK_EQ("Object",
+           const_cast<i::HeapEntry*>(
+               reinterpret_cast<const i::HeapEntry*>(global))->name());
+}
+
+
+TEST(DocumentURLWithException) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  CompileRun(
+      "function URLWithException() {}\n"
+      "URLWithException.prototype = { get URL() { throw new Error(); } };\n"
+      "document = { URL: new URLWithException() };");
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("document"));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  CHECK_NE(NULL, global);
+  CHECK_EQ("Object",
+           const_cast<i::HeapEntry*>(
+               reinterpret_cast<const i::HeapEntry*>(global))->name());
+}
+
+
+TEST(NodesIteration) {
+  v8::HandleScope scope;
+  LocalContext env;
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("iteration"));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  CHECK_NE(NULL, global);
+  // Verify that we can find this object by iteration.
+  const int nodes_count = snapshot->GetNodesCount();
+  int count = 0;
+  for (int i = 0; i < nodes_count; ++i) {
+    if (snapshot->GetNode(i) == global)
+      ++count;
+  }
+  CHECK_EQ(1, count);
+}
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 09aa613..fac9f0a 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -675,7 +675,7 @@
   CHECK(array->HasFastElements());  // Must be in fast mode.
 
   // array[length] = name.
-  ok = array->SetElement(0, *name, kNonStrictMode)->ToObjectChecked();
+  ok = array->SetElement(0, *name, kNonStrictMode, true)->ToObjectChecked();
   CHECK_EQ(Smi::FromInt(1), array->length());
   CHECK_EQ(array->GetElement(0), *name);
 
@@ -690,7 +690,8 @@
   CHECK(array->HasDictionaryElements());  // Must be in slow mode.
 
   // array[length] = name.
-  ok = array->SetElement(int_length, *name, kNonStrictMode)->ToObjectChecked();
+  ok = array->SetElement(
+      int_length, *name, kNonStrictMode, true)->ToObjectChecked();
   uint32_t new_int_length = 0;
   CHECK(array->length()->ToArrayIndex(&new_int_length));
   CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
@@ -717,9 +718,10 @@
   obj->SetProperty(
       *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
 
-  Object* ok = obj->SetElement(0, *first, kNonStrictMode)->ToObjectChecked();
+  Object* ok =
+      obj->SetElement(0, *first, kNonStrictMode, true)->ToObjectChecked();
 
-  ok = obj->SetElement(1, *second, kNonStrictMode)->ToObjectChecked();
+  ok = obj->SetElement(1, *second, kNonStrictMode, true)->ToObjectChecked();
 
   // Make the clone.
   Handle<JSObject> clone = Copy(obj);
@@ -737,8 +739,8 @@
   clone->SetProperty(
       *second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
 
-  ok = clone->SetElement(0, *second, kNonStrictMode)->ToObjectChecked();
-  ok = clone->SetElement(1, *first, kNonStrictMode)->ToObjectChecked();
+  ok = clone->SetElement(0, *second, kNonStrictMode, true)->ToObjectChecked();
+  ok = clone->SetElement(1, *first, kNonStrictMode, true)->ToObjectChecked();
 
   CHECK_EQ(obj->GetElement(1), clone->GetElement(0));
   CHECK_EQ(obj->GetElement(0), clone->GetElement(1));
diff --git a/test/cctest/test-liveedit.cc b/test/cctest/test-liveedit.cc
index 1086af0..2498fca 100644
--- a/test/cctest/test-liveedit.cc
+++ b/test/cctest/test-liveedit.cc
@@ -44,13 +44,13 @@
  public:
   StringCompareInput(const char* s1, const char* s2) : s1_(s1), s2_(s2) {
   }
-  int getLength1() {
+  int GetLength1() {
     return StrLength(s1_);
   }
-  int getLength2() {
+  int GetLength2() {
     return StrLength(s2_);
   }
-  bool equals(int index1, int index2) {
+  bool Equals(int index1, int index2) {
     return s1_[index1] == s2_[index2];
   }
 
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index 5b33f2e..2b184e9 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -64,7 +64,7 @@
  public:
   KangarooThread(v8::Isolate* isolate,
                  v8::Handle<v8::Context> context, int value)
-      : Thread(NULL, "KangarooThread"),
+      : Thread("KangarooThread"),
         isolate_(isolate), context_(context), value_(value) {
   }
 
@@ -150,7 +150,7 @@
   class ThreadWithSemaphore : public i::Thread {
    public:
     explicit ThreadWithSemaphore(JoinableThread* joinable_thread)
-      : Thread(NULL, joinable_thread->name_),
+      : Thread(joinable_thread->name_),
         joinable_thread_(joinable_thread) {
     }
 
@@ -314,7 +314,11 @@
 
 // Run parallel threads that lock and access different isolates in parallel
 TEST(SeparateIsolatesLocksNonexclusive) {
+#ifdef V8_TARGET_ARCH_ARM
+  const int kNThreads = 50;
+#else
   const int kNThreads = 100;
+#endif
   v8::Isolate* isolate1 = v8::Isolate::New();
   v8::Isolate* isolate2 = v8::Isolate::New();
   i::List<JoinableThread*> threads(kNThreads);
@@ -383,7 +387,11 @@
 
 // Use unlocker inside of a Locker, multiple threads.
 TEST(LockerUnlocker) {
+#ifdef V8_TARGET_ARCH_ARM
+  const int kNThreads = 50;
+#else
   const int kNThreads = 100;
+#endif
   i::List<JoinableThread*> threads(kNThreads);
   v8::Isolate* isolate = v8::Isolate::New();
   for (int i = 0; i < kNThreads; i++) {
@@ -431,7 +439,11 @@
 
 // Use Unlocker inside two Lockers.
 TEST(LockTwiceAndUnlock) {
+#ifdef V8_TARGET_ARCH_ARM
+  const int kNThreads = 50;
+#else
   const int kNThreads = 100;
+#endif
   i::List<JoinableThread*> threads(kNThreads);
   v8::Isolate* isolate = v8::Isolate::New();
   for (int i = 0; i < kNThreads; i++) {
@@ -607,3 +619,23 @@
   }
   StartJoinAndDeleteThreads(threads);
 }
+
+
+TEST(Regress1433) {
+  for (int i = 0; i < 10; i++) {
+    v8::Isolate* isolate = v8::Isolate::New();
+    {
+      v8::Locker lock(isolate);
+      v8::Isolate::Scope isolate_scope(isolate);
+      v8::HandleScope handle_scope;
+      v8::Persistent<Context> context = v8::Context::New();
+      v8::Context::Scope context_scope(context);
+      v8::Handle<String> source = v8::String::New("1+1");
+      v8::Handle<Script> script = v8::Script::Compile(source);
+      v8::Handle<Value> result = script->Run();
+      v8::String::AsciiValue ascii(result);
+      context.Dispose();
+    }
+    isolate->Dispose();
+  }
+}
diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc
index b967c73..2bcb3fe 100644
--- a/test/cctest/test-log-stack-tracer.cc
+++ b/test/cctest/test-log-stack-tracer.cc
@@ -27,8 +27,6 @@
 //
 // Tests of profiler-related functions from log.h
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include <stdlib.h>
 
 #include "v8.h"
@@ -413,5 +411,3 @@
   CompileRun("js_entry_sp_level2();");
   CHECK_EQ(0, GetJsEntrySp());
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-log-utils.cc b/test/cctest/test-log-utils.cc
deleted file mode 100644
index 861be12..0000000
--- a/test/cctest/test-log-utils.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
-//
-// Tests of logging utilities from log-utils.h
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-#include "v8.h"
-
-#include "log-utils.h"
-#include "cctest.h"
-
-using v8::internal::CStrVector;
-using v8::internal::EmbeddedVector;
-using v8::internal::LogDynamicBuffer;
-using v8::internal::MutableCStrVector;
-using v8::internal::ScopedVector;
-using v8::internal::Vector;
-using v8::internal::StrLength;
-
-// Fills 'ref_buffer' with test data: a sequence of two-digit
-// hex numbers: '0001020304...'. Then writes 'ref_buffer' contents to 'dynabuf'.
-static void WriteData(LogDynamicBuffer* dynabuf, Vector<char>* ref_buffer) {
-  static const char kHex[] = "0123456789ABCDEF";
-  CHECK_GT(ref_buffer->length(), 0);
-  CHECK_GT(513, ref_buffer->length());
-  for (int i = 0, half_len = ref_buffer->length() >> 1; i < half_len; ++i) {
-    (*ref_buffer)[i << 1] = kHex[i >> 4];
-    (*ref_buffer)[(i << 1) + 1] = kHex[i & 15];
-  }
-  if (ref_buffer->length() & 1) {
-    ref_buffer->last() = kHex[ref_buffer->length() >> 5];
-  }
-  CHECK_EQ(ref_buffer->length(),
-           dynabuf->Write(ref_buffer->start(), ref_buffer->length()));
-}
-
-
-static int ReadData(
-    LogDynamicBuffer* dynabuf, int start_pos, i::Vector<char>* buffer) {
-  return dynabuf->Read(start_pos, buffer->start(), buffer->length());
-}
-
-
-// Helper function used by CHECK_EQ to compare Vectors. Templatized to
-// accept both "char" and "const char" vector contents.
-template <typename E, typename V>
-static inline void CheckEqualsHelper(const char* file, int line,
-                                     const char* expected_source,
-                                     const Vector<E>& expected,
-                                     const char* value_source,
-                                     const Vector<V>& value) {
-  if (expected.length() != value.length()) {
-    V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
-             "#   Vectors lengths differ: %d expected, %d found\n"
-             "#   Expected: %.*s\n"
-             "#   Found: %.*s",
-             expected_source, value_source,
-             expected.length(), value.length(),
-             expected.length(), expected.start(),
-             value.length(), value.start());
-  }
-  if (strncmp(expected.start(), value.start(), expected.length()) != 0) {
-    V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
-             "#   Vectors contents differ:\n"
-             "#   Expected: %.*s\n"
-             "#   Found: %.*s",
-             expected_source, value_source,
-             expected.length(), expected.start(),
-             value.length(), value.start());
-  }
-}
-
-
-TEST(DynaBufSingleBlock) {
-  LogDynamicBuffer dynabuf(32, 32, "", 0);
-  EmbeddedVector<char, 32> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  EmbeddedVector<char, 32> buf;
-  CHECK_EQ(32, dynabuf.Read(0, buf.start(), buf.length()));
-  CHECK_EQ(32, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-
-  // Verify that we can't read and write past the end.
-  CHECK_EQ(0, dynabuf.Read(32, buf.start(), buf.length()));
-  CHECK_EQ(0, dynabuf.Write(buf.start(), buf.length()));
-}
-
-
-TEST(DynaBufCrossBlocks) {
-  LogDynamicBuffer dynabuf(32, 128, "", 0);
-  EmbeddedVector<char, 48> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  CHECK_EQ(48, dynabuf.Write(ref_buf.start(), ref_buf.length()));
-  // Verify that we can't write data when remaining buffer space isn't enough.
-  CHECK_EQ(0, dynabuf.Write(ref_buf.start(), ref_buf.length()));
-  EmbeddedVector<char, 48> buf;
-  CHECK_EQ(48, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-  CHECK_EQ(48, ReadData(&dynabuf, 48, &buf));
-  CHECK_EQ(ref_buf, buf);
-  CHECK_EQ(0, ReadData(&dynabuf, 48 * 2, &buf));
-}
-
-
-TEST(DynaBufReadTruncation) {
-  LogDynamicBuffer dynabuf(32, 128, "", 0);
-  EmbeddedVector<char, 128> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  EmbeddedVector<char, 128> buf;
-  CHECK_EQ(128, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-  // Try to read near the end with a buffer larger than remaining data size.
-  EmbeddedVector<char, 48> tail_buf;
-  CHECK_EQ(32, ReadData(&dynabuf, 128 - 32, &tail_buf));
-  CHECK_EQ(ref_buf.SubVector(128 - 32, 128), tail_buf.SubVector(0, 32));
-}
-
-
-TEST(DynaBufSealing) {
-  const char* seal = "Sealed";
-  const int seal_size = StrLength(seal);
-  LogDynamicBuffer dynabuf(32, 128, seal, seal_size);
-  EmbeddedVector<char, 100> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  // Try to write data that will not fit in the buffer.
-  CHECK_EQ(0, dynabuf.Write(ref_buf.start(), 128 - 100 - seal_size + 1));
-  // Now the buffer is sealed, writing of any amount of data is forbidden.
-  CHECK_EQ(0, dynabuf.Write(ref_buf.start(), 1));
-  EmbeddedVector<char, 100> buf;
-  CHECK_EQ(100, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-  // Check the seal.
-  EmbeddedVector<char, 50> seal_buf;
-  CHECK_EQ(seal_size, ReadData(&dynabuf, 100, &seal_buf));
-  CHECK_EQ(CStrVector(seal), seal_buf.SubVector(0, seal_size));
-  // Verify that there's no data beyond the seal.
-  CHECK_EQ(0, ReadData(&dynabuf, 100 + seal_size, &buf));
-}
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index 17c7387..262e7bb 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -2,8 +2,6 @@
 //
 // Tests of logging functions from log.h
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #ifdef __linux__
 #include <math.h>
 #include <pthread.h>
@@ -14,7 +12,9 @@
 #include "v8.h"
 #include "log.h"
 #include "cpu-profiler.h"
+#include "natives.h"
 #include "v8threads.h"
+#include "v8utils.h"
 #include "cctest.h"
 #include "vm-state-inl.h"
 
@@ -25,269 +25,75 @@
 
 namespace i = v8::internal;
 
-static void SetUp() {
-  // Log to memory buffer.
-  i::FLAG_logfile = "*";
-  i::FLAG_log = true;
-  LOGGER->Setup();
-}
-
-static void TearDown() {
-  LOGGER->TearDown();
-}
-
-
-TEST(EmptyLog) {
-  SetUp();
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 100));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 100));
-  TearDown();
-}
-
-
-TEST(GetMessages) {
-  SetUp();
-  LOGGER->StringEvent("aaa", "bbb");
-  LOGGER->StringEvent("cccc", "dddd");
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
-  char log_lines[100];
-  memset(log_lines, 0, sizeof(log_lines));
-  // See Logger::StringEvent.
-  const char* line_1 = "aaa,\"bbb\"\n";
-  const int line_1_len = StrLength(line_1);
-  // The exact size.
-  CHECK_EQ(line_1_len, LOGGER->GetLogLines(0, log_lines, line_1_len));
-  CHECK_EQ(line_1, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  // A bit more than the first line length.
-  CHECK_EQ(line_1_len, LOGGER->GetLogLines(0, log_lines, line_1_len + 3));
-  log_lines[line_1_len] = '\0';
-  CHECK_EQ(line_1, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  const char* line_2 = "cccc,\"dddd\"\n";
-  const int line_2_len = StrLength(line_2);
-  // Now start with line_2 beginning.
-  CHECK_EQ(0, LOGGER->GetLogLines(line_1_len, log_lines, 0));
-  CHECK_EQ(line_2_len, LOGGER->GetLogLines(line_1_len, log_lines, line_2_len));
-  CHECK_EQ(line_2, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  CHECK_EQ(line_2_len,
-           LOGGER->GetLogLines(line_1_len, log_lines, line_2_len + 3));
-  CHECK_EQ(line_2, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  // Now get entire buffer contents.
-  const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n";
-  const int all_lines_len = StrLength(all_lines);
-  CHECK_EQ(all_lines_len, LOGGER->GetLogLines(0, log_lines, all_lines_len));
-  CHECK_EQ(all_lines, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  CHECK_EQ(all_lines_len, LOGGER->GetLogLines(0, log_lines, all_lines_len + 3));
-  CHECK_EQ(all_lines, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  TearDown();
-}
-
-
-static int GetLogLines(int start_pos, i::Vector<char>* buffer) {
-  return LOGGER->GetLogLines(start_pos, buffer->start(), buffer->length());
-}
-
-
-TEST(BeyondWritePosition) {
-  SetUp();
-  LOGGER->StringEvent("aaa", "bbb");
-  LOGGER->StringEvent("cccc", "dddd");
-  // See Logger::StringEvent.
-  const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n";
-  const int all_lines_len = StrLength(all_lines);
-  EmbeddedVector<char, 100> buffer;
-  const int beyond_write_pos = all_lines_len;
-  CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(beyond_write_pos, &buffer));
-  CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos + 1, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(beyond_write_pos + 1, &buffer));
-  CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos + 100, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(beyond_write_pos + 100, &buffer));
-  CHECK_EQ(0, LOGGER->GetLogLines(10 * 1024 * 1024, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(10 * 1024 * 1024, &buffer));
-  TearDown();
-}
-
-
-TEST(MemoryLoggingTurnedOff) {
-  // Log to stdout
-  i::FLAG_logfile = "-";
-  i::FLAG_log = true;
-  LOGGER->Setup();
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 100));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 100));
-  LOGGER->TearDown();
-}
-
-
-static void CompileAndRunScript(const char *src) {
-  v8::Script::Compile(v8::String::New(src))->Run();
-}
-
-
-namespace v8 {
-namespace internal {
-
-class LoggerTestHelper : public AllStatic {
- public:
-  static bool IsSamplerActive() { return LOGGER->IsProfilerSamplerActive(); }
-  static void ResetSamplesTaken() {
-    reinterpret_cast<Sampler*>(LOGGER->ticker_)->ResetSamplesTaken();
-  }
-  static bool has_samples_taken() {
-    return reinterpret_cast<Sampler*>(LOGGER->ticker_)->samples_taken() > 0;
-  }
-};
-
-}  // namespace v8::internal
-}  // namespace v8
-
-using v8::internal::LoggerTestHelper;
-
-
 namespace {
 
 class ScopedLoggerInitializer {
  public:
   explicit ScopedLoggerInitializer(bool prof_lazy)
-      : saved_prof_lazy_(i::FLAG_prof_lazy),
+      : saved_log_(i::FLAG_log),
+        saved_prof_lazy_(i::FLAG_prof_lazy),
         saved_prof_(i::FLAG_prof),
         saved_prof_auto_(i::FLAG_prof_auto),
+        temp_file_(NULL),
+        // Need to run this prior to creating the scope.
         trick_to_run_init_flags_(init_flags_(prof_lazy)),
-        need_to_set_up_logger_(i::V8::IsRunning()),
         scope_(),
         env_(v8::Context::New()) {
-    if (need_to_set_up_logger_) LOGGER->Setup();
     env_->Enter();
   }
 
   ~ScopedLoggerInitializer() {
     env_->Exit();
     LOGGER->TearDown();
+    if (temp_file_ != NULL) fclose(temp_file_);
     i::FLAG_prof_lazy = saved_prof_lazy_;
     i::FLAG_prof = saved_prof_;
     i::FLAG_prof_auto = saved_prof_auto_;
+    i::FLAG_log = saved_log_;
   }
 
   v8::Handle<v8::Context>& env() { return env_; }
 
+  FILE* StopLoggingGetTempFile() {
+    temp_file_ = LOGGER->TearDown();
+    CHECK_NE(NULL, temp_file_);
+    fflush(temp_file_);
+    rewind(temp_file_);
+    return temp_file_;
+  }
+
  private:
   static bool init_flags_(bool prof_lazy) {
+    i::FLAG_log = true;
     i::FLAG_prof = true;
     i::FLAG_prof_lazy = prof_lazy;
     i::FLAG_prof_auto = false;
-    i::FLAG_logfile = "*";
+    i::FLAG_logfile = i::Log::kLogToTemporaryFile;
     return prof_lazy;
   }
 
+  const bool saved_log_;
   const bool saved_prof_lazy_;
   const bool saved_prof_;
   const bool saved_prof_auto_;
+  FILE* temp_file_;
   const bool trick_to_run_init_flags_;
-  const bool need_to_set_up_logger_;
   v8::HandleScope scope_;
   v8::Handle<v8::Context> env_;
 
   DISALLOW_COPY_AND_ASSIGN(ScopedLoggerInitializer);
 };
 
-
-class LogBufferMatcher {
- public:
-  LogBufferMatcher() {
-    // Skip all initially logged stuff.
-    log_pos_ = GetLogLines(0, &buffer_);
-  }
-
-  int log_pos() { return log_pos_; }
-
-  int GetNextChunk() {
-    int chunk_size = GetLogLines(log_pos_, &buffer_);
-    CHECK_GT(buffer_.length(), chunk_size);
-    buffer_[chunk_size] = '\0';
-    log_pos_ += chunk_size;
-    return chunk_size;
-  }
-
-  const char* Find(const char* substr) {
-    return strstr(buffer_.start(), substr);
-  }
-
-  const char* Find(const i::Vector<char>& substr) {
-    return Find(substr.start());
-  }
-
-  bool IsInSequence(const char* s1, const char* s2) {
-    const char* s1_pos = Find(s1);
-    const char* s2_pos = Find(s2);
-    CHECK_NE(NULL, s1_pos);
-    CHECK_NE(NULL, s2_pos);
-    return s1_pos < s2_pos;
-  }
-
-  void PrintBuffer() {
-    puts(buffer_.start());
-  }
-
- private:
-  EmbeddedVector<char, 102400> buffer_;
-  int log_pos_;
-};
-
 }  // namespace
 
 
-static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
-  CHECK(i::RuntimeProfiler::IsEnabled() ||
-        !LoggerTestHelper::IsSamplerActive());
-  LoggerTestHelper::ResetSamplesTaken();
-
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
-  CHECK(LoggerTestHelper::IsSamplerActive());
-
-  // Verify that the current map of compiled functions has been logged.
-  CHECK_GT(matcher->GetNextChunk(), 0);
-  const char* code_creation = "\ncode-creation,";  // eq. to /^code-creation,/
-  CHECK_NE(NULL, matcher->Find(code_creation));
-
-  // Force compiler to generate new code by parametrizing source.
-  EmbeddedVector<char, 100> script_src;
-  i::OS::SNPrintF(script_src,
-                  "function f%d(x) { return %d * x; }"
-                  "for (var i = 0; i < 10000; ++i) { f%d(i); }",
-                  matcher->log_pos(), matcher->log_pos(), matcher->log_pos());
-  // Run code for 200 msecs to get some ticks.
-  const double end_time = i::OS::TimeCurrentMillis() + 200;
-  while (i::OS::TimeCurrentMillis() < end_time) {
-    CompileAndRunScript(script_src.start());
-    // Yield CPU to give Profiler thread a chance to process ticks.
-    i::OS::Sleep(1);
-  }
-
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
-  CHECK(i::RuntimeProfiler::IsEnabled() ||
-        !LoggerTestHelper::IsSamplerActive());
-
-  // Wait 50 msecs to allow Profiler thread to process the last
-  // tick sample it has got.
-  i::OS::Sleep(50);
-
-  // Now we must have compiler and tick records.
-  CHECK_GT(matcher->GetNextChunk(), 0);
-  matcher->PrintBuffer();
-  CHECK_NE(NULL, matcher->Find(code_creation));
-  const char* tick = "\ntick,";
-  const bool ticks_found = matcher->Find(tick) != NULL;
-  CHECK_EQ(LoggerTestHelper::has_samples_taken(), ticks_found);
+static const char* StrNStr(const char* s1, const char* s2, int n) {
+  if (s1[n] == '\0') return strstr(s1, s2);
+  i::ScopedVector<char> str(n + 1);
+  i::OS::StrNCpy(str, s1, static_cast<size_t>(n));
+  str[n] = '\0';
+  char* found = strstr(str.start(), s2);
+  return found != NULL ? s1 + (found - str.start()) : NULL;
 }
 
 
@@ -296,29 +102,61 @@
 
   if (!i::V8::UseCrankshaft()) return;
 
-  // No sampling should happen prior to resuming profiler unless we
-  // are runtime profiling.
-  CHECK(i::RuntimeProfiler::IsEnabled() ||
-        !LoggerTestHelper::IsSamplerActive());
-
-  LogBufferMatcher matcher;
-  // Nothing must be logged until profiling is resumed.
-  CHECK_EQ(0, matcher.log_pos());
-
-  CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
-
-  // Nothing must be logged while profiling is suspended.
-  CHECK_EQ(0, matcher.GetNextChunk());
-
-  CheckThatProfilerWorks(&matcher);
-
-  CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
-
-  // No new data beyond last retrieved position.
-  CHECK_EQ(0, matcher.GetNextChunk());
-
+  LOGGER->StringEvent("test-start", "");
+  CompileRun("var a = (function(x) { return x + 1; })(10);");
+  LOGGER->StringEvent("test-profiler-start", "");
+  v8::V8::ResumeProfiler();
+  CompileRun(
+      "var b = (function(x) { return x + 2; })(10);\n"
+      "var c = (function(x) { return x + 3; })(10);\n"
+      "var d = (function(x) { return x + 4; })(10);\n"
+      "var e = (function(x) { return x + 5; })(10);");
+  v8::V8::PauseProfiler();
+  LOGGER->StringEvent("test-profiler-stop", "");
+  CompileRun("var f = (function(x) { return x + 6; })(10);");
   // Check that profiling can be resumed again.
-  CheckThatProfilerWorks(&matcher);
+  LOGGER->StringEvent("test-profiler-start-2", "");
+  v8::V8::ResumeProfiler();
+  CompileRun(
+      "var g = (function(x) { return x + 7; })(10);\n"
+      "var h = (function(x) { return x + 8; })(10);\n"
+      "var i = (function(x) { return x + 9; })(10);\n"
+      "var j = (function(x) { return x + 10; })(10);");
+  v8::V8::PauseProfiler();
+  LOGGER->StringEvent("test-profiler-stop-2", "");
+  LOGGER->StringEvent("test-stop", "");
+
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
+
+  const char* test_start_position =
+      StrNStr(log.start(), "test-start,", log.length());
+  CHECK_NE(NULL, test_start_position);
+  const char* test_profiler_start_position =
+      StrNStr(log.start(), "test-profiler-start,", log.length());
+  CHECK_NE(NULL, test_profiler_start_position);
+  CHECK_GT(test_profiler_start_position, test_start_position);
+  const char* test_profiler_stop_position =
+      StrNStr(log.start(), "test-profiler-stop,", log.length());
+  CHECK_NE(NULL, test_profiler_stop_position);
+  CHECK_GT(test_profiler_stop_position, test_profiler_start_position);
+  const char* test_profiler_start_2_position =
+      StrNStr(log.start(), "test-profiler-start-2,", log.length());
+  CHECK_NE(NULL, test_profiler_start_2_position);
+  CHECK_GT(test_profiler_start_2_position, test_profiler_stop_position);
+
+  // Nothing must be logged until profiling is resumed.
+  CHECK_EQ(NULL, StrNStr(test_start_position,
+                         "code-creation,",
+                         static_cast<int>(test_profiler_start_position -
+                                          test_start_position)));
+  // Nothing must be logged while profiling is suspended.
+  CHECK_EQ(NULL, StrNStr(test_profiler_stop_position,
+                         "code-creation,",
+                         static_cast<int>(test_profiler_start_2_position -
+                                          test_profiler_stop_position)));
 }
 
 
@@ -383,7 +221,7 @@
       {
         v8::Context::Scope context_scope(context);
         SignalRunning();
-        CompileAndRunScript(
+        CompileRun(
             "var j; for (var i=0; i<10000; ++i) { j = Math.sin(i); }");
       }
       context.Dispose();
@@ -531,34 +369,34 @@
 
 TEST(LogCallbacks) {
   ScopedLoggerInitializer initialize_logger(false);
-  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
-  obj->SetClassName(v8::String::New("Obj"));
+  obj->SetClassName(v8_str("Obj"));
   v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate();
   v8::Local<v8::Signature> signature = v8::Signature::New(obj);
-  proto->Set(v8::String::New("method1"),
+  proto->Set(v8_str("method1"),
              v8::FunctionTemplate::New(ObjMethod1,
                                        v8::Handle<v8::Value>(),
                                        signature),
              static_cast<v8::PropertyAttribute>(v8::DontDelete));
 
   initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
-  CompileAndRunScript("Obj.prototype.method1.toString();");
+  CompileRun("Obj.prototype.method1.toString();");
 
   LOGGER->LogCompiledFunctions();
-  CHECK_GT(matcher.GetNextChunk(), 0);
 
-  const char* callback_rec = "code-creation,Callback,";
-  char* pos = const_cast<char*>(matcher.Find(callback_rec));
-  CHECK_NE(NULL, pos);
-  pos += strlen(callback_rec);
-  EmbeddedVector<char, 100> ref_data;
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
+
+  i::EmbeddedVector<char, 100> ref_data;
   i::OS::SNPrintF(ref_data,
-                  "0x%" V8PRIxPTR ",1,\"method1\"", ObjMethod1);
-  *(pos + strlen(ref_data.start())) = '\0';
-  CHECK_EQ(ref_data.start(), pos);
+                  "code-creation,Callback,0x%" V8PRIxPTR ",1,\"method1\"\0",
+                  ObjMethod1);
+
+  CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
 
   obj.Dispose();
 }
@@ -581,524 +419,58 @@
 
 TEST(LogAccessorCallbacks) {
   ScopedLoggerInitializer initialize_logger(false);
-  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
-  obj->SetClassName(v8::String::New("Obj"));
+  obj->SetClassName(v8_str("Obj"));
   v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate();
-  inst->SetAccessor(v8::String::New("prop1"), Prop1Getter, Prop1Setter);
-  inst->SetAccessor(v8::String::New("prop2"), Prop2Getter);
+  inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter);
+  inst->SetAccessor(v8_str("prop2"), Prop2Getter);
 
   LOGGER->LogAccessorCallbacks();
-  CHECK_GT(matcher.GetNextChunk(), 0);
-  matcher.PrintBuffer();
+
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
 
   EmbeddedVector<char, 100> prop1_getter_record;
   i::OS::SNPrintF(prop1_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"",
                   Prop1Getter);
-  CHECK_NE(NULL, matcher.Find(prop1_getter_record));
+  CHECK_NE(NULL,
+           StrNStr(log.start(), prop1_getter_record.start(), log.length()));
+
   EmbeddedVector<char, 100> prop1_setter_record;
   i::OS::SNPrintF(prop1_setter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"",
                   Prop1Setter);
-  CHECK_NE(NULL, matcher.Find(prop1_setter_record));
+  CHECK_NE(NULL,
+           StrNStr(log.start(), prop1_setter_record.start(), log.length()));
+
   EmbeddedVector<char, 100> prop2_getter_record;
   i::OS::SNPrintF(prop2_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"",
                   Prop2Getter);
-  CHECK_NE(NULL, matcher.Find(prop2_getter_record));
+  CHECK_NE(NULL,
+           StrNStr(log.start(), prop2_getter_record.start(), log.length()));
 
   obj.Dispose();
 }
 
 
-TEST(LogTags) {
-  ScopedLoggerInitializer initialize_logger(false);
-  LogBufferMatcher matcher;
-
-  const char* open_tag = "open-tag,";
-  const char* close_tag = "close-tag,";
-
-  // Check compatibility with the old style behavior.
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 0);
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  CHECK_EQ(NULL, matcher.Find(open_tag));
-  CHECK_EQ(NULL, matcher.Find(close_tag));
-
-  const char* open_tag1 = "open-tag,1\n";
-  const char* close_tag1 = "close-tag,1\n";
-
-  // Check non-nested tag case.
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  CHECK_GT(matcher.GetNextChunk(), 0);
-  CHECK(matcher.IsInSequence(open_tag1, close_tag1));
-
-  const char* open_tag2 = "open-tag,2\n";
-  const char* close_tag2 = "close-tag,2\n";
-
-  // Check nested tags case.
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  CHECK_GT(matcher.GetNextChunk(), 0);
-  // open_tag1 < open_tag2 < close_tag2 < close_tag1
-  CHECK(matcher.IsInSequence(open_tag1, open_tag2));
-  CHECK(matcher.IsInSequence(open_tag2, close_tag2));
-  CHECK(matcher.IsInSequence(close_tag2, close_tag1));
-
-  // Check overlapped tags case.
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  CHECK_GT(matcher.GetNextChunk(), 0);
-  // open_tag1 < open_tag2 < close_tag1 < close_tag2
-  CHECK(matcher.IsInSequence(open_tag1, open_tag2));
-  CHECK(matcher.IsInSequence(open_tag2, close_tag1));
-  CHECK(matcher.IsInSequence(close_tag1, close_tag2));
-
-  const char* open_tag3 = "open-tag,3\n";
-  const char* close_tag3 = "close-tag,3\n";
-
-  // Check pausing overflow case.
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 2);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 2);
-  CHECK_EQ(v8::PROFILER_MODULE_CPU, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 3);
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 3);
-  CHECK_EQ(v8::PROFILER_MODULE_NONE, LOGGER->GetActiveProfilerModules());
-  // Must be no tags, because logging must be disabled.
-  CHECK_EQ(NULL, matcher.Find(open_tag3));
-  CHECK_EQ(NULL, matcher.Find(close_tag3));
-}
-
-
 TEST(IsLoggingPreserved) {
   ScopedLoggerInitializer initialize_logger(false);
 
   CHECK(LOGGER->is_logging());
-  LOGGER->ResumeProfiler(v8::PROFILER_MODULE_CPU, 1);
+  LOGGER->ResumeProfiler();
   CHECK(LOGGER->is_logging());
-  LOGGER->PauseProfiler(v8::PROFILER_MODULE_CPU, 1);
-  CHECK(LOGGER->is_logging());
-
-  CHECK(LOGGER->is_logging());
-  LOGGER->ResumeProfiler(
-      v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
-  CHECK(LOGGER->is_logging());
-  LOGGER->PauseProfiler(
-      v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
-  CHECK(LOGGER->is_logging());
-
-  CHECK(LOGGER->is_logging());
-  LOGGER->ResumeProfiler(
-      v8::PROFILER_MODULE_CPU |
-      v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
-  CHECK(LOGGER->is_logging());
-  LOGGER->PauseProfiler(
-      v8::PROFILER_MODULE_CPU |
-      v8::PROFILER_MODULE_HEAP_STATS | v8::PROFILER_MODULE_JS_CONSTRUCTORS, 1);
+  LOGGER->PauseProfiler();
   CHECK(LOGGER->is_logging());
 }
 
 
-static inline bool IsStringEqualTo(const char* r, const char* s) {
-  return strncmp(r, s, strlen(r)) == 0;
-}
-
-
-static bool Consume(const char* str, char** buf) {
-  if (IsStringEqualTo(str, *buf)) {
-    *buf += strlen(str);
-    return true;
-  }
-  return false;
-}
-
-
-namespace {
-
-// A code entity is a pointer to a position of code-creation event in buffer log
-// offset to a point where entity size begins, i.e.: '255,"func"\n'. This makes
-// comparing code entities pretty easy.
-typedef char* CodeEntityInfo;
-
-class Interval {
- public:
-  Interval()
-      : min_addr_(reinterpret_cast<Address>(-1)),
-        max_addr_(reinterpret_cast<Address>(0)), next_(NULL) {}
-
-  ~Interval() { delete next_; }
-
-  size_t Length() {
-    size_t result = max_addr_ - min_addr_ + 1;
-    if (next_ != NULL) result += next_->Length();
-    return result;
-  }
-
-  void CloneFrom(Interval* src) {
-    while (src != NULL) {
-      RegisterAddress(src->min_addr_);
-      RegisterAddress(src->max_addr_);
-      src = src->next_;
-    }
-  }
-
-  bool Contains(Address addr) {
-    if (min_addr_ <= addr && addr <= max_addr_) {
-      return true;
-    }
-    if (next_ != NULL) {
-      return next_->Contains(addr);
-    } else {
-      return false;
-    }
-  }
-
-  size_t GetIndex(Address addr) {
-    if (min_addr_ <= addr && addr <= max_addr_) {
-      return addr - min_addr_;
-    }
-    CHECK_NE(NULL, next_);
-    return (max_addr_ - min_addr_ + 1) + next_->GetIndex(addr);
-  }
-
-  Address GetMinAddr() {
-    return next_ == NULL ? min_addr_ : i::Min(min_addr_, next_->GetMinAddr());
-  }
-
-  Address GetMaxAddr() {
-    return next_ == NULL ? max_addr_ : i::Max(max_addr_, next_->GetMaxAddr());
-  }
-
-  void RegisterAddress(Address addr) {
-    if (min_addr_ == reinterpret_cast<Address>(-1)
-        || (size_t)(addr > min_addr_ ?
-           addr - min_addr_ : min_addr_ - addr) < MAX_DELTA) {
-      if (addr < min_addr_) min_addr_ = addr;
-      if (addr > max_addr_) max_addr_ = addr;
-    } else {
-      if (next_ == NULL) next_ = new Interval();
-      next_->RegisterAddress(addr);
-    }
-  }
-
-  Address raw_min_addr() { return min_addr_; }
-
-  Address raw_max_addr() { return max_addr_; }
-
-  Interval* get_next() { return next_; }
-
- private:
-  static const size_t MAX_DELTA = 0x100000;
-  Address min_addr_;
-  Address max_addr_;
-  Interval* next_;
-};
-
-
-// A structure used to return log parsing results.
-class ParseLogResult {
- public:
-  ParseLogResult()
-      : entities_map(NULL), entities(NULL),
-        max_entities(0) {}
-
-  ~ParseLogResult() {
-    i::DeleteArray(entities_map);
-    i::DeleteArray(entities);
-  }
-
-  void AllocateEntities() {
-    // Make sure that the test doesn't operate on a bogus log.
-    CHECK_GT(max_entities, 0);
-    CHECK_GT(bounds.GetMinAddr(), 0);
-    CHECK_GT(bounds.GetMaxAddr(), bounds.GetMinAddr());
-
-    entities = i::NewArray<CodeEntityInfo>(max_entities);
-    for (int i = 0; i < max_entities; ++i) {
-      entities[i] = NULL;
-    }
-    const size_t map_length = bounds.Length();
-    entities_map = i::NewArray<int>(static_cast<int>(map_length));
-    for (size_t i = 0; i < map_length; ++i) {
-      entities_map[i] = -1;
-    }
-  }
-
-  bool HasIndexForAddress(Address addr) {
-    return bounds.Contains(addr);
-  }
-
-  size_t GetIndexForAddress(Address addr) {
-    CHECK(HasIndexForAddress(addr));
-    return bounds.GetIndex(addr);
-  }
-
-  CodeEntityInfo GetEntity(Address addr) {
-    if (HasIndexForAddress(addr)) {
-      size_t idx = GetIndexForAddress(addr);
-      int item = entities_map[idx];
-      return item != -1 ? entities[item] : NULL;
-    }
-    return NULL;
-  }
-
-  void ParseAddress(char* start) {
-    Address addr =
-        reinterpret_cast<Address>(strtoul(start, NULL, 16));  // NOLINT
-    bounds.RegisterAddress(addr);
-  }
-
-  Address ConsumeAddress(char** start) {
-    char* end_ptr;
-    Address addr =
-        reinterpret_cast<Address>(strtoul(*start, &end_ptr, 16));  // NOLINT
-    CHECK(HasIndexForAddress(addr));
-    *start = end_ptr;
-    return addr;
-  }
-
-  Interval bounds;
-  // Memory map of entities start addresses.
-  int* entities_map;
-  // An array of code entities.
-  CodeEntityInfo* entities;
-  // Maximal entities count. Actual entities count can be lower,
-  // empty entity slots are pointing to NULL.
-  int max_entities;
-};
-
-}  // namespace
-
-
-typedef void (*ParserBlock)(char* start, char* end, ParseLogResult* result);
-
-static void ParserCycle(
-    char* start, char* end, ParseLogResult* result,
-    ParserBlock block_creation, ParserBlock block_delete,
-    ParserBlock block_move) {
-
-  const char* code_creation = "code-creation,";
-  const char* code_delete = "code-delete,";
-  const char* code_move = "code-move,";
-
-  const char* lazy_compile = "LazyCompile,";
-  const char* script = "Script,";
-  const char* function = "Function,";
-
-  while (start < end) {
-    if (Consume(code_creation, &start)) {
-      if (Consume(lazy_compile, &start)
-          || Consume(script, &start)
-          || Consume(function, &start)) {
-        block_creation(start, end, result);
-      }
-    } else if (Consume(code_delete, &start)) {
-      block_delete(start, end, result);
-    } else if (Consume(code_move, &start)) {
-      block_move(start, end, result);
-    }
-    while (start < end && *start != '\n') ++start;
-    ++start;
-  }
-}
-
-
-static void Pass1CodeCreation(char* start, char* end, ParseLogResult* result) {
-  result->ParseAddress(start);
-  ++result->max_entities;
-}
-
-
-static void Pass1CodeDelete(char* start, char* end, ParseLogResult* result) {
-  result->ParseAddress(start);
-}
-
-
-static void Pass1CodeMove(char* start, char* end, ParseLogResult* result) {
-  result->ParseAddress(start);
-  // Skip old address.
-  while (start < end && *start != ',') ++start;
-  CHECK_GT(end, start);
-  ++start;  // Skip ','.
-  result->ParseAddress(start);
-}
-
-
-static void Pass2CodeCreation(char* start, char* end, ParseLogResult* result) {
-  Address addr = result->ConsumeAddress(&start);
-  CHECK_GT(end, start);
-  ++start;  // Skip ','.
-
-  size_t idx = result->GetIndexForAddress(addr);
-  result->entities_map[idx] = -1;
-  for (int i = 0; i < result->max_entities; ++i) {
-    // Find an empty slot and fill it.
-    if (result->entities[i] == NULL) {
-      result->entities[i] = start;
-      result->entities_map[idx] = i;
-      break;
-    }
-  }
-  // Make sure that a slot was found.
-  CHECK_GE(result->entities_map[idx], 0);
-}
-
-
-static void Pass2CodeDelete(char* start, char* end, ParseLogResult* result) {
-  Address addr = result->ConsumeAddress(&start);
-  size_t idx = result->GetIndexForAddress(addr);
-  // There can be code deletes that are not related to JS code.
-  if (result->entities_map[idx] >= 0) {
-    result->entities[result->entities_map[idx]] = NULL;
-    result->entities_map[idx] = -1;
-  }
-}
-
-
-static void Pass2CodeMove(char* start, char* end, ParseLogResult* result) {
-  Address from_addr = result->ConsumeAddress(&start);
-  CHECK_GT(end, start);
-  ++start;  // Skip ','.
-  Address to_addr = result->ConsumeAddress(&start);
-  CHECK_GT(end, start);
-
-  size_t from_idx = result->GetIndexForAddress(from_addr);
-  size_t to_idx = result->GetIndexForAddress(to_addr);
-  // There can be code moves that are not related to JS code.
-  if (from_idx != to_idx && result->entities_map[from_idx] >= 0) {
-    CHECK_EQ(-1, result->entities_map[to_idx]);
-    result->entities_map[to_idx] = result->entities_map[from_idx];
-    result->entities_map[from_idx] = -1;
-  };
-}
-
-
-static void ParseLog(char* start, char* end, ParseLogResult* result) {
-  // Pass 1: Calculate boundaries of addresses and entities count.
-  ParserCycle(start, end, result,
-              Pass1CodeCreation, Pass1CodeDelete, Pass1CodeMove);
-
-  printf("min_addr: %p, max_addr: %p, entities: %d\n",
-         result->bounds.GetMinAddr(), result->bounds.GetMaxAddr(),
-         result->max_entities);
-
-  result->AllocateEntities();
-
-  // Pass 2: Fill in code entries data.
-  ParserCycle(start, end, result,
-              Pass2CodeCreation, Pass2CodeDelete, Pass2CodeMove);
-}
-
-
-static inline void PrintCodeEntityInfo(CodeEntityInfo entity) {
-  const int max_len = 50;
-  if (entity != NULL) {
-    char* eol = strchr(entity, '\n');
-    int len = static_cast<int>(eol - entity);
-    len = len <= max_len ? len : max_len;
-    printf("%-*.*s ", max_len, len, entity);
-  } else {
-    printf("%*s", max_len + 1, "");
-  }
-}
-
-
-static void PrintCodeEntitiesInfo(
-    bool is_equal, Address addr,
-    CodeEntityInfo l_entity, CodeEntityInfo r_entity) {
-  printf("%c %p ", is_equal ? ' ' : '*', addr);
-  PrintCodeEntityInfo(l_entity);
-  PrintCodeEntityInfo(r_entity);
-  printf("\n");
-}
-
-
-static inline int StrChrLen(const char* s, char c) {
-  return static_cast<int>(strchr(s, c) - s);
-}
-
-
-static bool AreFuncSizesEqual(CodeEntityInfo ref_s, CodeEntityInfo new_s) {
-  int ref_len = StrChrLen(ref_s, ',');
-  int new_len = StrChrLen(new_s, ',');
-  return ref_len == new_len && strncmp(ref_s, new_s, ref_len) == 0;
-}
-
-
-static bool AreFuncNamesEqual(CodeEntityInfo ref_s, CodeEntityInfo new_s) {
-  // Skip size.
-  ref_s = strchr(ref_s, ',') + 1;
-  new_s = strchr(new_s, ',') + 1;
-  CHECK_EQ('"', ref_s[0]);
-  CHECK_EQ('"', new_s[0]);
-  int ref_len = StrChrLen(ref_s + 1, '\"');
-  int new_len = StrChrLen(new_s + 1, '\"');
-  // A special case for ErrorPrototype. Haven't yet figured out why they
-  // are different.
-  const char* error_prototype = "\"ErrorPrototype";
-  if (IsStringEqualTo(error_prototype, ref_s)
-      && IsStringEqualTo(error_prototype, new_s)) {
-    return true;
-  }
-  // Built-in objects have problems too.
-  const char* built_ins[] = {
-      "\"Boolean\"", "\"Function\"", "\"Number\"",
-      "\"Object\"", "\"Script\"", "\"String\""
-  };
-  for (size_t i = 0; i < sizeof(built_ins) / sizeof(*built_ins); ++i) {
-    if (IsStringEqualTo(built_ins[i], new_s)) {
-      return true;
-    }
-  }
-  return ref_len == new_len && strncmp(ref_s, new_s, ref_len) == 0;
-}
-
-
-static bool AreEntitiesEqual(CodeEntityInfo ref_e, CodeEntityInfo new_e) {
-  if (ref_e == NULL && new_e != NULL) return true;
-  if (ref_e != NULL && new_e != NULL) {
-    return AreFuncSizesEqual(ref_e, new_e) && AreFuncNamesEqual(ref_e, new_e);
-  }
-  if (ref_e != NULL && new_e == NULL) {
-    // args_count entities (argument adapters) are not found by heap traversal,
-    // but they are not needed because they doesn't contain any code.
-    ref_e = strchr(ref_e, ',') + 1;
-    const char* args_count = "\"args_count:";
-    return IsStringEqualTo(args_count, ref_e);
-  }
-  return false;
-}
-
+typedef i::NativesCollection<i::TEST> TestSources;
 
 // Test that logging of code create / move / delete events
 // is equivalent to traversal of a resulting heap.
@@ -1112,86 +484,55 @@
   // P.S. No, V8 can't be re-initialized after disposal, see include/v8.h.
   CHECK(!i::V8::IsRunning());
 
-  i::FLAG_logfile = "*";
-  i::FLAG_log = true;
-  i::FLAG_log_code = true;
-
-  // Make sure objects move.
-  bool saved_always_compact = i::FLAG_always_compact;
-  if (!i::FLAG_never_compact) {
-    i::FLAG_always_compact = true;
-  }
-
-  v8::HandleScope scope;
-  v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>();
-  v8::Handle<v8::Context> env = v8::Context::New(
-      0, v8::Handle<v8::ObjectTemplate>(), global_object);
-  env->Enter();
+  // Start with profiling to capture all code events from the beginning.
+  ScopedLoggerInitializer initialize_logger(false);
 
   // Compile and run a function that creates other functions.
-  CompileAndRunScript(
+  CompileRun(
       "(function f(obj) {\n"
       "  obj.test =\n"
       "    (function a(j) { return function b() { return j; } })(100);\n"
       "})(this);");
-  HEAP->CollectAllGarbage(false);
-
-  EmbeddedVector<char, 204800> buffer;
-  int log_size;
-  ParseLogResult ref_result;
-
-  // Retrieve the log.
-  {
-    // Make sure that no GCs occur prior to LogCompiledFunctions call.
-    i::AssertNoAllocation no_alloc;
-
-    log_size = GetLogLines(0, &buffer);
-    CHECK_GT(log_size, 0);
-    CHECK_GT(buffer.length(), log_size);
-
-    // Fill a map of compiled code objects.
-    ParseLog(buffer.start(), buffer.start() + log_size, &ref_result);
-  }
+  v8::V8::PauseProfiler();
+  HEAP->CollectAllGarbage(true);
+  LOGGER->StringEvent("test-logging-done", "");
 
   // Iterate heap to find compiled functions, will write to log.
   LOGGER->LogCompiledFunctions();
-  char* new_log_start = buffer.start() + log_size;
-  const int new_log_size = LOGGER->GetLogLines(
-      log_size, new_log_start, buffer.length() - log_size);
-  CHECK_GT(new_log_size, 0);
-  CHECK_GT(buffer.length(), log_size + new_log_size);
+  LOGGER->StringEvent("test-traversal-done", "");
 
-  // Fill an equivalent map of compiled code objects.
-  ParseLogResult new_result;
-  ParseLog(new_log_start, new_log_start + new_log_size, &new_result);
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
+  v8::Handle<v8::String> log_str = v8::String::New(log.start(), log.length());
+  initialize_logger.env()->Global()->Set(v8_str("_log"), log_str);
 
-  // Test their actual equivalence.
-  Interval combined;
-  combined.CloneFrom(&ref_result.bounds);
-  combined.CloneFrom(&new_result.bounds);
-  Interval* iter = &combined;
-  bool results_equal = true;
-
-  while (iter != NULL) {
-    for (Address addr = iter->raw_min_addr();
-         addr <= iter->raw_max_addr(); ++addr) {
-      CodeEntityInfo ref_entity = ref_result.GetEntity(addr);
-      CodeEntityInfo new_entity = new_result.GetEntity(addr);
-      if (ref_entity != NULL || new_entity != NULL) {
-        const bool equal = AreEntitiesEqual(ref_entity, new_entity);
-        if (!equal) results_equal = false;
-        PrintCodeEntitiesInfo(equal, addr, ref_entity, new_entity);
-      }
-    }
-    iter = iter->get_next();
+  i::Vector<const unsigned char> source = TestSources::GetScriptsSource();
+  v8::Handle<v8::String> source_str = v8::String::New(
+      reinterpret_cast<const char*>(source.start()), source.length());
+  v8::TryCatch try_catch;
+  v8::Handle<v8::Script> script = v8::Script::Compile(source_str, v8_str(""));
+  if (script.IsEmpty()) {
+    v8::String::Utf8Value exception(try_catch.Exception());
+    printf("compile: %s\n", *exception);
+    CHECK(false);
   }
-  // Make sure that all log data is written prior crash due to CHECK failure.
-  fflush(stdout);
-  CHECK(results_equal);
-
-  env->Exit();
-  LOGGER->TearDown();
-  i::FLAG_always_compact = saved_always_compact;
+  v8::Handle<v8::Value> result = script->Run();
+  if (result.IsEmpty()) {
+    v8::String::Utf8Value exception(try_catch.Exception());
+    printf("run: %s\n", *exception);
+    CHECK(false);
+  }
+  // The result either be a "true" literal or problem description.
+  if (!result->IsTrue()) {
+    v8::Local<v8::String> s = result->ToString();
+    i::ScopedVector<char> data(s->Length() + 1);
+    CHECK_NE(NULL, data.start());
+    s->WriteAscii(data.start());
+    printf("%s\n", data.start());
+    // Make sure that our output is written prior crash due to CHECK failure.
+    fflush(stdout);
+    CHECK(false);
+  }
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 39856b6..96a181d 100755
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -137,8 +137,9 @@
   // Regression test. See:
   //    http://code.google.com/p/chromium/issues/detail?id=53548
   // Tests that --> is correctly interpreted as comment-to-end-of-line if there
-  // is only whitespace before it on the line, even after a multiline-comment
-  // comment. This was not the case if it occurred before the first real token
+  // is only whitespace before it on the line (with comments considered as
+  // whitespace, even a multiline-comment containing a newline).
+  // This was not the case if it occurred before the first real token
   // in the input.
   const char* tests[] = {
       // Before first real token.
@@ -152,6 +153,16 @@
       NULL
   };
 
+  const char* fail_tests[] = {
+      "x --> is eol-comment\nvar y = 37;\n",
+      "\"\\n\" --> is eol-comment\nvar y = 37;\n",
+      "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
+      "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
+      "var x = 42; --> is eol-comment\nvar y = 37;\n",
+      "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
+      NULL
+  };
+
   // Parser/Scanner needs a stack limit.
   int marker;
   i::Isolate::Current()->stack_guard()->SetStackLimit(
@@ -163,6 +174,13 @@
     CHECK(data != NULL && !data->HasError());
     delete data;
   }
+
+  for (int i = 0; fail_tests[i]; i++) {
+    v8::ScriptData* data =
+        v8::ScriptData::PreCompile(fail_tests[i], i::StrLength(fail_tests[i]));
+    CHECK(data == NULL || data->HasError());
+    delete data;
+  }
 }
 
 
@@ -253,7 +271,7 @@
       "{label: 42}",
       "var x = 42;",
       "function foo(x, y) { return x + y; }",
-      "native function foo(); return %ArgleBargle(glop);",
+      "%ArgleBargle(glop);",
       "var x = new new Function('this.x = 42');",
       NULL
   };
@@ -265,7 +283,7 @@
         reinterpret_cast<const i::byte*>(program),
         static_cast<unsigned>(strlen(program)));
     i::CompleteParserRecorder log;
-    i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+    i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
     scanner.Initialize(&stream);
 
     v8::preparser::PreParser::PreParseResult result =
@@ -358,7 +376,7 @@
       reinterpret_cast<const i::byte*>(*program),
       static_cast<unsigned>(kProgramSize));
   i::CompleteParserRecorder log;
-  i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+  i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
   scanner.Initialize(&stream);
 
 
@@ -576,7 +594,7 @@
                        i::Token::Value* expected_tokens,
                        int skip_pos = 0,  // Zero means not skipping.
                        int skip_to = 0) {
-  i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+  i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
   scanner.Initialize(stream);
 
   int i = 0;
@@ -655,7 +673,7 @@
   i::Utf8ToUC16CharacterStream stream(
        reinterpret_cast<const i::byte*>(re_source),
        static_cast<unsigned>(strlen(re_source)));
-  i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+  i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
   scanner.Initialize(&stream);
 
   i::Token::Value start = scanner.peek();
diff --git a/test/cctest/test-platform-tls.cc b/test/cctest/test-platform-tls.cc
index b2cb101..7f33aa2 100644
--- a/test/cctest/test-platform-tls.cc
+++ b/test/cctest/test-platform-tls.cc
@@ -48,7 +48,7 @@
 
 class TestThread : public Thread {
  public:
-  TestThread() : Thread(NULL, "TestThread") {}
+  TestThread() : Thread("TestThread") {}
 
   virtual void Run() {
     DoTest();
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc
index fbe5834..6d30443 100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -2,8 +2,6 @@
 //
 // Tests of profiles generator and utilities.
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 #include "profile-generator-inl.h"
 #include "cctest.h"
@@ -824,5 +822,3 @@
   for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
     i::DeleteArray(titles[i]);
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 6588c68..9f18b60 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -41,19 +41,25 @@
 #ifdef V8_INTERPRETED_REGEXP
 #include "interpreter-irregexp.h"
 #else  // V8_INTERPRETED_REGEXP
+#include "macro-assembler.h"
+#include "code.h"
 #ifdef V8_TARGET_ARCH_ARM
+#include "arm/assembler-arm.h"
 #include "arm/macro-assembler-arm.h"
 #include "arm/regexp-macro-assembler-arm.h"
 #endif
 #ifdef V8_TARGET_ARCH_MIPS
+#include "mips/assembler-mips.h"
 #include "mips/macro-assembler-mips.h"
 #include "mips/regexp-macro-assembler-mips.h"
 #endif
 #ifdef V8_TARGET_ARCH_X64
+#include "x64/assembler-x64.h"
 #include "x64/macro-assembler-x64.h"
 #include "x64/regexp-macro-assembler-x64.h"
 #endif
 #ifdef V8_TARGET_ARCH_IA32
+#include "ia32/assembler-ia32.h"
 #include "ia32/macro-assembler-ia32.h"
 #include "ia32/regexp-macro-assembler-ia32.h"
 #endif
diff --git a/test/cctest/test-sockets.cc b/test/cctest/test-sockets.cc
index 5246d09..4af55db 100644
--- a/test/cctest/test-sockets.cc
+++ b/test/cctest/test-sockets.cc
@@ -10,8 +10,8 @@
 
 class SocketListenerThread : public Thread {
  public:
-  explicit SocketListenerThread(Isolate* isolate, int port, int data_size)
-      : Thread(isolate, "SocketListenerThread"),
+  SocketListenerThread(int port, int data_size)
+      : Thread("SocketListenerThread"),
         port_(port),
         data_size_(data_size),
         server_(NULL),
@@ -92,8 +92,7 @@
   OS::SNPrintF(Vector<char>(port_str, kPortBuferLen), "%d", port);
 
   // Create a socket listener.
-  SocketListenerThread* listener = new SocketListenerThread(Isolate::Current(),
-      port, len);
+  SocketListenerThread* listener = new SocketListenerThread(port, len);
   listener->Start();
   listener->WaitForListening();
 
diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc
index 1e8a627..1aa57e3 100644
--- a/test/cctest/test-thread-termination.cc
+++ b/test/cctest/test-thread-termination.cc
@@ -161,12 +161,16 @@
 class TerminatorThread : public v8::internal::Thread {
  public:
   explicit TerminatorThread(i::Isolate* isolate)
-      : Thread(isolate, "TerminatorThread") { }
+      : Thread("TerminatorThread"),
+        isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { }
   void Run() {
     semaphore->Wait();
-    CHECK(!v8::V8::IsExecutionTerminating());
-    v8::V8::TerminateExecution();
+    CHECK(!v8::V8::IsExecutionTerminating(isolate_));
+    v8::V8::TerminateExecution(isolate_);
   }
+
+ private:
+  v8::Isolate* isolate_;
 };
 
 
@@ -196,8 +200,7 @@
 
 class LoopingThread : public v8::internal::Thread {
  public:
-  explicit LoopingThread(i::Isolate* isolate)
-      : Thread(isolate, "LoopingThread") { }
+  LoopingThread() : Thread("LoopingThread") { }
   void Run() {
     v8::Locker locker;
     v8::HandleScope scope;
@@ -233,7 +236,7 @@
   const int kThreads = 2;
   i::List<LoopingThread*> threads(kThreads);
   for (int i = 0; i < kThreads; i++) {
-    threads.Add(new LoopingThread(i::Isolate::Current()));
+    threads.Add(new LoopingThread());
   }
   for (int i = 0; i < kThreads; i++) {
     threads[i]->Start();
diff --git a/test/cctest/test-threads.cc b/test/cctest/test-threads.cc
index c6d5cb0..59d27ab 100644
--- a/test/cctest/test-threads.cc
+++ b/test/cctest/test-threads.cc
@@ -65,7 +65,7 @@
 
 class ThreadA: public v8::internal::Thread {
  public:
-  explicit ThreadA(i::Isolate* isolate) : Thread(isolate, "ThreadA") { }
+  ThreadA() : Thread("ThreadA") { }
   void Run() {
     v8::Locker locker;
     v8::HandleScope scope;
@@ -101,7 +101,7 @@
 
 class ThreadB: public v8::internal::Thread {
  public:
-  explicit ThreadB(i::Isolate* isolate) : Thread(isolate, "ThreadB") { }
+  ThreadB() : Thread("ThreadB") { }
   void Run() {
     do {
       {
@@ -126,8 +126,8 @@
 TEST(JSFunctionResultCachesInTwoThreads) {
   v8::V8::Initialize();
 
-  ThreadA threadA(i::Isolate::Current());
-  ThreadB threadB(i::Isolate::Current());
+  ThreadA threadA;
+  ThreadB threadB;
 
   threadA.Start();
   threadB.Start();
@@ -144,7 +144,7 @@
                            i::List<i::ThreadId>* refs,
                            unsigned int thread_no,
                            i::Semaphore* semaphore)
-    : Thread(NULL, "ThreadRefValidationThread"),
+    : Thread("ThreadRefValidationThread"),
       refs_(refs), thread_no_(thread_no), thread_to_start_(thread_to_start),
       semaphore_(semaphore) {
   }
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/message/regress/regress-1527.js
similarity index 88%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/message/regress/regress-1527.js
index edbcb19..682e386 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/message/regress/regress-1527.js
@@ -25,12 +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.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+var o1 = {foo: 'bar'};
+var o2 = {
+  1: 'blah',
+  2: o1.foo,
+  3: foo
 }
-
-test();
diff --git a/test/message/regress/regress-1527.out b/test/message/regress/regress-1527.out
new file mode 100644
index 0000000..dc17fb3
--- /dev/null
+++ b/test/message/regress/regress-1527.out
@@ -0,0 +1,32 @@
+# Copyright 2011 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*%(basename)s:32: ReferenceError: foo is not defined
+  3: foo
+     ^
+ReferenceError: foo is not defined
+    at *%(basename)s:32:6
diff --git a/test/mjsunit/argument-assigned.js b/test/mjsunit/argument-assigned.js
new file mode 100644
index 0000000..e30c881
--- /dev/null
+++ b/test/mjsunit/argument-assigned.js
@@ -0,0 +1,133 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(function() {
+  function f(x) {
+    var arguments = [ 1, 2, 3 ];
+    return x;
+  }
+  assertEquals(7, f(7));
+})();
+
+
+(function() {
+  function f(x) {
+    arguments[0] = 991;
+    var arguments = [ 1, 2, 3 ];
+    return x;
+  }
+  assertEquals(991, f(7));
+})();
+
+
+(function() {
+  function f(x) {
+    arguments[0] = 991;
+    for (var i = 0; i < 10; i++) {
+      if (i == 5) {
+        var arguments = [ 1, 2, 3 ];
+      }
+    }
+    return x;
+  }
+  assertEquals(991, f(7));
+})();
+
+
+(function() {
+  function f(x, s) {
+    eval(s);
+    return x;
+  }
+  assertEquals(7, f(7, "var arguments = [ 1, 2, 3 ];"));
+})();
+
+
+(function() {
+  function f(x, s) {
+    var tmp = arguments[0];
+    eval(s);
+    return tmp;
+  }
+  assertEquals(7, f(7, "var arguments = [ 1, 2, 3 ];"));
+})();
+
+
+(function() {
+  function f(x, s) {
+    var tmp = arguments[0];
+    eval(s);
+    return tmp;
+  }
+  assertEquals(7, f(7, ""));
+})();
+
+
+(function() {
+  function f(x, s) {
+    var tmp = arguments[0];
+    eval(s);
+    return x;
+  }
+  assertEquals(7, f(7, "var arguments = [ 1, 2, 3 ];"));
+})();
+
+
+(function() {
+  function f(x, s) {
+    var tmp = arguments[0];
+    eval(s);
+    return x;
+  }
+  assertEquals(7, f(7, ""));
+})();
+
+
+(function() {
+  function f(x) {
+    function g(y) {
+      x = y;
+    }
+    arguments = {};
+    g(991);
+    return x;
+  }
+  assertEquals(991, f(7));
+})();
+
+
+(function() {
+  function f(x) {
+    function g(y, s) {
+      eval(s);
+    }
+    arguments = {};
+    g(991, "x = y;");
+    return x;
+  }
+  assertEquals(991, f(7));
+})();
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/argument-named-arguments.js
similarity index 66%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/argument-named-arguments.js
index edbcb19..2845102 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/argument-named-arguments.js
@@ -25,12 +25,43 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Tests to verify proper arguments handling if the arguments
+// variable is declared as a parameter or local variable.
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+function e(a) {
+  assertEquals(9, a.length);
+  assertEquals("arguments", a);
+};
 
-test();
+e("arguments");
+
+
+function f(arguments) {
+  assertEquals(9, arguments.length);
+  assertEquals("arguments", arguments);
+};
+
+f("arguments");
+
+
+function g(x) {
+  var arguments;
+  assertEquals("arguments", x);
+  assertEquals(1, arguments.length);
+  assertEquals("[object Arguments]", '' + arguments);
+};
+
+g("arguments");
+
+
+function h(x) {
+  assertEquals("arguments", x);
+  assertEquals(1, arguments.length);
+  assertEquals("[object Arguments]", '' + arguments);
+  var arguments = "foobar";
+  assertEquals("arguments", x);
+  assertEquals(6, arguments.length);
+  assertEquals("foobar", '' + arguments);
+};
+
+h("arguments");
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/arguments-escape.js
similarity index 77%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/arguments-escape.js
index edbcb19..042100c 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/arguments-escape.js
@@ -25,12 +25,35 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+function foo(x) {
+  var a = arguments;
+  function bar(i) {
+    assertEquals(i, ++a[0]);
+    assertEquals(i, x);
+  };
+  bar(1);
+  bar(2);
+  bar(3);
+  return bar;
 }
+var baz = foo(0);
+baz(4);
+baz(5);
+baz(6);
 
-test();
+// Test writing a non-smi.
+function foo2(x) {
+  var a = arguments;
+  function bar2(i) {
+    assertEquals(i, ++a[0]);
+    assertEquals(i, x);
+  };
+  bar2(1.5);
+  bar2(2.5);
+  bar2(3.5);
+  return bar2;
+}
+var baz2 = foo2(0.5);
+baz2(4.5);
+baz2(5.5);
+baz2(6.5);
diff --git a/test/mjsunit/arguments.js b/test/mjsunit/arguments.js
index 0302739..78b7722 100644
--- a/test/mjsunit/arguments.js
+++ b/test/mjsunit/arguments.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -50,8 +50,6 @@
 assertEquals(2, argc2(1, 2));
 assertEquals(3, argc2(1, 2, 3));
 
-
-
 var index;
 
 function argv0() {
@@ -95,3 +93,98 @@
 // an unexpected number of arguments works.
 function f(a) { return arguments.length; };
 assertEquals(3, f(1, 2, 3));
+
+function f1(x, y) {
+  function g(a) {
+    a[0] = "three";
+    return a.length;
+  }
+  var l = g(arguments);
+  y = 5;
+  assertEquals(2, l);
+  assertEquals("three", x);
+  assertEquals(5, y);
+}
+f1(3, "five");
+
+
+function f2() {
+  if (arguments[0] > 0) {
+    return arguments.callee(arguments[0] - 1) + arguments[0];
+  }
+  return 0;
+}
+assertEquals(55, f2(10));
+
+
+function f3() {
+  assertEquals(0, arguments.length);
+}
+f3();
+
+
+function f4() {
+  var arguments = 0;
+  assertEquals(void 0, arguments.length);
+}
+f4();
+
+
+function f5(x, y, z) {
+  function g(a) {
+    x = "two";
+    y = "three";
+    a[1] = "drei";
+    a[2] = "fuenf";
+  };
+
+  g(arguments);
+  assertEquals("two", x);
+  assertEquals("drei", y);
+  assertEquals("fuenf", z);
+}
+f5(2, 3, 5);
+
+
+function f6(x, y) {
+  x = "x";
+  arguments[1] = "y";
+  return [arguments.length, arguments[0], y, arguments[2]];
+}
+
+assertArrayEquals([0, void 0, void 0, void 0], f6());
+assertArrayEquals([1, "x", void 0, void 0], f6(1));
+assertArrayEquals([2, "x", "y", void 0], f6(9, 17));
+assertArrayEquals([3, "x", "y", 7], f6(3, 5, 7));
+assertArrayEquals([4, "x", "y", "c"], f6("a", "b", "c", "d"));
+
+
+function list_args(a) {
+  assertEquals("function", typeof a.callee);
+  var result = [];
+  result.push(a.length);
+  for (i = 0; i < a.length; i++) result.push(a[i]);
+  return result;
+}
+
+
+function f1(x, y) {
+  function g(p) {
+    x = p;
+  }
+  g(y);
+  return list_args(arguments);
+}
+
+assertArrayEquals([0], f1());
+assertArrayEquals([1, void 0], f1(3));
+assertArrayEquals([2, 5, 5], f1(3, 5));
+assertArrayEquals([3, 5, 5, 7], f1(3, 5, 7));
+
+// Check out of bounds behavior.
+function arg_get(x) { return arguments[x]; }
+function arg_del(x) { return delete arguments[x]; }
+function arg_set(x) { return (arguments[x] = 117); }
+assertEquals(undefined, arg_get(0xFFFFFFFF));
+assertEquals(true, arg_del(0xFFFFFFFF));
+assertEquals(117, arg_set(0xFFFFFFFF));
\ No newline at end of file
diff --git a/test/mjsunit/array-reduce.js b/test/mjsunit/array-reduce.js
index 83d9023..1e96188 100755
--- a/test/mjsunit/array-reduce.js
+++ b/test/mjsunit/array-reduce.js
@@ -411,67 +411,77 @@
 
 // Test error conditions:
 
+var exception = false;
 try {
   [1].reduce("not a function");
-  assertUnreachable("Reduce callback not a function not throwing");
 } catch (e) {
+  exception = true;
   assertTrue(e instanceof TypeError,
              "reduce callback not a function not throwing TypeError");
   assertEquals("called_non_callable", e.type,
                "reduce non function TypeError type");
 }
+assertTrue(exception);
 
+exception = false;
 try {
   [1].reduceRight("not a function");
-  assertUnreachable("ReduceRight callback not a function not throwing");
 } catch (e) {
+  exception = true;
   assertTrue(e instanceof TypeError,
              "reduceRight callback not a function not throwing TypeError");
   assertEquals("called_non_callable", e.type,
                "reduceRight non function TypeError type");
 }
+assertTrue(exception);
 
-
+exception = false;
 try {
   [].reduce(sum);
-  assertUnreachable("Reduce no initial value not throwing");
 } catch (e) {
+  exception = true;
   assertTrue(e instanceof TypeError,
              "reduce no initial value not throwing TypeError");
   assertEquals("reduce_no_initial", e.type,
                "reduce no initial TypeError type");
 }
+assertTrue(exception);
 
+exception = false;
 try {
   [].reduceRight(sum);
-  assertUnreachable("ReduceRight no initial value not throwing");
 } catch (e) {
+  exception = true;
   assertTrue(e instanceof TypeError,
              "reduceRight no initial value not throwing TypeError");
   assertEquals("reduce_no_initial", e.type,
                "reduceRight no initial TypeError type");
 }
+assertTrue(exception);
 
-
+exception = false;
 try {
   [,,,].reduce(sum);
-  assertUnreachable("Reduce sparse no initial value not throwing");
 } catch (e) {
+  exception = true;
   assertTrue(e instanceof TypeError,
              "reduce sparse no initial value not throwing TypeError");
   assertEquals("reduce_no_initial", e.type,
                "reduce no initial TypeError type");
 }
+assertTrue(exception);
 
+exception = false;
 try {
   [,,,].reduceRight(sum);
-  assertUnreachable("ReduceRight sparse no initial value not throwing");
 } catch (e) {
+  exception = true;
   assertTrue(e instanceof TypeError,
              "reduceRight sparse no initial value not throwing TypeError");
   assertEquals("reduce_no_initial", e.type,
                "reduceRight no initial TypeError type");
 }
+assertTrue(exception);
 
 
 // Array changing length
@@ -511,4 +521,3 @@
             [3, 3, 2, [1, 2, 3, 4, 4, 5], 6],
             [6, 4, 3, [1, 2, 3, 4, 4, 5, 6], 10],
            ], arr, extender, 0);
-
diff --git a/test/mjsunit/array-sort.js b/test/mjsunit/array-sort.js
index 7060c5f..fd18a5b 100644
--- a/test/mjsunit/array-sort.js
+++ b/test/mjsunit/array-sort.js
@@ -70,30 +70,59 @@
   a.sort();
   assertArrayEquals([-1000000000, -10000000000, -1000000001, 1000000000, 10000000000, 1000000001], a);
 
+  // Other cases are tested implicitly in TestSmiLexicographicCompare.
+}
 
-  for (var xb = 1; xb <= 1000 * 1000 * 1000; xb *= 10) {
+TestNumberSort();
+
+function TestSmiLexicographicCompare() {
+
+  assertFalse(%_IsSmi(2147483648), 'Update test for >32 bit Smi');
+
+  // Collect a list of interesting Smis.
+  var seen = {};
+  var smis = [];
+  function add(x) {
+    if (x | 0 == x) {
+      x = x | 0;  // Canonicalizes to Smi if 32-bit signed and fits in Smi.
+    }
+    if (%_IsSmi(x) && !seen[x]) {
+      seen[x] = 1;
+      smis.push(x);
+    }
+  }
+  function addSigned(x) {
+    add(x);
+    add(-x);
+  }
+
+  var BIGGER_THAN_ANY_SMI = 10 * 1000 * 1000 * 1000;
+  for (var xb = 1; xb <= BIGGER_THAN_ANY_SMI; xb *= 10) {
     for (var xf = 0; xf <= 9; xf++) {
       for (var xo = -1; xo <= 1; xo++) {
-        for (var yb = 1; yb <= 1000 * 1000 * 1000; yb *= 10) {
-          for (var yf = 0; yf <= 9; yf++) {
-            for (var yo = -1; yo <= 1; yo++) {
-              var x = xb * xf + xo;
-              var y = yb * yf + yo;
-              if (!%_IsSmi(x)) continue;
-              if (!%_IsSmi(y)) continue;
-              var lex = %SmiLexicographicCompare(x, y);
-              if (lex < 0) lex = -1;
-              if (lex > 0) lex = 1;
-              assertEquals(lex, (x == y) ? 0 : ((x + "") < (y + "") ? -1 : 1), x + " < " + y);
-            }
-          }
-        }
+        addSigned(xb * xf + xo);
       }
     }
   }
+
+  for (var yb = 1; yb <= BIGGER_THAN_ANY_SMI; yb *= 2) {
+    for (var yo = -2; yo <= 2; yo++) {
+      addSigned(yb + yo);
+    }
+  }
+
+  for (var i = 0; i < smis.length; i++) {
+    for (var j = 0; j < smis.length; j++) {
+      var x = smis[i];
+      var y = smis[j];
+      var lex = %SmiLexicographicCompare(x, y);
+      var expected = (x == y) ? 0 : ((x + "") < (y + "") ? -1 : 1);
+      assertEquals(lex, expected, x + " < " + y);
+    }
+  }
 }
 
-TestNumberSort();
+TestSmiLexicographicCompare();
 
 
 // Test lexicographical string sorting.
@@ -374,4 +403,4 @@
   assertTrue(b instanceof o);
   return a.val - b.val;
 }
-arr.sort(cmpTest);
\ No newline at end of file
+arr.sort(cmpTest);
diff --git a/test/mjsunit/assert-opt-and-deopt.js b/test/mjsunit/assert-opt-and-deopt.js
index b624ba5..f589868 100644
--- a/test/mjsunit/assert-opt-and-deopt.js
+++ b/test/mjsunit/assert-opt-and-deopt.js
@@ -148,7 +148,7 @@
 tracker.AssertDeoptHappened(f, false);
 tracker.AssertDeoptCount(f, 0);
 
-for (var i = 0; i < 5; i++) f(1);
+for (var i = 0; i < 2; i++) f(1);
 
 tracker.AssertOptCount(f, 0);
 tracker.AssertIsOptimized(f, false);
diff --git a/test/mjsunit/binary-op-newspace.js b/test/mjsunit/binary-op-newspace.js
index 032284c..e3341c4 100644
--- a/test/mjsunit/binary-op-newspace.js
+++ b/test/mjsunit/binary-op-newspace.js
@@ -25,8 +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: --max-new-space-size=256
-
+// Flags: --max-new-space-size=256 --noopt
 
 // Check that a mod where the stub code hits a failure in heap number
 // allocation still works.
diff --git a/test/mjsunit/bit-not.js b/test/mjsunit/bit-not.js
index 85eccc4..d0316a7 100644
--- a/test/mjsunit/bit-not.js
+++ b/test/mjsunit/bit-not.js
@@ -68,6 +68,8 @@
 // the fast path and just use the slow path instead.
 function TryToGC() {
   var x = 0x40000000;
+  // Put in an eval to foil Crankshaft.
+  eval("");
   for (var i = 0; i < 1000000; i++) {
     assertEquals(~0x40000000, ~x);
   }
diff --git a/test/mjsunit/boolean.js b/test/mjsunit/boolean.js
new file mode 100644
index 0000000..d955855
--- /dev/null
+++ b/test/mjsunit/boolean.js
@@ -0,0 +1,74 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+assertEquals(Boolean(void 0), false);
+assertEquals(Boolean(null), false);
+assertEquals(Boolean(false), false);
+assertEquals(Boolean(true), true);
+assertEquals(Boolean(0), false);
+assertEquals(Boolean(1), true);
+assertEquals(Boolean(assertEquals), true);
+assertEquals(Boolean(new Object()), true);
+assertTrue(new Boolean(false) !== false);
+assertTrue(new Boolean(false) == false);
+assertTrue(new Boolean(true) !== true);
+assertTrue(new Boolean(true) == true);
+
+assertEquals(true, !false);
+assertEquals(false, !true);
+assertEquals(true, !!true);
+assertEquals(false, !!false);
+
+assertEquals(true, true ? true : false);
+assertEquals(false, false ? true : false);
+
+assertEquals(false, true ? false : true);
+assertEquals(true, false ? false : true);
+
+
+assertEquals(true, true && true);
+assertEquals(false, true && false);
+assertEquals(false, false && true);
+assertEquals(false, false && false);
+
+// Regression.
+var t = 42;
+assertEquals(void 0, t.p);
+assertEquals(void 0, t.p && true);
+assertEquals(void 0, t.p && false);
+assertEquals(void 0, t.p && (t.p == 0));
+assertEquals(void 0, t.p && (t.p == null));
+assertEquals(void 0, t.p && (t.p == t.p));
+
+var o = new Object();
+o.p = 'foo';
+assertEquals('foo', o.p);
+assertEquals('foo', o.p || true);
+assertEquals('foo', o.p || false);
+assertEquals('foo', o.p || (o.p == 0));
+assertEquals('foo', o.p || (o.p == null));
+assertEquals('foo', o.p || (o.p == o.p));
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/break.js
similarity index 71%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/break.js
index edbcb19..741263d 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/break.js
@@ -25,12 +25,52 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+function f() {
+  var i = 10;
+  var c = 0;
+  while (i-- > 0) {
+    c++;
+    if (i == 5) ;
+  }
+  assertEquals(10, c);
+}
+f();
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+
+function f2() {
+  var i = 10;
+  var c = 0;
+  while (i-- > 0) {
+    c++;
+    if (i == 5) break;
+  }
+  assertEquals(5, c);
+}
+f2();
+
+
+function f3() {
+  var i = 10;
+  var c = 0;
+  outer: while (i-- > 0) {
+    var j = 10;
+    inner1: inner2: inner3: while (j-- > 0) {
+      c++;
+      if (i == 8)
+        break inner2;
+      if (i == 6)
+        break outer;
+    }
+  }
+  assertEquals(22, c);
+}
+f3();
+
+outer2: {
+  break outer2;
+  assertUnreachable();
 }
 
-test();
+
+outer3: break outer3;  // nop
+l1: l2: l3: break l2;  // nop
diff --git a/test/mjsunit/bugs/bug-900066.js b/test/mjsunit/bugs/bug-900066.js
deleted file mode 100644
index 3b7cc3f..0000000
--- a/test/mjsunit/bugs/bug-900066.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * 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.
-
-// When a property of the arguments array is deleted, it
-// must be "disconnected" from the corresponding parameter.
-// Re-introducing the property does not connect to the parameter.
-
-function f(x) {
-  delete arguments[0];
-  arguments[0] = 100;
-  return x;
-}
-
-assertEquals(10, f(10));
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/compiler/inline-arguments.js
similarity index 85%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/compiler/inline-arguments.js
index edbcb19..532fc26 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/compiler/inline-arguments.js
@@ -25,12 +25,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --allow-natives-syntax
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+// Test inlining functions that use arguments.
+function f() { return g(1, 2, 3); }
 
-test();
+function g(x, y, z) { return %_ArgumentsLength(); }
+
+for (var i = 0; i < 5; ++i) f();
+%OptimizeFunctionOnNextCall(f);
+assertEquals(3, f());
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/compiler/regress-96989.js
similarity index 85%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/compiler/regress-96989.js
index edbcb19..aedeb24 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/compiler/regress-96989.js
@@ -25,12 +25,19 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+
+// Flags: --allow-natives-syntax
+
+// Test correct handling of uninitialized const.
 
 function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+  for (var i = 41; i < 42; i++) {
+    var c = t ^ i;
+  }
+  const t;
+  return c;
 }
 
-test();
+for (var i=0; i<10; i++) test();
+%OptimizeFunctionOnNextCall(test);
+assertEquals(41, test());
diff --git a/test/mjsunit/bugs/bug-1412.js b/test/mjsunit/compiler/regress-const.js
similarity index 73%
copy from test/mjsunit/bugs/bug-1412.js
copy to test/mjsunit/compiler/regress-const.js
index 8e700d5..aa55d0f 100644
--- a/test/mjsunit/bugs/bug-1412.js
+++ b/test/mjsunit/compiler/regress-const.js
@@ -25,10 +25,44 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-function f() { "use strict"; print(this); }
+// Flags: --allow-natives-syntax
 
-function g() { assertEquals(void 0, f.apply(undefined, arguments)); }
+// Test const initialization and assignments.
+function f() {
+  var x = 42;
+  while (true) {
+    const y = x;
+    if (--x == 0) return y;
+  }
+}
 
-for (var i = 0; i < 10; i++) g();
+function g() {
+  const x = 42;
+  x += 1;
+  return x;
+}
+
+for (var i = 0; i < 5; i++) {
+  f();
+  g();
+}
+
+%OptimizeFunctionOnNextCall(f);
 %OptimizeFunctionOnNextCall(g);
-g();
+
+assertEquals(42, f());
+assertEquals(42, g());
+
+
+function h(a, b) {
+  var r = a + b;
+  const X = 42;
+  return r + X;
+}
+
+for (var i = 0; i < 5; i++) h(1,2);
+
+%OptimizeFunctionOnNextCall(h);
+
+assertEquals(45, h(1,2));
+assertEquals("foo742", h("foo", 7));
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/compiler/regress-max-locals-for-osr.js
similarity index 75%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/compiler/regress-max-locals-for-osr.js
index edbcb19..cc150ed 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/compiler/regress-max-locals-for-osr.js
@@ -25,12 +25,19 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --allow-natives-syntax
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+var limit = %RunningInSimulator() ? 10000 : 10000000;
+
+function f() {
+  var a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+      a11, a12, a13, a14, a15, a16, a17, a18, a19, a20,
+      a21, a22, a23, a24, a25, a26, a27, a28, a29, a30,
+      a31, a32, a33, a34, a35, a36, a37, a38, a39, a40,
+      a41, a42, a43, a44, a45, a46, a47, a48, a49, a50,
+      a51, a52, a53, a54, a55, a56, a57, a58, a59, a60,
+      a61, a62, a63, a64;
+  for (a1 = 0; a1 < limit; a1++) a2 = 23;
 }
 
-test();
+f();
diff --git a/test/mjsunit/date-parse.js b/test/mjsunit/date-parse.js
index 23a6993..a1eef66 100644
--- a/test/mjsunit/date-parse.js
+++ b/test/mjsunit/date-parse.js
@@ -285,9 +285,9 @@
 
 // Negative tests.
 var testCasesNegative = [
-    'May 25 2008 1:30 (PM)) UTC',
-    'May 25 2008 1:30( )AM (PM)',
-    'May 25 2008 AAA (GMT)'];
+    'May 25 2008 1:30 (PM)) UTC',  // Bad unmatched ')' after number.
+    'May 25 2008 1:30( )AM (PM)',  // 
+    'May 25 2008 AAA (GMT)'];      // Unknown word after number.
 
 testCasesNegative.forEach(function (s) {
     assertTrue(isNaN(Date.parse(s)), s + " is not NaN.");
diff --git a/test/mjsunit/date.js b/test/mjsunit/date.js
index f13af82..a7f6cfa 100644
--- a/test/mjsunit/date.js
+++ b/test/mjsunit/date.js
@@ -187,3 +187,123 @@
 assertTrue(isNaN(d.getTime()));
 d = new Date(1969, 12, 1, -Infinity);
 assertTrue(isNaN(d.getTime()));
+
+// Parsing ES5 ISO-8601 dates.
+// When TZ is omitted, it defaults to 'Z' meaning UTC.
+
+// Check epoch.
+assertEquals(0, Date.parse("1970-01-01T00:00:00.000+00:00"));
+assertEquals(0, Date.parse("1970-01-01T00:00:00.000-00:00"));
+assertEquals(0, Date.parse("1970-01-01T00:00:00.000Z"));
+assertEquals(0, Date.parse("1970-01-01T00:00:00.000"));
+assertEquals(0, Date.parse("1970-01-01T00:00:00"));
+assertEquals(0, Date.parse("1970-01-01T00:00"));
+assertEquals(0, Date.parse("1970-01-01"));
+
+assertEquals(0, Date.parse("1970-01T00:00:00.000+00:00"));
+assertEquals(0, Date.parse("1970-01T00:00:00.000-00:00"));
+assertEquals(0, Date.parse("1970-01T00:00:00.000Z"));
+assertEquals(0, Date.parse("1970-01T00:00:00.000"));
+assertEquals(0, Date.parse("1970-01T00:00:00"));
+assertEquals(0, Date.parse("1970-01T00:00"));
+assertEquals(0, Date.parse("1970-01"));
+
+assertEquals(0, Date.parse("1970T00:00:00.000+00:00"));
+assertEquals(0, Date.parse("1970T00:00:00.000-00:00"));
+assertEquals(0, Date.parse("1970T00:00:00.000Z"));
+assertEquals(0, Date.parse("1970T00:00:00.000"));
+assertEquals(0, Date.parse("1970T00:00:00"));
+assertEquals(0, Date.parse("1970T00:00"));
+assertEquals(0, Date.parse("1970"));
+
+assertEquals(0, Date.parse("+001970-01-01T00:00:00.000+00:00"));
+assertEquals(0, Date.parse("+001970-01-01T00:00:00.000-00:00"));
+assertEquals(0, Date.parse("+001970-01-01T00:00:00.000Z"));
+assertEquals(0, Date.parse("+001970-01-01T00:00:00.000"));
+assertEquals(0, Date.parse("+001970-01-01T00:00:00"));
+assertEquals(0, Date.parse("+001970-01-01T00:00"));
+assertEquals(0, Date.parse("+001970-01-01"));
+
+assertEquals(0, Date.parse("+001970-01T00:00:00.000+00:00"));
+assertEquals(0, Date.parse("+001970-01T00:00:00.000-00:00"));
+assertEquals(0, Date.parse("+001970-01T00:00:00.000Z"));
+assertEquals(0, Date.parse("+001970-01T00:00:00.000"));
+assertEquals(0, Date.parse("+001970-01T00:00:00"));
+assertEquals(0, Date.parse("+001970-01T00:00"));
+assertEquals(0, Date.parse("+001970-01"));
+
+assertEquals(0, Date.parse("+001970T00:00:00.000+00:00"));
+assertEquals(0, Date.parse("+001970T00:00:00.000-00:00"));
+assertEquals(0, Date.parse("+001970T00:00:00.000Z"));
+assertEquals(0, Date.parse("+001970T00:00:00.000"));
+assertEquals(0, Date.parse("+001970T00:00:00"));
+assertEquals(0, Date.parse("+001970T00:00"));
+assertEquals(0, Date.parse("+001970"));
+
+// Check random date.
+assertEquals(70671003500, Date.parse("1972-03-28T23:50:03.500+01:00"));
+assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z"));
+assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500"));
+assertEquals(70674603000, Date.parse("1972-03-28T23:50:03"));
+assertEquals(70674600000, Date.parse("1972-03-28T23:50"));
+assertEquals(70588800000, Date.parse("1972-03-28"));
+
+assertEquals(68338203500, Date.parse("1972-03T23:50:03.500+01:00"));
+assertEquals(68341803500, Date.parse("1972-03T23:50:03.500Z"));
+assertEquals(68341803500, Date.parse("1972-03T23:50:03.500"));
+assertEquals(68341803000, Date.parse("1972-03T23:50:03"));
+assertEquals(68341800000, Date.parse("1972-03T23:50"));
+assertEquals(68256000000, Date.parse("1972-03"));
+
+assertEquals(63154203500, Date.parse("1972T23:50:03.500+01:00"));
+assertEquals(63157803500, Date.parse("1972T23:50:03.500Z"));
+assertEquals(63157803500, Date.parse("1972T23:50:03.500"));
+assertEquals(63157803000, Date.parse("1972T23:50:03"));
+assertEquals(63072000000, Date.parse("1972"));
+
+assertEquals(70671003500, Date.parse("+001972-03-28T23:50:03.500+01:00"));
+assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500Z"));
+assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500"));
+assertEquals(70674603000, Date.parse("+001972-03-28T23:50:03"));
+assertEquals(70674600000, Date.parse("+001972-03-28T23:50"));
+assertEquals(70588800000, Date.parse("+001972-03-28"));
+
+assertEquals(68338203500, Date.parse("+001972-03T23:50:03.500+01:00"));
+assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500Z"));
+assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500"));
+assertEquals(68341803000, Date.parse("+001972-03T23:50:03"));
+assertEquals(68341800000, Date.parse("+001972-03T23:50"));
+assertEquals(68256000000, Date.parse("+001972-03"));
+
+assertEquals(63154203500, Date.parse("+001972T23:50:03.500+01:00"));
+assertEquals(63157803500, Date.parse("+001972T23:50:03.500Z"));
+assertEquals(63157803500, Date.parse("+001972T23:50:03.500"));
+assertEquals(63157803000, Date.parse("+001972T23:50:03"));
+assertEquals(63072000000, Date.parse("+001972"));
+
+
+// Ensure that ISO-years in the range 00-99 aren't translated to the range
+// 1950..2049.
+assertEquals(-60904915200000, Date.parse("0040-01-01"));
+assertEquals(-60273763200000, Date.parse("0060-01-01"));
+assertEquals(-62167219200000, Date.parse("0000-01-01"));
+assertEquals(-62167219200000, Date.parse("+000000-01-01"));
+
+// Test negative years.
+assertEquals(-63429523200000, Date.parse("-000040-01-01"));
+assertEquals(-64060675200000, Date.parse("-000060-01-01"));
+assertEquals(-124397510400000, Date.parse("-001972-01-01"));
+
+// Check time-zones.
+assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z"));
+for (var i = 0; i < 24; i++) {
+  var hh = (i < 10) ? "0" + i : "" + i;
+  for (var j = 0; j < 60; j += 15) {
+    var mm = (j < 10) ? "0" + j : "" + j;
+    var ms = (i * 60 + j) * 60000;
+    var string = "1972-03-28T23:50:03.500-" + hh + ":" + mm;
+    assertEquals(70674603500 + ms, Date.parse(string), string);
+    string = "1972-03-28T23:50:03.500+" + hh + ":" + mm;
+    assertEquals(70674603500 - ms, Date.parse(string), string);
+  }
+}
diff --git a/test/mjsunit/debug-backtrace.js b/test/mjsunit/debug-backtrace.js
index d15b2d2..3647913 100644
--- a/test/mjsunit/debug-backtrace.js
+++ b/test/mjsunit/debug-backtrace.js
@@ -195,7 +195,7 @@
       assertEquals("m", response.lookup(frame.func.ref).inferredName);
       assertFalse(frame.constructCall);
       assertEquals(35, frame.line);
-      assertEquals(2, frame.column);
+      assertEquals(6, frame.column);
       assertEquals(0, frame.arguments.length);
 
       json = '{"seq":0,"type":"request","command":"frame","arguments":{"number":3}}'
@@ -269,4 +269,3 @@
 // Make sure that the debug event listener vas invoked.
 assertFalse(exception, "exception in listener");
 assertTrue(listenerCalled);
-
diff --git a/test/mjsunit/debug-evaluate-locals-optimized-double.js b/test/mjsunit/debug-evaluate-locals-optimized-double.js
new file mode 100644
index 0000000..9ed1dbb
--- /dev/null
+++ b/test/mjsunit/debug-evaluate-locals-optimized-double.js
@@ -0,0 +1,183 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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 --allow-natives-syntax
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var listenerComplete = false;
+var exception = false;
+
+var testingConstructCall = false;
+
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break)
+    {
+      assertEquals(6, exec_state.frameCount());
+
+      for (var i = 0; i < exec_state.frameCount(); i++) {
+        var frame = exec_state.frame(i);
+        if (i < exec_state.frameCount() - 1) {
+          var expected_a = i * 2 + 1 + (i * 2 + 1) / 100;
+          var expected_b = i * 2 + 2 + (i * 2 + 2) / 100;
+          var expected_x = (i + 1) * 2 + 1 + ((i + 1) * 2 + 1) / 100;
+          var expected_y = (i + 1) * 2 + 2 + ((i + 1) * 2 + 2) / 100;
+
+          // All frames except the bottom one has normal variables a and b.
+          assertEquals('a', frame.localName(0));
+          assertEquals('b', frame.localName(1));
+          assertEquals(expected_a, frame.localValue(0).value());
+          assertEquals(expected_b, frame.localValue(1).value());
+
+          // All frames except the bottom one has arguments variables x and y.
+          assertEquals('x', frame.argumentName(0));
+          assertEquals('y', frame.argumentName(1));
+          assertEquals(expected_x, frame.argumentValue(0).value());
+          assertEquals(expected_y, frame.argumentValue(1).value());
+
+          // All frames except the bottom one have two scopes.
+          assertEquals(2, frame.scopeCount());
+          assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
+          assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
+          assertEquals(expected_a, frame.scope(0).scopeObject().value()['a']);
+          assertEquals(expected_b, frame.scope(0).scopeObject().value()['b']);
+          assertEquals(expected_x, frame.scope(0).scopeObject().value()['x']);
+          assertEquals(expected_y, frame.scope(0).scopeObject().value()['y']);
+
+          // Evaluate in the inlined frame.
+          assertEquals(expected_a, frame.evaluate('a').value());
+          assertEquals(expected_x, frame.evaluate('x').value());
+          assertEquals(expected_x, frame.evaluate('arguments[0]').value());
+          assertEquals(expected_a + expected_b + expected_x + expected_y,
+                       frame.evaluate('a + b + x + y').value());
+          assertEquals(expected_x + expected_y,
+                       frame.evaluate('arguments[0] + arguments[1]').value());
+        } else {
+          // The bottom frame only have the global scope.
+          assertEquals(1, frame.scopeCount());
+          assertEquals(debug.ScopeType.Global, frame.scope(0).scopeType());
+        }
+
+        // Check the frame function.
+        switch (i) {
+          case 0: assertEquals(h, frame.func().value()); break;
+          case 1: assertEquals(g3, frame.func().value()); break;
+          case 2: assertEquals(g2, frame.func().value()); break;
+          case 3: assertEquals(g1, frame.func().value()); break;
+          case 4: assertEquals(f, frame.func().value()); break;
+          case 5: break;
+          default: assertUnreachable();
+        }
+
+        // Check for construct call.
+        assertEquals(testingConstructCall && i == 4, frame.isConstructCall());
+
+        // When function f is optimized (1 means YES, see runtime.cc) we
+        // expect an optimized frame for f with g1, g2 and g3 inlined.
+        if (%GetOptimizationStatus(f) == 1) {
+          if (i == 1 || i == 2 || i == 3) {
+            assertTrue(frame.isOptimizedFrame());
+            assertTrue(frame.isInlinedFrame());
+            assertEquals(4 - i, frame.inlinedFrameIndex());
+          } else if (i == 4) {
+            assertTrue(frame.isOptimizedFrame());
+            assertFalse(frame.isInlinedFrame());
+          } else {
+            assertFalse(frame.isOptimizedFrame());
+            assertFalse(frame.isInlinedFrame());
+          }
+        }
+      }
+
+      // Indicate that all was processed.
+      listenerComplete = true;
+    }
+  } catch (e) {
+    exception = e
+  };
+};
+
+f();f();f();
+%OptimizeFunctionOnNextCall(f);
+f();
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function h(x, y) {
+  var a = 1;
+  var b = 2;
+  a = a + a / 100;
+  b = b + b / 100;
+  debugger;  // Breakpoint.
+};
+
+function g3(x, y) {
+  var a = 3;
+  var b = 4;
+  a = a + a / 100;
+  b = b + b / 100;
+  h(a, b);
+  return a+b;
+};
+
+function g2(x, y) {
+  var a = 5;
+  var b = 6;
+  a = a + a / 100;
+  b = b + b / 100;
+  g3(a, b);
+};
+
+function g1(x, y) {
+  var a = 7;
+  var b = 8;
+  a = a + a / 100;
+  b = b + b / 100;
+  g2(a, b);
+};
+
+function f(x, y) {
+  var a = 9;
+  var b = 10;
+  a = a + a / 100;
+  b = b + b / 100;
+  g1(a, b);
+};
+
+// Test calling f normally and as a constructor.
+f(11.11, 12.12);
+testingConstructCall = true;
+new f(11.11, 12.12);
+
+// Make sure that the debug event listener vas invoked.
+assertFalse(exception, "exception in listener " + exception)
+assertTrue(listenerComplete);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-evaluate-locals-optimized.js b/test/mjsunit/debug-evaluate-locals-optimized.js
new file mode 100644
index 0000000..683c139
--- /dev/null
+++ b/test/mjsunit/debug-evaluate-locals-optimized.js
@@ -0,0 +1,172 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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 --allow-natives-syntax
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var listenerComplete = false;
+var exception = false;
+
+var testingConstructCall = false;
+
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break)
+    {
+      assertEquals(6, exec_state.frameCount());
+
+      for (var i = 0; i < exec_state.frameCount(); i++) {
+        var frame = exec_state.frame(i);
+        if (i < exec_state.frameCount() - 1) {
+          var expected_a = i * 2 + 1;
+          var expected_b = i * 2 + 2;
+          var expected_x = (i + 1) * 2 + 1;
+          var expected_y = (i + 1) * 2 + 2;
+
+          // All frames except the bottom one has normal variables a and b.
+          assertEquals('a', frame.localName(0));
+          assertEquals('b', frame.localName(1));
+          assertEquals(expected_a, frame.localValue(0).value());
+          assertEquals(expected_b, frame.localValue(1).value());
+
+          // All frames except the bottom one has arguments variables x and y.
+          assertEquals('x', frame.argumentName(0));
+          assertEquals('y', frame.argumentName(1));
+          assertEquals(expected_x, frame.argumentValue(0).value());
+          assertEquals(expected_y, frame.argumentValue(1).value());
+
+          // All frames except the bottom one have two scopes.
+          assertEquals(2, frame.scopeCount());
+          assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
+          assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
+          assertEquals(expected_a, frame.scope(0).scopeObject().value()['a']);
+          assertEquals(expected_b, frame.scope(0).scopeObject().value()['b']);
+          assertEquals(expected_x, frame.scope(0).scopeObject().value()['x']);
+          assertEquals(expected_y, frame.scope(0).scopeObject().value()['y']);
+
+          // Evaluate in the inlined frame.
+          assertEquals(expected_a, frame.evaluate('a').value());
+          assertEquals(expected_x, frame.evaluate('x').value());
+          assertEquals(expected_x, frame.evaluate('arguments[0]').value());
+          assertEquals(expected_a + expected_b + expected_x + expected_y,
+                       frame.evaluate('a + b + x + y').value());
+          assertEquals(expected_x + expected_y,
+                       frame.evaluate('arguments[0] + arguments[1]').value());
+        } else {
+          // The bottom frame only have the global scope.
+          assertEquals(1, frame.scopeCount());
+          assertEquals(debug.ScopeType.Global, frame.scope(0).scopeType());
+        }
+
+        // Check the frame function.
+        switch (i) {
+          case 0: assertEquals(h, frame.func().value()); break;
+          case 1: assertEquals(g3, frame.func().value()); break;
+          case 2: assertEquals(g2, frame.func().value()); break;
+          case 3: assertEquals(g1, frame.func().value()); break;
+          case 4: assertEquals(f, frame.func().value()); break;
+          case 5: break;
+          default: assertUnreachable();
+        }
+
+        // Check for construct call.
+        assertEquals(testingConstructCall && i == 4, frame.isConstructCall());
+
+        // When function f is optimized (1 means YES, see runtime.cc) we
+        // expect an optimized frame for f with g1, g2 and g3 inlined.
+        if (%GetOptimizationStatus(f) == 1) {
+          if (i == 1 || i == 2 || i == 3) {
+            assertTrue(frame.isOptimizedFrame());
+            assertTrue(frame.isInlinedFrame());
+            assertEquals(4 - i, frame.inlinedFrameIndex());
+          } else if (i == 4) {
+            assertTrue(frame.isOptimizedFrame());
+            assertFalse(frame.isInlinedFrame());
+          } else {
+            assertFalse(frame.isOptimizedFrame());
+            assertFalse(frame.isInlinedFrame());
+          }
+        }
+      }
+
+      // Indicate that all was processed.
+      listenerComplete = true;
+    }
+  } catch (e) {
+    exception = e
+  };
+};
+
+f();f();f();
+%OptimizeFunctionOnNextCall(f);
+f();
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function h(x, y) {
+  var a = 1;
+  var b = 2;
+  debugger;  // Breakpoint.
+};
+
+function g3(x, y) {
+  var a = 3;
+  var b = 4;
+  h(a, b);
+};
+
+function g2(x, y) {
+  var a = 5;
+  var b = 6;
+  g3(a, b);
+};
+
+function g1(x, y) {
+  var a = 7;
+  var b = 8;
+  g2(a, b);
+};
+
+function f(x, y) {
+  var a = 9;
+  var b = 10;
+  g1(a, b);
+};
+
+// Test calling f normally and as a constructor.
+f(11, 12);
+testingConstructCall = true;
+new f(11, 12);
+
+// Make sure that the debug event listener vas invoked.
+assertFalse(exception, "exception in listener " + exception)
+assertTrue(listenerComplete);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-evaluate-locals.js b/test/mjsunit/debug-evaluate-locals.js
index 4b87829..61b6dd9 100644
--- a/test/mjsunit/debug-evaluate-locals.js
+++ b/test/mjsunit/debug-evaluate-locals.js
@@ -33,33 +33,73 @@
 exception = false;
 
 
-function checkFrame0(name, value) {
-  assertTrue(name == 'a' || name == 'b');
-  if (name == 'a') {
-    assertEquals(1, value);
-  }
-  if (name == 'b') {
-    assertEquals(2, value);
+function h() {
+  var a = 1;
+  var b = 2;
+  debugger;  // Breakpoint.
+}
+
+function checkFrame0(frame) {
+  // Frame 0 (h) has normal variables a and b.
+  var count = frame.localCount();
+  assertEquals(2, count);
+  for (var i = 0; i < count; ++i) {
+    var name = frame.localName(i);
+    var value = frame.localValue(i).value();
+    if (name == 'a') {
+      assertEquals(1, value);
+    } else {
+      assertEquals('b', name);
+      assertEquals(2, value);
+    }
   }
 }
 
 
-function checkFrame1(name, value) {
-  assertTrue(name == '.arguments' || name == 'a');
-  if (name == 'a') {
-    assertEquals(3, value);
+function g() {
+  var a = 3;
+  eval("var b = 4;");
+  h();
+}
+
+function checkFrame1(frame) {
+  // Frame 1 (g) has normal variable a (and arguments).
+  var count = frame.localCount();
+  assertEquals(2, count);
+  for (var i = 0; i < count; ++i) {
+    var name = frame.localName(i);
+    var value = frame.localValue(i).value();
+    if (name == 'a') {
+      assertEquals(3, value);
+    } else {
+      assertEquals('arguments', name);
+    }
   }
 }
 
 
-function checkFrame2(name, value) {
-  assertTrue(name == '.arguments' || name == 'a' ||
-             name == 'arguments' || name == 'b');
-  if (name == 'a') {
-    assertEquals(5, value);
+function f() {
+  var a = 5;
+  var b = 0;
+  with ({b:6}) {
+    g();
   }
-  if (name == 'b') {
-    assertEquals(0, value);
+}
+
+function checkFrame2(frame) {
+  // Frame 2 (f) has normal variables a and b (and arguments).
+  var count = frame.localCount();
+  assertEquals(3, count);
+  for (var i = 0; i < count; ++i) {
+    var name = frame.localName(i);
+    var value = frame.localValue(i).value();
+    if (name == 'a') {
+      assertEquals(5, value);
+    } else if (name == 'b') {
+      assertEquals(0, value);
+    } else {
+      assertEquals('arguments', name);
+    }
   }
 }
 
@@ -68,23 +108,9 @@
   try {
     if (event == Debug.DebugEvent.Break)
     {
-      // Frame 0 has normal variables a and b.
-      var frame0 = exec_state.frame(0);
-      checkFrame0(frame0.localName(0), frame0.localValue(0).value());
-      checkFrame0(frame0.localName(1), frame0.localValue(1).value());
-
-      // Frame 1 has normal variable a (and the .arguments variable).
-      var frame1 = exec_state.frame(1);
-      checkFrame1(frame1.localName(0), frame1.localValue(0).value());
-      checkFrame1(frame1.localName(1), frame1.localValue(1).value());
-
-      // Frame 2 has normal variables a and b (and both the .arguments and
-      // arguments variable).
-      var frame2 = exec_state.frame(2);
-      checkFrame2(frame2.localName(0), frame2.localValue(0).value());
-      checkFrame2(frame2.localName(1), frame2.localValue(1).value());
-      checkFrame2(frame2.localName(2), frame2.localValue(2).value());
-      checkFrame2(frame2.localName(3), frame2.localValue(3).value());
+      checkFrame0(exec_state.frame(0));
+      checkFrame1(exec_state.frame(1));
+      checkFrame2(exec_state.frame(2));
 
       // Evaluating a and b on frames 0, 1 and 2 produces 1, 2, 3, 4, 5 and 6.
       assertEquals(1, exec_state.frame(0).evaluate('a').value());
@@ -105,26 +131,6 @@
 // Add the debug event listener.
 Debug.setListener(listener);
 
-function h() {
-  var a = 1;
-  var b = 2;
-  debugger;  // Breakpoint.
-};
-
-function g() {
-  var a = 3;
-  eval("var b = 4;");
-  h();
-};
-
-function f() {
-  var a = 5;
-  var b = 0;
-  with ({b:6}) {
-    g();
-  }
-};
-
 f();
 
 // Make sure that the debug event listener vas invoked.
diff --git a/test/mjsunit/debug-receiver.js b/test/mjsunit/debug-receiver.js
new file mode 100644
index 0000000..21cdde8
--- /dev/null
+++ b/test/mjsunit/debug-receiver.js
@@ -0,0 +1,126 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug;
+
+var test_name;
+var listener_delegate;
+var listener_called;
+var exception;
+var expected_receiver;
+var begin_test_count = 0;
+var end_test_count = 0;
+var break_count = 0;
+
+// Debug event listener which delegates. Exceptions have to be
+// explictly caught here and checked later because exception in the
+// listener are not propagated to the surrounding JavaScript code.
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      break_count++;
+      listener_called = true;
+      listener_delegate(exec_state);
+    }
+  } catch (e) {
+    exception = e;
+  }
+}
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+
+// Initialize for a new test.
+function BeginTest(name) {
+  test_name = name;
+  listener_called = false;
+  exception = null;
+  begin_test_count++;
+}
+
+
+// Check result of a test.
+function EndTest() {
+  assertTrue(listener_called, "listerner not called for " + test_name);
+  assertNull(exception, test_name);
+  end_test_count++;
+}
+
+
+// Check that the debugger correctly reflects that the receiver is not
+// converted to object for strict mode functions.
+function Strict() { "use strict"; debugger; }
+function TestStrict(receiver) {
+  expected_receiver = receiver;
+  Strict.call(receiver);
+}
+
+listener_delegate = function(exec_state) {
+  var receiver = exec_state.frame().receiver();
+  assertTrue(!receiver.isObject());
+  assertEquals(expected_receiver, receiver.value())
+}
+
+BeginTest("strict: undefined"); TestStrict(undefined); EndTest();
+BeginTest("strict: null"); TestStrict(null); EndTest();
+BeginTest("strict: 1"); TestStrict(1); EndTest();
+BeginTest("strict: 1.2"); TestStrict(1.2); EndTest();
+BeginTest("strict: 'asdf'"); TestStrict('asdf'); EndTest();
+BeginTest("strict: true"); TestStrict(true); EndTest();
+
+
+// Check that the debugger correctly reflects the object conversion of
+// the receiver for non-strict mode functions.
+function NonStrict() { debugger; }
+function TestNonStrict(receiver) {
+  // null and undefined should be transformed to the global object and
+  // primitives should be wrapped.
+  expected_receiver = (receiver == null) ? this : Object(receiver);
+  NonStrict.call(receiver);
+}
+
+listener_delegate = function(exec_state) {
+  var receiver = exec_state.frame().receiver();
+  assertTrue(receiver.isObject());
+  assertEquals(expected_receiver, receiver.value());
+}
+
+BeginTest("non-strict: undefined"); TestNonStrict(undefined); EndTest();
+BeginTest("non-strict: null"); TestNonStrict(null); EndTest();
+BeginTest("non-strict: 1"); TestNonStrict(1); EndTest();
+BeginTest("non-strict: 1.2"); TestNonStrict(1.2); EndTest();
+BeginTest("non-strict: 'asdf'"); TestNonStrict('asdf'); EndTest();
+BeginTest("non-strict: true"); TestNonStrict(true); EndTest();
+
+
+assertEquals(begin_test_count, break_count,
+             'one or more tests did not enter the debugger');
+assertEquals(begin_test_count, end_test_count,
+             'one or more tests did not have its result checked');
diff --git a/test/mjsunit/div-mod.js b/test/mjsunit/div-mod.js
index 3e343de..c314495 100644
--- a/test/mjsunit/div-mod.js
+++ b/test/mjsunit/div-mod.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
+
 // Test fast div and mod.
 
 function divmod(div_func, mod_func, x, y) {
@@ -190,3 +192,113 @@
 }
 
 negative_zero_modulus_test();
+
+
+function lithium_integer_mod() {
+  var left_operands = [
+    0,
+    305419896,  // 0x12345678
+  ];
+
+  // Test the standard lithium code for modulo opeartions.
+  var mod_func;
+  for (var i = 0; i < left_operands.length; i++) {
+    for (var j = 0; j < divisors.length; j++) {
+      mod_func = this.eval("(function(left) { return left % " + divisors[j]+ "; })");
+      assertEquals((mod_func)(left_operands[i]), left_operands[i] % divisors[j]);
+      assertEquals((mod_func)(-left_operands[i]), -left_operands[i] % divisors[j]);
+    }
+  }
+
+  var results_powers_of_two = [
+    // 0
+    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    // 305419896 == 0x12345678
+    [0, 0, 0, 8, 24, 56, 120, 120, 120, 632, 1656, 1656, 5752, 5752, 22136, 22136, 22136, 22136, 284280, 284280, 1332856, 3430008, 3430008, 3430008, 3430008, 36984440, 36984440, 36984440, 305419896, 305419896, 305419896],
+  ];
+
+  // Test the lithium code for modulo operations with a variable power of two
+  // right hand side operand.
+  for (var i = 0; i < left_operands.length; i++) {
+    for (var j = 0; j < 31; j++) {
+      assertEquals(results_powers_of_two[i][j], left_operands[i] % (2 << j));
+      assertEquals(results_powers_of_two[i][j], left_operands[i] % -(2 << j));
+      assertEquals(-results_powers_of_two[i][j], -left_operands[i] % (2 << j));
+      assertEquals(-results_powers_of_two[i][j], -left_operands[i] % -(2 << j));
+    }
+  }
+
+  // Test the lithium code for modulo operations with a constant power of two
+  // right hand side operand.
+  for (var i = 0; i < left_operands.length; i++) {
+    // With positive left hand side operand.
+    assertEquals(results_powers_of_two[i][0], left_operands[i] % -(2 << 0));
+    assertEquals(results_powers_of_two[i][1], left_operands[i] % (2 << 1));
+    assertEquals(results_powers_of_two[i][2], left_operands[i] % -(2 << 2));
+    assertEquals(results_powers_of_two[i][3], left_operands[i] % (2 << 3));
+    assertEquals(results_powers_of_two[i][4], left_operands[i] % -(2 << 4));
+    assertEquals(results_powers_of_two[i][5], left_operands[i] % (2 << 5));
+    assertEquals(results_powers_of_two[i][6], left_operands[i] % -(2 << 6));
+    assertEquals(results_powers_of_two[i][7], left_operands[i] % (2 << 7));
+    assertEquals(results_powers_of_two[i][8], left_operands[i] % -(2 << 8));
+    assertEquals(results_powers_of_two[i][9], left_operands[i] % (2 << 9));
+    assertEquals(results_powers_of_two[i][10], left_operands[i] % -(2 << 10));
+    assertEquals(results_powers_of_two[i][11], left_operands[i] % (2 << 11));
+    assertEquals(results_powers_of_two[i][12], left_operands[i] % -(2 << 12));
+    assertEquals(results_powers_of_two[i][13], left_operands[i] % (2 << 13));
+    assertEquals(results_powers_of_two[i][14], left_operands[i] % -(2 << 14));
+    assertEquals(results_powers_of_two[i][15], left_operands[i] % (2 << 15));
+    assertEquals(results_powers_of_two[i][16], left_operands[i] % -(2 << 16));
+    assertEquals(results_powers_of_two[i][17], left_operands[i] % (2 << 17));
+    assertEquals(results_powers_of_two[i][18], left_operands[i] % -(2 << 18));
+    assertEquals(results_powers_of_two[i][19], left_operands[i] % (2 << 19));
+    assertEquals(results_powers_of_two[i][20], left_operands[i] % -(2 << 20));
+    assertEquals(results_powers_of_two[i][21], left_operands[i] % (2 << 21));
+    assertEquals(results_powers_of_two[i][22], left_operands[i] % -(2 << 22));
+    assertEquals(results_powers_of_two[i][23], left_operands[i] % (2 << 23));
+    assertEquals(results_powers_of_two[i][24], left_operands[i] % -(2 << 24));
+    assertEquals(results_powers_of_two[i][25], left_operands[i] % (2 << 25));
+    assertEquals(results_powers_of_two[i][26], left_operands[i] % -(2 << 26));
+    assertEquals(results_powers_of_two[i][27], left_operands[i] % (2 << 27));
+    assertEquals(results_powers_of_two[i][28], left_operands[i] % -(2 << 28));
+    assertEquals(results_powers_of_two[i][29], left_operands[i] % (2 << 29));
+    assertEquals(results_powers_of_two[i][30], left_operands[i] % -(2 << 30));
+    // With negative left hand side operand.
+    assertEquals(-results_powers_of_two[i][0], -left_operands[i] % -(2 << 0));
+    assertEquals(-results_powers_of_two[i][1], -left_operands[i] % (2 << 1));
+    assertEquals(-results_powers_of_two[i][2], -left_operands[i] % -(2 << 2));
+    assertEquals(-results_powers_of_two[i][3], -left_operands[i] % (2 << 3));
+    assertEquals(-results_powers_of_two[i][4], -left_operands[i] % -(2 << 4));
+    assertEquals(-results_powers_of_two[i][5], -left_operands[i] % (2 << 5));
+    assertEquals(-results_powers_of_two[i][6], -left_operands[i] % -(2 << 6));
+    assertEquals(-results_powers_of_two[i][7], -left_operands[i] % (2 << 7));
+    assertEquals(-results_powers_of_two[i][8], -left_operands[i] % -(2 << 8));
+    assertEquals(-results_powers_of_two[i][9], -left_operands[i] % (2 << 9));
+    assertEquals(-results_powers_of_two[i][10], -left_operands[i] % -(2 << 10));
+    assertEquals(-results_powers_of_two[i][11], -left_operands[i] % (2 << 11));
+    assertEquals(-results_powers_of_two[i][12], -left_operands[i] % -(2 << 12));
+    assertEquals(-results_powers_of_two[i][13], -left_operands[i] % (2 << 13));
+    assertEquals(-results_powers_of_two[i][14], -left_operands[i] % -(2 << 14));
+    assertEquals(-results_powers_of_two[i][15], -left_operands[i] % (2 << 15));
+    assertEquals(-results_powers_of_two[i][16], -left_operands[i] % -(2 << 16));
+    assertEquals(-results_powers_of_two[i][17], -left_operands[i] % (2 << 17));
+    assertEquals(-results_powers_of_two[i][18], -left_operands[i] % -(2 << 18));
+    assertEquals(-results_powers_of_two[i][19], -left_operands[i] % (2 << 19));
+    assertEquals(-results_powers_of_two[i][20], -left_operands[i] % -(2 << 20));
+    assertEquals(-results_powers_of_two[i][21], -left_operands[i] % (2 << 21));
+    assertEquals(-results_powers_of_two[i][22], -left_operands[i] % -(2 << 22));
+    assertEquals(-results_powers_of_two[i][23], -left_operands[i] % (2 << 23));
+    assertEquals(-results_powers_of_two[i][24], -left_operands[i] % -(2 << 24));
+    assertEquals(-results_powers_of_two[i][25], -left_operands[i] % (2 << 25));
+    assertEquals(-results_powers_of_two[i][26], -left_operands[i] % -(2 << 26));
+    assertEquals(-results_powers_of_two[i][27], -left_operands[i] % (2 << 27));
+    assertEquals(-results_powers_of_two[i][28], -left_operands[i] % -(2 << 28));
+    assertEquals(-results_powers_of_two[i][29], -left_operands[i] % (2 << 29));
+    assertEquals(-results_powers_of_two[i][30], -left_operands[i] % -(2 << 30));
+  }
+
+}
+
+lithium_integer_mod();
+%OptimizeFunctionOnNextCall(lithium_integer_mod)
+lithium_integer_mod();
diff --git a/test/mjsunit/element-kind.js b/test/mjsunit/element-kind.js
new file mode 100644
index 0000000..48a029f
--- /dev/null
+++ b/test/mjsunit/element-kind.js
@@ -0,0 +1,102 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+// Test element kind of objects
+
+var element_kind = {
+  fast_elements                     :  1,
+  fast_double_elements              :  2,
+  dictionary_elements               :  3,
+  external_byte_elements            :  4,
+  external_unsigned_byte_elements   :  5,
+  external_short_elements           :  6,
+  external_unsigned_short_elements  :  7,
+  external_int_elements             :  8,
+  external_unsigned_int_elements    :  9,
+  external_float_elements           : 10,
+  external_double_elements          : 11,
+  external_pixel_elements           : 12
+}
+
+// We expect an object to only be of one element kind.
+function assertKind(expected, obj){
+  assertEquals(expected == element_kind.fast_elements,
+               %HasFastElements(obj));
+  assertEquals(expected == element_kind.fast_double_elements,
+               %HasFastDoubleElements(obj));
+  assertEquals(expected == element_kind.dictionary_elements,
+               %HasDictionaryElements(obj));
+  assertEquals(expected == element_kind.external_byte_elements,
+               %HasExternalByteElements(obj));
+  assertEquals(expected == element_kind.external_unsigned_byte_elements,
+               %HasExternalUnsignedByteElements(obj));
+  assertEquals(expected == element_kind.external_short_elements,
+               %HasExternalShortElements(obj));
+  assertEquals(expected == element_kind.external_unsigned_short_elements,
+               %HasExternalUnsignedShortElements(obj));
+  assertEquals(expected == element_kind.external_int_elements,
+               %HasExternalIntElements(obj));
+  assertEquals(expected == element_kind.external_unsigned_int_elements,
+               %HasExternalUnsignedIntElements(obj));
+  assertEquals(expected == element_kind.external_float_elements,
+               %HasExternalFloatElements(obj));
+  assertEquals(expected == element_kind.external_double_elements,
+               %HasExternalDoubleElements(obj));
+  assertEquals(expected == element_kind.external_pixel_elements,
+               %HasExternalPixelElements(obj));
+  // every external kind is also an external array
+  assertEquals(expected >= element_kind.external_byte_elements,
+               %HasExternalArrayElements(obj));
+}
+
+var me = {};
+assertKind(element_kind.fast_elements, me);
+me.dance = 0xD15C0;
+me.drink = 0xC0C0A;
+assertKind(element_kind.fast_elements, me);
+
+var you = new Array();
+for(i = 0; i < 1337; i++) {
+  you[i] = i;
+}
+assertKind(element_kind.fast_elements, you);
+
+assertKind(element_kind.dictionary_elements, new Array(0xC0C0A));
+
+// fast_double_elements not yet available
+
+
+assertKind(element_kind.external_byte_elements,           new Int8Array(9001));
+assertKind(element_kind.external_unsigned_byte_elements,  new Uint8Array(007));
+assertKind(element_kind.external_short_elements,          new Int16Array(666));
+assertKind(element_kind.external_unsigned_short_elements, new Uint16Array(42));
+assertKind(element_kind.external_int_elements,            new Int32Array(0xF));
+assertKind(element_kind.external_unsigned_int_elements,   new Uint32Array(23));
+assertKind(element_kind.external_float_elements,          new Float32Array(7));
+assertKind(element_kind.external_double_elements,         new Float64Array(0));
+assertKind(element_kind.external_pixel_elements,          new PixelArray(512));
diff --git a/test/mjsunit/error-constructors.js b/test/mjsunit/error-constructors.js
index 8f463fc..966a162 100644
--- a/test/mjsunit/error-constructors.js
+++ b/test/mjsunit/error-constructors.js
@@ -59,3 +59,24 @@
 ReferenceError.prototype.name = "not a reference error";
 assertEquals("ReferenceError", ReferenceError.prototype.name);
 
+// Check that message and name are not enumerable on Error objects.
+var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name');
+assertFalse(desc['enumerable']);
+desc = Object.getOwnPropertyDescriptor(Error.prototype, 'message');
+assertFalse(desc['enumerable']);
+
+var e = new Error("foobar");
+desc = Object.getOwnPropertyDescriptor(e, 'message');
+assertFalse(desc['enumerable']);
+desc = Object.getOwnPropertyDescriptor(e, 'arguments');
+assertFalse(desc['enumerable']);
+desc = Object.getOwnPropertyDescriptor(e, 'type');
+assertFalse(desc['enumerable']);
+desc = Object.getOwnPropertyDescriptor(e, 'stack');
+assertFalse(desc['enumerable']);
+
+// name is not tested above, but in addition we should have no enumerable
+// properties, so we simply assert that.
+for (var v in e) {
+  assertUnreachable();
+}
diff --git a/test/mjsunit/external-array.js b/test/mjsunit/external-array.js
index 32b2c0c..94105ec 100644
--- a/test/mjsunit/external-array.js
+++ b/test/mjsunit/external-array.js
@@ -87,8 +87,10 @@
 
 test_result_nan = [NaN, 0, 0, 0, 0, 0, 0, 0, NaN, NaN];
 test_result_low_int = [-1, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1, -1];
+test_result_low_double = [-1.25, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1.25, -1.25];
 test_result_middle = [253.75, -3, 253, 253, 253, 253, 253, 254, 253.75, 253.75];
 test_result_high_int = [256, 0, 0, 256, 256, 256, 256, 255, 256, 256];
+test_result_high_double = [256.25, 0, 0, 256, 256, 256, 256, 255, 256.25, 256.25];
 
 const kElementCount = 40;
 
@@ -120,15 +122,27 @@
   return sum;
 }
 
+function zero() {
+  return 0.0;
+}
 
-function test_store_middle_double(array, sum) {
+function test_store_middle_tagged(array, sum) {
   array[0] = 253.75;
   return array[0];
 }
 
+function test_store_high_tagged(array, sum) {
+  array[0] = 256.25;
+  return array[0];
+}
+
+function test_store_middle_double(array, sum) {
+  array[0] = 253.75 + zero(); // + forces double type feedback
+  return array[0];
+}
 
 function test_store_high_double(array, sum) {
-  array[0] = 256.25;
+  array[0] = 256.25 + zero(); // + forces double type feedback
   return array[0];
 }
 
@@ -142,6 +156,16 @@
   return array[0];
 }
 
+function test_store_low_tagged(array, sum) {
+  array[0] = -1.25;
+  return array[0];
+}
+
+function test_store_low_double(array, sum) {
+  array[0] = -1.25 + zero(); // + forces double type feedback
+  return array[0];
+}
+
 function test_store_high_int(array, sum) {
   array[0] = 256;
   return array[0];
@@ -168,7 +192,6 @@
 
 for (var t = 0; t < types.length; t++) {
   var type = types[t];
-  print ("type = " + t);
   var a = new type(kElementCount);
   for (var i = 0; i < kElementCount; i++) {
     a[i] = i;
@@ -180,9 +203,14 @@
   run_test(test_store, a, 820 * kRuns);
   run_test(test_store_const_key, a, 6 * kRuns);
   run_test(test_store_low_int, a, test_result_low_int[t]);
+  run_test(test_store_low_double, a, test_result_low_double[t]);
+  run_test(test_store_low_tagged, a, test_result_low_double[t]);
   run_test(test_store_high_int, a, test_result_high_int[t]);
   run_test(test_store_nan, a, test_result_nan[t]);
   run_test(test_store_middle_double, a, test_result_middle[t]);
+  run_test(test_store_middle_tagged, a, test_result_middle[t]);
+  run_test(test_store_high_double, a, test_result_high_double[t]);
+  run_test(test_store_high_tagged, a, test_result_high_double[t]);
 
   // Test the correct behavior of the |length| property (which is read-only).
   if (t != 0) {
diff --git a/test/mjsunit/function-bind.js b/test/mjsunit/function-bind.js
index 7a72cd5..e9d0221 100644
--- a/test/mjsunit/function-bind.js
+++ b/test/mjsunit/function-bind.js
@@ -62,7 +62,7 @@
 
 function f_bound_this(z) {
   return z + this.y - this.x;
-} 
+}
 
 assertEquals(3, f_bound_this(1))
 f = f_bound_this.bind(obj);
@@ -75,7 +75,7 @@
 
 // Test chained binds.
 
-// When only giving the thisArg, any number of binds should have 
+// When only giving the thisArg, any number of binds should have
 // the same effect.
 f = foo.bind(foo);
 assertEquals(3, f(1, 1, 1));
@@ -181,4 +181,3 @@
 // Test instanceof obj2 is bar, not f.
 assertTrue(obj2 instanceof bar);
 assertFalse(obj2 instanceof f);
-
diff --git a/test/mjsunit/function-call.js b/test/mjsunit/function-call.js
index 58d61af..06479ad 100644
--- a/test/mjsunit/function-call.js
+++ b/test/mjsunit/function-call.js
@@ -155,6 +155,7 @@
   // Sanity check that all functions are correct
   assertEquals(typeof(should_throw_on_null_and_undefined[i]), "function");
 
+  var exception = false;
   try {
     // We call all functions with no parameters, which means that essential
     // parameters will have the undefined value.
@@ -163,68 +164,84 @@
     // 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);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue("called_on_null_or_undefined" == e.type ||
                "null_to_object" == e.type);
   }
+  assertTrue(exception);
 
+  exception = false;
   try {
     should_throw_on_null_and_undefined[i].call(undefined);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue("called_on_null_or_undefined" == e.type ||
                "null_to_object" == e.type);
   }
+  assertTrue(exception);
 
+  exception = false;
   try {
     should_throw_on_null_and_undefined[i].apply(null);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue("called_on_null_or_undefined" == e.type ||
                "null_to_object" == e.type);
   }
+  assertTrue(exception);
 
+  exception = false;
   try {
     should_throw_on_null_and_undefined[i].apply(undefined);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue("called_on_null_or_undefined" == e.type ||
                "null_to_object" == e.type);
   }
+  assertTrue(exception);
 }
 
 // Test that all natives that are non generic throw on null and undefined.
 for (var i = 0; i < non_generic.length; i++) {
   // Sanity check that all functions are correct
   assertEquals(typeof(non_generic[i]), "function");
+
+  exception = false;
   try {
     non_generic[i].call(null);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue(e instanceof TypeError);
   }
+  assertTrue(exception);
 
+  exception = false;
   try {
     non_generic[i].call(null);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue(e instanceof TypeError);
   }
+  assertTrue(exception);
 
+  exception = false;
   try {
     non_generic[i].apply(null);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue(e instanceof TypeError);
   }
+  assertTrue(exception);
 
+  exception = false;
   try {
     non_generic[i].apply(null);
-    assertUnreachable();
   } catch (e) {
+    exception = true;
     assertTrue(e instanceof TypeError);
   }
+  assertTrue(exception);
 }
 
 
@@ -233,47 +250,55 @@
 var array = [1,2,3,4,5];
 for (var j = 0; j < mapping_functions.length; j++) {
   for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
+    exception = false;
     try {
       mapping_functions[j].call(array,
                                 should_throw_on_null_and_undefined[i],
                                 null);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue("called_on_null_or_undefined" == e.type ||
                  "null_to_object" == e.type);
     }
+    assertTrue(exception);
 
+    exception = false;
     try {
       mapping_functions[j].call(array,
                                 should_throw_on_null_and_undefined[i],
                                 undefined);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue("called_on_null_or_undefined" == e.type ||
                  "null_to_object" == e.type);
     }
+    assertTrue(exception);
   }
 }
 
 for (var j = 0; j < mapping_functions.length; j++) {
   for (var i = 0; i < non_generic.length; i++) {
+    exception = false;
     try {
       mapping_functions[j].call(array,
                                 non_generic[i],
                                 null);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue(e instanceof TypeError);
     }
+    assertTrue(exception);
 
+    exception = false;
     try {
       mapping_functions[j].call(array,
                                 non_generic[i],
                                 undefined);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue(e instanceof TypeError);
     }
+    assertTrue(exception);
   }
 }
 
@@ -281,39 +306,47 @@
 // Reduce functions do a call with null as this argument.
 for (var j = 0; j < reducing_functions.length; j++) {
   for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
+    exception = false;
     try {
       reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue("called_on_null_or_undefined" == e.type ||
                  "null_to_object" == e.type);
     }
+    assertTrue(exception);
 
+    exception = false;
     try {
       reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue("called_on_null_or_undefined" == e.type ||
                  "null_to_object" == e.type);
     }
+    assertTrue(exception);
   }
 }
 
 for (var j = 0; j < reducing_functions.length; j++) {
   for (var i = 0; i < non_generic.length; i++) {
+    exception = false;
     try {
       reducing_functions[j].call(array, non_generic[i]);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue(e instanceof TypeError);
     }
+    assertTrue(exception);
 
+    exception = false;
     try {
       reducing_functions[j].call(array, non_generic[i]);
-      assertUnreachable();
     } catch (e) {
+      exception = true;
       assertTrue(e instanceof TypeError);
     }
+    assertTrue(exception);
   }
 }
 
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index cefef0a..ffa9268 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -141,9 +141,11 @@
   "EnableAccessChecks": true,
 
   // These functions should not be callable as runtime functions.
-  "NewContext": true,
+  "NewFunctionContext": true,
   "NewArgumentsFast": true,
-  "PushContext": true,
+  "NewStrictArgumentsFast": true,
+  "PushWithContext": true,
+  "PushCatchContext": true,
   "LazyCompile": true,
   "LazyRecompile": true,
   "NotifyDeoptimized": true,
@@ -165,7 +167,8 @@
 
   "_SwapElements": true,
 
-  // Performance critical function which cannot afford type checks.
+  // Performance critical functions which cannot afford type checks.
+  "_IsNativeOrStrictMode": true,
   "_CallFunction": true,
 
   // Tries to allocate based on argument, and (correctly) throws
diff --git a/test/mjsunit/getter-in-prototype.js b/test/mjsunit/getter-in-prototype.js
index 5563123..01a3473 100644
--- a/test/mjsunit/getter-in-prototype.js
+++ b/test/mjsunit/getter-in-prototype.js
@@ -25,8 +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.
 
-// Test that exceptions are thrown when setting properties on object
-// that have only a getter in a prototype object.
+// Test that exceptions are not thrown when setting properties on object
+// that have only a getter in a prototype object, except when we are in strict
+// mode where exceptsions should be thrown.
 
 var o = {};
 var p = {};
@@ -34,25 +35,44 @@
 p.__defineGetter__(0, function(){});
 o.__proto__ = p;
 
-assertThrows("o.x = 42");
-assertThrows("o[0] = 42");
+assertDoesNotThrow("o.x = 42");
+assertDoesNotThrow("o[0] = 42");
+
+assertThrows(function() { 'use strict'; o.x = 42; });
+assertThrows(function() { 'use strict'; o[0] = 42; });
 
 function f() {
   with(o) {
     x = 42;
   }
 }
-assertThrows("f()");
+
+assertDoesNotThrow(f);
 
 __proto__ = p;
 function g() {
   eval('1');
   x = 42;
 }
-assertThrows("g()");
+
+function g_strict() {
+  'use strict';
+  eval('1');
+  x = 42;
+}
+
+assertDoesNotThrow(g);
+assertThrows(g_strict);
 
 __proto__ = p;
 function g2() {
   this[0] = 42;
 }
-assertThrows("g2()");
+
+function g2_strict() {
+  'use strict';
+  this[0] = 42;
+}
+
+assertDoesNotThrow(g2);
+assertThrows(g2_strict);
diff --git a/test/mjsunit/harmony/proxies.js b/test/mjsunit/harmony/proxies.js
new file mode 100644
index 0000000..84641d5
--- /dev/null
+++ b/test/mjsunit/harmony/proxies.js
@@ -0,0 +1,687 @@
+// Flags: --harmony-proxies
+
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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.
+
+
+// TODO(rossberg): test exception cases.
+
+
+// Getters.
+
+function TestGet(handler) {
+  var o = Proxy.create(handler)
+  assertEquals(42, o.a)
+  assertEquals(42, o["b"])
+}
+
+TestGet({
+  get: function(r, k) { return 42 }
+})
+TestGet({
+  get: function(r, k) { return this.get2(r, k) },
+  get2: function(r, k) { return 42 }
+})
+TestGet({
+  getPropertyDescriptor: function(k) { return {value: 42} }
+})
+TestGet({
+  getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
+  getPropertyDescriptor2: function(k) { return {value: 42} }
+})
+TestGet({
+  getPropertyDescriptor: function(k) {
+    return {get value() { return 42 }}
+  }
+})
+TestGet({
+  get: undefined,
+  getPropertyDescriptor: function(k) { return {value: 42} }
+})
+
+TestGet(Proxy.create({
+  get: function(pr, pk) {
+    return function(r, k) { return 42 }
+  }
+}))
+
+
+function TestGetCall(handler) {
+  var p = Proxy.create(handler)
+  assertEquals(55, p.f())
+  assertEquals(55, p.f("unused", "arguments"))
+  assertEquals(55, p.f.call(p))
+  assertEquals(55, p.withargs(45, 5))
+  assertEquals(55, p.withargs.call(p, 11, 22))
+  assertEquals("6655", "66" + p)  // calls p.toString
+}
+
+TestGetCall({
+  get: function(r, k) { return function() { return 55 } }
+})
+TestGetCall({
+  get: function(r, k) { return this.get2(r, k) },
+  get2: function(r, k) { return function() { return 55 } }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
+  getPropertyDescriptor2: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) {
+    return {get value() { return function() { return 55 } }}
+  }
+})
+TestGetCall({
+  get: undefined,
+  getPropertyDescriptor: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  get: function(r, k) {
+    if (k == "gg") {
+      return function() { return 55 }
+    } else if (k == "withargs") {
+      return function(n, m) { return n + m * 2 }
+    } else {
+      return function() { return this.gg() }
+    }
+  }
+})
+
+TestGetCall(Proxy.create({
+  get: function(pr, pk) {
+    return function(r, k) { return function() { return 55 } }
+  }
+}))
+
+
+
+// Setters.
+
+var key
+var val
+function TestSet(handler) {
+  var o = Proxy.create(handler)
+  assertEquals(42, o.a = 42)
+  assertEquals("a", key)
+  assertEquals(42, val)
+  assertEquals(43, o["b"] = 43)
+  assertEquals("b", key)
+  assertEquals(43, val)
+}
+
+TestSet({
+  set: function(r, k, v) { key = k; val = v; return true }
+})
+TestSet({
+  set: function(r, k, v) { return this.set2(r, k, v) },
+  set2: function(r, k, v) { key = k; val = v; return true }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) { return {writable: true} },
+  defineProperty: function(k, desc) { key = k; val = desc.value }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) { return {writable: true} },
+  defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
+  defineProperty2: function(k, desc) { key = k; val = desc.value }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) {
+    return {get writable() { return true }}
+  },
+  defineProperty: function(k, desc) { key = k; val = desc.value }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) {
+    return {set: function(v) { key = k; val = v }}
+  }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) { return null },
+  getPropertyDescriptor: function(k) { return {writable: true} },
+  defineProperty: function(k, desc) { key = k; val = desc.value }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) { return null },
+  getPropertyDescriptor: function(k) {
+    return {get writable() { return true }}
+  },
+  defineProperty: function(k, desc) { key = k; val = desc.value }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) { return null },
+  getPropertyDescriptor: function(k) {
+    return {set: function(v) { key = k; val = v }}
+  }
+})
+TestSet({
+  getOwnPropertyDescriptor: function(k) { return null },
+  getPropertyDescriptor: function(k) { return null },
+  defineProperty: function(k, desc) { key = k, val = desc.value }
+})
+
+TestSet(Proxy.create({
+  get: function(pr, pk) {
+    return function(r, k, v) { key = k; val = v; return true }
+  }
+}))
+
+
+
+// Property definition (Object.defineProperty and Object.defineProperties).
+
+var key
+var desc
+function TestDefine(handler) {
+  var o = Proxy.create(handler)
+  assertEquals(o, Object.defineProperty(o, "a", {value: 44}))
+  assertEquals("a", key)
+  assertEquals(1, Object.getOwnPropertyNames(desc).length)
+  assertEquals(44, desc.value)
+
+  assertEquals(o, Object.defineProperty(o, "b", {value: 45, writable: false}))
+  assertEquals("b", key)
+  assertEquals(2, Object.getOwnPropertyNames(desc).length)
+  assertEquals(45, desc.value)
+  assertEquals(false, desc.writable)
+
+  assertEquals(o, Object.defineProperty(o, "c", {value: 46, enumerable: false}))
+  assertEquals("c", key)
+  assertEquals(2, Object.getOwnPropertyNames(desc).length)
+  assertEquals(46, desc.value)
+  assertEquals(false, desc.enumerable)
+
+  var attributes = {configurable: true, mine: 66, minetoo: 23}
+  assertEquals(o, Object.defineProperty(o, "d", attributes))
+  assertEquals("d", key)
+  // Modifying the attributes object after the fact should have no effect.
+  attributes.configurable = false
+  attributes.mine = 77
+  delete attributes.minetoo
+  assertEquals(3, Object.getOwnPropertyNames(desc).length)
+  assertEquals(true, desc.configurable)
+  assertEquals(66, desc.mine)
+  assertEquals(23, desc.minetoo)
+
+  assertEquals(o, Object.defineProperty(o, "e", {get: function(){ return 5 }}))
+  assertEquals("e", key)
+  assertEquals(1, Object.getOwnPropertyNames(desc).length)
+  assertEquals(5, desc.get())
+
+  assertEquals(o, Object.defineProperty(o, "zzz", {}))
+  assertEquals("zzz", key)
+  assertEquals(0, Object.getOwnPropertyNames(desc).length)
+
+// TODO(rossberg): This test requires [s in proxy] to be implemented first.
+//  var d = Proxy.create({
+//    get: function(r, k) { return (k === "value") ? 77 : void 0 },
+//    getOwnPropertyNames: function() { return ["value"] }
+//  })
+//  assertEquals(1, Object.getOwnPropertyNames(d).length)
+//  assertEquals(77, d.value)
+//  assertEquals(o, Object.defineProperty(o, "p", d))
+//  assertEquals("p", key)
+//  assertEquals(1, Object.getOwnPropertyNames(desc).length)
+//  assertEquals(77, desc.value)
+
+  var props = {
+    'bla': {},
+    blub: {get: function() { return true }},
+    '': {get value() { return 20 }},
+    last: {value: 21, configurable: true, mine: "eyes"}
+  }
+  Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false})
+  assertEquals(o, Object.defineProperties(o, props))
+  assertEquals("last", key)
+  assertEquals(2, Object.getOwnPropertyNames(desc).length)
+  assertEquals(21, desc.value)
+  assertEquals(true, desc.configurable)
+  assertEquals(undefined, desc.mine)  // Arguably a bug in the spec...
+}
+
+TestDefine({
+  defineProperty: function(k, d) { key = k; desc = d; return true }
+})
+TestDefine({
+  defineProperty: function(k, d) { return this.defineProperty2(k, d) },
+  defineProperty2: function(k, d) { key = k; desc = d; return true }
+})
+TestDefine(Proxy.create({
+  get: function(pr, pk) {
+    return function(k, d) { key = k; desc = d; return true }
+  }
+}))
+
+
+
+// Property deletion (delete).
+
+var key
+function TestDelete(handler) {
+  var o = Proxy.create(handler)
+  assertEquals(true, delete o.a)
+  assertEquals("a", key)
+  assertEquals(true, delete o["b"])
+  assertEquals("b", key)
+
+  assertEquals(false, delete o.z1)
+  assertEquals("z1", key)
+  assertEquals(false, delete o["z2"])
+  assertEquals("z2", key);
+
+  (function() {
+    "use strict"
+    assertEquals(true, delete o.c)
+    assertEquals("c", key)
+    assertEquals(true, delete o["d"])
+    assertEquals("d", key)
+
+    assertThrows(function() { delete o.z3 }, TypeError)
+    assertEquals("z3", key)
+    assertThrows(function() { delete o["z4"] }, TypeError)
+    assertEquals("z4", key)
+  })()
+}
+
+TestDelete({
+  'delete': function(k) { key = k; return k < "z" }
+})
+TestDelete({
+  'delete': function(k) { return this.delete2(k) },
+  delete2: function(k) { key = k; return k < "z" }
+})
+TestDelete(Proxy.create({
+  get: function(pr, pk) {
+    return function(k) { key = k; return k < "z" }
+  }
+}))
+
+
+
+// Property descriptors (Object.getOwnPropertyDescriptor).
+
+function TestDescriptor(handler) {
+  var o = Proxy.create(handler)
+  var descs = [
+    {configurable: true},
+    {value: 34, enumerable: true, configurable: true},
+    {value: 3, writable: false, mine: "eyes", configurable: true},
+    {get value() { return 20 }, get configurable() { return true }},
+    {get: function() { "get" }, set: function() { "set" }, configurable: true}
+  ]
+  for (var i = 0; i < descs.length; ++i) {
+    assertEquals(o, Object.defineProperty(o, i, descs[i]))
+    var desc = Object.getOwnPropertyDescriptor(o, i)
+    for (p in descs[i]) {
+      // TODO(rossberg): Ignore user attributes as long as the spec isn't
+      // fixed suitably.
+      if (p != "mine") assertEquals(descs[i][p], desc[p])
+    }
+    assertEquals(undefined, Object.getOwnPropertyDescriptor(o, "absent"))
+  }
+}
+
+
+TestDescriptor({
+  defineProperty: function(k, d) { this["__" + k] = d; return true },
+  getOwnPropertyDescriptor: function(k) { return this["__" + k] }
+})
+TestDescriptor({
+  defineProperty: function(k, d) { this["__" + k] = d; return true },
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) { return this["__" + k] }
+})
+
+
+
+// Comparison.
+
+function TestComparison(eq) {
+  var o1 = Proxy.create({})
+  var o2 = Proxy.create({})
+
+  assertTrue(eq(o1, o1))
+  assertTrue(eq(o2, o2))
+  assertTrue(!eq(o1, o2))
+  assertTrue(!eq(o1, {}))
+  assertTrue(!eq({}, o2))
+  assertTrue(!eq({}, {}))
+}
+
+TestComparison(function(o1, o2) { return o1 == o2 })
+TestComparison(function(o1, o2) { return o1 === o2 })
+TestComparison(function(o1, o2) { return !(o1 != o2) })
+TestComparison(function(o1, o2) { return !(o1 !== o2) })
+
+
+
+// Type.
+
+assertEquals("object", typeof Proxy.create({}))
+assertTrue(typeof Proxy.create({}) == "object")
+assertTrue("object" == typeof Proxy.create({}))
+
+// No function proxies yet.
+
+
+
+// Element (in).
+
+var key
+function TestIn(handler) {
+  var o = Proxy.create(handler)
+  assertTrue("a" in o)
+  assertEquals("a", key)
+  assertTrue(99 in o)
+  assertEquals("99", key)
+  assertFalse("z" in o)
+  assertEquals("z", key)
+
+  if ("b" in o) {
+  } else {
+    assertTrue(false)
+  }
+  assertEquals("b", key)
+
+  if ("zz" in o) {
+    assertTrue(false)
+  }
+  assertEquals("zz", key)
+
+  if (!("c" in o)) {
+    assertTrue(false)
+  }
+  assertEquals("c", key)
+
+  if (!("zzz" in o)) {
+  } else {
+    assertTrue(false)
+  }
+  assertEquals("zzz", key)
+}
+
+TestIn({
+  has: function(k) { key = k; return k < "z" }
+})
+TestIn({
+  has: function(k) { return this.has2(k) },
+  has2: function(k) { key = k; return k < "z" }
+})
+TestIn({
+  getPropertyDescriptor: function(k) {
+    key = k; return k < "z" ? {value: 42} : void 0
+  }
+})
+TestIn({
+  getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
+  getPropertyDescriptor2: function(k) {
+    key = k; return k < "z" ? {value: 42} : void 0
+  }
+})
+TestIn({
+  getPropertyDescriptor: function(k) {
+    key = k; return k < "z" ? {get value() { return 42 }} : void 0
+  }
+})
+TestIn({
+  get: undefined,
+  getPropertyDescriptor: function(k) {
+    key = k; return k < "z" ? {value: 42} : void 0
+  }
+})
+
+TestIn(Proxy.create({
+  get: function(pr, pk) {
+    return function(k) { key = k; return k < "z" }
+  }
+}))
+
+
+
+// Instanceof (instanceof).
+
+function TestInstanceof() {
+  var o = {}
+  var p1 = Proxy.create({})
+  var p2 = Proxy.create({}, o)
+  var p3 = Proxy.create({}, p2)
+
+  var f = function() {}
+  f.prototype = o
+  var f1 = function() {}
+  f1.prototype = p1
+  var f2 = function() {}
+  f2.prototype = p2
+
+  assertTrue(o instanceof Object)
+  assertFalse(o instanceof f)
+  assertFalse(o instanceof f1)
+  assertFalse(o instanceof f2)
+  assertFalse(p1 instanceof Object)
+  assertFalse(p1 instanceof f)
+  assertFalse(p1 instanceof f1)
+  assertFalse(p1 instanceof f2)
+  assertTrue(p2 instanceof Object)
+  assertTrue(p2 instanceof f)
+  assertFalse(p2 instanceof f1)
+  assertFalse(p2 instanceof f2)
+  assertTrue(p3 instanceof Object)
+  assertTrue(p3 instanceof f)
+  assertFalse(p3 instanceof f1)
+  assertTrue(p3 instanceof f2)
+}
+
+TestInstanceof()
+
+
+
+// Prototype (Object.getPrototypeOf).
+
+function TestPrototype() {
+  var o = {}
+  var p1 = Proxy.create({})
+  var p2 = Proxy.create({}, o)
+  var p3 = Proxy.create({}, p2)
+  var p4 = Proxy.create({}, 666)
+
+  assertSame(Object.getPrototypeOf(o), Object.prototype)
+  assertSame(Object.getPrototypeOf(p1), null)
+  assertSame(Object.getPrototypeOf(p2), o)
+  assertSame(Object.getPrototypeOf(p3), p2)
+  assertSame(Object.getPrototypeOf(p4), null)
+}
+
+TestPrototype()
+
+
+
+// Property names (Object.getOwnPropertyNames, Object.keys).
+
+function TestPropertyNames(names, handler) {
+  var p = Proxy.create(handler)
+  assertArrayEquals(names, Object.getOwnPropertyNames(p))
+}
+
+TestPropertyNames([], {
+  getOwnPropertyNames: function() { return [] }
+})
+TestPropertyNames(["a", "zz", " ", "0"], {
+  getOwnPropertyNames: function() { return ["a", "zz", " ", 0] }
+})
+TestPropertyNames(["throw", "function "], {
+  getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
+  getOwnPropertyNames2: function() { return ["throw", "function "] }
+})
+TestPropertyNames(["[object Object]"], {
+  get getOwnPropertyNames() {
+    return function() { return [{}] }
+  }
+})
+
+
+function TestKeys(names, handler) {
+  var p = Proxy.create(handler)
+  assertArrayEquals(names, Object.keys(p))
+}
+
+TestKeys([], {
+  keys: function() { return [] }
+})
+TestKeys(["a", "zz", " ", "0"], {
+  keys: function() { return ["a", "zz", " ", 0] }
+})
+TestKeys(["throw", "function "], {
+  keys: function() { return this.keys2() },
+  keys2: function() { return ["throw", "function "] }
+})
+TestKeys(["[object Object]"], {
+  get keys() {
+    return function() { return [{}] }
+  }
+})
+TestKeys(["a", "0"], {
+  getOwnPropertyNames: function() { return ["a", 23, "zz", "", 0] },
+  getOwnPropertyDescriptor: function(k) { return {enumerable: k.length == 1} }
+})
+TestKeys(["23", "zz", ""], {
+  getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
+  getOwnPropertyNames2: function() { return ["a", 23, "zz", "", 0] },
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) { return {enumerable: k.length != 1} }
+})
+TestKeys(["a", "b", "c", "5"], {
+  get getOwnPropertyNames() {
+    return function() { return ["0", 4, "a", "b", "c", 5] }
+  },
+  get getOwnPropertyDescriptor() {
+    return function(k) { return {enumerable: k >= "44"} }
+  }
+})
+TestKeys([], {
+  get getOwnPropertyNames() {
+    return function() { return ["a", "b", "c"] }
+  },
+  getOwnPropertyDescriptor: function(k) { return {} }
+})
+
+
+
+// Fixing (Object.freeze, Object.seal, Object.preventExtensions,
+//         Object.isFrozen, Object.isSealed, Object.isExtensible)
+
+function TestFix(names, handler) {
+  var proto = {p: 77}
+  var assertFixing = function(o, s, f, e) {
+    assertEquals(s, Object.isSealed(o))
+    assertEquals(f, Object.isFrozen(o))
+    assertEquals(e, Object.isExtensible(o))
+  }
+
+  var o1 = Proxy.create(handler, proto)
+  assertFixing(o1, false, false, true)
+  Object.seal(o1)
+  assertFixing(o1, true, names.length === 0, false)
+  assertArrayEquals(names.sort(), Object.getOwnPropertyNames(o1).sort())
+  assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
+                    Object.keys(o1).sort())
+  assertEquals(proto, Object.getPrototypeOf(o1))
+  assertEquals(77, o1.p)
+  for (var n in o1) {
+    var desc = Object.getOwnPropertyDescriptor(o1, n)
+    if (desc !== undefined) assertFalse(desc.configurable)
+  }
+
+  var o2 = Proxy.create(handler, proto)
+  assertFixing(o2, false, false, true)
+  Object.freeze(o2)
+  assertFixing(o2, true, true, false)
+  assertArrayEquals(names.sort(), Object.getOwnPropertyNames(o2).sort())
+  assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
+                    Object.keys(o2).sort())
+  assertEquals(proto, Object.getPrototypeOf(o2))
+  assertEquals(77, o2.p)
+  for (var n in o2) {
+    var desc = Object.getOwnPropertyDescriptor(o2, n)
+    if (desc !== undefined) assertFalse(desc.writable)
+    if (desc !== undefined) assertFalse(desc.configurable)
+  }
+
+  var o3 = Proxy.create(handler, proto)
+  assertFixing(o3, false, false, true)
+  Object.preventExtensions(o3)
+  assertFixing(o3, names.length === 0, names.length === 0, false)
+  assertArrayEquals(names.sort(), Object.getOwnPropertyNames(o3).sort())
+  assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
+                    Object.keys(o3).sort())
+  assertEquals(proto, Object.getPrototypeOf(o3))
+  assertEquals(77, o3.p)
+}
+
+TestFix([], {
+  fix: function() { return {} }
+})
+TestFix(["a", "b", "c", "d", "zz"], {
+  fix: function() {
+    return {
+      a: {value: "a", writable: true, configurable: false, enumerable: true},
+      b: {value: 33, writable: false, configurable: false, enumerable: true},
+      c: {value: 0, writable: true, configurable: true, enumerable: true},
+      d: {value: true, writable: false, configurable: true, enumerable: true},
+      zz: {value: 0, enumerable: false}
+    }
+  }
+})
+TestFix(["a"], {
+  fix: function() { return this.fix2() },
+  fix2: function() {
+    return {a: {value: 4, writable: true, configurable: true, enumerable: true}}
+  }
+})
+TestFix(["b"], {
+  get fix() {
+    return function() {
+      return {b: {configurable: true, writable: true, enumerable: true}}
+    }
+  }
+})
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/hex-parsing.js
similarity index 80%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/hex-parsing.js
index edbcb19..6a42f49 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/hex-parsing.js
@@ -25,12 +25,15 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
+var k = 0x1000000000000081;
+assertEquals(1152921504606847200, k);
+k = 0x1000000000000281;
+assertEquals(1152921504606847700, k);
+k = 0x10000000000002810;
+assertEquals(18446744073709564000, k);
+k = 0x10000000000002810000;
+assertEquals(7.555786372591437e+22, k);
+k = 0xffffffffffffffff;
+assertEquals(18446744073709552000, k);
+k = 0xffffffffffffffffffff;
+assertEquals(1.2089258196146292e+24, k);
diff --git a/test/mjsunit/indexed-accessors.js b/test/mjsunit/indexed-accessors.js
index 1634857..b69695a 100644
--- a/test/mjsunit/indexed-accessors.js
+++ b/test/mjsunit/indexed-accessors.js
@@ -81,10 +81,11 @@
 expected[0] = 111;
 testArray();
 
-// Using a setter where only a getter is defined throws an exception.
+// Using a setter where only a getter is defined does not throw an exception,
+// unless we are in strict mode.
 var q = {};
 q.__defineGetter__('0', function() { return 42; });
-assertThrows('q[0] = 7');
+assertDoesNotThrow('q[0] = 7');
 
 // Using a getter where only a setter is defined returns undefined.
 var q1 = {};
diff --git a/test/mjsunit/json.js b/test/mjsunit/json.js
index 812ffeb..bead376 100644
--- a/test/mjsunit/json.js
+++ b/test/mjsunit/json.js
@@ -67,7 +67,7 @@
           valueOf: "not callable",
           toString: "not callable either",
           toISOString: function() { return 42; }};
-assertThrows("d4.toJSON()", TypeError);  // ToPrimitive throws. 
+assertThrows("d4.toJSON()", TypeError);  // ToPrimitive throws.
 
 var d5 = {toJSON: Date.prototype.toJSON,
           valueOf: "not callable",
@@ -196,9 +196,6 @@
 TestInvalid('"Unterminated string\\"');
 TestInvalid('"Unterminated string\\\\\\"');
 
-// JavaScript RegExp literals not valid in JSON.
-TestInvalid('/true/');
-
 // Test bad JSON that would be good JavaScript (ES5).
 TestInvalid("{true:42}");
 TestInvalid("{false:42}");
@@ -259,6 +256,7 @@
              JSON.stringify([1, 2, [3, [4], 5], 6, 7], null));
 assertEquals("[2,4,[6,[8],10],12,14]",
              JSON.stringify([1, 2, [3, [4], 5], 6, 7], DoubleNumbers));
+assertEquals('["a","ab","abc"]', JSON.stringify(["a","ab","abc"]));
 
 var circular = [1, 2, 3];
 circular[2] = circular;
@@ -382,7 +380,7 @@
 reJSON.toJSON = function() { return "has toJSON"; };
 
 assertEquals(
-    '[37,null,1,"foo","37","true",null,"has toJSON",null,"has toJSON"]',
+    '[37,null,1,"foo","37","true",null,"has toJSON",{},"has toJSON"]',
     JSON.stringify([num37, numFoo, numTrue,
                     strFoo, str37, strTrue,
                     func, funcJSON, re, reJSON]));
@@ -397,6 +395,9 @@
 var counter = { get toJSON() { getCount++;
                                return function() { callCount++;
                                                    return 42; }; } };
+
+// RegExps are not callable, so they are stringified as objects.
+assertEquals('{}', JSON.stringify(/regexp/));
 assertEquals('42', JSON.stringify(counter));
 assertEquals(1, getCount);
 assertEquals(1, callCount);
@@ -419,9 +420,9 @@
 // We don't currently allow plain properties called __proto__ in JSON
 // objects in JSON.parse. Instead we read them as we would JS object
 // literals. If we change that, this test should change with it.
-// 
-// Parse a non-object value as __proto__. This must not create a 
-// __proto__ property different from the original, and should not 
+//
+// Parse a non-object value as __proto__. This must not create a
+// __proto__ property different from the original, and should not
 // change the original.
 var o = JSON.parse('{"__proto__":5}');
 assertEquals(Object.prototype, o.__proto__);  // __proto__ isn't changed.
diff --git a/test/mjsunit/keywords-and-reserved_words.js b/test/mjsunit/keywords-and-reserved_words.js
new file mode 100644
index 0000000..ade4329
--- /dev/null
+++ b/test/mjsunit/keywords-and-reserved_words.js
@@ -0,0 +1,177 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test proper handling of keywords, future reserved words and
+// future reserved words in strict mode as specific by 7.6.1 and 7.6.2
+// in ECMA-262.
+
+// This code is based on:
+// http://trac.webkit.org/export/89109/trunk/LayoutTests/fast/js/script-tests/keywords-and-reserved_words.js
+
+function isKeyword(x)
+{
+  try {
+    eval("var " + x + ";");
+  } catch(e) {
+    return true;
+  }
+
+  return false;
+}
+
+function isStrictKeyword(x)
+{
+  try {
+    eval("'use strict'; var "+x+";");
+  } catch(e) {
+    return true;
+  }
+
+  return false;
+}
+
+function classifyIdentifier(x)
+{
+  if (isKeyword(x)) {
+    // All non-strict keywords are also keywords in strict code.
+    if (!isStrictKeyword(x)) {
+      return "ERROR";
+    }
+    return "keyword";
+  }
+
+  // Check for strict mode future reserved words.
+  if (isStrictKeyword(x)) {
+    return "strict";
+  }
+
+  return "identifier";
+}
+
+function testKeyword(word) {
+  // Classify word
+  assertEquals("keyword", classifyIdentifier(word));
+
+  // Simple use of a keyword
+  assertThrows("var " + word + " = 1;", SyntaxError);
+  if (word != "this") {
+    assertThrows("typeof (" + word + ");", SyntaxError);
+  }
+
+  // object literal properties
+  eval("var x = { " + word + " : 42 };");
+  eval("var x = { get " + word + " () {} };");
+  eval("var x = { set " + word + " (value) {} };");
+
+  // object literal with string literal property names
+  eval("var x = { '" + word + "' : 42 };");
+  eval("var x = { get '" + word + "' () { } };");
+  eval("var x = { set '" + word + "' (value) { } };");
+
+  // Function names and arguments
+  assertThrows("function " + word + " () { }", SyntaxError);
+  assertThrows("function foo (" + word + ") {}", SyntaxError);
+  assertThrows("function foo (a, " + word + ") { }", SyntaxError);
+  assertThrows("function foo (" + word + ", a) { }", SyntaxError);
+  assertThrows("function foo (a, " + word + ", b) { }", SyntaxError);
+  assertThrows("var foo = function (" + word + ") { }", SyntaxError);
+
+  // setter parameter
+  assertThrows("var x = { set foo(" + word + ") { } };", SyntaxError);
+}
+
+// Not keywords - these are all just identifiers.
+var identifiers = [
+  "x",            "keyword",
+  "id",           "strict",
+  "identifier",   "use",
+  // The following are reserved in ES3 but not in ES5.
+  "abstract",     "int",
+  "boolean",      "long",
+  "byte",         "native",
+  "char",         "short",
+  "double",       "synchronized",
+  "final",        "throws",
+  "float",        "transient",
+  "goto",         "volatile" ];
+
+for (var i = 0; i < identifiers.length; i++) {
+  assertEquals ("identifier", classifyIdentifier(identifiers[i]));
+}
+
+// 7.6.1.1 Keywords
+var keywords = [
+  "break",        "in",
+  "case",         "instanceof",
+  "catch",        "new",
+  "continue",     "return",
+  "debugger",     "switch",
+  "default",      "this",
+  "delete",       "throw",
+  "do",           "try",
+  "else",         "typeof",
+  "finally",      "var",
+  "for",          "void",
+  "function",     "while",
+  "if",           "with",
+  // In ES5 "const" is a "future reserved word" but we treat it as a keyword.
+  "const" ];
+
+for (var i = 0; i < keywords.length; i++) {
+  testKeyword(keywords[i]);
+}
+
+// 7.6.1.2 Future Reserved Words (without "const")
+var future_reserved_words = [
+  "class",
+  "enum",
+  "export",
+  "extends",
+  "import",
+  "super" ];
+
+for (var i = 0; i < future_reserved_words.length; i++) {
+  testKeyword(future_reserved_words[i]);
+}
+
+// 7.6.1.2 Future Reserved Words, in strict mode only.
+var future_strict_reserved_words = [
+  "implements",
+  "interface",
+  "let",
+  "package",
+  "private",
+  "protected",
+  "public",
+  "static",
+  "yield" ];
+
+for (var i = 0; i < future_strict_reserved_words.length; i++) {
+  assertEquals ("strict", classifyIdentifier(future_strict_reserved_words[i]));
+}
+
+// More strict mode specific tests can be found in mjsunit/strict-mode.js.
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/logical.js
similarity index 70%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/logical.js
index edbcb19..23c5390 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/logical.js
@@ -25,12 +25,25 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+var undef = void 0;
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+assertEquals(1, 1 || 0);
+assertEquals(2, 0 || 2);
+assertEquals('foo', 0 || 'foo');
+assertEquals(undef, undef || undef);
+assertEquals('foo', 'foo' || 'bar');
+assertEquals('bar', undef || 'bar');
+assertEquals('bar', undef || 'bar' || 'baz');
+assertEquals('baz', undef || undef || 'baz');
 
-test();
+assertEquals(0, 1 && 0);
+assertEquals(0, 0 && 2);
+assertEquals(0, 0 && 'foo');
+assertEquals(undef, undef && undef);
+assertEquals('bar', 'foo' && 'bar');
+assertEquals(undef, undef && 'bar');
+assertEquals('baz', 'foo' && 'bar' && 'baz');
+assertEquals(undef, 'foo' && undef && 'baz');
+
+assertEquals(0, undef && undef || 0);
+assertEquals('bar', undef && 0 || 'bar');
diff --git a/test/mjsunit/math-abs.js b/test/mjsunit/math-abs.js
index 33df6f4..2b07954 100644
--- a/test/mjsunit/math-abs.js
+++ b/test/mjsunit/math-abs.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: --max-new-space-size=256
+// Flags: --max-new-space-size=256 --allow-natives-syntax
 
 function zero() {
   var x = 0.5;
@@ -96,3 +96,16 @@
 for (var i = 0; i < 500; i++) {
   test();
 }
+
+// Regression test for optimized version of Math.abs, see:
+// http://codereview.chromium.org/6875002.
+function foo(x) {
+  return Math.abs(x);
+}
+// Get some smi type feedback.
+for(var i = 0; i < 1000; i++) {
+  foo(-i);
+}
+assertEquals(42, foo(-42));
+%OptimizeFunctionOnNextCall(foo)
+assertEquals(42, foo(-42));
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index b49bad2..b7b0c77 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -1,4 +1,4 @@
-# Copyright 2008 the V8 project authors. All rights reserved.
+# Copyright 2011 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
@@ -30,6 +30,9 @@
 # All tests in the bug directory are expected to fail.
 bugs: FAIL
 
+##############################################################################
+# Fails.
+regress/regress-1119: FAIL
 
 ##############################################################################
 # Too slow in debug mode with --stress-opt
@@ -139,3 +142,8 @@
 regress/regress-3218915: SKIP
 regress/regress-3247124: SKIP
 
+
+[ $isolates ]
+# d8-os writes temporary files that might interfer with each other when running
+# in multible threads. Skip this if running with isolates testing.
+d8-os: SKIP
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/multiline.js
similarity index 88%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/multiline.js
index edbcb19..ba538db 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/multiline.js
@@ -25,12 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
+var s = 'foo\
+bar';
+assertEquals("foobar", s);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/not.js
similarity index 74%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/not.js
index edbcb19..550a981 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/not.js
@@ -25,12 +25,35 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+function testNot(x) {
+  // The VM constant folds so we use that to check the result.
+  var expected = eval("!(" + x + ")");
+  var actual = !x;
+  assertEquals(expected, actual, "x: " + x);
 }
 
-test();
+testNot(0);
+testNot(1);
+testNot(-1);
+testNot(-0);
+
+testNot(NaN);
+testNot(Infinity);
+testNot(-Infinity);
+
+testNot(true);
+testNot(false);
+
+assertTrue(!"");
+assertFalse(!"foo");
+
+assertFalse(![]);
+assertFalse(![1]);
+assertFalse(![1,2]);
+
+assertFalse(!{});
+assertFalse(!{foo:1});
+assertFalse(!{foo:1,bar:2});
+
+assertFalse(!!0);
+assertTrue(!!1);
diff --git a/test/mjsunit/number-string-index-call.js b/test/mjsunit/number-string-index-call.js
index 4391917..85b79d1 100644
--- a/test/mjsunit/number-string-index-call.js
+++ b/test/mjsunit/number-string-index-call.js
@@ -25,8 +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: --call_regexp
-var callbacks = [ function() { return 'foo'; }, "nonobject", /abc/ ];
+var callbacks = [ function() {return 'foo'}, "nonobject", /abc/ ];
 assertEquals('foo', callbacks['0']());
 assertThrows("callbacks['1']()");
-assertEquals(['abc'], callbacks['2']("abcdefg"));
+assertThrows("callbacks['2']('abcdefg')");
diff --git a/test/mjsunit/numops-fuzz.js b/test/mjsunit/numops-fuzz.js
new file mode 100644
index 0000000..bd7e4fa
--- /dev/null
+++ b/test/mjsunit/numops-fuzz.js
@@ -0,0 +1,4609 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function f() {
+  var x = 0;
+  var tmp = 0;
+  assertEquals(0, x /= (tmp = 798469700.4090232, tmp));
+  assertEquals(0, x *= (2714102322.365509));
+  assertEquals(0, x *= x);
+  assertEquals(139516372, x -= (tmp = -139516372, tmp));
+  assertEquals(1, x /= (x%(2620399703.344006)));
+  assertEquals(0, x >>>= x);
+  assertEquals(-2772151192.8633175, x -= (tmp = 2772151192.8633175, tmp));
+  assertEquals(-2786298206.8633175, x -= (14147014));
+  assertEquals(1509750523, x |= ((1073767916)-(tmp = 919311632.2789925, tmp)));
+  assertEquals(2262404051.926751, x += ((752653528.9267509)%x));
+  assertEquals(-270926893, x |= (tmp = 1837232194, tmp));
+  assertEquals(0.17730273401688765, x /= ((tmp = -2657202795, tmp)-(((((x|(tmp = -1187733892.282897, tmp))-x)<<(556523578))-x)+(-57905508.42881298))));
+  assertEquals(122483.56550261026, x *= ((((tmp = 2570017060.15193, tmp)%((-1862621126.9968336)>>x))>>(x>>(tmp = 2388674677, tmp)))>>>(-2919657526.470434)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= (tmp = 2705124845.0455265, tmp));
+  assertEquals(0, x &= (-135286835.07069612));
+  assertEquals(-0, x *= ((tmp = -165810479.10020828, tmp)|x));
+  assertEquals(248741888, x += ((735976871.1308595)<<(-2608055185.0700903)));
+  assertEquals(139526144, x &= (tmp = -1454301068, tmp));
+  assertEquals(-0.047221345672746884, x /= (tmp = -2954726130.994727, tmp));
+  assertEquals(0, x <<= (x>>x));
+  assertEquals(0, x >>>= ((x+(912111201.488966))-(tmp = 1405800042.6070075, tmp)));
+  assertEquals(-1663642733, x |= (((-1663642733.5700119)<<(x^x))<<x));
+  assertEquals(-914358272, x <<= ((((-308411676)-(-618261840.9113789))%(-68488626.58621716))-x));
+  assertEquals(-1996488704, x &= (-1358622641.5848842));
+  assertEquals(-345978263, x += (1650510441));
+  assertEquals(3, x >>>= (-1106714178.701668));
+  assertEquals(1, x %= (((x>>(x>>(tmp = -3052773846.817114, tmp)))*(tmp = 1659218887.379526, tmp))&x));
+  assertEquals(-943225672, x += (-943225673));
+  assertEquals(-0.41714300120060854, x /= (tmp = 2261156652, tmp));
+  assertEquals(0, x >>>= ((3107060934.8863482)<<(tmp = 1902730887, tmp)));
+  assertEquals(0, x &= x);
+  assertEquals(1476628, x |= ((tmp = -2782899841.390033, tmp)>>>(2097653770)));
+  assertEquals(0.0008887648921591833, x /= ((tmp = 1661438264.5253348, tmp)%((tmp = 2555939813, tmp)*(-877024323.6515315))));
+  assertEquals(0, x <<= (tmp = -2366551345, tmp));
+  assertEquals(0, x &= (tmp = 1742843591, tmp));
+  assertEquals(0, x -= x);
+  assertEquals(4239, x += ((-3183564176.232031)>>>(349622674.1255014)));
+  assertEquals(-67560, x -= ((2352742295)>>>x));
+  assertEquals(-67560, x &= x);
+  assertEquals(-0.00003219917807302283, x /= (2098190203.699741));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>= ((((tmp = -869086522.8358297, tmp)/(187820779))-(tmp = -2000970995.1931965, tmp))|(1853528755.6064696)));
+  assertEquals(0, x >>= (-3040509919));
+  assertEquals(0, x %= (((tmp = -2386688049.194946, tmp)<<(tmp = -669711391, tmp))|x));
+  assertEquals(0, x %= (tmp = -298431511.4839926, tmp));
+  assertEquals(0, x /= (2830845091.2793818));
+  assertEquals(0, x /= ((((-2529926178)|x)^((tmp = 2139313707.0894063, tmp)%((-1825768525.0541775)-(-952600362.7758243))))+x));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x -= x);
+  assertEquals(NaN, x /= (tmp = -432944480, tmp));
+  assertEquals(0, x <<= (((((x^((-1777523727)+(2194962794)))>>>(((((-590335134.8224905)%(x*(2198198974)))|(tmp = -2068556796, tmp))/(1060765637))*(-147051676)))/((tmp = -477350113.92686677, tmp)<<((x/(2018712621.0397925))^((tmp = 491163813.3921983, tmp)+(((x|((((x%(1990073256.812654))%((-2024388518.9599915)>>((tmp = 223182187, tmp)*(-722241065))))>>>(tmp = 2517147885.305745, tmp))%(1189996239.11222)))&x)%(-306932860))))))&((tmp = 1117802724.485684, tmp)+((-1391614045)-x)))%((((x>>((2958453447)*x))^(((410825859)|(((tmp = -1119269292.5495896, tmp)>>>(((((((x%(tmp = 648541746.6059314, tmp))*((-2304508480)<<((((x^(1408199888.1454597))|((251623937)|x))/((-382389946.9984102)|(tmp = -2082681143.5893767, tmp)))-(((tmp = 631243472, tmp)>>>(1407556544))/(((x>>>x)>>>(tmp = -6329025.47865057, tmp))>>>(tmp = 948664752.543093, tmp))))))/((((-183248880)>>x)&x)&x))>>x)&(((-978737284.8492057)%(tmp = 2983300011.737006, tmp))&(tmp = 2641937234.2954116, tmp)))<<x)>>(2795416632.9722223)))%((((tmp = -50926632, tmp)/x)&(((tmp = -2510786916, tmp)/x)/(-699755674)))|((((tmp = 1411792593, tmp)>>(924286570.2637128))>>((1609997725)>>(2735658951.0762663)))*(tmp = 726205435, tmp)))))<<(tmp = -2135055357.3156831, tmp)))/(tmp = 1408695065, tmp))^(tmp = -1343267739.8562133, tmp))));
+  assertEquals(0, x %= (-437232116));
+  assertEquals(-2463314518.2747326, x -= (2463314518.2747326));
+  assertEquals(109, x >>= (2401429560));
+  assertEquals(-2687641732.0253763, x += (-2687641841.0253763));
+  assertEquals(-2336375490019484000, x *= (tmp = 869303174.6678596, tmp));
+  assertEquals(5.458650430363785e+36, x *= x);
+  assertEquals(0, x |= ((((-1676972008.797291)*x)*((tmp = 2606991807, tmp)-x))<<x));
+  assertEquals(0, x &= ((-3053393759.3496876)+(-1431008367)));
+  assertEquals(-856728369, x |= (x-(((((764337872)/x)<<((x|(((tmp = 1409368192.1268077, tmp)+(tmp = -848083676, tmp))|(-2797102463.7915916)))^x))/x)^(tmp = 856728369.0589117, tmp))));
+  assertEquals(-0, x %= x);
+  assertEquals(1116550103, x ^= (-3178417193));
+  assertEquals(1116550103, x %= (tmp = -1482481942, tmp));
+  assertEquals(133, x >>>= x);
+  assertEquals(-1.381429241671034e-7, x /= ((tmp = -962771116.8101778, tmp)^x));
+  assertEquals(-1092268961, x |= ((tmp = 3202672531, tmp)-((x-(tmp = 845529357, tmp))>>(tmp = -868680593, tmp))));
+  assertEquals(-1092268961, x %= (tmp = 2670840415.304719, tmp));
+  assertEquals(-122794480, x %= (tmp = 969474481, tmp));
+  assertEquals(-297606521542193600, x *= (2423614820));
+  assertEquals(72460064, x >>>= (tmp = -1230798655, tmp));
+  assertEquals(-203714325373689600, x *= (-2811401400));
+  assertEquals(2154914048, x >>>= (((2241377026.001436)/x)+x));
+  assertEquals(1177864081, x ^= (tmp = -968513903, tmp));
+  assertEquals(35947664, x &= (-2086226758.2704995));
+  assertEquals(20795732539020670, x += (x*(578500247)));
+  assertEquals(-892004992, x >>= x);
+  assertEquals(-7023661.354330708, x /= ((((((1740714214)%((tmp = -459699286, tmp)+(tmp = -1700187400, tmp)))>>(tmp = -3170295237, tmp))+(tmp = -497509780, tmp))+((1971976144.6197853)+(661992813.6077721)))>>>(-1683802728)));
+  assertEquals(-1634205696, x <<= x);
+  assertEquals(-7, x >>= (-3187653764.930914));
+  assertEquals(-5.095345981491203, x -= ((tmp = 748315289, tmp)/(tmp = -392887780, tmp)));
+  assertEquals(1486531570, x &= (1486531570.9300508));
+  assertEquals(5670, x >>= (((tmp = -2486758205.26425, tmp)*(732510414))|x));
+  assertEquals(5670, x >>= (((-1811879946.2553763)%(1797475764))/(((tmp = -2159923884, tmp)|x)+(tmp = -1774410807, tmp))));
+  assertEquals(38, x %= (x>>>x));
+  assertEquals(-151134215, x ^= (((tmp = -2593085609.5622163, tmp)+((tmp = -814992345.7516887, tmp)-(534809571)))|(tmp = -232678571, tmp)));
+  assertEquals(-234881024, x <<= x);
+  assertEquals(-234881024, x <<= (x>>>x));
+  assertEquals(55169095435288580, x *= x);
+  assertEquals(0, x >>= (tmp = 1176612256, tmp));
+  assertEquals(0, x <<= (1321866341.2486475));
+  assertEquals(0, x %= (x-(-602577995)));
+  assertEquals(0, x >>>= (((((tmp = -125628635.79970193, tmp)^(tmp = 1294209955.229382, tmp))&(((tmp = -2353256654.0725203, tmp)|((-1136743028.9425385)|((((950703429.1110399)-(x>>>x))/((((x%(-252705869.21126103))/((tmp = 886957620, tmp)<<(x%((tmp = -1952249741, tmp)*(tmp = -1998149844, tmp)))))|(tmp = 1933366713, tmp))|((tmp = -2957141565, tmp)>>>(tmp = 1408598804, tmp))))+(((((((-2455002047.4910946)%(tmp = -528017836, tmp))&((-2693432769)/(tmp = 2484427670.9045153, tmp)))%(-356969659))-((((((tmp = 3104828644.0753174, tmp)%(x>>>(tmp = 820832137.8175925, tmp)))*((tmp = 763080553.9260503, tmp)+(3173597855)))<<(((-510785437)^x)<<(x|(((x*(x%((tmp = -1391951515, tmp)/x)))-x)|(x-((-522681793.93221474)/((2514619703.2162743)*(2936688324))))))))|x)>>>(-2093210042)))&(763129279.3651779))&x))))-x))%(((-1331164821)&(tmp = 1342684586, tmp))<<(x<<(tmp = 2675008614.588005, tmp))))>>((2625292569.8984914)+(-3185992401))));
+  assertEquals(0, x *= (tmp = 671817215.1147974, tmp));
+  assertEquals(-1608821121, x ^= ((tmp = 2686146175.04077, tmp)>>>x));
+  assertEquals(-0, x %= x);
+  assertEquals(-0, x /= ((tmp = 286794551.0720866, tmp)|(x%x)));
+  assertEquals(0, x <<= (x|(tmp = 1095503996.2285218, tmp)));
+  assertEquals(443296752, x ^= (443296752));
+  assertEquals(110824188, x >>= ((184708570)>>(x&x)));
+  assertEquals(0.7908194935161674, x /= ((((167151154.63381648)&((tmp = -1434120690, tmp)-(tmp = 2346173080, tmp)))/(56656051.87305987))^(140138414)));
+  assertEquals(-0.9027245492678485, x *= ((tmp = 1724366578, tmp)/(((2979477411)<<(((897038568)>>(tmp = 348960298, tmp))%(281056223.2037884)))^((((-1383133388)-(((-1379748375)-((x>>(x&(tmp = 2456582046, tmp)))>>>(-2923911755.565961)))&x))<<(-2825791731))^(tmp = -1979992970, tmp)))));
+  assertEquals(0, x &= (2482304279));
+  assertEquals(-0, x *= (-2284213673));
+  assertEquals(0, x <<= ((2874381218.015819)|x));
+  assertEquals(0, x *= (x>>>(tmp = 2172786480, tmp)));
+  assertEquals(0, x &= (-1638727867.2978938));
+  assertEquals(0, x %= ((tmp = -2213947368.285817, tmp)>>x));
+  assertEquals(0, x >>>= (tmp = -531324706, tmp));
+  assertEquals(0, x %= (tmp = -2338792486, tmp));
+  assertEquals(0, x <<= (((tmp = 351012164, tmp)<<(x|((tmp = -3023836638.5337825, tmp)^(-2678806692))))|x));
+  assertEquals(0, x %= (x-(tmp = -3220231305.45039, tmp)));
+  assertEquals(0, x <<= (-2132833261));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x %= ((2544970469)+(((-2633093458.5911965)&(644108176))-(x>>>(tmp = -949043718, tmp)))));
+  assertEquals(-2750531265, x += (-2750531265));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x *= ((tmp = 1299005700, tmp)-x));
+  assertEquals(0, x >>= x);
+  assertEquals(-1785515304, x -= (((((-806054462.5563161)/x)>>>x)+(1785515304))|((tmp = 2937069788.9396844, tmp)/x)));
+  assertEquals(-3810117159.173689, x -= (2024601855.1736891));
+  assertEquals(-6.276064139320051, x /= (607087033.3053156));
+  assertEquals(134217727, x >>>= (((x%(tmp = 924293127, tmp))^x)|((x>>>(x&((((tmp = -413386639, tmp)/(x>>(tmp = 599075308.8479941, tmp)))^(tmp = -1076703198, tmp))*((tmp = -2239117284, tmp)>>(655036983)))))-x)));
+  assertEquals(134217727, x %= (tmp = 2452642261.038778, tmp));
+  assertEquals(-569504740360507, x *= ((tmp = -1086243941, tmp)>>(tmp = 1850668904.4885683, tmp)));
+  assertEquals(113378806, x >>>= (tmp = -2558233435, tmp));
+  assertEquals(979264375, x -= (((x>>(1950008052))%((2917183569.0209)*(tmp = 1184250640.446752, tmp)))|((((tmp = -691875212, tmp)-(-2872881803))>>(tmp = 44162204.97461021, tmp))^(tmp = 865885647, tmp))));
+  assertEquals(-1127813632, x <<= ((((tmp = -2210499281, tmp)>>>x)-(tmp = 2359697240, tmp))-x));
+  assertEquals(-1707799657, x ^= (653518231.3995534));
+  assertEquals(2916579668449318000, x *= x);
+  assertEquals(2916579669254640600, x += (x&(tmp = 2986558026.399422, tmp)));
+  assertEquals(870995175, x ^= (2598813927.8991632));
+  assertEquals(870995175, x %= (-2857038782));
+  assertEquals(1869503575895591000, x *= (x|(x|(((tmp = 2478650307.4118147, tmp)*((tmp = 2576240847.476932, tmp)>>>x))<<x))));
+  assertEquals(-134947790, x |= ((tmp = 1150911808, tmp)*((2847735464)/(-2603172652.929262))));
+  assertEquals(-137053182, x -= ((tmp = 2155921819.0929346, tmp)>>>(x-(((-1960937402)-(-1907735074.2875962))%((1827808310)^(tmp = -2788307127, tmp))))));
+  assertEquals(-134824702, x |= (((2912578752.2395406)^(x%(((-2585660111.0638976)<<(((((tmp = 747742706, tmp)%(-1630261205))&((((x|(x|(-2619903144.278758)))|((2785710568.8651934)>>((-968301967.5982246)<<(x&x))))>>((x>>>((x>>>(tmp = -1402085797.0310762, tmp))*((tmp = -323729645.2250068, tmp)<<(tmp = 2234667799, tmp))))>>>(-167003745)))>>((924665972.4681011)<<x)))>>>x)<<((((x+x)+x)-(((tmp = 2399203431.0526247, tmp)-(-2872533271))-(((tmp = 914778794.2087344, tmp)-(tmp = 806353942.9502392, tmp))|(((tmp = 262924334.99231672, tmp)&x)|(tmp = -460248836.5602243, tmp)))))/x)))%((-1681000689)/(tmp = -2805054623.654228, tmp)))))*(tmp = 957346233.9619625, tmp)));
+  assertEquals(-3274838, x %= ((((tmp = 3155450543.3524327, tmp)>>>x)<<(tmp = 2103079652.3410985, tmp))>>x));
+  assertEquals(-3274838, x |= ((((tmp = 2148004645.639173, tmp)>>>(tmp = -1285119223, tmp))<<(((((-711596054)>>>(tmp = -2779776371.3473206, tmp))^(((((tmp = -1338880329.383915, tmp)<<((-1245247254.477341)>>x))*(tmp = -2649052844.20065, tmp))>>((1734345880.4600453)%(x/(2723093117.118899))))*(1252918475.3285656)))<<(2911356885))^x))<<(-1019761103)));
+  assertEquals(1703281954, x &= (((tmp = 1036570471.7412028, tmp)+((tmp = 3043119517, tmp)%(2374310816.8346715)))%(tmp = -2979155076, tmp)));
+  assertEquals(1741588391, x |= ((tmp = 1230009575.6003838, tmp)>>>(-1247515003.8152597)));
+  assertEquals(72869474.64782429, x %= (tmp = 1668718916.3521757, tmp));
+  assertEquals(770936242.104203, x += (698066767.4563787));
+  assertEquals(-0.2820604726420833, x /= (tmp = -2733230342, tmp));
+  assertEquals(403480578, x |= ((969730374)&(tmp = 1577889835, tmp)));
+  assertEquals(-1669557233, x ^= ((-1616812135)+(tmp = -456209292, tmp)));
+  assertEquals(-1630427, x >>= ((2327783031.1175823)/(226947662.4579488)));
+  assertEquals(131022, x >>>= ((tmp = -1325018897.2482083, tmp)>>(x&((((((-1588579772.9240348)<<(tmp = -1775580288.356329, tmp))<<(tmp = -1021528325.2075481, tmp))>>((tmp = 2373033451.079956, tmp)*(tmp = 810304612, tmp)))-((tmp = -639152097, tmp)<<(tmp = 513879484, tmp)))&(2593958513)))));
+  assertEquals(1, x >>= ((3033200222)-x));
+  assertEquals(-561146816.4851823, x += (tmp = -561146817.4851823, tmp));
+  assertEquals(-4.347990105831158, x /= ((((-1270435902)*x)%((tmp = 637328492.7386824, tmp)-(x>>(-749100689))))%(x+x)));
+  assertEquals(-1, x >>= x);
+  assertEquals(1, x *= x);
+  assertEquals(111316849706694460, x += ((966274056)*(x|(115202150))));
+  assertEquals(-1001883840, x >>= x);
+  assertEquals(-1001883840, x &= x);
+  assertEquals(-3006880758, x += ((((-2275110637.4054556)/((x+(tmp = -1390035090.4324536, tmp))>>(-5910593)))&(tmp = 378982420, tmp))|(tmp = 2289970378.568629, tmp)));
+  assertEquals(314474, x >>>= (x>>((tmp = -228007336.31281257, tmp)%(tmp = 1127648013, tmp))));
+  assertEquals(-17694827, x ^= ((tmp = 2095133598.1849852, tmp)|(-1978322311)));
+  assertEquals(1, x /= x);
+  assertEquals(1, x %= (-2323617209.7531185));
+  assertEquals(0, x >>>= (x*(tmp = -1574455400.489434, tmp)));
+  assertEquals(0, x >>= (3131854684));
+  assertEquals(2853609824, x += ((-231012098)-(tmp = -3084621922, tmp)));
+  assertEquals(8143089027629311000, x *= x);
+  assertEquals(313052685, x ^= (tmp = 2962303501, tmp));
+  assertEquals(4776, x >>= (tmp = 2271457232, tmp));
+  assertEquals(0.000002812258572702285, x /= (tmp = 1698279115, tmp));
+  assertEquals(0, x >>>= (tmp = 1698465782.0927145, tmp));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x |= ((x<<((-1824760240.3040407)<<(2798263764.39145)))&(tmp = 1795988253.0493627, tmp)));
+  assertEquals(1782206945, x ^= (-2512760351.7881565));
+  assertEquals(7610569113843172000, x *= (((tmp = -44415823.92972565, tmp)&(tmp = 1402483498.9421625, tmp))+(tmp = 2909778666, tmp)));
+  assertEquals(15221138227873292000, x += (x-(tmp = -186948658.394145, tmp)));
+  assertEquals(0, x -= x);
+  assertEquals(-2238823252, x -= ((tmp = 2238823252, tmp)+x));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>= (2976069570));
+  assertEquals(0, x >>= ((tmp = -2358157433, tmp)/x));
+  assertEquals(-949967713, x ^= (tmp = -949967713, tmp));
+  assertEquals(-1, x >>= x);
+  assertEquals(-1522291702.1977966, x *= (1522291702.1977966));
+  assertEquals(-1522291702, x >>= ((((2290279800)|x)|(1793154434.6798015))&((-1161390929.0766077)>>>x)));
+  assertEquals(83894274, x &= (tmp = 1571058486, tmp));
+  assertEquals(43186847.90522933, x += ((tmp = -1131332988.0947707, tmp)%x));
+  assertEquals(0, x >>= (tmp = -1968312707.269359, tmp));
+  assertEquals(0, x &= (2507747643.26175));
+  assertEquals(0, x %= (tmp = 3190525303.366887, tmp));
+  assertEquals(-1968984602, x ^= (((x/(x|(-1607062026.5338054)))<<(tmp = 2207669861.8770065, tmp))+(tmp = 2325982694.956348, tmp)));
+  assertEquals(554, x >>>= (((tmp = -2302283871.993821, tmp)>>>(-3151835112))|(((((x%(-1534374264))/((731246012)<<(((883830997.1194847)<<(((-1337895080.1937215)/(tmp = 3166402571.8157315, tmp))^(tmp = -1563897595.5799441, tmp)))>>(tmp = -556816951.0537591, tmp))))>>(-2682203577))<<(x/((1654294674.865079)+x)))/((x^(-2189474695.4259806))/(-475915245.7363057)))));
+  assertEquals(1372586111, x ^= (1372586581));
+  assertEquals(1166831229, x -= ((-834168138)&(762573579)));
+  assertEquals(2333662456, x -= ((x>>x)-x));
+  assertEquals(-1961304840, x &= x);
+  assertEquals(-2130143128, x &= (2982852718.0711775));
+  assertEquals(1073741824, x <<= (-1446978661.6426942));
+  assertEquals(2097152, x >>>= ((-1424728215)-(((127872198)%(tmp = -2596923298, tmp))&x)));
+  assertEquals(2097152, x >>>= x);
+  assertEquals(0, x &= (x/(tmp = -518419194.42994523, tmp)));
+  assertEquals(0, x >>= ((x/(-1865078245))%(tmp = 2959239210, tmp)));
+  assertEquals(-0, x *= ((x|(-1721307400))|(-3206147171.9491577)));
+  assertEquals(0, x >>>= ((-694741143)&(tmp = -2196513947.699142, tmp)));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x &= ((tmp = 2037824385.8836646, tmp)+((tmp = 1203034986.4647732, tmp)/(x>>>(((-1374881234)/(899771270.3237157))+((-2296524362.8020077)|(-1529870870)))))));
+  assertEquals(0, x >>= (tmp = 2770637816, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(-1861843456, x |= ((632402668)*((x|(tmp = -1032952662.8269436, tmp))|(tmp = 2671272511, tmp))));
+  assertEquals(-1861843456, x >>= (((x>>>x)+x)<<(-1600908842)));
+  assertEquals(-58182608, x >>= (x-(tmp = -2496617861, tmp)));
+  assertEquals(-3636413, x >>= (tmp = -400700028, tmp));
+  assertEquals(-7272826, x += x);
+  assertEquals(-1, x >>= ((tmp = -3184897005.3614545, tmp)-((-1799843014)|(tmp = 2832132915, tmp))));
+  assertEquals(-121800925.94209385, x *= (121800925.94209385));
+  assertEquals(-30450232, x >>= (-979274206.6261561));
+  assertEquals(-30450232, x >>= (tmp = -1028204832.5078967, tmp));
+  assertEquals(-30450232, x |= x);
+  assertEquals(965888871, x ^= (((((-2157753481.3375635)*((tmp = -1810667184.8165767, tmp)&((tmp = 2503908344.422232, tmp)|x)))>>(x>>(1601560785)))<<x)^(tmp = 943867311.6380403, tmp)));
+  assertEquals(7546006, x >>>= x);
+  assertEquals(7546006, x <<= ((tmp = 1388931761.780241, tmp)*(x-(tmp = -1245147647.0070577, tmp))));
+  assertEquals(12985628, x += (x&(-1520746354)));
+  assertEquals(12985628, x &= x);
+  assertEquals(12985628, x %= (tmp = 308641965, tmp));
+  assertEquals(685733278, x |= ((tmp = -1275653544, tmp)-((tmp = -1956798010.3773859, tmp)%(tmp = 2086889575.643448, tmp))));
+  assertEquals(679679376, x &= (2860752368));
+  assertEquals(1770773904, x |= (x<<(3200659207)));
+  assertEquals(1224886544, x &= (-585733767.6876519));
+  assertEquals(1224886544, x %= ((tmp = -114218494, tmp)-x));
+  assertEquals(1208109328, x &= (tmp = 1854361593, tmp));
+  assertEquals(18434, x >>>= x);
+  assertEquals(-349394636955256100, x *= (x*(-1028198742)));
+  assertEquals(-519536600.7713163, x %= (-1054085356.9120367));
+  assertEquals(-1610612736, x ^= ((tmp = -3126078854, tmp)&x));
+  assertEquals(-2637321565906333700, x *= (1637464740.5658746));
+  assertEquals(-2637321568051070500, x -= ((tmp = -1006718806, tmp)<<(3005848133.106345)));
+  assertEquals(368168695, x ^= (x^(tmp = 368168695.6881037, tmp)));
+  assertEquals(43, x >>>= x);
+  assertEquals(-2081297089, x |= ((167169305.77248895)+(-2248466405.3199244)));
+  assertEquals(-2474622167, x -= (tmp = 393325078, tmp));
+  assertEquals(-135109701, x %= (-1169756233));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>= (((((tmp = -164768854, tmp)/(tmp = -1774989993.1909926, tmp))+x)-((-921438912)>>(tmp = -191772028.69249105, tmp)))-(tmp = 558728578.22033, tmp)));
+  assertEquals(0, x %= (tmp = 2188003745, tmp));
+  assertEquals(0, x <<= (((tmp = -999335540, tmp)>>((((325101977)/(tmp = -3036991542, tmp))<<(tmp = -213302488, tmp))+x))|(tmp = -1054204587, tmp)));
+  assertEquals(0, x &= ((2844053429.4720345)>>>x));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x -= (-1481729275.9118822));
+  assertEquals(NaN, x *= (tmp = 1098314618.2397528, tmp));
+  assertEquals(-1073741824, x ^= ((tmp = 1718545772, tmp)<<(((tmp = -81058910, tmp)-(2831123087.424368))+(tmp = 576710057.2361784, tmp))));
+  assertEquals(-2921155898.4793186, x -= (1847414074.4793184));
+  assertEquals(-1295646720, x <<= (2178621744));
+  assertEquals(-0.8906779709597907, x /= ((tmp = -2840292585.6837263, tmp)<<(x&((tmp = 892527695.6172305, tmp)>>>x))));
+  assertEquals(0, x <<= (((tmp = 3149667213.298993, tmp)>>(tmp = 1679370761.7226725, tmp))^(115417747.21537328)));
+  assertEquals(0, x |= x);
+  assertEquals(0, x %= ((-1112849427)>>(-1245508870.7514496)));
+  assertEquals(0, x &= x);
+  assertEquals(0, x |= x);
+  assertEquals(0, x >>>= ((3144100694.930459)>>>(tmp = 2408610503, tmp)));
+  assertEquals(0, x <<= ((tmp = 2671709754.0318713, tmp)%x));
+  assertEquals(0, x >>>= (x|((tmp = -3048578701, tmp)-(674147224))));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x &= ((tmp = -2084883715, tmp)|(((((-3008427069)+(875536047.4283574))>>>x)%(tmp = -450003426.1091652, tmp))%(((-2956878433.269356)|(x/((((x%((((((x<<(((tmp = -1581063482.510351, tmp)^x)-(tmp = 1364458217, tmp)))^((tmp = 1661446342, tmp)+(1307091014)))/(342270750.9901335))>>>(x&((1760980812.898993)&((tmp = 2878165745.6401143, tmp)/(((tmp = -981178013, tmp)/(-2338761668.29912))>>(-958462630))))))*((1807522840)^((tmp = 1885835034, tmp)^(-2538647938))))*(1673607540.0854697)))%x)>>x)<<x)))<<(853348877.2407281)))));
+  assertEquals(0, x >>>= x);
+  assertEquals(-1162790279, x -= (1162790279));
+  assertEquals(-1162790279, x >>= (((-490178658)*x)/((((((tmp = -1883861998.6699312, tmp)/(tmp = -2369967345.240594, tmp))+(3142759868.266447))&(508784917.8158537))&x)>>(-2129532322))));
+  assertEquals(-1360849740.9829152, x -= (x+(1360849740.9829152)));
+  assertEquals(1928392181, x ^= (-602670783));
+  assertEquals(19478708.898989897, x /= (((-2617861994)>>(tmp = 797256920, tmp))%(-1784987906)));
+  assertEquals(-8648903.575540157, x *= (((tmp = 673979276, tmp)/(-1517908716))%(x/x)));
+  assertEquals(-8648903.575540157, x %= ((((643195610.4221292)>>>(tmp = 2342669302, tmp))>>>(tmp = -1682965878, tmp))^((tmp = -208158937.63443017, tmp)>>((907286989)&(x<<(448634893))))));
+  assertEquals(1399288769, x ^= (tmp = -1407486728, tmp));
+  assertEquals(0, x &= (((1999255838.815517)/(tmp = 564646001, tmp))/(-3075888101.3274765)));
+  assertEquals(0, x ^= ((-78451711.59404826)%x));
+  assertEquals(-1351557131, x |= (2943410165));
+  assertEquals(1715626371, x -= (-3067183502));
+  assertEquals(71434240, x &= ((-1800066426)<<(((((x<<(-324796375))+x)<<(tmp = 2696824955.735132, tmp))^x)%(tmp = 444916469, tmp))));
+  assertEquals(71434240, x >>>= (((x&((x%x)|x))+(tmp = 2226992348.3050146, tmp))<<(-305526260)));
+  assertEquals(0, x -= (x%(tmp = 582790928.5832802, tmp)));
+  assertEquals(0, x *= ((x%(1865155340))>>>((x<<(2600488191))^(-308995123))));
+  assertEquals(0, x >>= (x&(-3120043868.8531103)));
+  assertEquals(0, x |= x);
+  assertEquals(-0, x *= (tmp = -172569944, tmp));
+  assertEquals(0, x <<= (-1664372874));
+  assertEquals(1377713344.6784928, x += (tmp = 1377713344.6784928, tmp));
+  assertEquals(1377713344, x |= x);
+  assertEquals(-232833282, x |= (tmp = 2685870654, tmp));
+  assertEquals(84639, x -= (((((2778531079.998492)%(2029165314))>>>(tmp = -468881172.3729558, tmp))^x)|((x>>>((((x%(3044318992.943596))&(1996754328.2214756))^(1985227172.7485228))%(tmp = -1984848676.1347625, tmp)))|((tmp = 2637662639, tmp)<<x))));
+  assertEquals(0, x ^= x);
+  assertEquals(1237720303, x -= (-1237720303));
+  assertEquals(2, x >>= (-2148785379.428976));
+  assertEquals(2, x &= (tmp = -3087007874, tmp));
+  assertEquals(0, x %= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x += x);
+  assertEquals(0, x &= (2055693082));
+  assertEquals(-1349456492, x += (x^(-1349456492.315998)));
+  assertEquals(671088640, x <<= (x>>(-2030805724.5472062)));
+  assertEquals(-417654580004782100, x *= (tmp = -622353822, tmp));
+  assertEquals(1538160360, x |= (195983080.56698656));
+  assertEquals(733, x >>>= (tmp = 661085269, tmp));
+  assertEquals(657, x &= (-1611460943.993404));
+  assertEquals(431649, x *= x);
+  assertEquals(863298, x += x);
+  assertEquals(0, x &= ((1899423003)/((472439729)>>((tmp = 2903738952, tmp)+(tmp = 2164601630.3456993, tmp)))));
+  assertEquals(0, x &= (x>>>(tmp = 1939167951.2828958, tmp)));
+  assertEquals(1557813284, x |= (x-(-1557813284)));
+  assertEquals(72876068, x &= (662438974.2372154));
+  assertEquals(0.6695448637501589, x /= (tmp = 108844189.45702457, tmp));
+  assertEquals(0, x -= x);
+  assertEquals(2944889412, x += (2944889412));
+  assertEquals(3787980288, x -= ((((tmp = -2003814373.2301111, tmp)<<x)>>>(tmp = -3088357284.4405823, tmp))-(843090884)));
+  assertEquals(1, x >>>= (729274079));
+  assertEquals(1, x %= (-148002187.33869123));
+  assertEquals(3073988415.673201, x *= (tmp = 3073988415.673201, tmp));
+  assertEquals(4839166225.673201, x += (tmp = 1765177810, tmp));
+  assertEquals(4529373898.673201, x += (-309792327));
+  assertEquals(3097903.090496063, x %= (-150875866.51942348));
+  assertEquals(1270874112, x <<= ((((((tmp = -960966763.1418135, tmp)>>((((-3208596981.613482)>>>(tmp = 746403937.6913509, tmp))>>>(-2190042854.066803))/(2449323432)))*(-1272232665.791577))<<(-99306767.7209444))^((-1942103828)/((1570981655)/(tmp = 2381666337, tmp))))+(tmp = -1946759395.1558368, tmp)));
+  assertEquals(1273845956, x |= (tmp = -3197282108.6120167, tmp));
+  assertEquals(159230744, x >>= (((tmp = -1036031403.8108604, tmp)>>>(((3084964493)>>((x*x)^x))+(((2980108409.352001)^x)-(tmp = -2501685423.513927, tmp))))&(326263839)));
+  assertEquals(-370091747145550100, x *= (tmp = -2324248055.674161, tmp));
+  assertEquals(143384219.54999557, x /= (tmp = -2581119096, tmp));
+  assertEquals(1843396287, x |= (tmp = 1842718767, tmp));
+  assertEquals(2.4895593465813803, x /= (740450831));
+  assertEquals(2.4895593465813803, x %= ((((((((-3175333618)>>>((tmp = -1403880166, tmp)<<(tmp = -134875360, tmp)))>>>(2721317334.998084))<<(x&(tmp = 2924634208.1484184, tmp)))*((((x>>(tmp = -200319931.15328693, tmp))-(tmp = -495128933, tmp))+((-788052518.6610589)*((((tmp = 107902557, tmp)&(1221562660))%(x<<(((3155498059)*(((tmp = -1354381139.4897022, tmp)^(tmp = 3084557138.332852, tmp))*((((tmp = 1855251464.8464525, tmp)/((-1857403525.2008865)>>x))|x)-(-2061968455.0023944))))*(1917481864.84619))))^(x-(-508176709.52712965)))))+((((x%(-1942063404))+(x%(tmp = 855152281.180481, tmp)))|(-522863804))>>x)))>>>((tmp = -2515550553, tmp)&(((((-801095375)-(tmp = -2298729336.9792976, tmp))^x)/(tmp = 2370468053, tmp))>>(x|(tmp = -900008879, tmp)))))>>>(((tmp = -810295719.9509168, tmp)*((tmp = -1306212963.6226444, tmp)/(((tmp = 3175881540.9514832, tmp)|(-1439142297.819246))+((tmp = -134415617, tmp)|((-245801870)+x)))))>>(tmp = 1889815478, tmp)))-(((tmp = 597031177, tmp)%(858071823.7655672))+((tmp = 2320838665.8243756, tmp)|((938555608)<<(2351739219.6461897))))));
+  assertEquals(6.197905740150709, x *= x);
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>= (-1639664165.9076233));
+  assertEquals(0, x >>= (-3135317748.801177));
+  assertEquals(0, x &= (3185479232.5325994));
+  assertEquals(-0, x *= ((-119759439.19668174)/(tmp = 2123964608, tmp)));
+  assertEquals(0, x /= (-1183061929.2827876));
+  assertEquals(0, x <<= (-1981831198));
+  assertEquals(0, x >>= ((((x<<(((((((-2133752838)&((tmp = -3045157736.9331336, tmp)>>>(x%x)))>>x)%(tmp = 3082217039, tmp))&(tmp = 270770770.97558427, tmp))|((-2212037556)^((((((2089224421)|(tmp = 360979560, tmp))<<x)%((tmp = -1679487690.6940534, tmp)+((173021423)|((tmp = 560900612, tmp)+((244376267.58977115)^x)))))<<(tmp = 2534513699, tmp))^x)))>>>(2915907189.4873834)))+(x*x))%(1637581117))%(tmp = 2363861105.3786244, tmp)));
+  assertEquals(0, x &= ((-2765495757.873004)&(1727406493)));
+  assertEquals(NaN, x -= (((((-1419667515.2616255)|x)-(150530256.48022234))%((((x|x)<<x)>>>(x^x))+x))-((-1216384577.3749187)*(495244398))));
+  assertEquals(NaN, x += (x^((tmp = 2472035493, tmp)+x)));
+  assertEquals(NaN, x %= ((tmp = -1753037412.885754, tmp)|((tmp = 2507058310, tmp)<<(1475945705))));
+  assertEquals(-1008981005, x |= ((tmp = -1140889842.6099494, tmp)-(tmp = -131908837, tmp)));
+  assertEquals(999230327.5872104, x -= (tmp = -2008211332.5872104, tmp));
+  assertEquals(975810, x >>= (((-1211913874)*x)>>>((-2842129009)>>(x&(tmp = -1410865834, tmp)))));
+  assertEquals(7623, x >>= ((tmp = -1051327071, tmp)-(((tmp = -237716102.8005445, tmp)|((2938903833.416546)&x))|(((-1831064579)^x)/((tmp = 2999232092, tmp)-(981996301.2875179))))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x %= (x|(tmp = -666201160.5810485, tmp)));
+  assertEquals(-1347124100, x |= (-1347124100));
+  assertEquals(-0, x %= (x&x));
+  assertEquals(-661607963, x ^= (tmp = -661607963.3794863, tmp));
+  assertEquals(3465, x >>>= (-828119020.8056595));
+  assertEquals(-268431991, x -= (((tmp = -1386256352, tmp)^((tmp = 743629575, tmp)%((x*((tmp = -1719517658, tmp)>>(2019516558)))<<((2637317661)|x))))<<(tmp = -51637065, tmp)));
+  assertEquals(1578876380, x += ((tmp = 1847308371, tmp)&(((((((tmp = 1487934776.1893163, tmp)%(tmp = 1423264469.3137975, tmp))|(((2653260792.5668964)/(-2417905016.043802))>>>(2097411118.4501896)))^x)^(((tmp = -71334226, tmp)|x)>>>(tmp = -2771758874.7696714, tmp)))^((tmp = -1464849031.3240793, tmp)%(tmp = 2349739690.6430283, tmp)))/x)));
+  assertEquals(3269293934, x += (1690417554));
+  assertEquals(4025392608.031957, x -= (((tmp = 268501120.7225704, tmp)<<(tmp = 2841620654.8903794, tmp))+((tmp = 1606704462.8455591, tmp)/((-2601879963)/(tmp = 2966620168.989736, tmp)))));
+  assertEquals(7, x >>>= (x^(-1913800035)));
+  assertEquals(1.4326776816275493e-8, x /= ((((tmp = -2703417892, tmp)/x)^((-2693772270.396241)>>>((x-(tmp = 615999818.5666655, tmp))>>((((2308121439.3702726)<<((-1794701502)>>(x+(tmp = -2253406035.972883, tmp))))<<((tmp = -197103799.0624652, tmp)|(629975898)))>>>x))))>>>((tmp = 2833656803, tmp)^(x^(tmp = -1580436025, tmp)))));
+  assertEquals(0, x >>>= (tmp = 1525372830.2126007, tmp));
+  assertEquals(0, x %= ((2354010949.24469)>>>(x<<x)));
+  assertEquals(0, x ^= (((1112335059.6922574)*(tmp = -1874363935, tmp))&(((((2154894295.8360596)<<x)&(tmp = -270736315.13505507, tmp))&x)>>>(-2205692260.552064))));
+  assertEquals(0, x >>>= (x<<((1488533932)*(tmp = 1707754286, tmp))));
+  assertEquals(0, x >>= (((tmp = 1232547376.463387, tmp)%((x>>(711691823.1608362))>>>x))>>(((895039781.7478573)*(((((-334946524)&x)*(tmp = -1214529640, tmp))^(tmp = -1586820245, tmp))*(1062595445)))+x)));
+  assertEquals(0, x *= (1863299863.2631998));
+  assertEquals(0, x /= (tmp = 1858428705.1330547, tmp));
+  assertEquals(0, x &= x);
+  assertEquals(611788028, x += (x^(611788028.1510412)));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>= ((tmp = -1617320707.1784317, tmp)-((-2139400380)-(-1402777976))));
+  assertEquals(0, x >>= (415866827.34665));
+  assertEquals(-1990811897, x -= (tmp = 1990811897, tmp));
+  assertEquals(-1990811895, x += ((x>>>(tmp = -2175453282.769696, tmp))&(tmp = -1459450498.7327478, tmp)));
+  assertEquals(-2377017935.149517, x += (-386206040.1495173));
+  assertEquals(1946129845, x |= (tmp = -2890956796.936539, tmp));
+  assertEquals(0, x %= x);
+  assertEquals(0, x <<= (1616188263));
+  assertEquals(-1081213596, x ^= (tmp = 3213753700, tmp));
+  assertEquals(3213753700, x >>>= (tmp = -3211181312, tmp));
+  assertEquals(-1081213596, x &= x);
+  assertEquals(-1081213583, x ^= (((tmp = 1599988273.4926577, tmp)>>((((-1061394954.6331315)^x)+((-1835761078)*x))+(x%(tmp = -696221869, tmp))))/((tmp = -1156966790.3436491, tmp)^x)));
+  assertEquals(0, x ^= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x += (-1257400530.9263027));
+  assertEquals(NaN, x /= (753062089));
+  assertEquals(NaN, x *= ((tmp = 305418865.57012296, tmp)^(((-2797769706)+((((tmp = -33288276.988654375, tmp)%(tmp = 1242979846, tmp))|(-316574800))-((tmp = -1766083579.4203427, tmp)*(((x*(tmp = -2400342309.2349987, tmp))>>(tmp = 2632061795, tmp))^(tmp = -1001440809, tmp)))))^((((x-(tmp = -1469542637.6925495, tmp))-x)-(3184196890))%(((((((633226688)*((tmp = -2692547856, tmp)>>(((tmp = -1244311756, tmp)>>>x)+((1746013631.405202)>>>(941829464.1962085)))))%(x-x))+(995681795))-(tmp = -3047070551.3642616, tmp))/(1968259705))-((-2853237880)^(tmp = -2746628223.4540343, tmp)))))));
+  assertEquals(0, x >>= x);
+  assertEquals(0.5713172378854926, x += (((x+(((x+x)/(tmp = 2642822318, tmp))*(-2590095885.4280834)))|(tmp = -1769210836, tmp))/(tmp = -3096722308.8665104, tmp)));
+  assertEquals(-0.000002311097780334994, x /= ((2269858877.9010344)>>(-2992512915.984787)));
+  assertEquals(-0.000002311097780334994, x %= (-1139222821));
+  assertEquals(-0.000004622195560669988, x += x);
+  assertEquals(1, x /= x);
+  assertEquals(1, x >>>= (((3002169429.6061807)/(-3068577366))>>>((tmp = -1844537620, tmp)%((((tmp = 2087505119, tmp)>>>x)+x)&(2179989542)))));
+  assertEquals(-534213071, x *= (-534213071));
+  assertEquals(-534213077.3716287, x -= (((tmp = -2390432951.154034, tmp)^x)/(-290501980)));
+  assertEquals(1836305, x >>>= (x&x));
+  assertEquals(1836305, x %= ((x|((3070123855)^(49986396)))+((-1863644960.4202995)>>>((tmp = 1886126804.6019692, tmp)^x))));
+  assertEquals(28692, x >>>= ((2561362139.491764)>>(((((tmp = -1347469854.7413375, tmp)/(((x|(x+x))^((x^(tmp = -2737413775.4595394, tmp))^x))<<(((tmp = 225344844.07128417, tmp)&x)&(tmp = 145794498, tmp))))*x)<<(1424529187))/((-2924344715)/(tmp = -2125770148, tmp)))));
+  assertEquals(-2089419535.2717648, x += (-2089448227.2717648));
+  assertEquals(18957929, x ^= (tmp = 2186590872, tmp));
+  assertEquals(-708972800, x -= (727930729));
+  assertEquals(-4198593, x |= (799483455.1885371));
+  assertEquals(-1, x >>= (-2330654693.6413193));
+  assertEquals(-1, x |= (((tmp = -116877155, tmp)>>>((((tmp = -1677422314.1333556, tmp)/(tmp = -3108738499.0798397, tmp))%((x&(x/x))%((tmp = -695607185.1561592, tmp)-(tmp = 2302449181.622259, tmp))))^(((-1482743646.5604773)^((897705064)>>>x))-(tmp = -2933836669, tmp))))%(((tmp = -2991584625, tmp)|(((x>>x)+(-1101066835))-x))>>(-33192973.819939613))));
+  assertEquals(-1, x &= x);
+  assertEquals(-524288, x <<= (-1177513101.3087924));
+  assertEquals(1978770334.9189441, x += (tmp = 1979294622.9189441, tmp));
+  assertEquals(901783582, x &= ((-368584615)^(((((-478030699.2647903)<<x)<<x)+(tmp = 708725752, tmp))^((tmp = -3081556856, tmp)/(tmp = 1149958711.0676727, tmp)))));
+  assertEquals(-1480333211.8654308, x += (tmp = -2382116793.865431, tmp));
+  assertEquals(956930239.6783283, x *= ((tmp = 956930239.6783283, tmp)/x));
+  assertEquals(1277610.4668602513, x /= ((tmp = 1571029828, tmp)>>(tmp = 2417481141, tmp)));
+  assertEquals(-1077333228, x ^= (tmp = 3218755006, tmp));
+  assertEquals(-50218, x |= (tmp = -1044436526.6435988, tmp));
+  assertEquals(-1, x >>= (-154655245.18921852));
+  assertEquals(0.00006276207290978003, x *= (((tmp = 2234286992.9800305, tmp)>>(tmp = 2132564046.0696363, tmp))/((((tmp = -2565534644.3428087, tmp)>>>(tmp = 2622809851.043325, tmp))>>>((tmp = 311277386, tmp)&x))-(tmp = -2003980974, tmp))));
+  assertEquals(0, x %= x);
+  assertEquals(1282114076, x += ((((422838227)>>>((tmp = 1024613366.1899053, tmp)-((368275340)<<(((tmp = -3066121318, tmp)+(-2319101378))&x))))^(x>>(tmp = 1920136319.803412, tmp)))^(1282264803.3968434)));
+  assertEquals(-277097604, x |= (-283585688.9123297));
+  assertEquals(553816692, x &= (x&(tmp = 554082036.676608, tmp)));
+  assertEquals(658505728, x <<= x);
+  assertEquals(658505728, x &= (x%(2846071230)));
+  assertEquals(39, x >>= (334728536.5172192));
+  assertEquals(0, x -= x);
+  assertEquals(0, x += x);
+  assertEquals(0, x &= (tmp = -335285336, tmp));
+  assertEquals(0, x <<= (tmp = 1255594828.3430014, tmp));
+  assertEquals(0, x %= (-630772751.1248167));
+  assertEquals(NaN, x /= ((((x&(tmp = -1576090612, tmp))%x)>>>x)*((-1038073094.2787619)>>>x)));
+  assertEquals(NaN, x += x);
+  assertEquals(NaN, x -= (((tmp = -2663887803, tmp)&((x+(-1402421046))/x))/(-2675654483)));
+  assertEquals(NaN, x %= (x&(tmp = 672002093, tmp)));
+  assertEquals(0, x |= x);
+  assertEquals(-2698925754, x += (tmp = -2698925754, tmp));
+  assertEquals(-2057748993, x += ((tmp = -2263466497, tmp)^x));
+  assertEquals(1, x /= x);
+  assertEquals(-2769559719.4045835, x -= (2769559720.4045835));
+  assertEquals(-1.3964174646069973, x /= (tmp = 1983332198, tmp));
+  assertEquals(-2140716624.3964174, x += (tmp = -2140716623, tmp));
+  assertEquals(0, x <<= ((2589073007)-(-816764911.8571186)));
+  assertEquals(-2837097288.161354, x -= (tmp = 2837097288.161354, tmp));
+  assertEquals(-1445059927.161354, x += (tmp = 1392037361, tmp));
+  assertEquals(155197984, x &= (tmp = -2694712730.924674, tmp));
+  assertEquals(155197984, x |= (x>>>(tmp = 69118015.20305443, tmp)));
+  assertEquals(155197984, x >>>= (((x^(-1353660241))*x)<<(((((x%(tmp = -1905584634, tmp))>>>(tmp = -860171244.5963638, tmp))&(-1084415001.7039547))+(x-(((tmp = 298064661, tmp)>>x)>>((tmp = 378629912.383446, tmp)-(x%x)))))+(((3212580683)/(((((x^x)>>(tmp = -1502887218, tmp))<<x)%(-142779025))|(((tmp = 1361745708, tmp)*(((((tmp = 1797072528.0673332, tmp)+x)%(tmp = 167297609, tmp))%(-287345856.1791787))^(((((((x*(tmp = -640510459.1514752, tmp))<<(x^(tmp = 1387982082.5646644, tmp)))>>(tmp = 2473373497.467914, tmp))^((234025940)*x))+(tmp = 520098202.9546956, tmp))*(x*(tmp = -362929250.1775775, tmp)))^(-2379972900))))*(tmp = -1385817972, tmp))))+(-1788631834)))));
+  assertEquals(0, x >>= ((tmp = -18671049, tmp)/((tmp = 651261550.6716013, tmp)>>(-58105114.70740628))));
+  assertEquals(0, x *= ((((x>>(tmp = 2256492150.737681, tmp))<<(x<<(((-2738910707)&x)<<(1892428322))))*(tmp = 1547934638, tmp))>>((((319464033.7888391)|(((((tmp = 2705641070, tmp)<<((tmp = 1566904759.36666, tmp)*((-682175559.7540412)&(-691692016.3021002))))%(tmp = 1118101737, tmp))|(902774462))<<x))^((tmp = -388997180, tmp)<<(x<<((((((-88462733)+(x>>>x))%x)*(tmp = -20297481.556210756, tmp))>>>(1927423855.1719701))-((2047811185.6278129)-(tmp = 2952219346.72126, tmp))))))|(-1685518403.7513878))));
+  assertEquals(0, x /= (tmp = 1858074757.563318, tmp));
+  assertEquals(-1351623058, x ^= (-1351623058.4756806));
+  assertEquals(1, x /= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x -= (x&(997878144.9798675)));
+  assertEquals(-0, x /= (-2769731277));
+  assertEquals(0, x >>>= ((-2598508325)>>(-1355571351)));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x -= (x&(tmp = 1672810223, tmp)));
+  assertEquals(-924449908.1999881, x -= (924449908.1999881));
+  assertEquals(-0, x %= x);
+  assertEquals(-0, x /= (tmp = 2007131382.059545, tmp));
+  assertEquals(-0, x += x);
+  assertEquals(225132064, x += ((((tmp = -2422670578.1260514, tmp)|x)+x)^(1660142894.7066057)));
+  assertEquals(Infinity, x /= (x-x));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= x);
+  assertEquals(-2455424946.732606, x -= (2455424946.732606));
+  assertEquals(1208029258, x &= ((tmp = 1823728509, tmp)+x));
+  assertEquals(1.3682499724725645, x /= ((((tmp = 1267938464.3854322, tmp)%((tmp = 2510853574, tmp)+(((2979355693.866435)-(tmp = 1989726095.7746763, tmp))<<x)))%((-1382092141.1627176)+(((-901799353)+((-2936414080.8254457)>>>(2515004943.0865674)))-(2532799222.353197))))<<(tmp = -2168058960.2694826, tmp)));
+  assertEquals(0.13799826710735907, x %= ((-1090423235)/(tmp = 2659024727, tmp)));
+  assertEquals(0, x >>= (1688542889.082693));
+  assertEquals(0, x <<= x);
+  assertEquals(NaN, x %= ((((tmp = 1461037539, tmp)<<((x<<(tmp = 2101282906.5302017, tmp))>>(-2792197742)))%(((x%x)^(((tmp = 1399565526, tmp)^(tmp = 643902, tmp))-((tmp = -1449543738, tmp)|x)))/x))*(x<<(471967867))));
+  assertEquals(0, x &= ((tmp = -2121748100.6824129, tmp)>>(tmp = -2817271480.6497793, tmp)));
+  assertEquals(0, x &= (3169130964.6291866));
+  assertEquals(-0, x /= (-2303316806));
+  assertEquals(0, x <<= (tmp = 120185946.51617038, tmp));
+  assertEquals(449448375, x ^= ((((tmp = -836410266.014014, tmp)/x)&((x>>>(tmp = -2602671283, tmp))+x))+(tmp = 449448375, tmp)));
+  assertEquals(202003841790140640, x *= x);
+  assertEquals(202003840800829020, x += (((tmp = -1339865843, tmp)+(tmp = 350554234.15375435, tmp))<<((((((tmp = -1798499687.8208885, tmp)>>(((x-(x^x))|((tmp = 463627396.23932934, tmp)/(2714928060)))&(tmp = 3048222568.1103754, tmp)))&(-3127578553))<<(tmp = -2569797028.8299003, tmp))&x)<<((tmp = 2104393646, tmp)/((tmp = 2314471015.742891, tmp)<<((2704090554.1746845)>>(((tmp = 1935999696, tmp)*(((1348554815)>>>x)>>>(146665093.82445252)))%x)))))));
+  assertEquals(202003841764125400, x -= (tmp = -963296372.2846234, tmp));
+  assertEquals(-413485056, x <<= (tmp = -2474480506.6054573, tmp));
+  assertEquals(-3171894580.186845, x += ((tmp = -1261111102, tmp)+(tmp = -1497298422.1868448, tmp)));
+  assertEquals(17136, x >>= (tmp = 3055058160, tmp));
+  assertEquals(17136, x %= (tmp = 1706784063.3577294, tmp));
+  assertEquals(17136, x >>= ((tmp = 2161213808, tmp)*x));
+  assertEquals(-17136, x /= ((((tmp = -1492618154, tmp)>>x)|(1381949066))>>(tmp = 2014457960, tmp)));
+  assertEquals(-34272, x += x);
+  assertEquals(-1498690902, x += (-1498656630));
+  assertEquals(-1168674482, x ^= (486325220));
+  assertEquals(-1168674482, x <<= ((x^x)*x));
+  assertEquals(794521557347068000, x *= (-679848469));
+  assertEquals(1.3330392590424505e+26, x *= (tmp = 167778866, tmp));
+  assertEquals(0, x <<= (tmp = -2501540637.3664584, tmp));
+  assertEquals(0, x >>>= (x-(x*(-890638026.1825848))));
+  assertEquals(0, x %= ((-285010538.2813468)&(1314684460.7634423)));
+  assertEquals(0, x -= x);
+  assertEquals(0, x *= x);
+  assertEquals(NaN, x %= (x*(x<<x)));
+  assertEquals(NaN, x %= (x<<(((tmp = -1763171810.601149, tmp)&(-138151449.18303752))^(x|x))));
+  assertEquals(0, x |= (x>>x));
+  assertEquals(0, x &= (tmp = 1107152048, tmp));
+  assertEquals(0, x >>= (1489117056.8200984));
+  assertEquals(518749976, x ^= (518749976.20107937));
+  assertEquals(356718654, x += (tmp = -162031322, tmp));
+  assertEquals(356718654, x %= (((x>>>((tmp = -373747439.09634733, tmp)*(tmp = 563665566, tmp)))*(tmp = 2853322586.588251, tmp))*((1303537213)%(-2995314284))));
+  assertEquals(5573728, x >>= (tmp = -2095997978, tmp));
+  assertEquals(5573728, x <<= x);
+  assertEquals(5573728, x >>= (((((tmp = 1745399178.334154, tmp)<<(tmp = 2647999783.8219824, tmp))^(tmp = 1571286759, tmp))%x)/(2166250345.181711)));
+  assertEquals(10886, x >>>= ((682837289)+(x*x)));
+  assertEquals(170, x >>>= x);
+  assertEquals(169.95167497151652, x -= (((tmp = 527356024.19706845, tmp)+((tmp = 1263164619.2954736, tmp)|(tmp = 2942471886, tmp)))/((3017909419.131321)+(tmp = 2137746252.8006272, tmp))));
+  assertEquals(-1915170061, x ^= (tmp = -1915170214, tmp));
+  assertEquals(206045792, x &= (((tmp = 887031922, tmp)>>>x)-((-1861922770)|(9633541))));
+  assertEquals(-1940321674, x |= (tmp = -2012149162.1817405, tmp));
+  assertEquals(-1940321674, x &= x);
+  assertEquals(1128412272.160699, x += (tmp = 3068733946.160699, tmp));
+  assertEquals(0.47486363523180236, x /= (tmp = 2376286976.807289, tmp));
+  assertEquals(-1.4931079540252477e-10, x /= (tmp = -3180370407.5892467, tmp));
+  assertEquals(0, x |= (((1220765170.5933602)*(884017786))*((x%(tmp = -2538196897.226384, tmp))<<(x^x))));
+  assertEquals(-525529894, x += (tmp = -525529894, tmp));
+  assertEquals(1621426184, x &= ((3046517714)*(((((-162481040.8033898)+(x/((x&(1489724492))/((x|(tmp = 943542303, tmp))>>>((-1840491388.1365871)<<(2338177232))))))+(((-2268887573.2430763)>>>(((tmp = 2919141667, tmp)+((tmp = 1326295559.692003, tmp)<<(-2256653815)))>>>(((((tmp = 1602731976.7514615, tmp)*(856036244.3730336))^x)>>>((((2846316421.252943)&(915324162))%(tmp = 1144577211.0221815, tmp))%x))*(x*x))))%(tmp = -2641416560, tmp)))*(x+(x>>>x)))>>x)));
+  assertEquals(1621426184, x %= (tmp = 1898223948, tmp));
+  assertEquals(-3.383396676504762, x /= ((tmp = 2211088034.5234556, tmp)^x));
+  assertEquals(7120923705.122882, x *= (((((tmp = 2632382342.914504, tmp)/(-615440284.1762738))&(2162453853.6658797))<<(-849038082.5298986))|(tmp = -2104667110.5603983, tmp)));
+  assertEquals(-1469010887, x &= x);
+  assertEquals(850767635866964700, x *= (tmp = -579143179.5338116, tmp));
+  assertEquals(0, x %= x);
+  assertEquals(-571457, x |= ((2849326490.8464212)|(tmp = 1450592063, tmp)));
+  assertEquals(-571457, x &= x);
+  assertEquals(-0.00018638416434019244, x /= (3066016912.021368));
+  assertEquals(0, x <<= (2058262829));
+  assertEquals(NaN, x %= ((x|((x%x)>>>x))%((tmp = -2970314895.6974382, tmp)+x)));
+  assertEquals(NaN, x *= (-698693934.9483855));
+  assertEquals(NaN, x += (-100150720.64391875));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x -= (-530301478));
+  assertEquals(NaN, x /= (1507673244));
+  assertEquals(0, x <<= (x%(tmp = 2977838420.857235, tmp)));
+  assertEquals(0, x <<= (tmp = 3200877763, tmp));
+  assertEquals(0, x <<= (tmp = -2592127060, tmp));
+  assertEquals(NaN, x -= (((((((1930632619)*(3018666359))<<((tmp = 2676511886, tmp)&(-2786714482.25468)))%x)-(-633193192))<<((tmp = 403293598, tmp)*(-2765170226)))%x));
+  assertEquals(530062092, x |= (tmp = 530062092, tmp));
+  assertEquals(129409, x >>>= x);
+  assertEquals(-152430382316341.78, x *= (-1177896300.229055));
+  assertEquals(-304860764632683.56, x += x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x %= (tmp = -63071565.367660046, tmp));
+  assertEquals(0, x &= ((((tmp = -1007464338, tmp)<<(x<<((x^(tmp = -726826835, tmp))|x)))>>>x)*(((tmp = 469293335.9161849, tmp)<<(((((tmp = 1035077379, tmp)*(tmp = -555174353.7567515, tmp))&(3109222796.8286266))-(((((x-(tmp = 1128900353.6650414, tmp))|(tmp = 3119921303, tmp))&((-1353827690)&(x%((-924615958)&x))))>>>x)+(tmp = 1167787910, tmp)))+x))%((605363594)>>(1784370958.269381)))));
+  assertEquals(0, x %= (2953812835.9781704));
+  assertEquals(0, x -= x);
+  assertEquals(0, x <<= x);
+  assertEquals(-901209266, x += (-901209266));
+  assertEquals(-901209266, x &= x);
+  assertEquals(404, x >>>= (-3195686249));
+  assertEquals(824237108, x ^= (824237472));
+  assertEquals(497790936.1853996, x /= ((tmp = 1253776028, tmp)/(757207285)));
+  assertEquals(497790936, x >>>= ((tmp = -2212598336, tmp)<<(x^(1335355792.9363852))));
+  assertEquals(0, x %= x);
+  assertEquals(-2659887352.6415873, x += (tmp = -2659887352.6415873, tmp));
+  assertEquals(1635079945, x |= ((x&(1234659380))>>((((tmp = 2694276886.979136, tmp)|x)^((tmp = 132795582, tmp)<<((-1089828902)>>>x)))<<((((tmp = -2098728613.0310376, tmp)<<(x/(tmp = -2253865599, tmp)))*((x+(x>>>((48633053.82579231)-(385301592))))*(tmp = -1847454853.333535, tmp)))/((-540428068.8583717)+x)))));
+  assertEquals(1, x /= x);
+  assertEquals(33554432, x <<= ((((2803140769)<<x)|(tmp = -1965793804, tmp))>>>(tmp = -2273336965.575082, tmp)));
+  assertEquals(67108864, x += x);
+  assertEquals(9007199254740992, x *= (x+((x>>x)%(2674760854))));
+  assertEquals(55369784, x %= (x|(-170725544.20038843)));
+  assertEquals(55369784, x %= (-1186186787));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= x);
+  assertEquals(NaN, x /= ((-2968110098)-((x/(x|(((((x|((x&((-130329882)>>>(((-135670650)|(x<<(tmp = 1280371822, tmp)))^x)))-(-1183024707.2230911)))&(-1072829280))>>>(-340696948.41492534))>>>(tmp = 436308526.4938295, tmp))<<(((tmp = 3113787500, tmp)*((2038309320)>>>(-1818917055)))&((2808000707)/(774731251))))))%x)));
+  assertEquals(0, x |= (x*(tmp = -843074864, tmp)));
+  assertEquals(0, x &= (tmp = -752261173.8090212, tmp));
+  assertEquals(0, x >>>= (tmp = 1532349931.7517128, tmp));
+  assertEquals(0, x <<= ((tmp = -8628768, tmp)-((((tmp = 225928543, tmp)%(x>>>(x+x)))^((tmp = -2051536806.5249376, tmp)-x))-((tmp = -2274310376.9964137, tmp)%(tmp = 2251342739, tmp)))));
+  assertEquals(0, x >>= (1011388449));
+  assertEquals(0, x += x);
+  assertEquals(0, x >>>= x);
+  assertEquals(-0, x *= ((-1781234179.8663826)>>(((1514201119.9761915)>>(((((1174857164.90042)^(tmp = 1124973934, tmp))^x)+((-1059246013.8834443)<<(2997611138.4876065)))%(((798188010)*(-1428293122))>>>(tmp = -3087267036.8035297, tmp))))<<x)));
+  assertEquals(1752554372, x ^= (tmp = -2542412924, tmp));
+  assertEquals(1752554372, x %= (tmp = 3037553410.2298307, tmp));
+  assertEquals(1859383977, x -= (x^(2446603103)));
+  assertEquals(1183048193, x &= ((tmp = -962336957, tmp)/(x/x)));
+  assertEquals(67738157, x %= ((((tmp = -1813911745.5223546, tmp)+x)<<(x-(((-1980179168)^x)|x)))|(1913769561.1308007)));
+  assertEquals(67698724, x &= ((1801574998.3142045)*((tmp = -2057492249, tmp)/((1713854494.72282)>>x))));
+  assertEquals(0, x -= x);
+  assertEquals(-25232836, x -= ((tmp = 25232836, tmp)|x));
+  assertEquals(-49, x >>= (x+((tmp = 2201204630.2897243, tmp)|(-1929326509))));
+  assertEquals(-1605632, x <<= x);
+  assertEquals(-165965313, x += (tmp = -164359681, tmp));
+  assertEquals(9.220413724941365e-10, x /= (((((tmp = 2579760013.0808706, tmp)*(tmp = -2535370639.9805303, tmp))>>((tmp = 2138199747.0301933, tmp)-(tmp = -2698019325.0972376, tmp)))*(tmp = -425284716, tmp))/((-1951538149.6611228)/(x^(2632919130)))));
+  assertEquals(0, x &= x);
+  assertEquals(0, x &= ((-645189137)/(tmp = 800952748, tmp)));
+  assertEquals(0, x &= (tmp = -1773606925, tmp));
+  assertEquals(0, x += x);
+  assertEquals(0, x >>>= (tmp = 211399355.0741787, tmp));
+  assertEquals(0, x <<= ((-1317040231.5737965)/((((((tmp = 838897586.0147077, tmp)|((-1902447594)|(tmp = 404942728.83034873, tmp)))^(2462760692.2907705))%((((((x%(tmp = -2888980287, tmp))<<(-368505224.49609876))-((x>>>(532513369))&(((((((tmp = -1298067543, tmp)^(tmp = -3130435881.100909, tmp))>>x)/(tmp = -3041161992, tmp))>>(x|(-431685991.95776653)))^((tmp = 1031777777, tmp)^((-105610810)>>>((-631433779)>>(tmp = -2577780871.167671, tmp)))))%(tmp = -3170517650.088039, tmp))))-(((tmp = 2175146237.968785, tmp)-((384631158.50508535)>>((893912279.4646157)|(tmp = -1478803924.5338967, tmp))))%(x/(-1089156420))))<<(tmp = -2024709456, tmp))>>x))*(tmp = -1423824994.6993582, tmp))%(tmp = 1739143409, tmp))));
+  assertEquals(-1799353648, x |= ((-1799353648.3589036)>>>((((x&(-923571640.1012449))%x)+((tmp = 971885508, tmp)>>((tmp = -2207464428.2123804, tmp)+(-3108177894.0459776))))-(-2048954486.7014258))));
+  assertEquals(-3666808032.2958965, x -= (tmp = 1867454384.2958965, tmp));
+  assertEquals(-260069478915415100, x *= (tmp = 70925305.23136711, tmp));
+  assertEquals(1142096768, x &= (tmp = 1866401706.9144325, tmp));
+  assertEquals(1, x >>>= (tmp = 2701377150.5717473, tmp));
+  assertEquals(1865946805, x |= (tmp = -2429020492, tmp));
+  assertEquals(1424222287, x ^= ((((tmp = 433781338, tmp)>>(x>>>((-2914418422.4829016)/(tmp = 1600920669, tmp))))|(tmp = 588320482.9566053, tmp))>>>((((((x+(tmp = -2556387365.5071325, tmp))+(tmp = -2381889946.1830974, tmp))/(3154278191))>>>(-1069701268.8022757))>>(((tmp = 182049089.28866422, tmp)>>x)>>>(tmp = -447146173, tmp)))/(x-(2103883357.0929923)))));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x -= (x%(3036884806)));
+  assertEquals(0, x >>>= (tmp = -652793480.3870945, tmp));
+  assertEquals(0, x += x);
+  assertEquals(304031003, x ^= ((tmp = -900156495, tmp)^(-666397014.0711515)));
+  assertEquals(1, x /= x);
+  assertEquals(-1974501681, x |= (x^(-1974501681.4628205)));
+  assertEquals(-1.3089278317616264, x /= (((-1723703186.962839)>>>x)|((2061022161.6239533)<<x)));
+  assertEquals(-1, x |= (tmp = -1987006457, tmp));
+  assertEquals(-0.14285714285714285, x /= ((((((x|(-1767793799.7595732))-(-1391656680))<<x)|(x>>(tmp = -2301588485.2811003, tmp)))>>>(((tmp = 1812723993, tmp)>>>((x^(((tmp = -3154100157.951021, tmp)%((tmp = -1254955564.4553523, tmp)-(((x>>>(((-1762886343)*x)*x))*(x^(x*(-750918563.4387553))))*x)))|((x>>x)>>(x<<((((-1766797454.5634143)^(tmp = -2251474340, tmp))-(-787637516.5276759))<<((1390653368)^(-1937605249.245374)))))))|(((tmp = 1156611894, tmp)<<x)<<(x>>((((x+(tmp = 2170166060.881797, tmp))&(x>>>(tmp = -1749295923.1498983, tmp)))>>(((-1014973878)|x)&(1302866805.684057)))*(tmp = 560439074.4002491, tmp))))))|(-2758270803.4510045)))&x));
+  assertEquals(0, x |= x);
+  assertEquals(0, x += ((x>>((x+(tmp = -2776680860.870219, tmp))-(((688502468)<<(((tmp = 475364260.57888806, tmp)<<x)+(329071671)))/(-1097134948))))*(tmp = -1281834214.3416953, tmp)));
+  assertEquals(0, x *= ((((1159762330)<<(tmp = -1892429200, tmp))%x)<<x));
+  assertEquals(0, x >>>= (-770595225));
+  assertEquals(NaN, x += (((x>>x)/(tmp = 281621135, tmp))/x));
+  assertEquals(0, x >>= (1363890241));
+  assertEquals(1639023942.9945002, x += (1639023942.9945002));
+  assertEquals(-2568590958567747000, x *= (-1567146697));
+  assertEquals(1793554700, x ^= (tmp = 3215813388.405799, tmp));
+  assertEquals(437879, x >>= x);
+  assertEquals(1339485943, x |= (1339220210));
+  assertEquals(1, x /= x);
+  assertEquals(512, x <<= (2509226729.1477118));
+  assertEquals(512, x <<= ((x>>(1326274040.7181284))<<(tmp = -760670199, tmp)));
+  assertEquals(1, x /= (x<<(x^x)));
+  assertEquals(0, x >>>= (((((1382512625.8298302)&(x>>>x))*(tmp = -815316595, tmp))>>>x)-(-95538051)));
+  assertEquals(-544344229.3548596, x -= (tmp = 544344229.3548596, tmp));
+  assertEquals(-1088688458.7097192, x += x);
+  assertEquals(-1022850479579041900, x *= (939525418.3104812));
+  assertEquals(2069622661, x |= (-2632744187.7721186));
+  assertEquals(-1353480538017756400, x -= ((tmp = 1308085980, tmp)*((x>>>(-629663391.5165792))&(tmp = 3182319856.674114, tmp))));
+  assertEquals(1.3702811563654176e+27, x *= ((((3061414617.6321163)/(tmp = 2628865442, tmp))+(-1549548261))+(x&((tmp = 809684398, tmp)|(x^(tmp = 801765002, tmp))))));
+  assertEquals(0, x >>>= ((-2988504159)&((tmp = -260444190.02252054, tmp)^(2178729442.260293))));
+  assertEquals(-1518607002, x -= (tmp = 1518607002, tmp));
+  assertEquals(724566016, x <<= (tmp = 1042915731.7055794, tmp));
+  assertEquals(707584, x >>>= (-208959862.93305588));
+  assertEquals(0, x >>>= (((tmp = 877181764, tmp)>>(-970697753.3318911))%x));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x += x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x /= (x^((x/(-2903618412.4936123))+(tmp = 1169288899, tmp))));
+  assertEquals(0, x >>>= x);
+  assertEquals(-1302645245, x ^= ((1855892732.3544865)+(tmp = 1136429319.5633948, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x &= (-1384534597.409375));
+  assertEquals(-0, x /= (tmp = -680466419.8289509, tmp));
+  assertEquals(-0, x *= (318728599.95017374));
+  assertEquals(NaN, x %= (x>>(2019695267)));
+  assertEquals(0, x >>= (tmp = 1280789995, tmp));
+  assertEquals(0, x *= (tmp = 2336951458, tmp));
+  assertEquals(0, x >>= ((2981466013.758637)%(731947033)));
+  assertEquals(0, x -= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x /= ((((3068070149.1452317)>>x)%(((1448965452)*((tmp = -2961594129, tmp)+(1829082104.0681171)))>>(-2331499703)))>>>(tmp = -3206314941.2626476, tmp)));
+  assertEquals(0, x >>= (x%(1869217101.9823673)));
+  assertEquals(0, x <<= (x+x));
+  assertEquals(0, x >>>= ((1202130282)>>>x));
+  assertEquals(0, x += x);
+  assertEquals(2603245248.6273212, x += (tmp = 2603245248.6273212, tmp));
+  assertEquals(-1691864471, x ^= (x>>>(2504513614.117516)));
+  assertEquals(136835305, x -= ((-1618979896)&(-746953306)));
+  assertEquals(-2568499564.1261334, x += (tmp = -2705334869.1261334, tmp));
+  assertEquals(1038075700, x ^= (1530399136));
+  assertEquals(2076151400, x += x);
+  assertEquals(-524018410.1751909, x -= ((2398973627.175191)-(-201196183)));
+  assertEquals(0.327110599608614, x /= ((3181340288.602796)&x));
+  assertEquals(0.327110599608614, x %= (tmp = -2284484060, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(403217947.5779772, x += (tmp = 403217947.5779772, tmp));
+  assertEquals(403217947, x |= x);
+  assertEquals(-Infinity, x *= ((58693583.845808744)+(((tmp = -1527787016, tmp)*x)/((((2532689893.3191843)/(tmp = 2781746479.850424, tmp))|(((((460850355.9211761)/((((tmp = 626683450, tmp)<<((tmp = 1349974710, tmp)-((tmp = -1349602292, tmp)/(-2199808871.1229663))))>>((x/(-3092436372.3078623))&(tmp = -1190631012.0323825, tmp)))^((-2907082828.4552956)-(tmp = 1858683340.1157017, tmp))))^(-1513755598.5398848))%x)/x))&(1147739260.136806)))));
+  assertEquals(0, x &= (tmp = -3047356844.109563, tmp));
+  assertEquals(637934616, x -= (tmp = -637934616, tmp));
+  assertEquals(-1553350083, x ^= (-2056266203.094929));
+  assertEquals(-0.13467351026547192, x %= ((tmp = 824736251, tmp)/(2544186314)));
+  assertEquals(1, x /= x);
+  assertEquals(1, x |= x);
+  assertEquals(0, x >>>= (2166609431.9515543));
+  assertEquals(0, x <<= (x|(tmp = 121899222.14603412, tmp)));
+  assertEquals(0, x *= (1300447849.6595674));
+  assertEquals(0, x %= (tmp = -2360500865.3944597, tmp));
+  assertEquals(0, x %= (tmp = -1693401247, tmp));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x /= (471265307));
+  assertEquals(257349748, x ^= (257349748.689448));
+  assertEquals(257349748, x &= x);
+  assertEquals(981, x >>>= (tmp = -1959001422, tmp));
+  assertEquals(0, x >>= ((-79932778.18114972)/x));
+  assertEquals(0, x <<= (((-2599621472)^(tmp = 662071103, tmp))%(tmp = -2675822640.7641535, tmp)));
+  assertEquals(0, x &= (tmp = 2582354953.878623, tmp));
+  assertEquals(0, x /= ((-953254484)/((-2571632163.376176)-(tmp = -342034471, tmp))));
+  assertEquals(0, x <<= ((x-(tmp = -3013057672, tmp))&(tmp = -3204761036, tmp)));
+  assertEquals(0, x ^= ((x&((515934453)>>>x))/x));
+  assertEquals(1, x |= ((-1914707646.2075093)>>>(tmp = -1918045025, tmp)));
+  assertEquals(-2002844120.8792589, x += (tmp = -2002844121.8792589, tmp));
+  assertEquals(573030794, x >>>= (tmp = 1707788162, tmp));
+  assertEquals(1.917619109627369, x /= ((1909436830.484202)%((123114323)<<(tmp = -1288988388.6444468, tmp))));
+  assertEquals(-1400358045, x |= (-1400358046));
+  assertEquals(-2043022529.4273133, x += (tmp = -642664484.4273133, tmp));
+  assertEquals(-81408068.86728716, x %= (tmp = -980807230.2800131, tmp));
+  assertEquals(0.1436896445024992, x /= (((tmp = 3201789924.913518, tmp)%(tmp = -962242528.6008646, tmp))^((tmp = -338830119.55884504, tmp)*(tmp = -916120166, tmp))));
+  assertEquals(0.1436896445024992, x %= (tmp = 2598469263, tmp));
+  assertEquals(0, x *= (x-x));
+  assertEquals(-1409286144, x += (((-111514798.64745283)|(2372059654))<<(tmp = 175644313, tmp)));
+  assertEquals(-2393905467.0073113, x += (-984619323.0073113));
+  assertEquals(-835111172.0073113, x %= (x^(-765900532.5585573)));
+  assertEquals(-835111172.0073113, x %= (tmp = -946478116, tmp));
+  assertEquals(-100, x >>= ((-1020515908)>>(((x&((x^(169474253.53811646))>>(-221739002)))+x)*((201939882.92880356)/(tmp = -50402570, tmp)))));
+  assertEquals(2131506964, x &= (tmp = -2163460268, tmp));
+  assertEquals(1074275840, x &= ((-1561930379.8719592)*(tmp = -2871750052.876917, tmp)));
+  assertEquals(-954232605.5377102, x -= (tmp = 2028508445.5377102, tmp));
+  assertEquals(-29, x >>= (-279577351.87217045));
+  assertEquals(-232, x <<= x);
+  assertEquals(-70, x |= (215185578));
+  assertEquals(-1, x >>= (x>>(-1691303095)));
+  assertEquals(1, x /= x);
+  assertEquals(3149465364.2236686, x *= (3149465364.2236686));
+  assertEquals(3304787832.3790073, x += (tmp = 155322468.15533853, tmp));
+  assertEquals(100068712.23500109, x %= (tmp = 3204719120.1440063, tmp));
+  assertEquals(91628864, x &= (tmp = 629090241, tmp));
+  assertEquals(-113202292046379710, x *= (-1235443583));
+  assertEquals(122, x >>>= (tmp = 3196555256, tmp));
+  assertEquals(122, x >>>= (((2226535734)-x)^(2248399036.393125)));
+  assertEquals(6.904199169070746e-8, x /= (tmp = 1767040564.9149356, tmp));
+  assertEquals(-212687449.99999994, x += ((((2244322375)*(((2515994102)^x)>>x))<<(x-(-832407685.3251972)))^(2266670502)));
+  assertEquals(366515938514778750, x *= (tmp = -1723260768.3940866, tmp));
+  assertEquals(366515938514778750, x += ((-1643386193.9159095)/(tmp = 425161225.95316494, tmp)));
+  assertEquals(654872716.4123061, x /= ((-1377382984)-(tmp = -1937058061.811642, tmp)));
+  assertEquals(654872716, x &= x);
+  assertEquals(-86260926.17813063, x -= (tmp = 741133642.1781306, tmp));
+  assertEquals(1052176592, x >>>= x);
+  assertEquals(2020882856, x ^= (-3107796616));
+  assertEquals(0, x <<= ((606939871.9812952)|(tmp = -3127138319.1557302, tmp)));
+  assertEquals(NaN, x -= ((x%((1120711400.2242608)%x))*(tmp = -930171286.7999947, tmp)));
+  assertEquals(NaN, x %= (3215044180));
+  assertEquals(NaN, x %= (tmp = 2882893804.20102, tmp));
+  assertEquals(NaN, x %= ((217170359.5778643)^x));
+  assertEquals(0, x &= ((-1095125960.9903677)>>(x^(-2227981276))));
+  assertEquals(-748549860, x += (-748549860));
+  assertEquals(1816208256, x <<= (-610872411.3826082));
+  assertEquals(201400576, x &= (((tmp = 1910394603.4836266, tmp)<<x)^x));
+  assertEquals(0, x %= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x <<= (((((2670901339.6696005)%(2180020861))*((2134469504)/(2237096063.0680027)))*((tmp = 1203829756, tmp)>>((765467065)+(x|(2673651811.9494815)))))<<((-1463378514)|(((x/(tmp = -1075050081, tmp))-((-879974865)+x))>>>(tmp = 2172883926, tmp)))));
+  assertEquals(433013198, x ^= (433013198.2833413));
+  assertEquals(0, x >>= ((((-2404431196)%(x%(tmp = 1443152875.8809233, tmp)))&(x|((1414364997.0517852)/((tmp = -435854369, tmp)+(tmp = 2737625141, tmp)))))|(((tmp = 2241746562.2197237, tmp)^(tmp = -1606928010.1992552, tmp))|((tmp = -3083227418.686173, tmp)>>(tmp = -2717460410, tmp)))));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x *= ((tmp = 2302521322, tmp)>>>(((((((tmp = 344089066.9725498, tmp)%(tmp = 1765830559, tmp))-x)|x)^(((-2450263325)/(tmp = 371928405.17475057, tmp))>>>(1330100413.7731652)))^(((173024329)%(tmp = -2927276187, tmp))+(x>>>(-1042229940.308507))))|(((((tmp = 379074096, tmp)+((142762508)-((-2773070834.526266)-(x&((tmp = 57957493, tmp)<<(2189553500))))))+((36991093)+(tmp = 339487168.58069587, tmp)))*(-1257565451))&(tmp = 645233114, tmp)))));
+  assertEquals(-2644503151.1185284, x += (-2644503151.1185284));
+  assertEquals(-5289006302.237057, x += x);
+  assertEquals(-4008773824.2370567, x -= (tmp = -1280232478, tmp));
+  assertEquals(1975449413, x |= ((tmp = 1957832005.4285066, tmp)>>((1681236712.9715524)&(-675823978))));
+  assertEquals(-146472960, x <<= (-648510672.5644083));
+  assertEquals(-3, x |= (((((x>>>(tmp = 2271744104, tmp))+(tmp = -210058133.30147195, tmp))+(tmp = -2827493425, tmp))/(tmp = 765962538, tmp))%(tmp = 1048631551, tmp)));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>= (1070524782.5154183));
+  assertEquals(0, x <<= (462502504));
+  assertEquals(0, x %= (540589670.0730014));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x /= ((-1268640098)%x));
+  assertEquals(NaN, x %= (1741157613.744652));
+  assertEquals(NaN, x += x);
+  assertEquals(NaN, x %= ((x|(tmp = 1992323492.7000637, tmp))*x));
+  assertEquals(NaN, x /= ((tmp = -2271503368.0341196, tmp)>>((tmp = 1224449194, tmp)>>>(tmp = 2976803997, tmp))));
+  assertEquals(NaN, x += (tmp = -1078313742.1633894, tmp));
+  assertEquals(NaN, x += (-787923311));
+  assertEquals(NaN, x %= x);
+  assertEquals(-1299878219, x ^= (2995089077));
+  assertEquals(536887953, x &= ((625660571.2651105)&(x^(((tmp = 950150725.2319129, tmp)+(-2122154205.466675))/(tmp = 1754964696.974752, tmp)))));
+  assertEquals(4096, x >>>= x);
+  assertEquals(1, x /= x);
+  assertEquals(-82508517, x ^= (((-930231800)%(tmp = -423861640.4356506, tmp))+x));
+  assertEquals(-82508517, x &= (x&x));
+  assertEquals(-479519, x %= ((tmp = 1861364600.595756, tmp)|x));
+  assertEquals(479518, x ^= (((x>>(-1539139751.6860313))>>(tmp = -456165734, tmp))|(-2786433531)));
+  assertEquals(959036, x += x);
+  assertEquals(29, x >>>= ((tmp = -1049329009.7632706, tmp)^(((((((1117739997)/(((-841179741.4939663)*(-1211599672))>>>((-413696355)%(tmp = -1753423217.2170188, tmp))))<<(tmp = 1599076219.09274, tmp))>>>(-1382960317))^(((x^(tmp = 515115394, tmp))>>>(tmp = -388476217, tmp))>>>(x/x)))^x)<<(136327532.213817))));
+  assertEquals(24, x &= (2388755418));
+  assertEquals(0, x >>>= (tmp = -405535917, tmp));
+  assertEquals(0, x &= (tmp = -1427139674, tmp));
+  assertEquals(NaN, x /= (x^((1530470340)%x)));
+  assertEquals(0, x |= ((x>>(-1429690909.8472774))*((((tmp = 2033516515, tmp)/(1314782862))>>>x)>>(tmp = 1737186497.6441216, tmp))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x %= (3115422786));
+  assertEquals(-0, x *= (x+(tmp = -2558930842.267017, tmp)));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x &= (2695531252.254449));
+  assertEquals(-613178182, x ^= (-613178182));
+  assertEquals(54, x >>>= (x%(((tmp = 2277868389, tmp)^((((tmp = -1143932265.3616111, tmp)^((x&((x-((-2100384445.7850044)|(tmp = 908075129.3456883, tmp)))*x))+(((tmp = 1031013284.0275401, tmp)*((((tmp = -233393205, tmp)>>>(tmp = -111859419, tmp))*(-1199307178))|(tmp = -1998399599, tmp)))>>>((((-731759641.9036775)>>>(tmp = 2147849691, tmp))>>>(tmp = -2121899736, tmp))>>>(x>>>x)))))>>((1900348757.360562)^(tmp = 2726336203.6149445, tmp)))>>>((x*((tmp = -2697628471.0234947, tmp)%((x^(tmp = -2751379613.9474974, tmp))*x)))+(x>>(tmp = 42868998.384643435, tmp)))))+(598988941))));
+  assertEquals(34, x &= ((tmp = 2736218794.4991407, tmp)%(2169273288.1339874)));
+  assertEquals(2.086197133417468, x /= ((tmp = 2176358852.297597, tmp)%x));
+  assertEquals(2, x <<= (((tmp = -1767330075, tmp)|(-3107230779.8512735))&x));
+  assertEquals(4194304, x <<= (tmp = 1061841749.105744, tmp));
+  assertEquals(48609515, x ^= (44415211.320786595));
+  assertEquals(48609515, x %= (1308576139));
+  assertEquals(23735, x >>>= ((-324667786)-x));
+  assertEquals(23735, x <<= ((-1270911229)<<(((((tmp = -882992909.2692418, tmp)+(tmp = 394833767.947718, tmp))-x)<<(702856751))/x)));
+  assertEquals(-31080872939240, x *= (tmp = -1309495384, tmp));
+  assertEquals(-14625.31935626114, x /= ((668084131)+(1457057357)));
+  assertEquals(-14625.31935626114, x %= (266351304.6585492));
+  assertEquals(-12577, x |= (-945583977.619837));
+  assertEquals(-4097, x |= ((tmp = -2621808583.2322493, tmp)-(tmp = -2219802863.9072213, tmp)));
+  assertEquals(-1004843865, x &= ((-1004839768)+((tmp = 2094772311, tmp)/(-1340720370.275643))));
+  assertEquals(-31401371, x >>= ((2035921047)>>>((tmp = -1756995278, tmp)>>>(-537713689))));
+  assertEquals(1791746374.016472, x -= ((tmp = -1823147745, tmp)-(x/(tmp = -1906333520, tmp))));
+  assertEquals(3.7289343120517406, x /= (tmp = 480498240, tmp));
+  assertEquals(7.457868624103481, x += x);
+  assertEquals(234881024, x <<= (-781128807.2532628));
+  assertEquals(67108864, x &= (tmp = -2060391332, tmp));
+  assertEquals(-605958718, x -= (673067582));
+  assertEquals(-605958718, x <<= ((x%x)&((tmp = 1350579401.0801518, tmp)|x)));
+  assertEquals(-109268090.4715271, x %= (tmp = -496690627.5284729, tmp));
+  assertEquals(-109268090, x <<= (((-2004197436.8023896)%((x|((tmp = 271117765.61283946, tmp)-((1595775845.0754795)*(555248692.2512416))))/x))<<x));
+  assertEquals(-652725370, x &= (-543590449));
+  assertEquals(0.321858133298825, x /= (tmp = -2027990914.2267523, tmp));
+  assertEquals(1959498446, x ^= (1959498446));
+  assertEquals(1959498446, x &= (x%(tmp = 3155552362.973523, tmp)));
+  assertEquals(14949, x >>>= ((tmp = 586618136, tmp)>>>(tmp = 699144121.9458897, tmp)));
+  assertEquals(-28611391568319.285, x *= (tmp = -1913933478.3811147, tmp));
+  assertEquals(1680557633, x &= (((tmp = 2606436319.199714, tmp)<<(1575299025.6917372))|((-1092689109)/(735420388))));
+  assertEquals(1680361024, x &= ((tmp = 1860756552.2186172, tmp)|(-360434860.1699109)));
+  assertEquals(820488, x >>>= (1788658731));
+  assertEquals(820488, x >>= (-1555444352));
+  assertEquals(2104296413, x ^= (2103543509));
+  assertEquals(16843328, x &= ((x<<((-2920883149)/(1299091676)))-(((((tmp = 3199460211, tmp)+(-237287821.61504316))&(tmp = -1524515028.3596857, tmp))-(tmp = -700644414.6785603, tmp))+(-180715428.86124516))));
+  assertEquals(1326969834, x |= (tmp = -2968063574.793867, tmp));
+  assertEquals(0, x %= (x>>>(tmp = 1350490461.0012388, tmp)));
+  assertEquals(0, x &= ((-2620439260.902854)+x));
+  assertEquals(-1775533561, x |= ((-1775533561)|(((x>>>((861896808.2264911)>>>(970216466.6532537)))%x)%(tmp = 2007357223.8893046, tmp))));
+  assertEquals(-1775533561, x &= x);
+  assertEquals(-23058877.415584415, x /= ((tmp = -3002439857, tmp)>>((((x-(tmp = 1583620685.137125, tmp))|x)%(-2568798248.6863875))^x)));
+  assertEquals(-577.4155844151974, x %= (((-1440361053.047877)+((tmp = 821546785.0910633, tmp)-(((tmp = 1023830881.1444875, tmp)/(-754884477))+(tmp = 651938896.6258571, tmp))))>>(tmp = 346467413.8959185, tmp)));
+  assertEquals(-1, x >>= (tmp = 2993867511, tmp));
+  assertEquals(-1, x |= (tmp = 823150253.4916545, tmp));
+  assertEquals(-0, x %= x);
+  assertEquals(-0, x /= ((tmp = 997969036, tmp)&((((tmp = 928480121, tmp)>>(((-2610875857.086055)>>>(tmp = -2251704283, tmp))|x))+(10781750))>>x)));
+  assertEquals(0, x >>>= ((tmp = -1872319523, tmp)>>>(-278173884)));
+  assertEquals(0, x |= (x/(x*x)));
+  assertEquals(0, x %= ((77912826.10575807)^(tmp = 2770214585.3019757, tmp)));
+  assertEquals(0, x &= (tmp = 722275824, tmp));
+  assertEquals(-1417226266, x |= (tmp = 2877741030.1195555, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x %= (tmp = -1740126105, tmp));
+  assertEquals(910709964, x |= (tmp = 910709964, tmp));
+  assertEquals(-1744830464, x <<= (tmp = -2445932551.1762686, tmp));
+  assertEquals(318767104, x >>>= (tmp = -2465332061.628887, tmp));
+  assertEquals(301989888, x &= (-2771167302.022801));
+  assertEquals(301989888, x |= x);
+  assertEquals(37748736, x >>= (tmp = -835820125, tmp));
+  assertEquals(1474977371, x ^= (tmp = -2857738661.6610327, tmp));
+  assertEquals(470467500, x += (-1004509871));
+  assertEquals(0.30466562575942585, x /= (((tmp = 1515955042, tmp)<<(x+((1607647367)-(tmp = 1427642709.697169, tmp))))^x));
+  assertEquals(1.0348231148499734e-10, x /= (tmp = 2944132397, tmp));
+  assertEquals(0, x >>= (x>>>(tmp = -2847037519.569043, tmp)));
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x >>>= (-1817784819.9058492));
+  assertEquals(0, x >>= x);
+  assertEquals(-0, x *= ((tmp = -1387748473, tmp)|(x+(352432111))));
+  assertEquals(-0, x *= (((-2591789329)/(tmp = -2144460203, tmp))>>(tmp = -568837912.5033123, tmp)));
+  assertEquals(0, x <<= (-2963600437.305708));
+  assertEquals(0, x &= ((588720662)>>>x));
+  assertEquals(1561910729, x += (1561910729));
+  assertEquals(0, x ^= x);
+  assertEquals(-0, x *= (-2722445702));
+  assertEquals(0, x &= (tmp = -2738643199.732308, tmp));
+  assertEquals(0, x /= (((1859901899.227291)>>>((tmp = -1067365693, tmp)+((-1975435278)|x)))|((1844023313.3719304)&(tmp = -624215417.0227654, tmp))));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x %= (-2852766277));
+  assertEquals(0, x <<= (-1482859558));
+  assertEquals(0, x >>= x);
+  assertEquals(-1196775786, x += (tmp = -1196775786, tmp));
+  assertEquals(-68176201, x |= ((tmp = 2336517643, tmp)+x));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>= (2969141362.868086));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x >>= ((x-((((tmp = -905994835, tmp)|(tmp = 2850569869.33876, tmp))<<((-2405056608.27147)>>(tmp = 1280271785, tmp)))&(-1942926558)))*(tmp = 707499803.177796, tmp)));
+  assertEquals(0, x &= ((-697565829.8780258)+((2978584888.549406)%x)));
+  assertEquals(0, x >>= (748642824.4181392));
+  assertEquals(0, x += x);
+  assertEquals(0, x >>>= (-1701028721));
+  assertEquals(92042539, x -= ((-92042539)|(x*(x%(-293705541.00228095)))));
+  assertEquals(0, x %= x);
+  assertEquals(0, x >>= x);
+  assertEquals(0, x %= (-2278672472.458228));
+  assertEquals(0, x %= (((-2374117528.0359464)/((tmp = -2809986062, tmp)|(tmp = 895734980, tmp)))&(tmp = 1564711307.41494, tmp)));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x += x);
+  assertEquals(-0, x /= ((tmp = -2749286790.3666043, tmp)<<(x^(-2966741582.324482))));
+  assertEquals(0, x *= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(-1882562314, x ^= (2412404982.782115));
+  assertEquals(-806620, x %= (((tmp = 1527219936.5232096, tmp)*(-1139841417))>>>(tmp = 201632907.3236668, tmp)));
+  assertEquals(-1613240, x += x);
+  assertEquals(-1664766177387640, x *= (1031939561));
+  assertEquals(-9.478083550117849e+23, x *= (tmp = 569334221.1571662, tmp));
+  assertEquals(-8.462574598319509e+21, x /= ((x-(tmp = -2985531211.114498, tmp))>>(tmp = 174615992.91117632, tmp)));
+  assertEquals(1638924288, x <<= (((((x>>((-1823401733.4788911)+((tmp = 1362371590, tmp)>>>x)))^(tmp = -56634380, tmp))/(tmp = 2387980757.1540084, tmp))%((((tmp = -3175469977, tmp)^(tmp = -1816794042, tmp))+(232726694))*(tmp = 822706176, tmp)))/(tmp = 1466729893.836311, tmp)));
+  assertEquals(2686072821796307000, x *= x);
+  assertEquals(-1007977445.9812208, x /= (-2664814408.800125));
+  assertEquals(-1007977445, x &= x);
+  assertEquals(322314656346249100, x *= (tmp = -319763758.54942775, tmp));
+  assertEquals(197436885.26815608, x /= (tmp = 1632494637, tmp));
+  assertEquals(-67191339, x |= ((-399580815.1746769)/((1335558363)/(tmp = 224694526, tmp))));
+  assertEquals(1229588737, x &= (tmp = 1296763683.5732255, tmp));
+  assertEquals(1229588737, x -= ((((1171546503)|((tmp = -2701891308, tmp)%(-2155432197.022206)))/(-306122816.85682726))>>x));
+  assertEquals(4162606632, x -= (tmp = -2933017895, tmp));
+  assertEquals(1.6487311395551163, x /= (2524733434.1748486));
+  assertEquals(-1929308648.9913044, x += (-1929308650.6400356));
+  assertEquals(-3858617297.982609, x += x);
+  assertEquals(788529152, x <<= (x^(1401824663)));
+  assertEquals(6160384, x >>>= ((((((x>>>x)>>((((x*(tmp = -1958877151, tmp))>>>(1310891043))-(tmp = 564909413.9962088, tmp))%(-175978438)))%x)|((tmp = -1193552419.7837512, tmp)*(tmp = 1508330424.9068346, tmp)))|(1428324616.3303494))-((1828673751)/(tmp = 1281364779, tmp))));
+  assertEquals(6160384, x |= x);
+  assertEquals(1, x /= x);
+  assertEquals(1, x &= (tmp = -855689741, tmp));
+  assertEquals(0, x >>>= x);
+  assertEquals(-1088569655.3528988, x -= (tmp = 1088569655.3528988, tmp));
+  assertEquals(-1088569655, x >>= ((tmp = 2429646226.626727, tmp)<<((-1539293782.4487276)>>(x^((tmp = 1140855945.537702, tmp)+x)))));
+  assertEquals(-311, x %= ((x/x)<<x));
+  assertEquals(1.2007722007722008, x /= (x|(tmp = 448796341.87655175, tmp)));
+  assertEquals(3, x |= (x+x));
+  assertEquals(-9.32416092168023e-10, x /= (-3217447688));
+  assertEquals(0, x >>= (615837464.0921166));
+  assertEquals(0, x >>>= (tmp = -2993750670.683118, tmp));
+  assertEquals(0, x >>>= (x%x));
+  assertEquals(1610612736, x ^= ((-1322905256.6770213)<<(-2567950598)));
+  assertEquals(1693676493, x ^= (83063757.63660407));
+  assertEquals(-758030371, x ^= (tmp = -1239274480, tmp));
+  assertEquals(-758030371, x %= (tmp = 1961339006, tmp));
+  assertEquals(-1509754528, x ^= (tmp = 1960027837, tmp));
+  assertEquals(-1509754528, x <<= x);
+  assertEquals(-1509754528, x -= (((tmp = -50690205.33559728, tmp)/((tmp = -1364565380, tmp)<<(tmp = 2585052504, tmp)))<<(tmp = -2356889596, tmp)));
+  assertEquals(1, x >>>= (-3204164321));
+  assertEquals(1, x *= x);
+  assertEquals(1114370230.591965, x *= ((tmp = 1114370229.591965, tmp)+x));
+  assertEquals(-4.886305275432552, x /= ((-228059887.33344483)%(2841553631.3685856)));
+  assertEquals(2.358309397373389e-9, x /= (((x*(tmp = 203428818.08174622, tmp))&(x-(((510438355)*x)+x)))+x));
+  assertEquals(0, x >>>= ((tmp = 1444810010, tmp)&(tmp = -3135701995.2235208, tmp)));
+  assertEquals(0, x /= (1865982928.6819582));
+  assertEquals(0, x *= x);
+  assertEquals(2078726016.3772051, x -= (tmp = -2078726016.3772051, tmp));
+  assertEquals(1580337898, x ^= ((tmp = -2714629398.447015, tmp)^x));
+  assertEquals(1268363034, x -= ((x+((tmp = 1144068248.3834887, tmp)&(-954104940.155973)))<<(tmp = 1270573731.7828264, tmp)));
+  assertEquals(1744830464, x <<= (((1444869551.7830744)>>>((((x+(tmp = -904688528, tmp))<<x)-((tmp = 121151912.85873199, tmp)/(tmp = -2414150217.66479, tmp)))|(((-472906698)|(3215236833.8417764))+(907737193.9056952))))-((x&(-732223723))|(-221800427.7392578))));
+  assertEquals(717338523283226600, x *= (x^(tmp = -2407450097.0604715, tmp)));
+  assertEquals(402653184, x >>= ((-3191405201.168252)*((tmp = -1941299639.695196, tmp)|(((x>>(((3215741220)>>>x)/(x+x)))^(((tmp = -2144862025.9842231, tmp)|((tmp = -1966913385, tmp)&x))%x))*((tmp = -1124749626.6112225, tmp)/(tmp = 837842574, tmp))))));
+  assertEquals(402653184, x &= ((x|x)>>x));
+  assertEquals(134217728, x &= ((2720231644.3849487)*x));
+  assertEquals(134217726.75839183, x -= ((2438054684.738043)/(((((-984359711)*(x|((tmp = 177559682, tmp)^x)))/(-1253443505))/((2727868438.416792)*(x+((x<<(((tmp = 3023774345, tmp)&(-705699616.0846889))/x))<<x))))^(1963626488.548761))));
+  assertEquals(1, x /= x);
+  assertEquals(245781494, x += ((tmp = 2551445099, tmp)^(2528486814)));
+  assertEquals(-1474427807, x ^= (-1497868393.342241));
+  assertEquals(-1057271682, x += ((((((x>>x)%(-1556081693))|(x/(((1166243186.6325684)-(((tmp = 2870118257.1019487, tmp)/(x+(-69909960)))^(2270610694.671496)))/((1463187204.5849519)-x))))-x)-(x<<(-3077313003)))%x));
+  assertEquals(-1065725846, x &= ((tmp = -1808223767, tmp)|(-481628214.3871765)));
+  assertEquals(-1065725846, x ^= (x&(((tmp = -1785170598, tmp)-(tmp = -2525350446.346484, tmp))/((((((-1783948056)^(tmp = 3027265884.41588, tmp))|((((tmp = 2195362566.2237773, tmp)<<(-2919444619))<<((tmp = -2507253075.2897573, tmp)^(x^((tmp = 1067516137, tmp)+((667737752)^(x*(tmp = -1187604212.7293758, tmp)))))))%(-617406719.5140038)))*(tmp = 511060465.6632478, tmp))*((tmp = 2580189800.752836, tmp)|((((tmp = 2357895660, tmp)%((-814381220)*(x-((x>>>(((x<<x)<<(tmp = 1919573020, tmp))-x))>>>((-2756011312.136148)>>(tmp = -1603458856, tmp))))))/((tmp = -1609199312, tmp)&(-3127643445)))%x)))<<(-2261731798)))));
+  assertEquals(1.6020307924030301, x /= (tmp = -665234308.2628405, tmp));
+  assertEquals(-1120020556.697667, x *= (tmp = -699125486.2321637, tmp));
+  assertEquals(-215875188, x -= (((((tmp = -1307845034, tmp)>>>((((-2820720421)^x)-(((x<<x)|(tmp = -3042092997.57406, tmp))+(((-1294857544)+((tmp = -668029108.1487186, tmp)>>(x<<x)))^(912144065.5274727))))^(389671596.2983854)))|(-2774264897.146559))%(x-((tmp = 1378085269, tmp)^x)))+((-1659377450.5247462)&(((1613063452.834885)>>>((-344896580.0694165)>>>((-13450558)+x)))^x))));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>>= (2355750790));
+  assertEquals(1969435421.4409347, x += (1969435421.4409347));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>>= (((x*((-1022802960.6953495)<<(tmp = -2848428731.8339424, tmp)))^(-1630921485))%(1532937011)));
+  assertEquals(0, x <<= ((x+((x^(x^(tmp = 2017651860, tmp)))&(((x<<(((tmp = -1913317290.8189478, tmp)|(x-((((x%((tmp = -3035245210, tmp)+(-2270863807)))>>>((-2351852712)*(x^(-2422943296.0239563))))&((((-1578312517)%x)*x)*(-65592270.28452802)))>>>(tmp = 1104329727.2094703, tmp))))-(tmp = -1431159990.3340137, tmp)))&x)|((tmp = -2589292678.801344, tmp)&(x+((((tmp = -2557773457.456996, tmp)>>(451910805.309445))-x)>>(((tmp = -1937832765.7654495, tmp)^x)%x)))))))%x));
+  assertEquals(0, x %= (tmp = -626944459, tmp));
+  assertEquals(-732310021, x |= (tmp = -732310021, tmp));
+  assertEquals(-732310021, x |= x);
+  assertEquals(671352839, x ^= (x-((-3087309090.7153115)|x)));
+  assertEquals(134479872, x &= (tmp = 2357183984, tmp));
+  assertEquals(18084835973136384, x *= x);
+  assertEquals(0, x <<= ((1040482277)-(tmp = -357113781.82650447, tmp)));
+  assertEquals(74957, x |= ((((tmp = -70789345.7489841, tmp)%(tmp = 1415750131, tmp))&x)|((307027314)>>(2284275468))));
+  assertEquals(9, x >>>= x);
+  assertEquals(0, x &= (x&((x*((x*(x%x))%(x>>x)))/x)));
+  assertEquals(-1872875060, x |= (2422092236.6850452));
+  assertEquals(9, x >>>= (-382763684));
+  assertEquals(4608, x <<= x);
+  assertEquals(40.480234260614935, x /= (((((((tmp = 814638767.5666755, tmp)&((tmp = 2081507162, tmp)^(x>>>(1460148331.2229118))))&(tmp = 1187669197.7318723, tmp))<<(412000677.93339765))^((tmp = 556111951, tmp)>>(tmp = -2232569601.292395, tmp)))&(-3006386864))/x));
+  assertEquals(32, x &= (-3053435209.383913));
+  assertEquals(418357217, x ^= (418357185));
+  assertEquals(204275, x >>= ((-1188650337.9010527)^((51494580)%(-2544545273))));
+  assertEquals(982392804, x += (((x+(((tmp = -982596937.9757051, tmp)+x)%(-2298479347)))^((((tmp = 1610297674.0732534, tmp)>>>x)*(((x>>(-2746780903.08599))&(-2376190704.247188))^(((20545353)/(tmp = 1468302977, tmp))-(x<<x))))>>(((-1434332028.0447056)/((tmp = 1983686888, tmp)&((tmp = 2324500847, tmp)%(394330230.6163173))))%(((-1129687479.2158055)+((-3127595161)*((-3066570223)&((tmp = 3192134577.4963055, tmp)/(-2697915283.3233275)))))+(-1112243977.5306559)))))|(x&(-2622725228))));
+  assertEquals(-2735750653096133600, x *= (-2784782870.9218984));
+  assertEquals(-1876329472, x |= ((((((2752866171)<<(-1681590319))/x)>>((tmp = 1451415208, tmp)>>>(1126858636.6634417)))+(((tmp = 2165569430.4844217, tmp)/x)^(((tmp = -1675421843.4364457, tmp)-(-2187743422.2866993))|x)))*x));
+  assertEquals(3520612287495799000, x *= x);
+  assertEquals(-200278016, x |= ((((-2379590931)%((((-1558827450.833285)&x)>>(-665140792))-((tmp = -445783631.05567217, tmp)+(tmp = 93938389.53113222, tmp))))/(3103476273.734701))^x));
+  assertEquals(-9178285062592.75, x *= ((2042671875.7211144)%(((tmp = 589269308.0452716, tmp)/x)<<(-130695915.9934752))));
+  assertEquals(60048960, x |= (x<<x));
+  assertEquals(60048960, x <<= ((((((tmp = -2793966650, tmp)/(-2882180652))&(((x<<((tmp = -384468710, tmp)+(2236162820.9930468)))>>>((((969371919)>>((tmp = -3153268403.2565875, tmp)-((((573811084)/x)^(tmp = -968372697.4844134, tmp))>>>(((-3096129189)>>x)/(tmp = 830228804.6249363, tmp)))))<<(((1243972633.3592157)|x)&((-1687610429)&(tmp = -1945063977.458529, tmp))))<<(((tmp = -217456781.37068868, tmp)-(400259171.68077815))^x)))>>>x))%(((2728450651.300167)/(((-2713666705.089135)%(tmp = 740472459, tmp))^x))|x))^x)*(-2463032364)));
+  assertEquals(60048960, x %= (tmp = -442107222.9513445, tmp));
+  assertEquals(-1573781504, x <<= (960581227));
+  assertEquals(1297, x >>>= (tmp = -1692919563, tmp));
+  assertEquals(1297, x &= x);
+  assertEquals(-3113308397155.233, x *= (tmp = -2400391979.3024154, tmp));
+  assertEquals(-3115513013486.233, x -= (2204616331));
+  assertEquals(-3113809649082.233, x -= (-1703364404));
+  assertEquals(0, x >>>= (((-1181206665)-(550946816.586771))|(tmp = -2346300456, tmp)));
+  assertEquals(0, x %= (tmp = 1649529739.2785435, tmp));
+  assertEquals(0, x ^= ((tmp = -2452761827.2870226, tmp)%(((1090281070.5550141)/(tmp = 992149154.6500508, tmp))*(x<<((((((x>>>x)|((tmp = -2410892363, tmp)%(tmp = 2585150431.0231533, tmp)))/x)*(tmp = 1541294271, tmp))+x)&((97566561.77126992)&((((-640933510.1287451)&(((((x>>>((-1821077041)<<((tmp = -1138504062.093695, tmp)-(tmp = -181292160, tmp))))%x)-(x>>((x&(((tmp = 1067551355, tmp)/(x|(1004837864.8550552)))&(x-(-103229639.25084043))))&((tmp = 2064184671.210937, tmp)+((((tmp = -2245728052, tmp)|(1538407002.8365717))+(x<<((x>>((76549490)/(tmp = 628901902.6084052, tmp)))<<((x<<x)^(-1907669184)))))+(-1409123688))))))>>>((((-1911547456.933543)-((-512313175)+((tmp = -2620903017, tmp)^(tmp = 2148757592.244808, tmp))))<<((-1740876865)>>>x))+((tmp = 691314720.9488736, tmp)<<(614057604.4104803))))|(x^((tmp = -3040687.291528702, tmp)/(x^(((x+(-2899641915))^((tmp = -1220211746, tmp)/x))%x))))))^(tmp = 119850608, tmp))%(2091975696))))))));
+  assertEquals(291273239, x -= (tmp = -291273239, tmp));
+  assertEquals(2206394018, x += (1915120779));
+  assertEquals(235641480, x <<= (x&(x&(-1810963865.1415658))));
+  assertEquals(28764, x >>= ((tmp = -1927011875, tmp)^((tmp = -1986461808, tmp)|((-868139264.8399222)*((421956566)%(3068424525))))));
+  assertEquals(-99780626900900, x *= ((tmp = -1512869526.3223472, tmp)+(tmp = -1956071751, tmp)));
+  assertEquals(51218520, x &= (((-2353401311)>>>x)-(2216842509)));
+  assertEquals(51218520, x >>>= ((tmp = -1534539302.6990812, tmp)<<x));
+  assertEquals(-2147483648, x <<= (-292608644));
+  assertEquals(-2147483648, x |= ((((((x<<((-2981292735)-x))>>((tmp = 2540545320.96558, tmp)&(tmp = -2343790880, tmp)))>>>((((((x^((-172697043.94487858)/((2627260337)>>(2879112814.1247935))))&(tmp = 3000943191, tmp))<<(tmp = 1094830905, tmp))-x)>>>x)>>((((tmp = 3095796200, tmp)^(x|(tmp = 1460377694, tmp)))<<(x^(tmp = -357546193, tmp)))/((2729539495)>>x))))%(tmp = 268894171.74961245, tmp))|(x>>(tmp = 2735650924, tmp)))/(-2197885357.09768)));
+  assertEquals(-2147483648, x |= x);
+  assertEquals(-1967162776824578000, x *= (tmp = 916031551, tmp));
+  assertEquals(-2147483648, x &= x);
+  assertEquals(-457743917756973060, x *= (tmp = 213153622, tmp));
+  assertEquals(0, x >>>= ((((tmp = 2930076928.480559, tmp)+(x^x))<<(tmp = -1349755597.1280541, tmp))|(x+(2865632849))));
+  assertEquals(0, x <<= ((x>>x)-(x>>(-2629977861))));
+  assertEquals(0, x <<= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x |= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(749327478, x |= ((tmp = 749327478, tmp)^(x>>(tmp = 881107862, tmp))));
+  assertEquals(1897869364, x += (1148541886));
+  assertEquals(463347, x >>>= (tmp = -726431220, tmp));
+  assertEquals(-395990542, x += (-396453889));
+  assertEquals(-2824792585.1675367, x -= (2428802043.1675367));
+  assertEquals(-2147483648, x <<= (tmp = -1420072385.9175675, tmp));
+  assertEquals(8388608, x >>>= (-2211390680.488455));
+  assertEquals(8388608, x >>= (((x/(x|(((x^(((tmp = -2175960170.8055067, tmp)|((tmp = -1964957385.9669886, tmp)/(tmp = -475033330, tmp)))&((x|((tmp = 1386597019.2014387, tmp)>>((tmp = -2406589229.8801174, tmp)+x)))<<(tmp = -844032843.8415492, tmp))))>>(x^x))|x)))-((x&((tmp = 1858138856, tmp)*(-3156357504)))%x))<<(((2046448340)+x)/(-2645926916))));
+  assertEquals(8359470765396279, x *= ((tmp = 871437183.7888144, tmp)-(-125089387.17460155)));
+  assertEquals(0, x ^= x);
+  assertEquals(-303039014, x += ((tmp = -2475713214, tmp)|(-372871718.2343409)));
+  assertEquals(2655126577, x -= (-2958165591));
+  assertEquals(1830332793, x ^= (tmp = -212161208, tmp));
+  assertEquals(1830332793, x ^= (((2352454407.0126333)<<((((tmp = 3083552367, tmp)/x)-(-1243111279))-((tmp = -1669093976, tmp)%(((-757485455)-(tmp = -116051602, tmp))<<x))))>>(((((-2235071915.9536905)>>(tmp = -1284656185, tmp))-x)>>((-1807028069.7202528)>>>((x%((tmp = -3070857953.311804, tmp)+((tmp = 2759633693.441942, tmp)%((169489938)*(-1582267384)))))<<(x^((tmp = -787578860, tmp)<<x)))))>>((x/(x|(409464362)))-(tmp = -64033017, tmp)))));
+  assertEquals(397605933.90319204, x %= (tmp = 716363429.548404, tmp));
+  assertEquals(186400, x &= (((x%(-1745754586))>>>x)<<(x&(x&((-2163627752)-((1784050895)+(((-2864781121.899456)>>>x)&x)))))));
+  assertEquals(186400, x %= (tmp = -423209729, tmp));
+  assertEquals(186400, x <<= ((x<<(x+(1232575114.4447284)))*x));
+  assertEquals(1386299, x ^= ((tmp = -1074209615, tmp)>>>(x>>>((tmp = -1456741008.2654872, tmp)>>((1724761067)>>(-2016103779.9084842))))));
+  assertEquals(347302967.20758367, x -= (-345916668.20758367));
+  assertEquals(1.9325619389304094, x /= (179711170.03359854));
+  assertEquals(-3703324711.628227, x *= (tmp = -1916277371, tmp));
+  assertEquals(-920980517031624800, x *= (tmp = 248690187.53332615, tmp));
+  assertEquals(0, x &= (((tmp = -2753945953.082594, tmp)*x)-(172907186)));
+  assertEquals(-0, x /= (((((-2744323543.187253)>>((tmp = 2663112845, tmp)>>(((-121791600)+(x^x))*(2758944252.4214177))))|x)/(tmp = -2746716631.6805267, tmp))-x));
+  assertEquals(0, x ^= ((tmp = 983113117, tmp)&((2638307333)+((((tmp = 3076361304.56189, tmp)<<(-2663410588.5895214))%((-1109962112)-(tmp = -2381021732, tmp)))%((tmp = 410559095, tmp)&x)))));
+  assertEquals(0, x <<= (tmp = 1510895336.5111506, tmp));
+  assertEquals(0, x <<= (tmp = -1688348296.2730422, tmp));
+  assertEquals(2269471424, x -= (-2269471424));
+  assertEquals(-2022580224, x ^= (x%((tmp = 160999480.21415842, tmp)&x)));
+  assertEquals(-2077171712, x &= (tmp = 3032415014.3817654, tmp));
+  assertEquals(270727, x >>>= (2973489165.1553965));
+  assertEquals(270727, x |= x);
+  assertEquals(-1895894537, x |= ((tmp = -1895903118.129186, tmp)|x));
+  assertEquals(-1895894537, x -= ((((((((3143124509)>>>(-2866190144.8724117))*((x>>((961021882)*(tmp = 2363055833.8634424, tmp)))/((2032785518)+((2713643671.3420825)>>((-447782997.0173557)*((tmp = 1174918125.3178625, tmp)*((((tmp = -541539365.548115, tmp)%(-359633101))|(1765169562.2880063))+(tmp = -2512371966.374508, tmp))))))))/x)>>(x*((((-847238927.6399388)&(857288850))%(-2427015402))^((2221426567)%(x+x)))))>>>x)<<((tmp = 2009453564.2808268, tmp)>>((2924411494)<<(x>>(tmp = -1240031020.8711805, tmp)))))%(tmp = 3118159353, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x %= (-30151583));
+  assertEquals(-1035186736, x ^= ((tmp = -517593368, tmp)<<(tmp = 3216155585, tmp)));
+  assertEquals(49740, x >>>= x);
+  assertEquals(49740, x %= (640223506));
+  assertEquals(388, x >>>= ((x>>(tmp = 3161620923.50496, tmp))+(2605183207)));
+  assertEquals(776, x += x);
+  assertEquals(-97905, x ^= ((((((tmp = 145447047.8783008, tmp)^(((x>>>(tmp = 3014858214.2409887, tmp))>>>(629911626.132971))>>(((x+((369309637.229408)-x))<<(-2661038814.9204755))*(x+(x%(3025191323.4780884))))))+x)*(-482550691))|(-632782135))/x));
+  assertEquals(-97905, x %= ((((-492914681)-((-2508632959.269368)&(tmp = 1209318291, tmp)))>>(-723512989.459533))>>>(((-528429623.985692)&(x^(tmp = -925044503, tmp)))-(-1696531234))));
+  assertEquals(9585389025, x *= x);
+  assertEquals(-715425728, x <<= ((583763091)<<(-1223615295)));
+  assertEquals(-520093696, x <<= ((tmp = -1891357699.671592, tmp)*(((tmp = 3206095739.5163193, tmp)+(-2908596651.798733))>>>((tmp = -2820415686, tmp)>>(x|((((tmp = -566367675.6250327, tmp)*(-959117054))>>((((-187457085.89686918)*x)*(tmp = -2394776877.5373516, tmp))>>>x))|(((tmp = 80478970.46290505, tmp)<<(tmp = 2173570349.493097, tmp))-(x/((-2896765964)-((x/((tmp = 198741535.7034216, tmp)%(436741457)))%(tmp = 2936044280.0587225, tmp)))))))))));
+  assertEquals(-2520.5909527086624, x /= ((211290893.06029093)>>(663265322)));
+  assertEquals(-2520.5909527086624, x %= (x^((1057915688)<<(tmp = 1914820571.1142511, tmp))));
+  assertEquals(1, x >>>= (((894963408.7746166)+(tmp = -2888351666, tmp))|x));
+  assertEquals(-1989841636629996300, x += ((1424670316.224575)*((-2144149843.0876865)|((((421479301.0983993)|((3082651798)^(tmp = -271906497, tmp)))>>x)+((tmp = -178372083, tmp)%x)))));
+  assertEquals(17935384255.088326, x /= (((((((tmp = 1168194849.2361898, tmp)>>>(-107316520.53815603))>>>(x^(((x%((x>>>(((-2456622387)/x)&((2124689803)|(((-1130151701)^(2796315158))>>x))))-((-884686033.5491502)>>>((-2371185318.5358763)&x))))+(tmp = 558422989, tmp))|((tmp = -420359120.0596726, tmp)/((-1820568437.0587764)&(2298602280.266465))))))>>(x-((tmp = -1164568978, tmp)^x)))^x)-x)+x));
+  assertEquals(134233150, x &= ((x>>(((tmp = 98498118.13041973, tmp)-(804574397))/(tmp = -1564490985.7904541, tmp)))+x));
+  assertEquals(4, x >>= (449610809));
+  assertEquals(1912543790, x |= (1912543790));
+  assertEquals(2487274263, x += (tmp = 574730473, tmp));
+  assertEquals(-2140759118, x ^= (tmp = 338055333.9701035, tmp));
+  assertEquals(311607367, x += (2452366485));
+  assertEquals(9509, x >>= (372113647.84365284));
+  assertEquals(-2001075684.1562128, x += (-2001085193.1562128));
+  assertEquals(-638703280, x ^= (((tmp = 1096152237, tmp)&x)|((2707404245.0966487)-(((tmp = 1550233654.9691348, tmp)+(tmp = 2008619647, tmp))&((tmp = -2653266325, tmp)+(tmp = -280936332, tmp))))));
+  assertEquals(-101811850, x |= (-2250090202));
+  assertEquals(-13, x >>= ((-561312810.0218933)|(tmp = 79838949.86521482, tmp)));
+  assertEquals(-13, x >>= ((tmp = -936543584, tmp)/(1180727664.1746705)));
+  assertEquals(-1547, x *= (((tmp = 1005197689, tmp)>>>x)>>>(tmp = 34607588, tmp)));
+  assertEquals(2393209, x *= x);
+  assertEquals(2393209, x |= x);
+  assertEquals(0, x >>= (-2691279235.1215696));
+  assertEquals(0, x *= (((896175510.4920144)*((((tmp = 1770236555.7788959, tmp)%(537168585.7310632))/x)&(tmp = 1094337576, tmp)))&(((x-x)-x)>>x)));
+  assertEquals(-1922620126, x ^= (-1922620126));
+  assertEquals(3.43481396325761, x /= (tmp = -559745053.6088333, tmp));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>>= (tmp = 2106956255.6602135, tmp));
+  assertEquals(-1339003770, x ^= ((tmp = 2955963526.960022, tmp)+x));
+  assertEquals(-0, x *= ((((tmp = 368669994, tmp)>>>(x*x))<<(tmp = 2355889375, tmp))&(tmp = -2267550563.9174895, tmp)));
+  assertEquals(0, x >>= (753848520.8946902));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x %= ((tmp = -2872753234.2257266, tmp)|x));
+  assertEquals(NaN, x %= (x>>>(tmp = 890474186.0898918, tmp)));
+  assertEquals(NaN, x %= ((tmp = 1341133992.284471, tmp)&(tmp = -2979219283.794898, tmp)));
+  assertEquals(NaN, x += (-2865467651.1743298));
+  assertEquals(NaN, x += ((-1424445677)%(x^(tmp = 1150366884, tmp))));
+  assertEquals(0, x &= (x+((tmp = 1499426534, tmp)+x)));
+  assertEquals(0, x |= (((((tmp = -2413914642, tmp)<<((x>>>x)^(1218748804)))+((((-1085643932.2642736)-(-1199134221.533854))>>(tmp = 2148778719, tmp))-((tmp = 1589158782.0040946, tmp)/(tmp = -2485474016.1575155, tmp))))>>>(x>>x))/(2230919719)));
+  assertEquals(0, x %= ((tmp = -2576387170.517563, tmp)>>>((tmp = -2362334915.919525, tmp)>>>(((3096453582)-(700067891.4834484))^(2396394772.9253683)))));
+  assertEquals(-1798103432, x ^= (((((tmp = 2396144191, tmp)*(x>>>(1512158325)))&(((-1256228298.5444434)&(((-2963136043.434966)&((tmp = 2472984854, tmp)+(tmp = -454900927, tmp)))%(tmp = 484255852.65332687, tmp)))>>((x%x)-x)))&(tmp = 929723984, tmp))^(tmp = -1798103432.5838807, tmp)));
+  assertEquals(-2137913344, x &= ((((x|(-2970116473))&(((x/x)/((tmp = 2853070005, tmp)>>>x))%(((tmp = -3123344846, tmp)/((2224296621.6742916)-(tmp = -2246403296.455411, tmp)))+((x&(((x^(x*(2829687641)))+x)&(tmp = 988992521, tmp)))^x))))<<((((-820608336)^(tmp = 2851897085, tmp))>>(tmp = -402427624, tmp))>>>x))-(((x*(((-2287402266.4821453)%(tmp = -520664172.1831205, tmp))^(x/(1875488837))))<<(tmp = 402393637, tmp))&(tmp = 1576638746.3047547, tmp))));
+  assertEquals(-2827557853031924000, x *= (tmp = 1322578326.6507945, tmp));
+  assertEquals(6.424459501778244e+27, x *= (tmp = -2272087729.3065624, tmp));
+  assertEquals(-1586887483, x |= (-1586887483));
+  assertEquals(-567868980691736100, x *= (tmp = 357850816, tmp));
+  assertEquals(1489101591, x ^= (x%(x|(421921075))));
+  assertEquals(-801213804822328000, x *= (x|(-672326904.6888077)));
+  assertEquals(612257233.6612054, x /= (((tmp = -350127617, tmp)>>>(-1140467595.9752212))<<((x^x)+(-3117914887))));
+  assertEquals(19097.231243331422, x /= ((x^(tmp = -570012517, tmp))>>>x));
+  assertEquals(0, x >>= ((x%(((-2347648358)%((x-(tmp = -456496327, tmp))|(x^(-1977407615.4582832))))<<(x/(tmp = -2021394626.214082, tmp))))%(tmp = -949323000.2442119, tmp)));
+  assertEquals(0, x <<= x);
+  assertEquals(NaN, x %= (x^(x>>(((tmp = 597147546.7701412, tmp)&(((((-972400689.6267757)|(tmp = -2390675341.6367044, tmp))|(tmp = 1890069123.9831812, tmp))<<(((1606974563)-(tmp = -2211617255.8450356, tmp))&((((x+((2433096953)&(-2527357746.681596)))*(tmp = -313956807.55609417, tmp))|((tmp = -2146031047.968496, tmp)/(tmp = 2851650714.68952, tmp)))>>(((tmp = 2630692376.6265225, tmp)-(tmp = -3162222598, tmp))>>((tmp = 1915552466, tmp)*(x>>>(-2413248225.7536864)))))))&(x%((((1218471556)|x)+(tmp = -849693122.6355379, tmp))+x))))>>>(x/((tmp = 689889363, tmp)/x))))));
+  assertEquals(0, x >>>= (45649573.23297));
+  assertEquals(0, x >>>= (tmp = 1084439432.771266, tmp));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x *= (tmp = 1642750077, tmp));
+  assertEquals(0, x >>>= (tmp = -1944001182.0778434, tmp));
+  assertEquals(1682573000, x |= (tmp = -2612394296.2858696, tmp));
+  assertEquals(3041823595, x -= (((tmp = 720576773, tmp)|(x^(-1068335724.2253149)))>>(x*(-2501017061))));
+  assertEquals(6083647190, x += x);
+  assertEquals(-6536258988089986000, x *= ((tmp = 632312939.6147232, tmp)|((-1621821634)+(((tmp = -2281369913.562131, tmp)&((tmp = -381226774, tmp)|x))&(664399051)))));
+  assertEquals(4.272268155938712e+37, x *= x);
+  assertEquals(733271152, x %= (-1345127171));
+  assertEquals(847089925, x ^= (tmp = 432620917.57699084, tmp));
+  assertEquals(1337073824, x <<= x);
+  assertEquals(-25810602, x ^= (tmp = 2982414838, tmp));
+  assertEquals(-25282209, x |= ((tmp = -2927596922, tmp)>>>(-2404046645.01413)));
+  assertEquals(639190091919681, x *= x);
+  assertEquals(173568320, x &= ((((tmp = -718515534.4119437, tmp)&(tmp = 2989263401, tmp))<<x)|((tmp = 537073030.5331153, tmp)-(tmp = 883595389.314624, tmp))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>>= (tmp = -1844717424.917882, tmp));
+  assertEquals(0, x >>= (tmp = -462881544.2225325, tmp));
+  assertEquals(0, x >>= x);
+  assertEquals(-1868450038, x ^= (2426517258.6111603));
+  assertEquals(1, x /= x);
+  assertEquals(1175936039.4202638, x += (tmp = 1175936038.4202638, tmp));
+  assertEquals(-127916015, x ^= ((x/(1841969600.3012052))-(tmp = 1099467723, tmp)));
+  assertEquals(395713785658171900, x *= (-3093543726));
+  assertEquals(395713787128560900, x += (((((-717204758)*(tmp = -588182129.6898501, tmp))-x)+(tmp = 20638023, tmp))^x));
+  assertEquals(-962609355, x |= ((x^(-3118556619.912983))<<((tmp = 876126864, tmp)&x)));
+  assertEquals(-962609355, x %= (tmp = -2079049990, tmp));
+  assertEquals(-114583755, x -= (((-2806715240)&(((1961136061.0329285)>>>((2087162059)*x))+((tmp = -1890084022.7631018, tmp)%(tmp = 2137514142.358262, tmp))))+(x<<(tmp = 2991240918, tmp))));
+  assertEquals(-425721856, x <<= x);
+  assertEquals(3778560, x >>>= ((x|(3198503572))>>(1158434541.1099558)));
+  assertEquals(3778560, x %= (tmp = -2592585378.9592104, tmp));
+  assertEquals(624640, x &= (tmp = 2261638192.9864054, tmp));
+  assertEquals(1249280, x += x);
+  assertEquals(1048576, x &= ((tmp = -2144301819.9892588, tmp)^((x-x)<<x)));
+  assertEquals(2097152, x <<= (x/x));
+  assertEquals(5069061551149729, x *= (tmp = 2417116904.8069615, tmp));
+  assertEquals(1.4836296666029616e+25, x += ((tmp = 2926833006.7121572, tmp)*x));
+  assertEquals(-256, x >>= ((-469330345.3589895)%((x^(((2554170843.4978285)/(2495676674.815263))>>>x))*(-918892963))));
+  assertEquals(-134217728, x <<= (x|(((((1687450853.1321645)+(tmp = 2369533014.5803776, tmp))+(tmp = -2613779445, tmp))+(tmp = -2488826226.3733397, tmp))>>(tmp = -220646936.41245174, tmp))));
+  assertEquals(704164545131708400, x *= ((-2632786741)+(-2613647956)));
+  assertEquals(9216, x >>>= (-1925405359.657349));
+  assertEquals(4491403261551.008, x *= (tmp = 487348444.1787118, tmp));
+  assertEquals(4490606381829.008, x -= (tmp = 796879722, tmp));
+  assertEquals(-60294056, x >>= x);
+  assertEquals(-3193966580.494005, x += (tmp = -3133672524.494005, tmp));
+  assertEquals(550500358, x >>>= ((tmp = -2779637628.390116, tmp)-((tmp = 29230786.984039664, tmp)%(tmp = -310649504.7704866, tmp))));
+  assertEquals(68812544, x >>= (-1347584797));
+  assertEquals(1.2120221595741834e-11, x /= ((2791020260)*((((1964870148.6358237)^x)|(-3082869417))-((x^x)&((1234292117.8790703)<<(-1792461937.2469518))))));
+  assertEquals(1.2120221595741834e-11, x %= (x-(2780439348)));
+  assertEquals(-1421552183, x |= (tmp = -1421552183.5930738, tmp));
+  assertEquals(-1420954119, x |= ((((-2547788562.5735893)<<x)%(435385623))>>(x|x)));
+  assertEquals(1, x /= x);
+  assertEquals(1, x >>= (x>>>(((2975715011.501709)-(tmp = -1473273552.981069, tmp))/(1654883913.042487))));
+  assertEquals(-65382, x ^= ((x/((tmp = -2780026200, tmp)<<x))^(((-2683084424)<<x)>>(-1716245874))));
+  assertEquals(1530921106, x &= (1530940914));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>= x);
+  assertEquals(0, x /= (tmp = 773741434.1972584, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(0, x <<= (-67977514.99888301));
+  assertEquals(0, x %= (2496550482.524729));
+  assertEquals(-0, x /= (tmp = -515040417, tmp));
+  assertEquals(0, x <<= (-1673460935.2858837));
+  assertEquals(-2638209488, x += (-2638209488));
+  assertEquals(-2400951839498683400, x *= (910068685));
+  assertEquals(1600582036, x ^= (((-1247602308.4812562)>>(((-2393714444.179732)>>>x)%(-778140635.7165127)))+(-1933914727.2268424)));
+  assertEquals(0, x *= ((x-x)>>(-1270234575)));
+  assertEquals(0, x >>>= (tmp = 3193676327.493656, tmp));
+  assertEquals(0, x ^= (x>>>(1148676785.389884)));
+  assertEquals(0, x >>= (tmp = -2269181763.8663893, tmp));
+  assertEquals(0, x >>= (3149450221));
+  assertEquals(0, x >>= (1069630750));
+  assertEquals(-625009654, x ^= ((-2143499112)%(-759244728.6214335)));
+  assertEquals(3583943, x >>>= (-2942645558.1204453));
+  assertEquals(1791971, x >>= (x/x));
+  assertEquals(223996, x >>= x);
+  assertEquals(6999, x >>= (tmp = -1051883611.9443719, tmp));
+  assertEquals(1459617792, x <<= (-1572314984));
+  assertEquals(2622356453.269262, x -= (tmp = -1162738661.2692618, tmp));
+  assertEquals(5103676461.269262, x += (2481320008));
+  assertEquals(823989684.2692623, x %= (x^(((((1048362966)*((tmp = -2423040747.6233954, tmp)>>>x))*((tmp = 2330818588.4081, tmp)>>(tmp = 103312020.98346841, tmp)))+(tmp = 2264492857.144133, tmp))>>>((tmp = 2523442834, tmp)<<x))));
+  assertEquals(0, x >>>= (tmp = -2018700898.531027, tmp));
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x <<= (tmp = -2489442223, tmp));
+  assertEquals(0, x >>= ((3045836220)>>>x));
+  assertEquals(-1156905149, x ^= (3138062147));
+  assertEquals(-0, x %= x);
+  assertEquals(-3118433907.512866, x -= ((tmp = 1338611238, tmp)-(-1779822669.5128663)));
+  assertEquals(100679693, x &= (1040565279));
+  assertEquals(10136400582574248, x *= x);
+  assertEquals(0, x %= x);
+  assertEquals(2400318405, x += (2400318405));
+  assertEquals(1.0036190808578471, x /= (((tmp = -2313492253.9889445, tmp)|(x-((tmp = -205459123, tmp)>>x)))+x));
+  assertEquals(0, x >>>= (tmp = 882343227.1675215, tmp));
+  assertEquals(0, x &= ((tmp = 2307828832.2706165, tmp)^((((((1404388047)<<((807879382)-(-2862921873)))-x)*(tmp = -1897734732, tmp))>>(tmp = 1981888881.2306776, tmp))%x)));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x *= (((x*x)*((((2764801384.171454)%(x>>>x))&(384818815))+(x>>(tmp = -1481683516, tmp))))&x));
+  assertEquals(0, x >>= (tmp = -2202536436, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x &= (tmp = 15161124, tmp));
+  assertEquals(-1586110900, x ^= (-1586110900));
+  assertEquals(-1586127952, x -= ((tmp = 560737212, tmp)%((1349529668)>>>(tmp = -1956656528, tmp))));
+  assertEquals(-1174945870, x -= ((1178456190)|x));
+  assertEquals(1335167624.3422346, x -= (tmp = -2510113494.3422346, tmp));
+  assertEquals(1329952126.3422346, x -= (x>>x));
+  assertEquals(1, x >>= x);
+  assertEquals(3, x |= (x<<x));
+  assertEquals(3, x -= (x-x));
+  assertEquals(-1938525669, x |= (tmp = 2356441625.5128202, tmp));
+  assertEquals(-1938525669, x ^= ((tmp = -197149141.3622346, tmp)/(2833823156)));
+  assertEquals(-2.6292393147661324, x /= (737295254.2254335));
+  assertEquals(2925975987.370761, x -= (-2925975990));
+  assertEquals(2925975987.370761, x %= (tmp = 3041184582.8197603, tmp));
+  assertEquals(-1908068660, x ^= ((tmp = -1380575181, tmp)-(2375164084.8366547)));
+  assertEquals(-477017165, x >>= (tmp = 2420877826.353099, tmp));
+  assertEquals(-477017165, x %= ((tmp = -2919204062.3683634, tmp)-(tmp = -2263328990, tmp)));
+  assertEquals(-2105539936, x &= ((tmp = -1630795440, tmp)-(x&((933423833)>>(-475069901)))));
+  assertEquals(-4979480720, x -= (tmp = 2873940784, tmp));
+  assertEquals(-4190953472, x -= (x&(tmp = -645918862.9001305, tmp)));
+  assertEquals(17564091004468855000, x *= x);
+  assertEquals(-857277134, x |= (tmp = 2363948338, tmp));
+  assertEquals(1015632515, x -= (-1872909649));
+  assertEquals(-1150380043, x ^= (tmp = -2014853770, tmp));
+  assertEquals(1607729152, x <<= ((2194449589)+(x|(tmp = -1470075256.4605722, tmp))));
+  assertEquals(1608356496, x |= ((((x|(670426524))<<((-2415862218)>>(tmp = 1572561529.9213061, tmp)))^((-1989566800.3681061)|x))&(2170270618.3401785)));
+  assertEquals(-1836056576, x <<= (tmp = 2906301296.540217, tmp));
+  assertEquals(-2952415961567723500, x *= (tmp = 1608020145, tmp));
+  assertEquals(1435500544, x <<= x);
+  assertEquals(700928, x >>>= (tmp = 2924829771.1804566, tmp));
+  assertEquals(0, x <<= ((x^(2410009094))|(((-164334714.18698573)%(x*x))|(tmp = 2182431441.2575436, tmp))));
+  assertEquals(-143321285, x ^= (tmp = -143321285, tmp));
+  assertEquals(-2, x >>= x);
+  assertEquals(-1, x >>= (x&(1109737404)));
+  assertEquals(1, x >>>= x);
+  assertEquals(0, x ^= x);
+  assertEquals(-2463707358.165766, x += (-2463707358.165766));
+  assertEquals(1831259938, x >>= (((((x-(tmp = 1359448920.5452857, tmp))%(tmp = -104541523, tmp))/((3133289055.9780197)*x))>>x)%x));
+  assertEquals(1858895646, x ^= ((tmp = 131424376, tmp)>>(tmp = -396761023, tmp)));
+  assertEquals(1, x >>= x);
+  assertEquals(-1888369021, x |= ((tmp = -2038869285.046599, tmp)^((tmp = -1318286592.4250565, tmp)-(tmp = 2825123496, tmp))));
+  assertEquals(1036458508, x <<= ((tmp = 2722401450, tmp)/((tmp = 1090712291, tmp)>>((tmp = -2155694696.9755683, tmp)*(tmp = 1661107340, tmp)))));
+  assertEquals(1, x /= (x%((tmp = -1716050484, tmp)+(tmp = -1683833551.797319, tmp))));
+  assertEquals(0, x >>= (tmp = -2899315628, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x <<= x);
+  assertEquals(1546062911, x |= (1546062911));
+  assertEquals(1546195271, x += ((tmp = -3210667091, tmp)>>(tmp = 1323121165, tmp)));
+  assertEquals(3092390542, x += x);
+  assertEquals(-1199626354, x |= (406783756));
+  assertEquals(-3650317194584908300, x *= (tmp = 3042878461.625484, tmp));
+  assertEquals(-7.650495675092354e+27, x *= (2095844078));
+  assertEquals(0, x >>= (tmp = 342617880.3384919, tmp));
+  assertEquals(22, x ^= (((tmp = 381409558.9104688, tmp)>>((2823172888.974557)>>x))>>x));
+  assertEquals(736383550, x += (736383528));
+  assertEquals(0, x %= x);
+  assertEquals(0, x += x);
+  assertEquals(-1553157831, x -= (1553157831));
+  assertEquals(1838556960, x <<= (3158944357.262641));
+  assertEquals(5503285699.188747, x *= ((tmp = 2437440276, tmp)/(814308583.8128904)));
+  assertEquals(5824889900.188747, x -= (((tmp = 1171445694, tmp)-(tmp = -1584666956, tmp))^(tmp = 1217545373, tmp)));
+  assertEquals(747032, x >>>= (-89332085));
+  assertEquals(747032, x |= (x^(x^(x>>>x))));
+  assertEquals(747032, x >>>= ((-1558482440)*((tmp = -2413907480, tmp)+(3003996862.384156))));
+  assertEquals(7.747761349084291e+23, x += ((tmp = 518064022.64624584, tmp)*((tmp = 2001951702, tmp)*x)));
+  assertEquals(0, x <<= (2769324707.5640426));
+  assertEquals(NaN, x %= (((((((-2458056470.7717686)&x)>>(tmp = -361831232.42602444, tmp))*(2611108609.6727047))>>>x)/(-1713747021.8431413))*(-1143281532)));
+  assertEquals(NaN, x %= ((x^((-613836813)*(tmp = -3180432597.0601435, tmp)))%x));
+  assertEquals(NaN, x /= ((-1607092857)^x));
+  assertEquals(0, x &= (-1190719534));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x += (x>>(642177579.1580218)));
+  assertEquals(-3129552333, x += (-3129552333));
+  assertEquals(1165414963, x &= x);
+  assertEquals(2222, x >>= (((tmp = 2606317568, tmp)|x)+(tmp = 1844107136, tmp)));
+  assertEquals(NaN, x %= ((x^x)<<(x/(((tmp = -1362148700, tmp)&((tmp = 76371048, tmp)<<x))>>>((x^(-2605741153))>>(((tmp = -2131608159.7634726, tmp)|(((2827792229.8004875)|(((-848439251)+(-2576768890.123433))|((tmp = -2617711776, tmp)-((-199980264)&((tmp = -46967951.76266599, tmp)/(-733253537))))))*(tmp = 1820087608, tmp)))>>>(tmp = -3118359396.4298744, tmp)))))));
+  assertEquals(NaN, x /= ((2144871731)*x));
+  assertEquals(NaN, x *= x);
+  assertEquals(NaN, x %= (tmp = 234811462.08692443, tmp));
+  assertEquals(0, x >>>= ((1121416685)|(x^(((tmp = -2905413334, tmp)<<(tmp = -3091554324.030834, tmp))<<x))));
+  assertEquals(-55938048, x |= ((tmp = -55938048, tmp)+(x*(tmp = -1518809027.2695136, tmp))));
+  assertEquals(-3.3234995678333864e-10, x /= (x*(tmp = -3008876576, tmp)));
+  assertEquals(0, x <<= (x/((((((-2168824234.2418427)>>(((tmp = 1976810951, tmp)%x)<<(x*(x>>(x%(3146266192))))))%(tmp = 1756971968.122397, tmp))>>>(-2859440157.8352804))/(-1001406.1919288635))>>>(-1358031926))));
+  assertEquals(-0, x *= (tmp = -1756000533, tmp));
+  assertEquals(-0, x %= (2522761446.869926));
+  assertEquals(0, x >>>= (((1087690535)>>>(2741387979))^x));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>= (-819422694.2188396));
+  assertEquals(0, x ^= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x &= (tmp = 86627723, tmp));
+  assertEquals(0, x += x);
+  assertEquals(0, x %= (tmp = -2317915475, tmp));
+  assertEquals(Infinity, x += (((-3072799584)^(-2487458319))/(((tmp = -3050692353, tmp)&x)>>(-777977292.8500206))));
+  assertEquals(Infinity, x += x);
+  assertEquals(Infinity, x -= (tmp = 484428269, tmp));
+  assertEquals(Infinity, x *= x);
+  assertEquals(Infinity, x /= (2059586218.2278104));
+  assertEquals(Infinity, x *= (tmp = 415918523.8350445, tmp));
+  assertEquals(-1800869091, x |= (((-1800869091)>>>(x>>>(tmp = -2832575051, tmp)))>>>x));
+  assertEquals(6196126991451132000, x *= ((-1467292383.8458765)+(-1973339154.7911158)));
+  assertEquals(6196126992684649000, x += (1233517421));
+  assertEquals(1, x /= x);
+  assertEquals(-7153809722216516000, x -= (((-2984550787.146106)<<(tmp = 743743974, tmp))*((3155151275)/((-1771412568.8965073)%x))));
+  assertEquals(-7153809721471491000, x -= (-745024056));
+  assertEquals(5.117699353102001e+37, x *= x);
+  assertEquals(0, x >>= x);
+  assertEquals(-0, x *= ((-2651785447.666973)<<(-1124902998)));
+  assertEquals(-0, x /= (2119202944));
+  assertEquals(1042673805.5205957, x -= ((x<<x)-(tmp = 1042673805.5205957, tmp)));
+  assertEquals(62, x >>>= (tmp = 2769597912.977452, tmp));
+  assertEquals(34, x &= ((tmp = -61541150, tmp)%(x^(-943160469))));
+  assertEquals(34, x ^= ((-2625482224.4605474)<<(-2277806338.3461556)));
+  assertEquals(536870912, x <<= ((-2373927426.4757633)^x));
+  assertEquals(536870912, x &= x);
+  assertEquals(512, x >>>= ((-1626769708.310139)<<((tmp = 641796314, tmp)/(721629637.3215691))));
+  assertEquals(0, x <<= (-113973033));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x += (-1602711788.2390788));
+  assertEquals(NaN, x *= (x%x));
+  assertEquals(0, x &= (x<<(x|(x>>((x>>>(x%((1182960050)^(((-220896609)-((((tmp = 1518275435.360103, tmp)/(tmp = -88234820, tmp))^x)/x))>>(3169930777.548236)))))-(tmp = -2912668817.662395, tmp))))));
+  assertEquals(0, x *= ((2323969408.7524366)/(((tmp = -3089229853, tmp)>>>((((tmp = -1012580544.5631487, tmp)>>(1138049418.9023373))>>x)&x))*(tmp = 626912001, tmp))));
+  assertEquals(0, x >>>= x);
+  assertEquals(NaN, x /= (x%(-868024322)));
+  assertEquals(NaN, x /= (tmp = -1749532322, tmp));
+  assertEquals(1861918711, x |= (-2433048585.853014));
+  assertEquals(1861918711, x >>= (((102451747)>>>((((241651917.47259736)/((((((((1759022236)^(tmp = -2592022722, tmp))+((-1748044969)>>>(704597925)))/(-1639604842))%((1349846853.7345295)<<(-729695861)))/(x>>((tmp = -2654474404.7365866, tmp)>>x)))>>>(((-480356478)|(x%((tmp = -1668269244.6979945, tmp)+(tmp = -2441424458.565183, tmp))))^((1634981212.7598324)>>>(tmp = 122455570.22000062, tmp))))<<x))*((tmp = -1058636137.5037816, tmp)+((2794083757.138838)&((x/(50081370))&x))))/x))/((tmp = -243106636, tmp)<<((x*((tmp = -648475219.5971704, tmp)>>((tmp = -1568913034, tmp)-((tmp = 911458615, tmp)|x))))>>>(tmp = 2714767933.920696, tmp)))));
+  assertEquals(0, x ^= x);
+  assertEquals(-2080484602, x |= (((1544771831.4758213)|x)^(-538113039)));
+  assertEquals(696451072, x <<= (tmp = -1587032689, tmp));
+  assertEquals(-162595645, x += (tmp = -859046717, tmp));
+  assertEquals(516546456, x >>>= x);
+  assertEquals(623083588, x += ((-1371850352)^(tmp = -1469933252, tmp)));
+  assertEquals(92342412, x %= (tmp = -132685294, tmp));
+  assertEquals(500272110, x |= ((tmp = 1616032506, tmp)%((tmp = 1589569590.4269853, tmp)|(-972791738.1829333))));
+  assertEquals(3247086, x %= (((tmp = 1372216208, tmp)|(-638950076.3387425))&((-2619249161.849716)&(73957896))));
+  assertEquals(0, x >>>= (tmp = -1482343462.6911879, tmp));
+  assertEquals(1265125662, x ^= (tmp = -3029841634, tmp));
+  assertEquals(4941897, x >>>= (-2039728632));
+  assertEquals(206857, x &= (tmp = 226962365.45571184, tmp));
+  assertEquals(1.0925018562586405e+24, x += ((tmp = 2687424146, tmp)*(((-1998020319)%x)*(-2080331363))));
+  assertEquals(-1.755270751212437e+32, x *= (-160665242));
+  assertEquals(0, x <<= (3152796521.6427975));
+  assertEquals(0, x ^= ((((((tmp = -855001595, tmp)<<(2007525777))-(x-(x-x)))/(3036585090.9701214))&(1827983388))*((tmp = -915604789.0515733, tmp)&(((((tmp = -806628722.7820358, tmp)%x)/(tmp = -2773117447, tmp))|x)<<(((tmp = -2902300974.7300634, tmp)|x)/(-1608133440))))));
+  assertEquals(0, x |= ((((((119024954)*(((x^(tmp = 2939514414, tmp))|x)^(x-(tmp = -1597415597.6795669, tmp))))+(((tmp = -182277816.14547157, tmp)<<(((-2983451324.3908825)^(tmp = 1572568307, tmp))+(-1165604960.8619013)))/(x>>((tmp = -2127699399, tmp)>>((x^(((((tmp = -1968667383, tmp)^(tmp = 3120052415.9964113, tmp))|(((x|(((x^((tmp = 2831505153, tmp)<<((-3150506831.547093)+((x%(tmp = 383761651, tmp))%(2856803457)))))+(((tmp = -2426953997, tmp)^(tmp = -2667954801.1010714, tmp))*(tmp = -2707801631, tmp)))&(tmp = 2082935238.794707, tmp)))^((tmp = 697573323.5349133, tmp)-x))%(tmp = 661936357, tmp)))/(-1717944600.261446))>>>((2423776015.0968056)^((-1410322010)|((x<<(tmp = 2935993226, tmp))/(tmp = -1533896392, tmp))))))*(tmp = -596675330, tmp))))))>>>(((2944268153)^(x&(144579050.93126357)))/(-2123810677.2619643)))>>>(1473040195.9009588))*x));
+  assertEquals(0, x /= (2877666495));
+  assertEquals(2174852514, x -= (tmp = -2174852514, tmp));
+  assertEquals(543713128, x >>>= x);
+  assertEquals(2978128878.939105, x += (tmp = 2434415750.939105, tmp));
+  assertEquals(3529591145844655600, x *= (tmp = 1185170719.3753138, tmp));
+  assertEquals(659, x >>>= ((((((x<<(((((-425423078)/(((tmp = 160617689.20550323, tmp)&(-1524740325.5003028))%(tmp = -1869426475, tmp)))<<(((x^(-487449247))>>>(tmp = -1962893666.7754712, tmp))%x))*x)>>((tmp = 623413085, tmp)&(x+(((((-2200726309.083274)-(x-x))+x)&(-1304849509))|((((tmp = -431896184, tmp)>>>(x>>(-1932126133)))<<((1078543321.2196498)*(-10761352)))>>(tmp = -2681391737.5003796, tmp)))))))/x)-(tmp = -1768629117, tmp))/(((((tmp = -2320718566.0664535, tmp)%x)+(-2831503351.995921))>>>(-2695416841.3578796))*(943979723)))<<x)|((652520546.7651662)>>(1045534827.6806792))));
+  assertEquals(531, x &= (tmp = -293707149, tmp));
+  assertEquals(0, x >>= (tmp = -678056747.5701449, tmp));
+  assertEquals(1184651529.8021393, x += (tmp = 1184651529.8021393, tmp));
+  assertEquals(1721719611, x |= (tmp = 1645413178, tmp));
+  assertEquals(-406880257, x |= (tmp = 2268544460, tmp));
+  assertEquals(-4194304, x <<= (tmp = -109701322.43455839, tmp));
+  assertEquals(17592186044416, x *= x);
+  assertEquals(0, x ^= (x&x));
+  assertEquals(0, x <<= (tmp = 1715401127, tmp));
+  assertEquals(-1793087394, x |= (tmp = -1793087394.730585, tmp));
+  assertEquals(-2, x >>= x);
+  assertEquals(263607360.10747814, x += (tmp = 263607362.10747814, tmp));
+  assertEquals(1073214955, x |= (893759979.3631718));
+  assertEquals(703953930, x -= ((2738450011)%(x^(tmp = 679402836, tmp))));
+  assertEquals(1, x >>= (tmp = 2262515165.6670284, tmp));
+  assertEquals(0, x >>= (((tmp = 747896494, tmp)^((tmp = -1005070319, tmp)+x))|x));
+  assertEquals(0, x >>= ((953612771)>>>(tmp = 3066170923.3875694, tmp)));
+  assertEquals(-314941454, x -= (x+(((314941454)%(((tmp = 2200222912.9440064, tmp)>>>(2534128736.805429))>>>(x|((747716234)%(((tmp = -252254528, tmp)%(-1553513480.1875453))&x)))))<<x)));
+  assertEquals(-535686958, x &= (-522809126));
+  assertEquals(0.5480312086215239, x /= (tmp = -977475278, tmp));
+  assertEquals(-1199953459.6090598, x *= ((-2189571393)+((3186862741.37774)>>(tmp = -2193090564.5026345, tmp))));
+  assertEquals(-1199953459.6090598, x %= ((tmp = 2986532440, tmp)*(2685122845)));
+  assertEquals(-1199953459.6090598, x %= (1951182743.7399902));
+  assertEquals(51262285383887820, x *= (-42720228));
+  assertEquals(-424776752, x |= x);
+  assertEquals(166221344210236600, x *= (tmp = -391314598.6158786, tmp));
+  assertEquals(-1883425600, x >>= (((tmp = -1020679296, tmp)^((-1416867718)+(-1412351617)))<<(-2743753169)));
+  assertEquals(0, x &= (x/(-2250026610)));
+  assertEquals(-1111956501, x ^= (tmp = 3183010795, tmp));
+  assertEquals(2012059503, x ^= (tmp = -900369276, tmp));
+  assertEquals(15719214, x >>>= (tmp = -3196277049, tmp));
+  assertEquals(15719214, x |= x);
+  assertEquals(100779035, x -= ((-1245802025)^(-2964289852)));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x &= (((x<<((2361941389.708063)%x))>>((328256762.09842086)>>>((((tmp = 3094192285, tmp)-(((x>>(tmp = -2920437464, tmp))<<(tmp = -2693021467, tmp))-(x>>>((2410065554)%(x%(tmp = 2487056196.689908, tmp))))))-(tmp = -866314146, tmp))^((1754098471)-((((((-2450740191)-(tmp = 1977885539.6785035, tmp))*((tmp = -1205431332, tmp)>>>x))>>(-870601854))>>(tmp = -301859264, tmp))|((tmp = -2308971516.8301244, tmp)/x))))))&((2307007357)-((tmp = -1518812934, tmp)+(2562270162)))));
+  assertEquals(0, x <<= x);
+  assertEquals(-1802124619, x |= (-1802124619));
+  assertEquals(-1802124619, x %= ((1617132364.306333)+((1678465962.079633)|((516698570)%(((569813606)*(-1800804098.6270027))%((tmp = 1976706935, tmp)-((tmp = -1830228989.5488424, tmp)>>(((x^((tmp = 1015246068.3791624, tmp)>>x))^((-2171682812.246772)-(tmp = -398330350, tmp)))&x))))))));
+  assertEquals(904564673.6237984, x -= (tmp = -2706689292.6237984, tmp));
+  assertEquals(818237248768128900, x *= x);
+  assertEquals(254842325.2585001, x %= (1550087667.9657679));
+  assertEquals(-1163919360, x <<= x);
+  assertEquals(-3.4644526843674166, x /= ((-446801454)+(x>>>(tmp = -2025151870, tmp))));
+  assertEquals(0, x &= ((((((((-1739617728)&(x&(((tmp = -2946470036.552597, tmp)/x)*x)))^(-1130501404))>>>x)/((1870230831)>>>(840301398)))%x)/x)/(-2927537567)));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>>= (x&(x&x)));
+  assertEquals(0, x &= ((-579614044)-(-756012505.4048488)));
+  assertEquals(-2970367642, x -= (tmp = 2970367642, tmp));
+  assertEquals(-415129376, x ^= (tmp = 2847041926.060355, tmp));
+  assertEquals(-1505681312, x &= (tmp = -1225184902.9215767, tmp));
+  assertEquals(-3174471329.5807734, x += (-1668790017.5807734));
+  assertEquals(-Infinity, x /= (x>>x));
+  assertEquals(NaN, x -= x);
+  assertEquals(0, x ^= (x^(((-1407936301.5682082)<<((x^(((tmp = 3213446217.307076, tmp)|x)|((tmp = 3219810777.3171635, tmp)/(tmp = 1561807400, tmp))))>>>((tmp = 2449910203.0949173, tmp)|((((1954662538.7453175)>>(tmp = -1711636239.9916713, tmp))>>>(tmp = 406219731.214718, tmp))<<(((-907908634.4609842)^((((((tmp = 2408712345, tmp)*(tmp = 1740346634.5154347, tmp))>>(tmp = 715783991, tmp))^(tmp = -655628853.2821262, tmp))%(tmp = 2819143280.434571, tmp))/(-1240412852)))*x)))))/x)));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>>= (((-3198075268.8543105)>>(((((x+((tmp = -133461401.50823164, tmp)-((x&(((((tmp = 2617977319, tmp)>>((tmp = -2704719576.8734636, tmp)|((tmp = -977362542.2423751, tmp)<<(x<<(tmp = 3054487697.1441813, tmp)))))>>>((-1635655471)%x))/(-2079513672))%(tmp = 1993563806, tmp)))<<(tmp = -1310524200.6106496, tmp))))%((((-2558804500.7722936)+(tmp = -1641265491, tmp))<<((tmp = -1309608349, tmp)>>>x))/((tmp = -2306644272, tmp)<<x)))*(-2009396162.3063657))+(267343314.3720045))-(-2212612983.661479)))|x));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x *= x);
+  assertEquals(-824822309, x |= (-824822309));
+  assertEquals(-807944741, x |= (((-598067403)*((x&(tmp = 2897778389, tmp))>>>(-1322468310.3699632)))|x));
+  assertEquals(90004223.44097246, x /= (((tmp = -481122620, tmp)&x)%((tmp = 1109368524, tmp)/(((-3150568522.633032)<<(tmp = 2923396776, tmp))^(x-((x/x)&(x/(-287976185.1049104))))))));
+  assertEquals(0.4521931751193329, x /= (tmp = 199039323, tmp));
+  assertEquals(1.8110466604491368e-10, x /= (2496860986.492693));
+  assertEquals(0, x |= x);
+  assertEquals(-1225944576, x += ((tmp = -807700791.631221, tmp)<<((-700782615.4781106)-((((-2954619897)>>>x)<<((tmp = 997657844, tmp)>>>(1227994596)))/((-1234591654.8495834)*((tmp = -191189053.70693636, tmp)+(tmp = -3027659304, tmp)))))));
+  assertEquals(-1225811383, x |= (-1866233271));
+  assertEquals(3069155913, x >>>= (((x/(-99524153.40911508))%(x>>>((((tmp = 2985975640, tmp)/(tmp = 2781516546.2494454, tmp))&(((2234114508)|(((x/(tmp = -1224195047, tmp))<<x)^(x>>>((537884375.5698513)+x))))^((tmp = -2144817497.5089426, tmp)|(-498079183.8178189))))>>>((x+x)&(-3086080103.6460695)))))<<(((tmp = 2151157136, tmp)*x)/(((x/x)>>>(-1149734628.4364533))-((3025445835.654089)+(tmp = 530902725.91127443, tmp))))));
+  assertEquals(-1733702568, x ^= (tmp = 776361489.423534, tmp));
+  assertEquals(8981504, x &= ((tmp = 2902581847, tmp)*(x-(-2697760560))));
+  assertEquals(1153166.8526612986, x -= ((x/(tmp = -1375025594.5027463, tmp))+((3043576689.1538706)%(x+x))));
+  assertEquals(3389855, x |= (x+x));
+  assertEquals(-488458393.17759943, x += (-491848248.17759943));
+  assertEquals(40982867145206920, x *= ((3132857155)|(tmp = -218356553, tmp)));
+  assertEquals(688, x >>= (((((tmp = 403321821, tmp)+((tmp = 2536984658, tmp)%((tmp = 2759309029.8753624, tmp)|(((tmp = 1994203554.7417293, tmp)^((704660500.434877)*(tmp = 1536292958.2691746, tmp)))+(-164139788)))))/((1205950994.1255205)+x))^((((tmp = 975272146.0133443, tmp)-(150107797))/(-1764309514))^((x>>>(x^(x^x)))+(203250124))))>>>(tmp = 1864959239.512323, tmp)));
+  assertEquals(10, x >>= ((tmp = 1631996431.9620514, tmp)>>x));
+  assertEquals(10, x %= (tmp = 2678904916, tmp));
+  assertEquals(335544320, x <<= (tmp = -2759037415.6811256, tmp));
+  assertEquals(-153389967, x |= ((tmp = -2411636565, tmp)+(tmp = -2305156154, tmp)));
+  assertEquals(-1171, x >>= x);
+  assertEquals(813080576, x &= (((tmp = -65428547, tmp)&(tmp = 3163266999, tmp))<<x));
+  assertEquals(4346532303, x += ((tmp = -761515569.0707853, tmp)>>>(((tmp = 143240971.0661509, tmp)<<x)*(x^((tmp = -271697192.8471005, tmp)&x)))));
+  assertEquals(-863299035, x ^= ((((2663001827.1492147)>>>((x/(((tmp = 482665912, tmp)-(x>>(tmp = 354425840.784659, tmp)))>>((-2012932893)>>>x)))/((tmp = -1354385830.6042836, tmp)>>>(-2149023857))))^((tmp = 585746520, tmp)+(tmp = 756104608, tmp)))^(517529841.184085)));
+  assertEquals(-997654012, x &= (((tmp = -404836025.15326166, tmp)+((tmp = 3035650114.0402126, tmp)<<((-1308209196)>>(tmp = 693748480, tmp))))<<(((465774671.4458921)<<x)/(1971108057))));
+  assertEquals(-320581507110848260, x *= ((x-(tmp = -2266777911.7123194, tmp))^(tmp = -2810021113.304348, tmp)));
+  assertEquals(-320581508271196300, x += ((-1195215841.5355926)|(x-((2715907107.4276557)+(((-843426980)>>(x&(x%(tmp = -1139279208.34768, tmp))))^x)))));
+  assertEquals(368031616, x &= x);
+  assertEquals(368031616, x %= (tmp = 1211767328, tmp));
+  assertEquals(-67505614939510744, x *= (tmp = -183423412.56766033, tmp));
+  assertEquals(959424552, x >>= ((tmp = -171120122.5083747, tmp)/x));
+  assertEquals(30949179.096774194, x /= (((x-((((x&(tmp = -180770090, tmp))<<(((tmp = -2061363045.419958, tmp)*((655711531)^((1205768703)-(tmp = 2468523718.8679857, tmp))))+(-2746704581)))+((-853685888)*(tmp = -2299124234, tmp)))|(tmp = 2429502966, tmp)))|(((-985794986.0232368)>>>(2890862426))%x))>>(tmp = 1005542138.8415397, tmp)));
+  assertEquals(30949179, x |= x);
+  assertEquals(30949179, x %= (810126097.6814196));
+  assertEquals(120895, x >>= (tmp = 3065886056.1873975, tmp));
+  assertEquals(1934320, x <<= (1478650660.7445493));
+  assertEquals(0, x >>= (1069658046.2191329));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x %= (x*x));
+  assertEquals(NaN, x *= ((((2148513916)+(tmp = -210070225.85489202, tmp))>>(975470028))+((-3060642402)>>x)));
+  assertEquals(NaN, x *= (2888778384));
+  assertEquals(NaN, x -= (294531300.16350067));
+  assertEquals(-465620423, x ^= (tmp = -465620423.5891335, tmp));
+  assertEquals(1613303808, x &= (-2530649850.1952305));
+  assertEquals(2045458658, x |= (tmp = 432158946.5708574, tmp));
+  assertEquals(0, x >>>= (2277328255.770018));
+  assertEquals(0, x &= (-64904722.41319156));
+  assertEquals(0, x >>= x);
+  assertEquals(3109394857.361766, x += (3109394857.361766));
+  assertEquals(1519021650, x ^= ((tmp = -2632472653, tmp)|(tmp = 2161964921.8225584, tmp)));
+  assertEquals(370854, x >>>= ((1486892931.4564312)-((tmp = 3017755741.9547133, tmp)>>>x)));
+  assertEquals(1333145110.39802, x -= ((-1051580495.39802)-(tmp = 281193761, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x |= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(799202788.1455135, x -= (tmp = -799202788.1455135, tmp));
+  assertEquals(1539080192, x <<= (x%(((((x-x)|(((((x%(959993901))+(tmp = -2647575570.092733, tmp))/(tmp = -2040600976.5104427, tmp))*(x*(tmp = 2785252760, tmp)))>>(-377867259)))/((x&(1549738240.013423))>>>(tmp = -1502185618, tmp)))*x)%(1159283801.0002391))));
+  assertEquals(0, x >>= (-268660225));
+  assertEquals(-0, x /= (-2795206270.635887));
+  assertEquals(0, x >>>= (1869556260.2489955));
+  assertEquals(64202212, x ^= ((((tmp = -942983515.5386059, tmp)*(((1057759788)-x)*(tmp = 2038041858, tmp)))>>x)+(tmp = 64202212, tmp)));
+  assertEquals(2021126977, x -= ((tmp = -2009912898, tmp)^((2240062309)%x)));
+  assertEquals(4332348265459724000, x *= (tmp = 2143530968, tmp));
+  assertEquals(1472, x >>>= ((283380755)<<x));
+  assertEquals(-1672370407872, x *= (tmp = -1136121201, tmp));
+  assertEquals(338573318, x ^= (tmp = 2329579078.4832354, tmp));
+  assertEquals(2377388772.1662374, x -= (tmp = -2038815454.1662374, tmp));
+  assertEquals(-1.264761712403516, x /= ((((tmp = -2106209534, tmp)>>((((((tmp = 626190172, tmp)/x)>>>(-824270996.8545206))/((1258369810.9498723)-(tmp = -2947556209, tmp)))^((((366784589.24711144)|(1462064104.828938))-(1571045395.777879))<<(444685689.60103726)))>>(tmp = -2757110357.410516, tmp)))/(x>>>((tmp = 829226010, tmp)>>>(629512715))))|x));
+  assertEquals(-2905481691.264762, x -= (2905481690));
+  assertEquals(-1710543566.1481905, x -= (-1194938125.1165714));
+  assertEquals(-3421087132.296381, x += x);
+  assertEquals(-884178944, x <<= ((-1820881235)|x));
+  assertEquals(-884178944, x &= (x%(tmp = -2298828530, tmp)));
+  assertEquals(1516503040, x <<= ((tmp = -3039882653, tmp)+((tmp = 1956034508, tmp)<<(x>>(tmp = 280388051, tmp)))));
+  assertEquals(3033006080, x += x);
+  assertEquals(846431222.321887, x %= (x+(-1939718651.1609435)));
+  assertEquals(-846431224, x ^= ((-1742116766.54132)/x));
+  assertEquals(1157918728, x &= (tmp = 1966568030, tmp));
+  assertEquals(1157918728, x >>>= ((((((tmp = -2392096728.184257, tmp)*(x&(-3051259597.301086)))>>>(((tmp = 1712991918.071982, tmp)*(tmp = -714525951, tmp))-((-1784801647)>>((-1270567991)%(((214272558)/(((-3110194570)|(tmp = 2558910020, tmp))&(-1266294955.717899)))*((2654922400.609189)>>>(tmp = 370485018, tmp)))))))*(((tmp = -2621203138.1838865, tmp)%(858913517))*((tmp = -1564229442.2596471, tmp)>>((tmp = 1898557618, tmp)|(-1282356275)))))*(tmp = -1253508468, tmp))+((-361964404.75944185)|x)));
+  assertEquals(961668975, x += (-196249753));
+  assertEquals(1, x >>= (tmp = 890453053, tmp));
+  assertEquals(1, x >>= (((((tmp = 871309275, tmp)/(x>>>((tmp = 2033022083, tmp)&(tmp = -1393761939, tmp))))%((437488665.104565)^(tmp = 2808776860.4572067, tmp)))-((tmp = -359283111.49483967, tmp)<<((tmp = 2985855945, tmp)%(tmp = -596479825.9114966, tmp))))/(-1965528507)));
+  assertEquals(0, x >>= ((tmp = -1753776989, tmp)%(tmp = 322622654, tmp)));
+  assertEquals(84411424, x ^= (((x|(x|(tmp = -1617122265, tmp)))&(tmp = -313813263, tmp))&(1472888112.0258927)));
+  assertEquals(67633184, x &= ((1556833131.0776267)<<(x<<(1501219716.5575724))));
+  assertEquals(68002293, x |= (((tmp = 188984203.0350548, tmp)>>>(tmp = 1356052777, tmp))%(x*(tmp = -2944960865, tmp))));
+  assertEquals(67108864, x &= (((1046644783.9042064)<<x)+((-2796345632)>>>(((-1913290350.3687286)<<(((((tmp = -2223692353, tmp)>>x)&(x<<(x>>((((tmp = -976850020, tmp)%(tmp = 1379692507, tmp))>>>(1120103052.2077985))>>(tmp = 5592070.612784743, tmp)))))<<(x+((tmp = -3154037212.9764376, tmp)%(((x-(-1961060483.6965141))+(((1920670676)-(2852444470.7530622))/(((1445954602)>>((1353665887)>>(tmp = 111411560.64111042, tmp)))<<x)))+x))))<<((-1773130852.6651905)^((1216129132)>>(1511187313.2680469)))))|((tmp = -1107142147, tmp)|(tmp = -768165441.4956136, tmp))))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x %= (tmp = -1655707538.0778136, tmp));
+  assertEquals(-184120712930843900, x += (x+((tmp = -3174410166, tmp)+((tmp = -301807453, tmp)*(tmp = 610060182.1666535, tmp)))));
+  assertEquals(-54598560, x >>= (-1365351357));
+  assertEquals(-6763.94449950446, x /= (((-1953016847)<<((673287269.7002038)%(-558739761)))>>>(tmp = 1607754129, tmp)));
+  assertEquals(-1, x >>= x);
+  assertEquals(1, x >>>= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>= ((-384747983)+((((tmp = -949058352.381772, tmp)>>>(-1920744986))-(-882729639))^((x^((tmp = 2351364046, tmp)<<(((tmp = -3110165747, tmp)^(-1266489735))-((tmp = -371614326, tmp)>>((tmp = -2064968414, tmp)&(-2075036504.617934))))))&(((-2616501739)&(tmp = 2591437335.4029164, tmp))>>x)))));
+  assertEquals(0, x >>>= ((tmp = 2946468282, tmp)&((-2741453019)>>x)));
+  assertEquals(0, x -= ((x%(-134700915))&(-1955768279)));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x /= (x^(((((((tmp = 3185669685.772061, tmp)>>(tmp = -1973500738, tmp))-(tmp = -87401348.93002152, tmp))>>(tmp = -2813508730, tmp))&(tmp = -778957225, tmp))<<(x-(x&((-2821756608)+(((((tmp = 2475456548, tmp)/(tmp = 997998362, tmp))<<((tmp = -83043634, tmp)|x))%(636120329))%(tmp = -1910213427.7556462, tmp))))))%x)));
+  assertEquals(0, x &= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>>= (x%x));
+  assertEquals(0, x %= (745221113));
+  assertEquals(0, x >>>= ((1467615554.7672596)|x));
+  assertEquals(0, x /= (tmp = 735317995, tmp));
+  assertEquals(-1513001460, x |= (2781965836));
+  assertEquals(-1513001460, x |= (x%(1970577124.3780568)));
+  assertEquals(-0, x %= x);
+  assertEquals(1864972269, x ^= (-2429995027.840316));
+  assertEquals(1226843341, x &= (tmp = -639621923.5135081, tmp));
+  assertEquals(1226843339.3171186, x += ((1297620268.272113)/(-771070549)));
+  assertEquals(76677708, x >>>= (1009134980));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x ^= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(716040787, x |= ((1851586229)-(1135545441.3502865)));
+  assertEquals(1385693184, x <<= x);
+  assertEquals(1321, x >>= (x^((tmp = -1576632297.0860603, tmp)>>>(405218605))));
+  assertEquals(-1319012931, x |= (-1319014243));
+  assertEquals(-1319012931, x >>= ((((1689898279.3580785)<<((((x^(x>>>((((tmp = 2635260332, tmp)*(tmp = 2053357650, tmp))*x)*(2856480122.339903))))>>x)&(-2382703000.077593))%(1183918594)))*(tmp = -1670081449, tmp))<<x));
+  assertEquals(-528327581.7646315, x %= (tmp = -790685349.2353685, tmp));
+  assertEquals(2073431790, x ^= (tmp = 2601800333, tmp));
+  assertEquals(-6514722684180, x -= (((tmp = 824141806.0668694, tmp)>>>(((-1865885282.8723454)&(x&(x|((900188006.3757659)>>>(x&x)))))+(2227126244.0526423)))*x));
+  assertEquals(1450593, x >>>= ((2157053647)>>(x+(-2934071355.418474))));
+  assertEquals(576782336, x <<= ((1054640368.827202)&((tmp = -3182236876.434615, tmp)>>(tmp = 2129856634.0328193, tmp))));
+  assertEquals(2950754326, x -= (tmp = -2373971990, tmp));
+  assertEquals(738197504, x <<= (1188157369.5988827));
+  assertEquals(0, x <<= (x+((tmp = -839533141, tmp)&((((((tmp = -1148768474.7306862, tmp)|(172650299))+(tmp = -2739838654, tmp))/(3132557129))%x)>>>(tmp = -1229961746.2466633, tmp)))));
+  assertEquals(0, x %= (tmp = -2974207636, tmp));
+  assertEquals(0, x %= ((2323482163)>>>x));
+  assertEquals(0, x &= (((x/(x+(x>>((tmp = 55935149, tmp)%x))))|((3109182235)>>>(tmp = 1217127738.8831062, tmp)))+((((tmp = -385114910, tmp)*((((((tmp = -2535158574.634239, tmp)&(x+x))<<(-2821692922.43476))&(-776804130.9457026))>>((-1374832535)^(tmp = 2175402162.701251, tmp)))%(-1646995095)))-(x*(tmp = -921556123, tmp)))^(79224621))));
+  assertEquals(128935435, x |= ((tmp = 2279459038, tmp)%(tmp = -537630900.5271742, tmp)));
+  assertEquals(128935435, x /= ((((((x<<(2750024311))-((-1332480769.4784315)&(1418160003)))&(1551783357))<<(((((-2870460218.55027)|((-1958752193.7746758)&(2551525625)))>>>((((tmp = -1698256471, tmp)^(((((((((tmp = -830799466, tmp)+x)-(-111590590))+(tmp = -1105568112.3921182, tmp))/((tmp = -3058577907, tmp)|(((-1944923240.2965696)%(-2884545285))<<(tmp = -1993196044.1645615, tmp))))^(x>>(tmp = -2961488181.3795304, tmp)))&x)*x)|(((tmp = 97259132.88922262, tmp)<<((1601451019.343733)&x))*(x|x))))+((((x>>x)<<x)+(-868409202.2512136))/(((tmp = -2893170791, tmp)-((x|(-853641616))%(((tmp = 549313922, tmp)&(-768036601.6759064))%(tmp = -543862220.9338839, tmp))))-((tmp = 1639851636, tmp)+((2164412959)/(-273028039.941242))))))>>>((((-2382311775.753495)^(-2062191030.2406163))>>>(tmp = -1054563031, tmp))/(-862111938.7009578))))%x)+(-3103170117.625942)))%((tmp = -1144062234, tmp)>>x))>>>(tmp = 1216332814.00042, tmp)));
+  assertEquals(41.631074722901715, x /= (x&(-2542806180.962227)));
+  assertEquals(41.631074722901715, x %= (-14003386.556780577));
+  assertEquals(8, x &= (x&((-2231622948)%(tmp = 488279963.9445952, tmp))));
+  assertEquals(9.002961614252625e-9, x /= ((53802728.56204891)<<(((867697152.3709695)-(538719895.5707034))&(-631307825.4491808))));
+  assertEquals(0, x >>= x);
+  assertEquals(-0, x *= (tmp = -785674989, tmp));
+  assertEquals(-0, x += x);
+  assertEquals(0, x /= (-250703244));
+  assertEquals(0, x <<= ((tmp = -661062581.5511999, tmp)|x));
+  assertEquals(0, x &= (-1299482308));
+  assertEquals(0, x &= ((-399690060)>>>(2448074202.385213)));
+  assertEquals(0, x &= (2574341201));
+  assertEquals(0, x <<= ((x|(((tmp = 2458873162.645012, tmp)+(tmp = -1999705422.8188977, tmp))<<((x^(tmp = -392530472, tmp))>>>x)))&(((tmp = 2463000826.7781224, tmp)|(tmp = 3020656037, tmp))-x)));
+  assertEquals(1397603760, x += ((tmp = -1359413071, tmp)-(tmp = -2757016831, tmp)));
+  assertEquals(513823851, x -= (883779909));
+  assertEquals(-1765712747, x ^= (2288060670.6797976));
+  assertEquals(3117741504918286000, x *= x);
+  assertEquals(3117741506284045300, x += (1365759456));
+  assertEquals(6035555595.597267, x /= (tmp = 516562470, tmp));
+  assertEquals(104203275, x &= (tmp = 376835755.32434213, tmp));
+  assertEquals(10858322520725624, x *= x);
+  assertEquals(59458951, x >>>= (153765028));
+  assertEquals(49370856, x += ((tmp = -1291276092, tmp)>>x));
+  assertEquals(0, x %= x);
+  assertEquals(0, x += x);
+  assertEquals(-1494589645, x -= (1494589645));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x <<= (x&((2730708043.467806)<<x)));
+  assertEquals(0, x /= ((tmp = -1483912394.153527, tmp)>>>((tmp = 1800568769, tmp)^((((((tmp = 1351568510, tmp)>>(tmp = -1337992543.2562337, tmp))>>>(tmp = 2602239360.40513, tmp))*x)%x)+(-2095840128.0700707)))));
+  assertEquals(-0, x /= ((2363946613)^(tmp = -2227868069, tmp)));
+  assertEquals(0, x &= ((((2634933507)<<(2798775374.140882))>>>x)>>>(((tmp = 1135200853.6396222, tmp)-(tmp = -1529829490.7007523, tmp))-(((((((((x^((x|(2135742668.591568))-(924230444.8390535)))%(tmp = -2459525610.51898, tmp))+(x&((tmp = 1177231743.809653, tmp)/(tmp = 1743270357.2735395, tmp))))|(((tmp = -1894305017, tmp)^((tmp = 1791704240, tmp)&x))%(-1569751461)))>>>(tmp = -2078321944, tmp))|x)*(((x*(tmp = -163239354, tmp))<<((tmp = 2859087562.694203, tmp)&(-657988325.9410558)))^(2508013840)))-((-243572350)+(x%((-1095206140)+((tmp = 3213566608.942816, tmp)*((2256442613)%((tmp = 1723751298, tmp)^(x-((-1145710681.2693722)|x)))))))))+(1556870627)))));
+  assertEquals(130883024.97423434, x -= (-130883024.97423434));
+  assertEquals(0.046720352789736276, x /= (tmp = 2801413456, tmp));
+  assertEquals(1806558189, x |= (tmp = 1806558189.157823, tmp));
+  assertEquals(72.40475060062144, x /= (x%((1932591076.531628)>>(1982030182))));
+  assertEquals(-1077558321.5975945, x += (tmp = -1077558394.002345, tmp));
+  assertEquals(98187, x >>>= x);
+  assertEquals(97792, x &= (tmp = -1032487404, tmp));
+  assertEquals(709197609, x |= (x^(709179177)));
+  assertEquals(11081212, x >>>= (tmp = 1412940006.169063, tmp));
+  assertEquals(11081212, x &= x);
+  assertEquals(-1920311203, x -= ((tmp = 1931392415, tmp)<<((x%(tmp = -2873576383, tmp))%x)));
+  assertEquals(-1920311203, x |= (x&(-993884718.2172024)));
+  assertEquals(-4, x >>= (1409411613.0051966));
+  assertEquals(-7947632484, x *= ((-2856731734)^((-1181032235.9132767)-((tmp = 780101930, tmp)+((tmp = -1732707132.6253016, tmp)^x)))));
+  assertEquals(-2016362769, x ^= (tmp = 2711125619.2455907, tmp));
+  assertEquals(-61535, x >>= x);
+  assertEquals(-124771649, x ^= (tmp = 124726558, tmp));
+  assertEquals(-1, x >>= x);
+  assertEquals(-0, x %= (x*x));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x /= (2444628112));
+  assertEquals(0, x <<= ((-38968517.72504854)<<x));
+  assertEquals(-1504619917, x |= (tmp = 2790347379, tmp));
+  assertEquals(-1504619917, x &= x);
+  assertEquals(2790347379, x >>>= ((1825218368)<<(-1843582593.2843356)));
+  assertEquals(7786038495492170000, x *= x);
+  assertEquals(-11011696, x |= (((tmp = 2931644407.4936504, tmp)-(3077095016.001658))%(tmp = -1731851949, tmp)));
+  assertEquals(-107866, x %= ((-697845074.1661191)>>(772708134)));
+  assertEquals(356779149, x ^= (-356884949.503757));
+  assertEquals(0, x %= x);
+  assertEquals(0, x *= ((tmp = 1542291783, tmp)^x));
+  assertEquals(0, x += ((tmp = 1105314644.002441, tmp)&x));
+  assertEquals(-1005882993, x ^= (-1005882993.0899806));
+  assertEquals(-1301065066, x += (tmp = -295182073, tmp));
+  assertEquals(-1454702592, x <<= ((-2440858737.390277)&(-1363565201.7888322)));
+  assertEquals(-201539012492525570, x *= ((((tmp = -1416268089, tmp)|x)-(tmp = 1669129769, tmp))&(x<<((x/(-2614041678.7423654))%x))));
+  assertEquals(-2.1995276811535986e+25, x *= (x/(-1846667987.154371)));
+  assertEquals(0, x |= ((x*(((x>>>((tmp = 1044173034, tmp)>>>((x<<((tmp = -2906412863, tmp)%((tmp = -437401503, tmp)<<(((((x|(2167319070))<<((tmp = 2766179640.1840167, tmp)&(-2372076054)))*(tmp = -241617431.06416297, tmp))*((((((tmp = 2570465382.5574293, tmp)>>>(x/((-2851324509.354545)%x)))>>(((x+((tmp = -614687945, tmp)^x))^((((tmp = 1653437743, tmp)>>x)/(tmp = 3072995069, tmp))>>x))*(((((-290508242)>>((tmp = 2969511554, tmp)<<(tmp = 158176292.95642304, tmp)))<<(32376015))+(tmp = 2391895870.4562025, tmp))*x)))&((((x/(tmp = 365292078.53605413, tmp))>>x)/(1167322811.0008812))|(((tmp = 2487970377.365221, tmp)^x)<<((tmp = 2342607988.711308, tmp)/(((2276081555.340126)-(((tmp = -2571071930, tmp)>>(tmp = -248468735.76550984, tmp))>>>(tmp = -2862254985.608489, tmp)))^(-1312017395))))))<<x)&(2762717852.949236)))+((((-2492896493)&x)<<(-2756272781.4642315))/x)))))*(2405395452))))>>((-1433975206)/((tmp = -2064757738.6740267, tmp)<<((((tmp = -1563531255, tmp)-(-589277532.2110934))<<x)^(2249328237.0923448)))))-x))-(-225624231)));
+  assertEquals(0, x *= (tmp = 1657982666.2188392, tmp));
+  assertEquals(86443387, x |= (tmp = 86443387.25165462, tmp));
+  assertEquals(86443387, x %= (-1341731981.702294));
+  assertEquals(172886774, x <<= ((-1799840391)&(1011948481.310498)));
+  assertEquals(-1115684864, x <<= x);
+  assertEquals(-2098253702059525600, x *= (1880686715.1865616));
+  assertEquals(-2098253700213206300, x -= (tmp = -1846319435.0583687, tmp));
+  assertEquals(570692096, x &= (((tmp = -1572055366.64332, tmp)%(tmp = 1720120910, tmp))%((x-(912386952.5959761))*(tmp = -1146251719.4027123, tmp))));
+  assertEquals(603979776, x <<= ((-329752233.8144052)&(tmp = -368636559, tmp)));
+  assertEquals(603979776, x <<= x);
+  assertEquals(364791569817010200, x *= x);
+  assertEquals(0, x &= ((2074587775.983799)/(tmp = 438856632.76449287, tmp)));
+  assertEquals(0, x &= (((1509671758)*(tmp = -935801537.7325008, tmp))>>>(((tmp = -1752877566, tmp)<<x)%(tmp = -517163766, tmp))));
+  assertEquals(-2031730599, x ^= ((2264285273)&(tmp = -1762662949.014101, tmp)));
+  assertEquals(-843578945, x %= (-1188151654));
+  assertEquals(-2147483648, x <<= x);
+  assertEquals(-2147483648, x >>= (tmp = -3165079200.229641, tmp));
+  assertEquals(-44086313.1323726, x %= ((x%(-254466243.48728585))-((x>>(-457411829.1063688))-((-2606923436.9333453)/x))));
+  assertEquals(-44086313, x |= x);
+  assertEquals(1037812, x >>>= ((tmp = 342497258.9786743, tmp)+(1652928385.8150895)));
+  assertEquals(-2371695599678100, x *= (tmp = -2285284425, tmp));
+  assertEquals(-2371697387004653, x += (tmp = -1787326553.0542095, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>= ((x^(tmp = 544039787, tmp))>>>x));
+  assertEquals(0, x &= ((x%(((((((tmp = -424572417.1088555, tmp)|(-2381863189))/(tmp = -2007482475.1809125, tmp))&(((((tmp = 311016073, tmp)>>(tmp = -1548839845, tmp))+((-2557740399.7947464)<<(2399113209)))&x)>>>x))%(-297180308.7721617))-(tmp = 860906293, tmp))^x))%(-2740622304)));
+  assertEquals(4971841192462909000, x += ((tmp = -2723203837.572612, tmp)+((((-2909100706)+(-951999374))|(-3116735764))*(3087123539.422669))));
+  assertEquals(-460, x >>= (1081807537.557404));
+  assertEquals(2354165127.3906384, x += (tmp = 2354165587.3906384, tmp));
+  assertEquals(357.8680960002211, x /= ((((x<<(((x&x)+(1113841407))|((x/(tmp = 384533564, tmp))>>>(-605853882))))%x)&((tmp = 2050375842, tmp)>>>x))>>(((2745147573)^x)<<(x-(900043292)))));
+  assertEquals(0, x *= (x>>>(-295974954.5058532)));
+  assertEquals(0, x *= ((-2448592125.815531)*(tmp = -94957474.8986013, tmp)));
+  assertEquals(0, x &= ((x>>x)^(tmp = -1335129180, tmp)));
+  assertEquals(395092065, x |= ((3081659156)^(tmp = -1608334475, tmp)));
+  assertEquals(395092065, x &= x);
+  assertEquals(-413337639, x += (x^(tmp = -664996071.3641524, tmp)));
+  assertEquals(-1604423637896759800, x *= (x>>>(tmp = 1242912352.955432, tmp)));
+  assertEquals(0, x &= ((((((tmp = 651293313, tmp)|(((2541604468.635497)>>>(tmp = 758815817.7145422, tmp))>>>((-1948795647)/x)))&x)/((tmp = -3161497100, tmp)+(782910972.3648237)))>>>x)%(834206255.5560443)));
+  assertEquals(0, x >>>= (tmp = 125945571, tmp));
+  assertEquals(NaN, x -= (x%x));
+  assertEquals(NaN, x %= (tmp = 282259853, tmp));
+  assertEquals(NaN, x += (tmp = -2081332383, tmp));
+  assertEquals(0, x >>>= (((x>>(-2298589097.7522116))|((((x>>>(x-(tmp = 755218194, tmp)))|x)%x)-(tmp = 2206031927, tmp)))>>>((((x&(x-x))^(tmp = 2836686653, tmp))*((x<<(tmp = -1624140906.4099245, tmp))>>>((2942895486)|((x>>>x)>>>(-1586571476)))))|((781668993)+(-1857786909)))));
+  assertEquals(0, x &= (tmp = -708084218.9248881, tmp));
+  assertEquals(0, x %= (1645913394.5625715));
+  assertEquals(0, x <<= ((x^((tmp = 1185413900, tmp)*((-2441179733.997965)*(tmp = 2554099020.066989, tmp))))%((1704286567.29923)/x)));
+  assertEquals(0, x += x);
+  assertEquals(0, x *= x);
+  assertEquals(0, x |= (x>>>(139138112.141927)));
+  assertEquals(0, x >>>= (tmp = 2142326564, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(-0, x /= ((((x+(2817799428))|x)%((1050079768)-(x>>>((1452893834.8981247)|((((tmp = -1737187310.889149, tmp)/(tmp = -362842139, tmp))%(1234225406))%(((x|x)*((-1055695643.739629)-((x-x)*(945954197.676585))))-(tmp = 786185315.346615, tmp)))))))<<(-173891691)));
+  assertEquals(0, x &= (-2842855092.319309));
+  assertEquals(0, x &= ((-3188403836.570895)/x));
+  assertEquals(0, x *= (x+x));
+  assertEquals(NaN, x /= (x>>>(((tmp = 391037497.68871593, tmp)/((192754032)*(1382659402.5745282)))/((((-2187364928)>>>x)>>(tmp = 2563448665.7594023, tmp))^(tmp = 1500866009.7632217, tmp)))));
+  assertEquals(NaN, x /= ((tmp = -935036555.2500343, tmp)-(x/(((x&(x^(tmp = -3001352832.5034075, tmp)))^x)/((1122547613)>>x)))));
+  assertEquals(0, x >>= (tmp = -2951766379.0809536, tmp));
+  assertEquals(-632945188, x ^= (-632945188.7188203));
+  assertEquals(-632945188, x %= ((((((tmp = -3181527314.82724, tmp)&(2280175415))>>(x^(x|x)))^(tmp = -524233678.52970886, tmp))*x)|((tmp = 1782882786, tmp)>>>(tmp = -592607219, tmp))));
+  assertEquals(404189184, x <<= ((tmp = -2761472127, tmp)^(36616299.88780403)));
+  assertEquals(872651572, x ^= (tmp = 739568436.6252247, tmp));
+  assertEquals(13, x >>>= ((tmp = -1033843418.865577, tmp)%(x%(1247263629.0445533))));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>= (3189175317));
+  assertEquals(0, x &= (((2391973519.6142406)^((-2950058736.191456)|(x*x)))>>(tmp = 343822384.294345, tmp)));
+  assertEquals(0, x >>>= (tmp = -2306246544, tmp));
+  assertEquals(-1572339598, x ^= ((tmp = 2991380083.337327, tmp)&(tmp = -1361507970, tmp)));
+  assertEquals(649, x >>>= ((1961407923.4950056)>>(x-(-872821523.7513013))));
+  assertEquals(649, x ^= (((x&(tmp = -702931788, tmp))^(((x>>x)|(((tmp = 2710759269, tmp)/(x>>(x*((((((tmp = -2428445134.9555864, tmp)+(-1859938743))%(x<<x))*((236868604)+((tmp = -3066688385, tmp)/(787503572.8839133))))/(tmp = 3215629315, tmp))>>(-1315823020)))))%(1461368627.1293125)))>>>(tmp = -2921804417.5735087, tmp)))/(x>>>(((tmp = 2175260691.824617, tmp)/((-582958935.7628009)-((((((x>>x)|(2590503723.4810824))^(tmp = -1994324549, tmp))-(-684683327))/(tmp = -3133419531, tmp))|(tmp = -328974092.05095506, tmp))))>>(-447624639.4518213)))));
+  assertEquals(649, x %= ((((1854382717)|(((x+(tmp = 2568081234, tmp))-x)+((tmp = 1043086140, tmp)<<((tmp = 2979118595.0496006, tmp)+((x&(2669577199.852803))/(-2567808445.101112))))))<<((((tmp = -1471092047, tmp)&((-3099138855.21041)-((tmp = -798574377.526715, tmp)&((2255586141)<<(-1069867774)))))>>>(((x*(tmp = -2810255707.781517, tmp))/x)*(2706435744.054121)))^(394262253)))^((844325548.0612085)/(tmp = 1434691648, tmp))));
+  assertEquals(823215943.1924392, x += (tmp = 823215294.1924392, tmp));
+  assertEquals(536872706, x &= ((-334612686)%((1303605874)|x)));
+  assertEquals(-30666374.413486242, x += ((tmp = -567539080.4134862, tmp)%(tmp = -1655555936.3195171, tmp)));
+  assertEquals(-56438727096752984, x *= (tmp = 1840410814, tmp));
+  assertEquals(-33200107.984488487, x %= (((tmp = 3007206509, tmp)-(3079337725.6659536))%(1819565202.5011497)));
+  assertEquals(-1214493182, x ^= (-3060193769));
+  assertEquals(-1214493179.1335113, x -= ((-3218099496.595745)/(1122662554)));
+  assertEquals(-1214493179, x >>= ((-375364195)<<(((tmp = 619439637.8754326, tmp)>>(-1830023279.9486575))&(tmp = -1106180387.2448823, tmp))));
+  assertEquals(-303623295, x >>= (-2109241374.3349872));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x |= x);
+  assertEquals(1917126206, x -= (-1917126206));
+  assertEquals(2659779928, x -= (tmp = -742653722, tmp));
+  assertEquals(-1635187368, x >>= ((tmp = -674385169, tmp)*((9848362.783326745)|(x*(55220544.00989556)))));
+  assertEquals(-1981113695, x ^= ((tmp = 392404985, tmp)>>(((x<<((2006207061)<<(tmp = 2558988218, tmp)))*((((tmp = 1789304307.1153054, tmp)/(2538061546))<<(tmp = 556026116, tmp))&((tmp = 1076457999.6424632, tmp)*(tmp = -1822378633.2489474, tmp))))%(((((-1117046924)&((-69013651)%(x&(((-2320327696)/(x&x))-(tmp = 2458222544, tmp)))))>>((-3092360983.0037227)/(-3171415636)))*(((tmp = 2520431213, tmp)<<(1066492762.6149663))+((tmp = 1272200889, tmp)^((1687693123.2295754)+x))))-(-1096823395)))));
+  assertEquals(-990556848, x >>= x);
+  assertEquals(981202869119695100, x *= x);
+  assertEquals(981202869119695100, x -= (x/x));
+  assertEquals(0, x ^= (x>>x));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x *= ((((2980512718)>>>x)<<((x^(-1111233869))>>((2531466092.6036797)>>>(((tmp = -1791229364, tmp)*(-2210950307.206208))%((tmp = -806645443, tmp)<<((((((((tmp = 112334634.26187229, tmp)%(x|((((2154021796.1166573)+x)&((-1047293079.9686966)^(tmp = -1894127139, tmp)))+(tmp = 1910946653.2314827, tmp))))^(293142672.5016146))-x)<<(-1593533039.8718698))+x)>>(x<<(((46359706.50393462)&(tmp = 272146661, tmp))|(tmp = 2117690168, tmp))))%(tmp = -1784737092.4924843, tmp)))))))-(1465796246)));
+  assertEquals(0, x &= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x &= (x+(-1612418456)));
+  assertEquals(0, x &= ((tmp = -843964311, tmp)/x));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x *= x);
+  assertEquals(NaN, x += (x>>>(54020240)));
+  assertEquals(489206868, x |= (489206868));
+  assertEquals(489206868, x &= x);
+  assertEquals(489206848, x &= ((tmp = -1699133906.2361684, tmp)>>(tmp = 2658633814, tmp)));
+  assertEquals(489206848, x |= x);
+  assertEquals(1910559006, x -= (tmp = -1421352158, tmp));
+  assertEquals(1, x >>= x);
+  assertEquals(0, x -= x);
+  assertEquals(0, x %= (x^(tmp = 2745376003.2927403, tmp)));
+  assertEquals(0, x %= (((tmp = 3199743302.1063356, tmp)^((-1905944176)&(x>>>(187247029.5209098))))<<((x*((-1394648387)*(1252234289)))-(3140049815))));
+  assertEquals(0, x <<= (-2567872355));
+  assertEquals(0, x %= (tmp = 1057707555.8604916, tmp));
+  assertEquals(0, x %= ((tmp = -1877857405.0228279, tmp)>>>(((tmp = 423831184, tmp)*((tmp = -2106757468.324615, tmp)%(tmp = -1197717524.6540637, tmp)))>>(tmp = -93746263.46774769, tmp))));
+  assertEquals(0, x |= x);
+  assertEquals(-0, x *= ((tmp = 1317609776.6323466, tmp)*(tmp = -26959885.89325118, tmp)));
+  assertEquals(0, x >>= (-1288116122.0091262));
+  assertEquals(0, x &= ((370818172.92511404)%((tmp = -528319853.54781747, tmp)*(x/((tmp = -2839758076, tmp)^(x+(((-1258213460.041857)<<(tmp = 302017800.72064054, tmp))|((((tmp = -624254210, tmp)^((-338165065.97507)|((623392964)-x)))>>>x)%(tmp = 2767629843.0643625, tmp)))))))));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x |= ((-2001549164.1988192)*x));
+  assertEquals(0, x -= x);
+  assertEquals(0, x *= (((((165836842.14390492)*(tmp = -3220002961, tmp))|(-2840620221.747431))%((x/(tmp = 3153915610, tmp))>>>(tmp = 2018941558, tmp)))>>>x));
+  assertEquals(-0, x *= (-231994402.93764925));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x %= (tmp = 2702385056.1149964, tmp));
+  assertEquals(0, x <<= (tmp = 378459323, tmp));
+  assertEquals(0, x >>>= ((x&(x&(((-1014963013)<<(x&((tmp = -3110294840, tmp)|(x+(x<<(1129643420))))))+(1093795819.1853619))))+((((tmp = -2295103369.697398, tmp)&(((370501313.43019223)>>>(2465439579))/x))-x)>>x)));
+  assertEquals(0, x /= ((tmp = 1779625847, tmp)+(tmp = -662459654.6908865, tmp)));
+  assertEquals(0, x -= x);
+  assertEquals(0, x %= ((tmp = 2723291421, tmp)|(277246502.4027958)));
+  assertEquals(0, x ^= (((-2936270162)>>>((((tmp = -2019015609.1648235, tmp)|(47218153))*(-823685284))+x))&(x<<(x*(x|(((tmp = -941955398, tmp)^(tmp = -2365238993.5300865, tmp))-(778674685)))))));
+  assertEquals(0, x >>>= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x &= (-175235975.8858137));
+  assertEquals(-2684493800.1062117, x += (tmp = -2684493800.1062117, tmp));
+  assertEquals(-1290806265.6063132, x -= (-1393687534.4998984));
+  assertEquals(-1290806265, x >>= (((x>>(tmp = -1710112056.4935386, tmp))*(586227650.2860553))<<(tmp = -2918251533.6052856, tmp)));
+  assertEquals(23470008, x >>>= x);
+  assertEquals(1668734969, x |= ((-295560682.9663689)^(x|((((tmp = -1183847364, tmp)&(3135327694))+(1679127747.1406744))-((-1895825528)%((tmp = -3180115006, tmp)+((tmp = 2373812187, tmp)|x)))))));
+  assertEquals(1744306169, x |= (1188503928.5009093));
+  assertEquals(1744306169, x %= (tmp = -2723982401.4997177, tmp));
+  assertEquals(3488612338, x += x);
+  assertEquals(3488612337, x += (((x/(-325849204))>>x)|(-1820624550.9149108)));
+  assertEquals(-1511119305, x ^= (tmp = 1778506182.2952862, tmp));
+  assertEquals(-12211415, x %= (x^(tmp = -54943035, tmp)));
+  assertEquals(-12211415, x %= ((-1267051884)%(-643566443.0122576)));
+  assertEquals(-30.84976063258681, x /= (((1052047194)>>>x)&(1495698235.5117269)));
+  assertEquals(-61.69952126517362, x += x);
+  assertEquals(-244, x <<= (x^(x+(tmp = -2822258210.076373, tmp))));
+  assertEquals(-6652, x &= ((tmp = 2593685093, tmp)>>((((2047688852.4609032)<<((x*(-611076291))*x))^(-2665364024.817528))>>>(165267874))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x /= (2454186758));
+  assertEquals(0, x &= (tmp = -2226895206, tmp));
+  assertEquals(0, x += x);
+  assertEquals(-21390701, x += ((-1369004846.0816503)>>(tmp = -2661552634.039692, tmp)));
+  assertEquals(-0.012568536912921919, x /= (1701924507.856429));
+  assertEquals(7.09517966608176e-11, x /= (tmp = -177141911.8955555, tmp));
+  assertEquals(0, x >>= (tmp = 231535697, tmp));
+  assertEquals(1383687797, x ^= (tmp = -2911279499.568808, tmp));
+  assertEquals(1383687797, x %= (tmp = -2258636646.5294995, tmp));
+  assertEquals(1319, x >>= ((tmp = -2549411892.8426056, tmp)/(((((1532476676)^(153720871.82640445))+x)/(((2988190456.3206205)&(tmp = -2920873674, tmp))-(((((tmp = -1044518167.0581458, tmp)>>x)-((((tmp = -194701879.13505793, tmp)&(498352051))&((tmp = -2167339635.6529818, tmp)^(((x>>(tmp = 700159851, tmp))*(tmp = 2874921158, tmp))/x)))-((2856128689)|((-1876321441)>>>(2110732915)))))^((((tmp = -193379494.18825436, tmp)/(-3055182489.533142))<<x)+((tmp = -2286109605, tmp)>>(tmp = 698475484.3987849, tmp))))^(3182231653.500364))))|(((tmp = -194670835, tmp)>>>((786780139)%(((2114171416.2305853)^(1703145352.8143656))/x)))>>>((tmp = -3029462067, tmp)>>((67647572.02624655)&(x*(-2394283060))))))));
+  assertEquals(13903855, x |= ((tmp = -2515306586, tmp)>>>x));
+  assertEquals(54311, x >>>= ((-2413722658)-((tmp = -2159787584, tmp)^(tmp = 949937622.9744623, tmp))));
+  assertEquals(108622, x += x);
+  assertEquals(1250717187, x ^= ((tmp = 842692148, tmp)+(((2649331689.694273)<<x)-(tmp = -2992181273, tmp))));
+  assertEquals(4536777, x %= (tmp = 73304730, tmp));
+  assertEquals(0, x -= x);
+  assertEquals(-580081499, x ^= ((tmp = -580081499.0170684, tmp)^(x%(tmp = -1542730817.88261, tmp))));
+  assertEquals(-1382738784, x <<= x);
+  assertEquals(-1382738784, x <<= x);
+  assertEquals(2912228512, x >>>= (x*(x>>>x)));
+  assertEquals(-1076374105, x |= (2589443367));
+  assertEquals(-0.2818750938197037, x /= (((tmp = -1559525732.9603848, tmp)|(-477068917.5483327))>>>((-688616257)*((((tmp = -1192490153.1226473, tmp)*(-502280624.0265591))<<(-442688727.4881985))%(x+(((((tmp = -2948836853.831935, tmp)-(tmp = -2850398330.910424, tmp))>>>(x>>>(-1947835558)))^x)+(x*x)))))));
+  assertEquals(2032826546, x |= (tmp = 2032826546.819327, tmp));
+  assertEquals(3408404827.14316, x += (tmp = 1375578281.1431599, tmp));
+  assertEquals(258183922.14315987, x %= (tmp = 350024545, tmp));
+  assertEquals(479694848, x <<= (tmp = -481187157, tmp));
+  assertEquals(-2147483648, x <<= (((tmp = -2956588045.472398, tmp)>>>(((tmp = -1838455399.1775856, tmp)&(((((tmp = -637547, tmp)/x)&(x^((-44876328.1767962)+(((-2059598286)-(1071496688))%(tmp = -1492254402, tmp)))))-(x%x))*(x|x)))>>(1226250760)))<<x));
+  assertEquals(-2288163338.9020815, x -= (140679690.9020816));
+  assertEquals(4954833118513997000, x *= (-2165419327.4906025));
+  assertEquals(1578331238, x ^= (-2410854298.2270393));
+  assertEquals(-810627292, x += (-2388958530));
+  assertEquals(-810627292, x ^= ((1495296640.4087524)/(tmp = 1561790291, tmp)));
+  assertEquals(657116606535253200, x *= x);
+  assertEquals(0.675840332689047, x %= (((-1816548473)^(((tmp = -151918689.19451094, tmp)|(1819911186.535233))/((((((1514297447)+(tmp = 856485190.9684253, tmp))&(((1809369464.4363992)<<(493538496))*x))+((x*(x>>(x&(tmp = 222293461, tmp))))>>>(((784519621)|x)^((-580766922)>>(tmp = -947264116, tmp)))))>>>((((2794210354.22964)>>>(((2896952532.0183973)*((x+(tmp = -1813175940, tmp))<<(tmp = -1302618293, tmp)))&x))>>(x-(((x|((1456466890.1952953)*x))^(-169979758.19158387))-(x-x))))>>x))&(tmp = 2671604078.3026733, tmp))))/(-1701675745)));
+  assertEquals(0.675840332689047, x %= ((tmp = 2421871143, tmp)^x));
+  assertEquals(NaN, x %= ((((tmp = 1175526323.433271, tmp)+(tmp = 2813009575.952405, tmp))%((tmp = -3112133516.3303423, tmp)&x))&((((((-424329392)^(tmp = 1430146361, tmp))+x)-(1533557337.268306))%((tmp = -3117619446, tmp)-(-3127129232)))>>>x)));
+  assertEquals(NaN, x += x);
+  assertEquals(0, x >>>= ((1710641057.7325037)%(104961723.56541145)));
+  assertEquals(0, x <<= (tmp = -970072906, tmp));
+  assertEquals(0, x *= (87768668));
+  assertEquals(-1464968122, x ^= (tmp = -1464968122, tmp));
+  assertEquals(-1467983895, x ^= ((tmp = -1204896021, tmp)>>>(((91792661)&(x>>>(((-2364345606)>>>x)*x)))+x)));
+  assertEquals(2.991581508270506, x /= (-490704963.5591147));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>= ((tmp = 639854873, tmp)%(tmp = 743486160.3597239, tmp)));
+  assertEquals(0, x <<= (tmp = 1045577245.3403939, tmp));
+  assertEquals(0, x >>= ((tmp = -1932462290, tmp)|(tmp = 1629217987, tmp)));
+  assertEquals(517617438, x ^= ((tmp = 2737789043, tmp)%(tmp = -2220171604.135681, tmp)));
+  assertEquals(126371, x >>>= ((tmp = 205210223.69909227, tmp)-(tmp = 598118404, tmp)));
+  assertEquals(918548455, x |= ((918228734.8363427)+(x+x)));
+  assertEquals(918548455, x |= ((tmp = 599828198, tmp)>>((tmp = -851081330, tmp)|(tmp = -1152596996.8443217, tmp))));
+  assertEquals(918548443.7739062, x -= ((tmp = 1497642976.2260938, tmp)%(x>>(tmp = -548469702.5849569, tmp))));
+  assertEquals(0.7739062309265137, x %= (x&x));
+  assertEquals(2317939163.8239403, x *= (tmp = 2995116296, tmp));
+  assertEquals(1014415360, x <<= (-279972114));
+  assertEquals(0, x &= ((296810932)/(x*(tmp = -2750499950, tmp))));
+  assertEquals(0, x *= (x%((126285451.05086231)>>>(x*(tmp = -2789790532, tmp)))));
+  assertEquals(0, x >>>= ((975695102.5771483)%(x-((-1011726540)-((tmp = 2223194882, tmp)/x)))));
+  assertEquals(-1747794584, x |= (-1747794584.3839395));
+  assertEquals(-543544679, x %= (tmp = -1204249905, tmp));
+  assertEquals(-543544679, x %= (-881024001));
+  assertEquals(1, x /= x);
+  assertEquals(-1879376393, x |= ((tmp = 161643764, tmp)|(tmp = 2281346499.9084272, tmp)));
+  assertEquals(1.321124264431369, x /= (-1422558379.7061746));
+  assertEquals(1, x >>>= (x&(tmp = -963118950.4710281, tmp)));
+  assertEquals(3, x ^= ((x+x)/x));
+  assertEquals(1, x /= x);
+  assertEquals(1, x &= (2090796073));
+  assertEquals(-1284301873, x ^= (((-11041168.146357536)+(tmp = -1273260707.8134556, tmp))+x));
+  assertEquals(292559045, x &= (x&((-2401110739)^((tmp = 630802904, tmp)^(((1012634447.0346229)+x)%((tmp = -1240091095, tmp)%(x/(-1483936527))))))));
+  assertEquals(0, x %= x);
+  assertEquals(0, x /= (tmp = 613145428.3653506, tmp));
+  assertEquals(0, x /= ((x-(tmp = 3116638456, tmp))*(-973300716)));
+  assertEquals(0, x %= (tmp = -1794741286.0464535, tmp));
+  assertEquals(0, x &= x);
+  assertEquals(0, x >>= (-551370105.0746605));
+  assertEquals(-1471996874, x ^= ((2822970422.2331414)-x));
+  assertEquals(-277914313, x |= (tmp = -818980601.2544096, tmp));
+  assertEquals(-34, x >>= x);
+  assertEquals(305422768, x -= (-305422802));
+  assertEquals(-2406146240, x += (tmp = -2711569008, tmp));
+  assertEquals(1073745408, x &= (tmp = -3046625618, tmp));
+  assertEquals(1073745408, x <<= ((-1234108306.7646303)<<((-233519302)|x)));
+  assertEquals(1073745408, x %= (tmp = 1898831268, tmp));
+  assertEquals(1073745408, x <<= (((tmp = 3089406038, tmp)/x)&(-2960027680)));
+  assertEquals(65536, x >>>= (2858188366));
+  assertEquals(128, x >>>= ((-2640257239.857275)%((tmp = -3185405235.3177376, tmp)*x)));
+  assertEquals(128, x >>>= x);
+  assertEquals(128, x -= (x&(x-(tmp = -247588018, tmp))));
+  assertEquals(81616906825.07776, x *= (tmp = 637632084.57092, tmp));
+  assertEquals(78860097686.07776, x -= (((1507215684)^((709254783)+(((x<<x)*((-2890828152.667641)%(2537817529.2041526)))^x)))+(3114024487)));
+  assertEquals(-2920545695.721283, x += (((tmp = -2555437435, tmp)>>>x)-((2920546109.72129)+x)));
+  assertEquals(-2879412281.721283, x += ((-1662428756)>>>(tmp = -1928491386.6926208, tmp)));
+  assertEquals(67403845, x &= (tmp = 2921644117, tmp));
+  assertEquals(16850961, x >>>= (((-1039328365)>>>(tmp = -768615112, tmp))<<((1037261855)*(tmp = -2906902831.4797926, tmp))));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x *= ((-2729056530)/((-1776175111)%(1493002300.4604707))));
+  assertEquals(0, x *= (tmp = 370696035.22912216, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x |= ((((((tmp = -1541196993, tmp)^x)/(854730380.1799632))/(2879117705.492209))+((((-2892068577)^(-2460614446.1044483))>>>((743413943)<<(-1285280084.4220598)))/(tmp = -1719994579.5141463, tmp)))%(((((tmp = 2522797851.088227, tmp)<<(tmp = 2257160597.1538725, tmp))/(-680406007))&((x>>>(tmp = -260350730, tmp))^(tmp = 1920522110.852598, tmp)))>>(-697620442))));
+  assertEquals(0, x &= x);
+  assertEquals(-591399642.958673, x += (x-(tmp = 591399642.958673, tmp)));
+  assertEquals(27, x >>>= (tmp = -726721317.2109983, tmp));
+  assertEquals(-2043736843, x -= (2043736870));
+  assertEquals(-3991674, x >>= (tmp = 1098126089, tmp));
+  assertEquals(-997919, x >>= ((x%(((x*(((-1497329257.1781685)%(2334511329.2690516))/(-3072526140.6635056)))+(-1843998852))-(tmp = 240300314.34070587, tmp)))+(714080860.6032693)));
+  assertEquals(-0, x %= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x >>= (tmp = 538348328.5363884, tmp));
+  assertEquals(0, x *= (800317515));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>= (984205514));
+  assertEquals(857282491, x += (tmp = 857282491, tmp));
+  assertEquals(587792897, x &= (tmp = 2951307845.164059, tmp));
+  assertEquals(595301269, x |= (tmp = 24285588.90314555, tmp));
+  assertEquals(1190602538, x += x);
+  assertEquals(0, x -= x);
+  assertEquals(-442423060, x |= ((x^((x-(tmp = 2342497475.637024, tmp))%(-1900074414.7678084)))|((tmp = 1932380130, tmp)%(x%(2291727569.817062)))));
+  assertEquals(-442423060, x %= (((tmp = 703479475.545413, tmp)>>(x-x))<<(2435723056.753845)));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>= x);
+  assertEquals(-1265317851, x |= (tmp = -1265317851, tmp));
+  assertEquals(-2, x >>= (-2015895906.8256726));
+  assertEquals(-0, x %= x);
+  assertEquals(-0, x %= (((1219237746)+(284683029))*(((tmp = 2288119628, tmp)|(-404658161.2563329))*(-265228691.74142504))));
+  assertEquals(1039509109, x -= (-1039509109));
+  assertEquals(2079018218, x += x);
+  assertEquals(-1979.9362673719077, x /= ((3219723500)>>x));
+  assertEquals(-62, x >>= ((x/(326466691))*(tmp = -607654070, tmp)));
+  assertEquals(-45, x |= (tmp = -2954888429.549882, tmp));
+  assertEquals(-1180929712, x &= (3114037588.570232));
+  assertEquals(815550480, x &= (-2302684143.3378315));
+  assertEquals(815550480, x %= (-2177479570));
+  assertEquals(815550480, x %= (tmp = 2895822167, tmp));
+  assertEquals(815550480, x %= (-1247621230.5438688));
+  assertEquals(283929811, x -= ((tmp = 251831053.17096448, tmp)|((tmp = 1140463506.004994, tmp)+(tmp = -743224673.546309, tmp))));
+  assertEquals(1825767424, x <<= (((tmp = 1732353599, tmp)^(tmp = 658726044, tmp))>>>((-2827889370.932477)%(tmp = 1950139204.3291233, tmp))));
+  assertEquals(1828450414, x |= (tmp = 1618538606, tmp));
+  assertEquals(0, x <<= (-2411670689.045702));
+  assertEquals(0, x <<= (-27744888.428537607));
+  assertEquals(-0, x /= (tmp = -1597552450, tmp));
+  assertEquals(0, x >>>= (((2165722776.7220936)>>>(tmp = 1233069931, tmp))>>>(-1120420811)));
+  assertEquals(-0, x *= ((tmp = -1505252656, tmp)>>((((3035637099.6156535)&((467761577.7669761)>>(-361034537)))^(tmp = -2347994840.6541123, tmp))*(tmp = -2191739821, tmp))));
+  assertEquals(0, x &= (795727404.0738752));
+  assertEquals(-0, x *= (tmp = -3125944685.3991394, tmp));
+  assertEquals(-0, x *= (x&x));
+  assertEquals(0, x >>= ((tmp = -2045709233, tmp)^x));
+  assertEquals(NaN, x /= (x>>(x/(3102894071))));
+  assertEquals(NaN, x += ((tmp = 2149079756.8941655, tmp)-(tmp = 810121645.305179, tmp)));
+  assertEquals(0, x >>>= (-859842989));
+  assertEquals(0, x >>>= (tmp = 2530531143.9369526, tmp));
+  assertEquals(0, x >>= (((-932981419.6254237)|(tmp = 1591591715, tmp))>>>(x+((3149795006)>>>(tmp = 613352154, tmp)))));
+  assertEquals(-4294967295, x -= ((((-2289331668)%(-282648480.0078714))>>(-1373720705.5142756))>>>((tmp = 15511563.517014384, tmp)/(360279080))));
+  assertEquals(1, x &= x);
+  assertEquals(0, x >>= (x^(-2791872557.5190563)));
+  assertEquals(0, x &= ((tmp = 336466956.7847167, tmp)>>((1235728252.053619)|(x<<((1828176636.13488)%x)))));
+  assertEquals(-0, x *= (-364042830.8894656));
+  assertEquals(0, x >>>= x);
+  assertEquals(-1675298680, x |= ((2323049541.321387)+(296619075)));
+  assertEquals(-0, x %= x);
+  assertEquals(-1583048579.4420977, x += (-1583048579.4420977));
+  assertEquals(0, x -= x);
+  assertEquals(-2, x ^= ((603171992.0545617)/(((-271888695.718297)%(tmp = -400159585, tmp))^((((tmp = 1536123971, tmp)-(tmp = -2310418666.6243773, tmp))|((tmp = 2242779597.1219435, tmp)<<(tmp = 1758127684.4745512, tmp)))/x))));
+  assertEquals(-2, x &= (x&x));
+  assertEquals(0, x &= ((tmp = -1098806007.4049063, tmp)/(((2862384059.3229523)/((((tmp = -92960842, tmp)-(x>>(tmp = 1244068344.2269042, tmp)))&x)*(tmp = -1919148313, tmp)))<<(-2486665929))));
+  assertEquals(0, x &= x);
+  assertEquals(-1441272634.582818, x -= (1441272634.582818));
+  assertEquals(-3, x >>= (tmp = 3186393693.7727594, tmp));
+  assertEquals(-1206855850, x ^= (((tmp = 607979495.303539, tmp)-(tmp = -2480131951, tmp))^(x*((tmp = 1324153477, tmp)/((1248126288)+(x|(1917331780.0741704)))))));
+  assertEquals(-1206855853, x ^= (x>>>(653288765.1749961)));
+  assertEquals(-1206857725, x &= (3149461539.6019173));
+  assertEquals(3088109571, x >>>= (x*(x<<(tmp = 1543540084, tmp))));
+  assertEquals(536903680, x &= (tmp = 644851760, tmp));
+  assertEquals(536903674.312194, x += (((-3183290076)-((tmp = 40738191.12097299, tmp)-x))/((x>>>(3151371851.9408646))^(tmp = 472698205.22445416, tmp))));
+  assertEquals(2127424750.0506563, x -= (tmp = -1590521075.7384624, tmp));
+  assertEquals(2127424750.0506563, x %= (tmp = 3027273433.361373, tmp));
+  assertEquals(0, x >>= (x>>(1445204441.702043)));
+  assertEquals(NaN, x %= (x<<x));
+  assertEquals(0, x ^= ((tmp = -2903841152.136344, tmp)-(x%(2938662860))));
+  assertEquals(0, x <<= (x<<x));
+  assertEquals(0, x >>>= (tmp = -979481631.33442, tmp));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x &= (((x%((((((tmp = 1657446354.6820035, tmp)>>(-1916527001.2992697))/x)>>(tmp = 1450467955, tmp))&(277676820))+(x/(-945587805))))/((tmp = -690095354, tmp)^x))+(tmp = -2651195021, tmp)));
+  assertEquals(0, x <<= (752343428.2934296));
+  assertEquals(0, x /= (tmp = 3022310299, tmp));
+  assertEquals(0, x >>= (x%((388245402)>>>x)));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x %= ((tmp = 1205123529.8649468, tmp)>>>(-2848300932)));
+  assertEquals(0, x >>= ((x>>>x)<<(tmp = 487841938, tmp)));
+  assertEquals(0, x *= (((273436000.9463471)|(tmp = 141134074.27978027, tmp))^(tmp = 1220326800.7885802, tmp)));
+  assertEquals(1525600768, x |= (((x^(-2674777396))-(tmp = 1966360716.3434916, tmp))<<(794782595.9340223)));
+  assertEquals(761927595, x %= (tmp = -763673173, tmp));
+  assertEquals(1.1353588586934338, x /= ((x&((-1897159300.4789193)*(-348338328.0939896)))&(978680905.6470605)));
+  assertEquals(8.631173314966319e-10, x /= (1315416592));
+  assertEquals(0, x >>= ((tmp = -2581239435, tmp)-((-628818404.1122074)<<x)));
+  assertEquals(0, x -= x);
+  assertEquals(0, x *= (2925158236));
+  assertEquals(0, x /= (x+(tmp = 1405531594.0181243, tmp)));
+  assertEquals(0, x *= (2712022631.230831));
+  assertEquals(0, x >>= (tmp = 80518779.81608999, tmp));
+  assertEquals(1953477932.8046472, x += (tmp = 1953477932.8046472, tmp));
+  assertEquals(1953477932, x >>= (tmp = 3025539936, tmp));
+  assertEquals(1953477932, x -= ((-2675119685.8812313)>>(x/(-1808264410.9754841))));
+  assertEquals(1292620430, x += ((-660857502)%((((tmp = -698782819, tmp)%(tmp = 2847304199, tmp))<<(-2423443217.1315413))+x)));
+  assertEquals(78895, x >>>= x);
+  assertEquals(2, x >>= x);
+  assertEquals(2, x <<= (tmp = 1313641888.8301702, tmp));
+  assertEquals(1857416935.2532766, x += (tmp = 1857416933.2532766, tmp));
+  assertEquals(-1677721600, x <<= (tmp = -2482476902, tmp));
+  assertEquals(309226853.62854385, x -= (tmp = -1986948453.6285439, tmp));
+  assertEquals(33965156, x &= (2409088742));
+  assertEquals(Infinity, x /= (x-(x<<((x/(tmp = -3106546671.536726, tmp))/((tmp = 2695710176, tmp)-((((-2102442864)&(857636911.7079853))/x)%(-65640292)))))));
+  assertEquals(1270005091, x |= (tmp = 1270005091.0081215, tmp));
+  assertEquals(1270005091, x %= (tmp = -1833876598.2761571, tmp));
+  assertEquals(158750636, x >>>= x);
+  assertEquals(-1000809106.0879555, x -= (tmp = 1159559742.0879555, tmp));
+  assertEquals(72400936, x &= ((2448271389.3097963)%(tmp = 1517733861, tmp)));
+  assertEquals(282816, x >>= x);
+  assertEquals(282816, x %= (tmp = 3192677386, tmp));
+  assertEquals(0.00021521351827207216, x /= (1314118194.2040696));
+  assertEquals(Infinity, x /= (((tmp = 2822091386.1977024, tmp)&x)%(tmp = -3155658210, tmp)));
+  assertEquals(NaN, x %= (-359319199));
+  assertEquals(0, x >>>= (((tmp = -2651558483, tmp)-(x<<(tmp = 2537675226.941645, tmp)))<<(tmp = 667468049.0240343, tmp)));
+  assertEquals(-0, x *= (tmp = -2827980482.12998, tmp));
+  assertEquals(-0, x %= (((tmp = -689972329.3533998, tmp)>>>x)|(tmp = -7488144, tmp)));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x |= x);
+  assertEquals(-2410373675.2262926, x -= (2410373675.2262926));
+  assertEquals(1840423, x >>= ((-1081642113)^x));
+  assertEquals(-4829451429403412, x *= (-2624098606.35485));
+  assertEquals(-94552231, x %= (tmp = -97015883, tmp));
+  assertEquals(-94433287, x ^= (((tmp = -2297735280, tmp)&(((tmp = 2261074987.7072973, tmp)%((((2565078998)^(-2573247878))|x)|(((tmp = -2120919004.7239416, tmp)>>(tmp = -579224101, tmp))>>>(1905808441))))*(x|(3149383322))))>>(542664972)));
+  assertEquals(0, x ^= (x<<(tmp = -3112569312, tmp)));
+  assertEquals(0, x <<= (-2141934818.7052917));
+  assertEquals(0, x >>= (tmp = -2539525922, tmp));
+  assertEquals(-434467613, x ^= (tmp = -434467613, tmp));
+  assertEquals(-274792709, x |= (1233452601.462551));
+  assertEquals(-274726917, x |= (-2130333750));
+  assertEquals(-272629761, x |= (-1516071602.5622227));
+  assertEquals(-272629761, x |= ((tmp = 3012131694, tmp)&((tmp = -2595342375.8674774, tmp)-((tmp = -2710765792, tmp)>>>((x-(tmp = 2397845540, tmp))+(2496667307))))));
+  assertEquals(-4194305, x |= (1343705633.165825));
+  assertEquals(4190207, x >>>= ((tmp = 276587830, tmp)*((tmp = -1517753936, tmp)>>x)));
+  assertEquals(0, x >>= (x|((2247486919)-((-1664642412.4710495)*((((tmp = -358185292.17083216, tmp)-(tmp = -1472193444, tmp))*(tmp = 2699733752, tmp))&((x|(x<<(1137610148.1318119)))>>(((375089690.8764564)*x)&(tmp = 859788933.9560187, tmp))))))));
+  assertEquals(0, x %= (3080673960));
+  assertEquals(0, x >>>= (1328846190.1963305));
+  assertEquals(1249447579, x |= (-3045519717.580775));
+  assertEquals(-0.8743931060971377, x /= (-1428931187));
+  assertEquals(1, x |= ((tmp = -1756877535.7557893, tmp)/((-142900015.93200803)<<(1414557031.347334))));
+  assertEquals(759627265, x ^= (759627264.0514802));
+  assertEquals(741823, x >>= (1106391210));
+  assertEquals(610451, x &= ((x>>>((919849416)+((tmp = -427708986, tmp)^((x%x)|(tmp = -2853100288.932063, tmp)))))*x));
+  assertEquals(372650423401, x *= x);
+  assertEquals(410404493, x >>>= ((((-1425086765)>>>x)>>((2813118707.914771)>>(-424850240)))^x));
+  assertEquals(120511585729013, x *= ((tmp = -1889454669, tmp)>>>x));
+  assertEquals(120513295294304.22, x -= (tmp = -1709565291.2115698, tmp));
+  assertEquals(6164, x >>>= ((2244715719.397763)^(tmp = -741235818.6903033, tmp)));
+  assertEquals(937572790.468221, x -= (tmp = -937566626.468221, tmp));
+  assertEquals(937572790, x |= ((2129102867.156146)*(x%x)));
+  assertEquals(32, x &= ((2700124055.3712993)>>>((1977241506)>>>(-2915605511))));
+  assertEquals(32, x %= (tmp = -2513825862, tmp));
+  assertEquals(0, x <<= (-1379604802));
+  assertEquals(0, x >>>= (tmp = -1033248759, tmp));
+  assertEquals(-1151517050, x ^= (3143450246));
+  assertEquals(-180577, x |= ((738373819.4081701)^(-357134176)));
+  assertEquals(-0, x %= x);
+  assertEquals(-2086887759, x |= (tmp = 2208079537, tmp));
+  assertEquals(-2, x >>= (1460216478.7305799));
+  assertEquals(-2, x %= ((-1979700249.0593133)^(-3156454032.4790583)));
+  assertEquals(-256, x <<= ((1810316926)>>>(tmp = 414362256, tmp)));
+  assertEquals(-1, x >>= (((((((-1616428585.595561)*((tmp = 2574896242.9045777, tmp)|(86659152.37838173)))>>(((tmp = 2476869361, tmp)&((x+((tmp = -2445847462.1974697, tmp)>>(tmp = -1960643509.5255682, tmp)))+(x|(((((2231574372.778028)|(tmp = 1824767560, tmp))>>>((1108035230.2692142)|(tmp = 2354035815, tmp)))/((tmp = -2602922032, tmp)>>(-925080304.7681987)))-x))))-(x>>x)))>>>((tmp = 751425805.8402164, tmp)|(tmp = 1165240270.3437088, tmp)))-x)*(2870745939))-(x>>>((tmp = 2986532631.405425, tmp)>>>(((tmp = 2547448699, tmp)+(((((x<<(((((-2756908638.4197435)>>>(3134770084))-(-1147872642.3756688))%(x*(tmp = -282198341.6600039, tmp)))+(-770969864.2055655)))+((-2725270341)^x))/(-3093925722))>>(x&x))>>((tmp = -2705768192, tmp)>>>(((tmp = 577253091.6042917, tmp)/(((x&(((((x+x)>>>(-1000588972))/(x&(717414336)))^(tmp = 428782104.21504414, tmp))>>>(1084724288.953223)))%(tmp = -2130932217.4562194, tmp))&x))-(-286367389)))))+((x>>(tmp = 2001277117, tmp))>>((tmp = 1028512592, tmp)^((tmp = 2055148650, tmp)+((tmp = 1490798399, tmp)/(tmp = -2077566434.2678986, tmp))))))))));
+  assertEquals(-1, x |= (tmp = 1542129482, tmp));
+  assertEquals(-671816743, x &= (tmp = -671816743.9111726, tmp));
+  assertEquals(-1840333080, x -= (1168516337));
+  assertEquals(-1755382023, x |= ((((tmp = 2625163636.0142937, tmp)>>>((tmp = 1534304735, tmp)^x))-(tmp = -1959666777.9995313, tmp))%x));
+  assertEquals(-1750421896, x += (x>>>(tmp = -1364828055.1003118, tmp)));
+  assertEquals(-72864007, x %= (tmp = 239651127, tmp));
+  assertEquals(-72863956, x -= (((tmp = -1103261657.626319, tmp)*((tmp = 2789506613, tmp)+((tmp = 2294239314, tmp)>>>(2588428607.5454817))))>>x));
+  assertEquals(-170337477, x -= (tmp = 97473521, tmp));
+  assertEquals(-170337477, x |= (((tmp = 246292300.58998203, tmp)/(((tmp = -2664407492, tmp)|((-2416228818)^(tmp = 909802077, tmp)))%(tmp = 532643021.68109465, tmp)))/(tmp = 1015597843.8295637, tmp)));
+  assertEquals(1, x >>>= (((tmp = -2247554641.7422867, tmp)/(1186555294))%(tmp = -785511772.3124621, tmp)));
+  assertEquals(1188939891.668705, x -= (tmp = -1188939890.668705, tmp));
+  assertEquals(1188939891, x &= x);
+  assertEquals(1188413555, x &= (((tmp = -372965330.5709038, tmp)%(((tmp = 3108909487, tmp)|(x^(-1056955571.9951684)))^(-1549217484.009048)))/(x>>>(1403428437.9368362))));
+  assertEquals(-0.7343692094664643, x /= (-1618278026.4758227));
+  assertEquals(0, x -= x);
+  assertEquals(0, x &= (-2701762139.7500515));
+  assertEquals(0, x >>>= (((-1692761485.2299166)^x)+(tmp = -1221349575.938864, tmp)));
+  assertEquals(0, x <<= ((2148160230)<<x));
+  assertEquals(0, x <<= (((x<<(-740907931.38363))&(tmp = -930960051.6095045, tmp))>>(x/((tmp = -1921545150.1239789, tmp)/(-3015379806)))));
+  assertEquals(0, x <<= x);
+  assertEquals(NaN, x /= (x|x));
+  assertEquals(0, x >>= (tmp = -2265988773, tmp));
+  assertEquals(-0, x *= (((x<<(-928153614))<<(-989694208))^(2544757713.481016)));
+  assertEquals(0, x >>= ((tmp = 578009959.5299993, tmp)>>x));
+  assertEquals(0, x /= ((((tmp = 412689800.0431709, tmp)&(1630886276))*(tmp = 2028783080.7296097, tmp))/x));
+  assertEquals(0, x |= ((((x*(-2197198786))>>((2719887264.761987)<<(tmp = 2253246512, tmp)))-(tmp = -150703768.07045603, tmp))/(((-3160098146)%(((((1486098047.843547)>>(((tmp = -593773744.1144242, tmp)&(x<<(2651087978)))|((-680492758.930413)>>(tmp = 88363052.13662052, tmp))))<<x)<<(tmp = 2232672341, tmp))/((x<<x)&(((((348589117.64135563)<<(-1010050456.3097556))^(x/(tmp = -2282328795, tmp)))-(tmp = 1653716293, tmp))-((3157124731)/((tmp = 3007369535.341745, tmp)%(tmp = -2246556917, tmp)))))))+x)));
+  assertEquals(0, x >>= ((1935211663.5568764)>>(x-(tmp = 2116580032, tmp))));
+  assertEquals(-1725272693, x ^= (tmp = -1725272693, tmp));
+  assertEquals(313683, x >>>= (-1782632531.2877684));
+  assertEquals(0.009772287443565642, x /= (tmp = 32099240, tmp));
+  assertEquals(-647945916.9902277, x += (-647945917));
+  assertEquals(3647021380, x >>>= ((((((((2470411371.688199)<<x)>>x)-(x>>>((tmp = 1750747780, tmp)/x)))-x)<<(tmp = -2666186351.695101, tmp))^(((tmp = 2749205312.6666174, tmp)%x)&(2069802830.360536)))<<(tmp = 6051917.9244532585, tmp)));
+  assertEquals(-647939220, x |= ((x>>>((tmp = -2980404582.794245, tmp)>>>(-996846982)))^x));
+  assertEquals(-572178450, x |= ((-800571300.3277931)+(tmp = 2084365671, tmp)));
+  assertEquals(1172311208, x &= (x&((tmp = -1207487657.8953774, tmp)^x)));
+  assertEquals(12176516458994, x += ((((tmp = -1534997221, tmp)%(412142731))*((tmp = 2958726303, tmp)>>(1489169839)))+(((-574726407.2051775)>>>(((1772885017)<<(947804536.9958035))>>(-2406844737)))>>x)));
+  assertEquals(-1480065024, x <<= x);
+  assertEquals(-1736999042.227129, x += (tmp = -256934018.22712898, tmp));
+  assertEquals(-1338699394, x ^= ((((((x%(((tmp = -2551168455.222048, tmp)|(3213507293.930222))/((-1559278033)>>((tmp = 3107774495.3698573, tmp)-(2456375180.8660913)))))*((x*(tmp = 1088820004.8562922, tmp))+((tmp = 1850986704.9836102, tmp)%(tmp = -1226590364, tmp))))*(1786192008))&(((2193303940.310299)%(tmp = 1041726867.0602217, tmp))|((2210722848)/((-1293401295.6714435)&((tmp = 3052430315, tmp)|x)))))>>>(tmp = -2028014470.1524236, tmp))+(((1695818039.0383925)<<((1669068145)*(-2746592133.899276)))<<(tmp = 519092169, tmp))));
+  assertEquals(-334674849, x >>= (1170377794));
+  assertEquals(-10214, x >>= ((tmp = 1074704264.3712895, tmp)>>>((tmp = -1200860192, tmp)^((tmp = 539325023.4101218, tmp)*((tmp = -588989295, tmp)|x)))));
+  assertEquals(1384169472, x &= (1384171140));
+  assertEquals(1384169472, x >>>= ((tmp = -2161405973.830981, tmp)*(tmp = 2054628644, tmp)));
+  assertEquals(1610140972, x |= (527961388));
+  assertEquals(1073273198, x += ((tmp = -259650225.71344328, tmp)&(tmp = -344359694, tmp)));
+  assertEquals(65507, x >>= ((x<<((tmp = 2925070713.5245204, tmp)%(x+((tmp = -1229447799, tmp)/(((x/(x|(((-2337139694)|((((((2996268529.7965417)&x)%(((tmp = -1088587413, tmp)>>(-1384104418.90339))>>((tmp = -1643984822.3946526, tmp)+x)))%(((1118125268.4540217)-((((-1975051668.6652594)-(-704573232))+((tmp = 1674952373, tmp)/(tmp = 1321895696.0062659, tmp)))*(tmp = 1820002533.2021284, tmp)))>>>(tmp = -583960746.9993203, tmp)))|((tmp = -2577675508.550925, tmp)&x))/(tmp = 1459790066, tmp)))/(((((1051712301.7804044)&(tmp = -2726396354, tmp))^(tmp = 263937254.18934345, tmp))+(((x^x)*(((tmp = -2289491571, tmp)+x)%(-2239181148)))&x))>>(tmp = -1743418186.3030887, tmp)))))/(tmp = 1475718622, tmp))<<x)))))|(x&((((tmp = -2934707420, tmp)<<x)/x)^(1022527598.7386684)))));
+  assertEquals(2047, x >>= (x-(tmp = 2300626270, tmp)));
+  assertEquals(8384512, x <<= (tmp = -1917680820, tmp));
+  assertEquals(0, x <<= (2393691134));
+  assertEquals(0, x >>= x);
+  assertEquals(649995936.5853252, x -= (tmp = -649995936.5853252, tmp));
+  assertEquals(649995936, x &= x);
+  assertEquals(-0.33672017582945424, x /= (tmp = -1930374188, tmp));
+  assertEquals(-0.33672017582945424, x += (x&((1208055031)^(-2761287670.968586))));
+  assertEquals(0, x |= x);
+  assertEquals(0, x <<= ((-2038368978)/x));
+  assertEquals(0, x >>= (x&((tmp = 2481378057.738218, tmp)&(x+(1172701643)))));
+  assertEquals(0, x <<= ((x*(((((((tmp = 70690601.3046323, tmp)&(((((((((((x+(x+(x^(3118107461))))<<(264682213.41888392))&(tmp = -709415381.8623683, tmp))%(((((-1840054964)>>>(tmp = -405893120.89603686, tmp))|((-625507229)^(3128979265)))>>(x>>((tmp = -2480442390, tmp)*((x>>(tmp = -421414980.88330936, tmp))>>>((tmp = 1850868592, tmp)&(-2948543832.879225))))))|((2986545185)&((tmp = -1947550706, tmp)%(((tmp = 2590238422.1414256, tmp)/(((tmp = -361038812, tmp)>>x)|(((tmp = 1798444068, tmp)|((x&((tmp = -3104542069, tmp)-x))*((tmp = -1158658918, tmp)+((tmp = 2777031040.5552707, tmp)<<(-2816019335.9008327)))))<<x)))/(((2287795988.231702)/x)/(((-2588712925)>>>(2521189250))*((tmp = -2533527920, tmp)+(tmp = 1762281307.2162101, tmp)))))))))/x)/(tmp = 1047121955.5357032, tmp))|(((-121292251)<<(x^(x-(tmp = 1420006180, tmp))))%((-2278606219)>>>(((tmp = -1412487726, tmp)&(((((tmp = 253596554.16016424, tmp)/(tmp = 2083376247.0079951, tmp))^(x^((1549116789.8449988)>>>((((-1844170084)^(tmp = 1886066422, tmp))&x)<<(34918329)))))^(tmp = -440805555.3369155, tmp))-x))%(-1936512969)))))+(2911511178.4035435))|(1012059391))|(x>>>(tmp = -2551794626.158037, tmp)))+((2926596072.210515)/(tmp = -280299595.0450909, tmp))))&((tmp = 1501086971, tmp)^(tmp = 2114076983, tmp)))-((-1679390574.1466925)-(941349044)))-((x>>x)>>((-2600539474.2033434)+(tmp = 2567056503.9079475, tmp))))*(tmp = 1285896052, tmp))%(((tmp = 1191465410.7595167, tmp)>>((tmp = -2857472754, tmp)%x))>>>(((tmp = 1960819627.6552541, tmp)&(-2651207221.127376))*((((-687312743)+((x>>x)<<x))|((((((1549588195)*((tmp = 2733091019, tmp)^((527322540)<<(x>>x))))%(tmp = -2063962943, tmp))*x)*(734060600))&(-3049417708)))+(((((1084267726)+((x|x)^((tmp = -1917070472.4858549, tmp)%((690016078.9375831)*x))))%((((((tmp = -2091172769, tmp)%(2532365378))>>>(-871354260))/(tmp = 254167019.07825458, tmp))&(1330216175.9871218))>>(tmp = 1931099207, tmp)))^(-1116448185.2618852))>>((961660080.8135855)/x)))))))>>>(-1486048007.7053368)));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x %= (tmp = -1202200444.6506357, tmp));
+  assertEquals(-0, x *= (-527500796.4145117));
+  assertEquals(0, x >>= (tmp = -2082822707, tmp));
+  assertEquals(0, x *= ((-1882398459.290778)>>>x));
+  assertEquals(0, x &= (x/(tmp = -1569332286.392817, tmp)));
+  assertEquals(-390169607, x |= (-390169607.11600184));
+  assertEquals(-780339214, x += x);
+  assertEquals(-780339214, x %= (2765959073));
+  assertEquals(-5954, x >>= (tmp = -1900007055, tmp));
+  assertEquals(743563420, x &= ((((-1520146483.5367205)|(-2075330284.3762321))-(tmp = -2263151872, tmp))%(-1264641939.957402)));
+  assertEquals(1487126840, x += (x>>>(((x+((tmp = -1263274491, tmp)>>>x))&(470419048.0490037))%(tmp = -2642587112, tmp))));
+  assertEquals(Infinity, x /= (x^x));
+  assertEquals(0, x ^= ((tmp = -1436368543, tmp)+(x/(tmp = -1125415374.3297129, tmp))));
+  assertEquals(0, x += x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x &= (tmp = 3101147204.2905564, tmp));
+  assertEquals(0, x &= (tmp = 2914487586.606511, tmp));
+  assertEquals(0, x += x);
+  assertEquals(0, x -= (((-1738542908.6138556)&(((x+x)-(tmp = -2801153969, tmp))%(tmp = -1206684064.1477358, tmp)))>>((-2575546469.271897)|(tmp = -2573119106, tmp))));
+  assertEquals(-1468808707, x ^= (tmp = -1468808707, tmp));
+  assertEquals(1357349882, x <<= (tmp = -2808501087.7003627, tmp));
+  assertEquals(-572025862, x |= ((((tmp = -2415486246.573399, tmp)/((tmp = -707895732.4593301, tmp)&x))%((-1960091005.0425267)*(972618070.9166157)))-(1649962343)));
+  assertEquals(327213586796843100, x *= (x%(1337884626)));
+  assertEquals(42991616, x &= (-2905576654.1280055));
+  assertEquals(-26049289585042860, x *= (-605915571.6557121));
+  assertEquals(597809748, x >>= ((362850791.077795)/(tmp = 1222777657.4401796, tmp)));
+  assertEquals(597809748, x |= x);
+  assertEquals(770065246, x -= ((-711227660)|(tmp = -508554506, tmp)));
+  assertEquals(593000483097040500, x *= x);
+  assertEquals(0, x %= x);
+  assertEquals(0, x <<= (317862995.456813));
+  assertEquals(0, x >>= ((tmp = 2518385735, tmp)+((-2973864605.267604)/(-930953312.718833))));
+  assertEquals(1227822411, x ^= (x^(1227822411.8553264)));
+  assertEquals(1090520320, x &= (x+((((-2100097959)>>(x/(tmp = -2002285068, tmp)))/(-364207954.9242482))-((tmp = 2771293106.7927113, tmp)-(tmp = -847237774, tmp)))));
+  assertEquals(1090520320, x >>= (((((2439492849)<<((-2932672756.2578926)*((743648426.7224461)+((2942284935)<<((x/(((tmp = 886289462.6565771, tmp)+(-459458622.7475352))>>(tmp = -785521448.4979162, tmp)))|(tmp = -11630282.877367258, tmp))))))-(tmp = -647511106.9602091, tmp))^x)&x));
+  assertEquals(115944291.48829031, x %= (243644007.12792742));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>>= ((tmp = -819782567, tmp)%(tmp = 2774793208.1994505, tmp)));
+  assertEquals(0, x >>= (tmp = 721096000.2409859, tmp));
+  assertEquals(0, x &= ((x%x)%x));
+  assertEquals(-0, x *= ((-1670466344)<<x));
+  assertEquals(0, x >>= (-677240844.904707));
+  assertEquals(NaN, x %= (((((-1575993236.6126876)/(-2846264078.9581823))^((((-2220459664)-(((-1809496020)>>>(tmp = -3015964803.4566207, tmp))&x))/(tmp = -3081895596.0486784, tmp))>>>(x&x)))%(x^(-1338943139)))^(x-((((2074140963.2841332)^(tmp = 1878485274, tmp))%(((x/(-2568856967.6491556))^x)<<((x+x)^((((2139002721)|(x<<(-1356174045.840464)))>>x)-(tmp = 2305062176, tmp)))))>>>(((((x<<(tmp = -1663280319.078543, tmp))-((1498355849.4158854)-((-1321681257)>>>(tmp = -1321415088.6152222, tmp))))^(-2266278142.1584673))+(858538943))&((((x-((x|(((tmp = -1576599651, tmp)+((tmp = 1595319586, tmp)&(-2736785205.9203863)))>>((x+((-1856237826)+x))<<(tmp = -1590561854.3540869, tmp))))^(((-41283672.55606127)&(tmp = 2971132248, tmp))+x)))/(-849371349.1667476))%(x*((-1705070934.6892798)>>>x)))<<((2418200640)*x)))))));
+  assertEquals(0, x >>>= (tmp = 664214199.5283061, tmp));
+  assertEquals(0, x <<= ((-2827299151)<<(1815817649)));
+  assertEquals(1405772596, x |= (tmp = 1405772596, tmp));
+  assertEquals(-1483422104, x <<= (-2791499935.6822596));
+  assertEquals(-45271, x >>= (1740128943.4254808));
+  assertEquals(-45271, x <<= ((2072269957)-((tmp = -2553664811.4472017, tmp)*(tmp = -2502730352, tmp))));
+  assertEquals(1192951471.6745887, x -= (-1192996742.6745887));
+  assertEquals(-353370112, x <<= (tmp = -1410280844, tmp));
+  assertEquals(0, x ^= (x%((2754092728)*(-1017564599.1094015))));
+  assertEquals(-2662096003.2397957, x -= (tmp = 2662096003.2397957, tmp));
+  assertEquals(-2587094028.50764, x -= (tmp = -75001974.7321558, tmp));
+  assertEquals(6693055512339889000, x *= x);
+  assertEquals(897526784, x %= (x-((tmp = 897526813, tmp)%(-1525574090))));
+  assertEquals(7011928, x >>= ((-440899641.344357)%x));
+  assertEquals(8382047686388683, x += (x*(1195398423.8538609)));
+  assertEquals(16764095372777366, x += x);
+  assertEquals(16764096859576696, x -= (tmp = -1486799329.7207344, tmp));
+  assertEquals(16764099774187724, x += (2914611029));
+  assertEquals(16764102926624664, x -= (-3152436939.724612));
+  assertEquals(-538220648, x |= x);
+  assertEquals(269110324, x /= (((-2114698894.6014318)/(tmp = 767687453, tmp))>>(623601568.1558858)));
+  assertEquals(256, x >>= x);
+  assertEquals(-293446891, x += (x+(-293447403)));
+  assertEquals(119, x >>>= ((1759400753)>>(2481263470.4489403)));
+  assertEquals(14, x >>= (762849027.89693));
+  assertEquals(16, x += (x&(x>>(1104537666.1510491))));
+  assertEquals(-12499808227.980995, x *= (tmp = -781238014.2488122, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(1, x &= x);
+  assertEquals(0, x >>>= ((tmp = 1513381008, tmp)|(tmp = 1593208075.7259543, tmp)));
+  assertEquals(0, x &= (-788154636.2843091));
+  assertEquals(-0, x /= (tmp = -2124830879, tmp));
+  assertEquals(0, x &= (934237436));
+  assertEquals(0, x |= x);
+  assertEquals(-79370942.97651315, x += (-79370942.97651315));
+  assertEquals(-79370942.97651315, x %= ((tmp = -2683255523, tmp)<<(tmp = 2323123280.287587, tmp)));
+  assertEquals(-79370942, x |= x);
+  assertEquals(0.05861647801688159, x /= (-1354072177.061561));
+  assertEquals(0, x <<= (((((((tmp = 1989257036, tmp)&(tmp = 1565496213.6578887, tmp))&x)&(tmp = -2798643735.905287, tmp))&(2354854813.43784))%(tmp = 1118124748, tmp))<<((tmp = 2453617740, tmp)*(((tmp = 1762604500.492329, tmp)<<(-2865619363))%(((2474193854.640994)|((tmp = 1425847419.6256948, tmp)|(((-1271669386)%((x|((tmp = -2059795445.3607287, tmp)+x))*(x*x)))>>>(tmp = -2997360849.0750895, tmp))))/(tmp = 2326894252, tmp))))));
+  assertEquals(0, x >>>= ((-671325215)/((-727408755.8793397)>>(tmp = 315457854, tmp))));
+  assertEquals(0, x >>= (x&x));
+  assertEquals(0, x <<= ((x/x)>>>(((((x&x)-((x*(((tmp = -2689062497.0087833, tmp)^x)/((-1465906334.9701924)<<(tmp = -349000262, tmp))))*x))%(1630399442.5429945))*x)+((tmp = 605234630, tmp)%(tmp = 2325750892.5065155, tmp)))));
+  assertEquals(0, x |= (x%((x>>(((((tmp = 1622100459, tmp)<<x)&((((((tmp = 2411490075, tmp)<<x)|x)>>((x<<x)-(-2133780459)))/x)&(x+x)))%(x/((((tmp = 580125125.5035453, tmp)>>>(-470336002.1246581))|((tmp = 871348531, tmp)*x))>>(2866448831.23781))))-((2352334552)-(-562797641.6467373))))-(x^(tmp = -681731388, tmp)))));
+  assertEquals(0, x <<= (tmp = -1358347010.3729038, tmp));
+  assertEquals(-260967814, x |= ((tmp = -260967814.45976686, tmp)%(tmp = 1126020255.1772437, tmp)));
+  assertEquals(NaN, x %= ((((tmp = 3176388281, tmp)<<(tmp = 611228283.2600244, tmp))>>>((tmp = 3068009824, tmp)+(tmp = 2482705111, tmp)))>>>((tmp = -750778285.2580311, tmp)>>>x)));
+  assertEquals(0, x <<= (x>>>x));
+  assertEquals(0, x /= (1238919162));
+  assertEquals(0, x >>= (x^x));
+  assertEquals(0, x &= (-2137844801));
+  assertEquals(0, x >>>= (x^(x*(-1774217252))));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x |= x);
+  assertEquals(0, x &= (x<<(tmp = 2791377560, tmp)));
+  assertEquals(-1330674638.8117397, x += (tmp = -1330674638.8117397, tmp));
+  assertEquals(353, x >>>= (-212202857.4320326));
+  assertEquals(353, x ^= ((((x+(tmp = 1448262278, tmp))-(-3141272537))>>(tmp = 1116596587.7832575, tmp))>>>((x-(((tmp = 303953098, tmp)>>>((tmp = 691514425, tmp)/((176223098)*(((2876180016)%(-1805235275.892374))|x))))<<(((tmp = 528736141.838547, tmp)^(2556817082))*(2898381286.2846575))))|((-1445518239)&(tmp = 389789481.9604758, tmp)))));
+  assertEquals(0, x >>>= (-227376461.14343977));
+  assertEquals(0, x <<= (tmp = -2575967504, tmp));
+  assertEquals(0, x <<= (x^((-2668391896)>>((x+(tmp = 598697235.9205595, tmp))+((((-2105306785)|((-1174912319.794015)>>>(x-((148979923)%((((tmp = -2459140558.4436393, tmp)|(1265905916.494016))^(tmp = 1213922357.2230597, tmp))|(1028030636))))))%x)+(((tmp = 1393280827.0135512, tmp)^((tmp = 1210906638, tmp)+(-1572777641.1396031)))<<x))))));
+  assertEquals(0, x *= (tmp = 2134187165, tmp));
+  assertEquals(-1084549964, x -= (tmp = 1084549964, tmp));
+  assertEquals(-2045706240, x &= ((tmp = -1250758905.7889671, tmp)*(x+(((x<<(x/(tmp = -738983664.845448, tmp)))>>>x)&(tmp = 2197525295, tmp)))));
+  assertEquals(-2045706240, x ^= (((522049712.14743733)>>(tmp = -2695628092, tmp))>>>(tmp = -2603972068, tmp)));
+  assertEquals(2249261056, x >>>= x);
+  assertEquals(-33291, x |= ((((1891467762)<<(184547486.213719))-((458875403.50689447)^(((x&(x*x))|x)%(-3127945140))))|(-100765232)));
+  assertEquals(-33291, x %= (1460486884.1367688));
+  assertEquals(-1, x >>= (tmp = -2667341441, tmp));
+  assertEquals(-3.6289151568259606e-10, x /= (tmp = 2755644474.4072013, tmp));
+  assertEquals(-3.6289151568259606e-10, x %= (tmp = 1186700893.0751028, tmp));
+  assertEquals(0, x <<= (tmp = -1199872107.9612694, tmp));
+  assertEquals(371216449, x ^= ((tmp = 371324611.1357789, tmp)&(x-(x|((tmp = -518410357, tmp)>>((tmp = 687379733, tmp)/x))))));
+  assertEquals(0.3561383159088311, x /= (((((x%(((((-2293101242)%((((495316779)/x)-((-3198854939.8857965)>>>((tmp = -288916023, tmp)-(x^(tmp = -2504080119.431858, tmp)))))^(-1201674989)))-((2965433901)*(405932927)))/((1974547923)|(tmp = 534069372, tmp)))-(x-((x+(-1258297330))%x))))<<(((-2648166176.4947824)^(-3043930615))&(1550481610)))<<(tmp = -3118264986.743822, tmp))<<x)|x));
+  assertEquals(-46272499.15029934, x -= (tmp = 46272499.50643766, tmp));
+  assertEquals(-6, x >>= ((tmp = -731454087.0621192, tmp)>>>x));
+  assertEquals(-2.7207928474520667e-9, x /= (((x<<(x|((tmp = -1650731700.9540024, tmp)/(tmp = -677823292, tmp))))^((((((1972576122.928667)>>x)%(2952412902.115453))<<((-2888879343)+(tmp = -425663504, tmp)))>>>(((((tmp = 1089969932, tmp)>>>(x|((-2088509661)/(1131470551))))>>>x)+x)|(tmp = 955695979.7982506, tmp)))|(((((tmp = 826954002.6188571, tmp)^(2016485728))|((x/(((x<<(tmp = 2493217141, tmp))/(-2259979800.997408))-(tmp = -427592173.41389966, tmp)))%(((-471172918)/x)>>>((383234436.16425097)&(tmp = 1664411146.5308032, tmp)))))*(tmp = 1863669754.7545495, tmp))*(x>>(2062197604)))))>>>((x-(2624545856))*(tmp = 1025803102, tmp))));
+  assertEquals(0, x >>= ((tmp = 1068702028, tmp)*(296106770)));
+  assertEquals(0, x ^= (x/x));
+  assertEquals(85359536, x ^= (((x|(((tmp = 740629227, tmp)<<(-1107397366))%((tmp = 2315368172, tmp)>>(((-2269513683)|(-2698795048))+(-396757976)))))*(929482738.803125))^(((-1415213955.4198723)-(tmp = -2885808324, tmp))>>>((tmp = -472842353.85736656, tmp)&(tmp = 1684231312.4497018, tmp)))));
+  assertEquals(2075131904, x <<= x);
+  assertEquals(123, x >>>= (x>>>(tmp = 754093009, tmp)));
+  assertEquals(0, x >>= ((-2690948145)/((1988638799)+x)));
+  assertEquals(0, x >>>= (tmp = -798849903.2467625, tmp));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x *= (2431863540.4609756));
+  assertEquals(484934656, x |= ((-2322193663)*(tmp = -2754666771, tmp)));
+  assertEquals(-82505091404694530, x *= (tmp = -170136513, tmp));
+  assertEquals(-82505090515370620, x += ((-148762237)&(tmp = 889417717, tmp)));
+  assertEquals(-908221124, x %= (tmp = -2346393300, tmp));
+  assertEquals(-1242515799, x ^= (2083328917));
+  assertEquals(-1126056310271520600, x *= ((((tmp = -3065605442, tmp)<<(-3012703413))|x)^(-2081329316.4781387)));
+  assertEquals(-1126056309941068000, x += ((((tmp = 1886925157, tmp)&((tmp = -163003119.31722307, tmp)/((tmp = 2094816076, tmp)>>((tmp = -706947027, tmp)^x))))^((1819889650.5261197)<<(-1641091933)))>>x));
+  assertEquals(-1864360191, x |= (((x/x)|x)|x));
+  assertEquals(-1864360191, x &= x);
+  assertEquals(-3728720382, x += x);
+  assertEquals(1042663165, x ^= (535165183.4230335));
+  assertEquals(2644530017.8833704, x += (1601866852.8833704));
+  assertEquals(-574949401, x |= ((tmp = 943193254.5210983, tmp)^((x%(tmp = -2645213497, tmp))*(-1904818769))));
+  assertEquals(1763223578, x ^= ((x^(tmp = -2244359016, tmp))^(tmp = 320955522, tmp)));
+  assertEquals(-1.9640961474334235, x /= (tmp = -897727731.0502782, tmp));
+  assertEquals(1, x >>>= (x-(-3183031393.8967886)));
+  assertEquals(1, x &= (tmp = 1732572051.4196641, tmp));
+  assertEquals(1, x >>= (-1642797568));
+  assertEquals(-2339115203.3140306, x += (-2339115204.3140306));
+  assertEquals(1955852093, x ^= (((((-1469402389)/(-2648643333.1454573))>>>x)<<(x/x))>>x));
+  assertEquals(-965322519, x ^= (3001399252));
+  assertEquals(-2139727840, x &= (tmp = 2298411812.964484, tmp));
+  assertEquals(2103328, x &= (tmp = -2488723009, tmp));
+  assertEquals(1799011007, x |= (tmp = -2498057537.226923, tmp));
+  assertEquals(1799011007, x |= ((-308193085)>>>x));
+  assertEquals(1799011007, x |= x);
+  assertEquals(818879107, x ^= (1542823996.423564));
+  assertEquals(-2601416919234843600, x *= ((-2357923057.076759)-x));
+  assertEquals(-2601416920481796600, x -= (x|(tmp = -3048039765, tmp)));
+  assertEquals(-33690112, x <<= x);
+  assertEquals(1039491072, x &= (tmp = 1039491474.3389125, tmp));
+  assertEquals(126891, x >>= (-3079837011.6151257));
+  assertEquals(-163191923097543, x *= (((tmp = -2847221258.4048786, tmp)*(x-(tmp = 1527622853.5925639, tmp)))^x));
+  assertEquals(753616551, x ^= (-946895202));
+  assertEquals(-347691264, x <<= (tmp = -433184408.33790135, tmp));
+  assertEquals(0, x <<= (x|(tmp = -1911731462.6835637, tmp)));
+  assertEquals(-0, x *= (tmp = -2616154415.1662617, tmp));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x -= x);
+  assertEquals(0, x *= (2272504250.501526));
+  assertEquals(0, x ^= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x >>>= (2475346113));
+  assertEquals(NaN, x /= (((x+(-2646140897))&(((tmp = 1039073714.142481, tmp)-x)*x))|(x*(((-1277822905.773948)>>(tmp = 2035512354.2400663, tmp))*(77938193.80013895)))));
+  assertEquals(0, x ^= (x<<(tmp = 2491934268, tmp)));
+  assertEquals(0, x &= (tmp = 569878335.4607931, tmp));
+  assertEquals(-88575883, x ^= ((453890820.8012209)-((1569189876)%((-1280613677.7083852)^(-1902514249.29567)))));
+  assertEquals(-88575883, x %= (tmp = 257947563.19206762, tmp));
+  assertEquals(-88575881.7863678, x -= ((tmp = 1257547359.029678, tmp)/(x^(tmp = 948265672.821815, tmp))));
+  assertEquals(-169, x >>= (tmp = -2530523309.6703596, tmp));
+  assertEquals(-1, x >>= x);
+  assertEquals(-1, x |= x);
+  assertEquals(131071, x >>>= (-673590289));
+  assertEquals(1117196836, x -= (-1117065765));
+  assertEquals(3092236000.7125187, x -= (-1975039164.7125185));
+  assertEquals(1, x /= x);
+  assertEquals(-1599945863, x ^= (tmp = 2695021432.453696, tmp));
+  assertEquals(940543782, x ^= (tmp = 2561494111, tmp));
+  assertEquals(891400321673221800, x *= (tmp = 947749949.2662871, tmp));
+  assertEquals(-1509927296, x >>= ((tmp = 1113290009, tmp)-x));
+  assertEquals(-23, x >>= (tmp = 3216989626.7370152, tmp));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x <<= (431687857.15246475));
+  assertEquals(-0, x /= (tmp = -1924652745.081665, tmp));
+  assertEquals(0, x <<= (1312950547.2179976));
+  assertEquals(0, x %= ((tmp = 2110842937.8580878, tmp)|(x<<x)));
+  assertEquals(0, x >>>= ((((-386879000)-((tmp = -2334036143.9396124, tmp)/((tmp = 965101904.2841234, tmp)<<(((3029227182.8426695)<<((tmp = -464466927, tmp)>>((((((tmp = 849594477.4111787, tmp)^(x&((513950657.6663146)%(x>>>x))))-((2898589263)|x))+(tmp = 2842171258.621288, tmp))>>>(tmp = -3158746843, tmp))<<(tmp = -2891369879, tmp))))-(x-(x&(tmp = -1707413686.2706504, tmp)))))))-(-2860419051))*(-1708418923)));
+  assertEquals(-328055783, x += ((((2857010474.8010874)|((tmp = -1415997622.320347, tmp)-(-1706423374)))%(tmp = 824357977.1339042, tmp))^(x>>(x|x))));
+  assertEquals(-168539902503779140, x *= ((tmp = -1057687018, tmp)<<((1408752963)-(2030056734))));
+  assertEquals(-Infinity, x /= ((x-(2232683614.320658))*(((tmp = 195551174, tmp)*((((739595970)>>>(tmp = -2218890946.8788786, tmp))>>>(((tmp = -240716255.22407627, tmp)&(((((1598029916.3478878)|((tmp = -881749732, tmp)+(x>>x)))^(4443059))<<(((tmp = 2453020763, tmp)+((x>>>(tmp = -1904203813, tmp))&(-355424604.49235344)))<<(tmp = 2814696070, tmp)))%((tmp = -250266444, tmp)>>>(((((2710614972)&(((tmp = 910572052.6994087, tmp)^(tmp = -1028443184.3220406, tmp))/((-2718010521)^(tmp = 676361106, tmp))))|x)^(-1326539884))>>(-1573782639.7129154)))))/(tmp = 1923172768, tmp)))>>>(tmp = -2858780232.4886074, tmp)))/((((((-2060319376.353397)%x)>>(tmp = -3122570085.9065285, tmp))/(tmp = -1499018723.8064275, tmp))*((-655257391)<<x))>>x))));
+  assertEquals(NaN, x += ((3059633304)%((((tmp = 2538190083, tmp)*((tmp = -2386800763.356364, tmp)/x))&(1341370996))%(-2929765076.078223))));
+  assertEquals(NaN, x %= ((x&(347774821))>>>(462318570.2578629)));
+  assertEquals(NaN, x *= ((2829810152.071517)*(tmp = 768565684.6892327, tmp)));
+  assertEquals(NaN, x -= x);
+  assertEquals(0, x >>>= (x&(tmp = 1786182552, tmp)));
+  assertEquals(973967377, x ^= ((tmp = 2115869489.836838, tmp)&(994956497)));
+  assertEquals(985246427.4230617, x += (11279050.423061728));
+  assertEquals(985246427, x &= x);
+  assertEquals(0, x >>= ((tmp = 1090502660.1867907, tmp)>>((-1599370623.5747645)-(tmp = -1321550958, tmp))));
+  assertEquals(0, x %= (tmp = -2386531950.018572, tmp));
+  assertEquals(0, x >>>= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x >>>= (tmp = -1535987507.682257, tmp));
+  assertEquals(-0, x /= (-2570639987));
+  assertEquals(-542895632, x |= (tmp = -542895632, tmp));
+  assertEquals(-33930977, x >>= (tmp = -861198108.1147206, tmp));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x ^= (x*(-608154714.1872904)));
+  assertEquals(-140011520, x |= ((tmp = 377418995, tmp)<<((1989575902)>>(tmp = -2558458031.066773, tmp))));
+  assertEquals(-140026048, x -= ((((tmp = 1465272774.7540011, tmp)<<((2164701398)<<(tmp = -818119264, tmp)))>>((tmp = -1490486001, tmp)>>(664410099.6412607)))>>(x>>>(((tmp = -2438272073.2205153, tmp)%(tmp = 2142162105.4572072, tmp))-(tmp = 2259040711.6543813, tmp)))));
+  assertEquals(39214588236996610, x *= (x<<(-401696127.06632423)));
+  assertEquals(1, x /= x);
+  assertEquals(0, x %= x);
+  assertEquals(0, x *= ((tmp = -1709874807.176726, tmp)&(-2786424611)));
+  assertEquals(-1320474063.3408537, x += (tmp = -1320474063.3408537, tmp));
+  assertEquals(88, x >>>= (tmp = -3179247911.7094674, tmp));
+  assertEquals(1606348131, x += ((tmp = 1555621121.5726175, tmp)|(-3026277110.9493155)));
+  assertEquals(200793516, x >>>= x);
+  assertEquals(-2952688672.1074514, x -= (tmp = 3153482188.1074514, tmp));
+  assertEquals(1342278624, x >>>= ((x>>>((tmp = 1264475713, tmp)-(-913041544)))>>>((tmp = 2008379930, tmp)%(tmp = 3105129336, tmp))));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x /= (tmp = 788363717, tmp));
+  assertEquals(430466213, x -= (tmp = -430466213, tmp));
+  assertEquals(164757385222499550, x *= (tmp = 382741735, tmp));
+  assertEquals(164757385222499550, x %= (((tmp = 1974063648, tmp)%((806015603)>>>x))*((tmp = 2836795324, tmp)<<(tmp = -1785878767, tmp))));
+  assertEquals(-190957725.86956096, x /= (x^((-2939333300.066044)-(x|(-2085991826)))));
+  assertEquals(-190957725.86956096, x %= (tmp = -948386352, tmp));
+  assertEquals(0.6457336106922105, x /= (-295722141));
+  assertEquals(0, x |= ((415991250)&((x>>(tmp = -3188277823, tmp))<<(511898664.1008285))));
+  assertEquals(0, x &= ((793238922)|x));
+  assertEquals(-1576701979, x ^= (2718265317));
+  assertEquals(-49271937, x >>= x);
+  assertEquals(-49271937, x |= x);
+  assertEquals(-49271937, x &= x);
+  assertEquals(775316382, x -= (-824588319));
+  assertEquals(912498176, x <<= (tmp = -2223542776.836312, tmp));
+  assertEquals(0, x -= (x&((tmp = 1999412385.1074471, tmp)/(-1628205254))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>= (-768730139.7749677));
+  assertEquals(-1861304245, x |= (((5128483)^(((tmp = -1768372004, tmp)/(x^(tmp = 1310002444.757094, tmp)))*((tmp = 188242683.09898067, tmp)^(tmp = -2263757432, tmp))))^((tmp = 2223246327, tmp)*((tmp = -2360528979, tmp)-((tmp = 2442334308, tmp)>>(458302081))))));
+  assertEquals(1, x /= x);
+  assertEquals(2, x += x);
+  assertEquals(1, x /= x);
+  assertEquals(0, x ^= x);
+  assertEquals(-0, x *= (-1852374359.3930533));
+  assertEquals(0, x <<= (tmp = 1223645195.148961, tmp));
+  assertEquals(1789655087, x |= ((-2505312209.770559)>>x));
+  assertEquals(-65568768, x <<= x);
+  assertEquals(4229398528, x >>>= x);
+  assertEquals(-8408187, x |= (-3029781627));
+  assertEquals(-8408187, x |= (((2322165037)-((tmp = -1424506897.362995, tmp)%x))&x));
+  assertEquals(-7884926, x += (x>>>(x|(2738095820))));
+  assertEquals(-7884926, x %= (576507013));
+  assertEquals(751801768, x ^= (tmp = -750241238, tmp));
+  assertEquals(-1986010067668600800, x *= (tmp = -2641667195, tmp));
+  assertEquals(1921196240, x ^= (x%(-1954178308)));
+  assertEquals(847388880, x ^= ((tmp = 1632856124, tmp)&((tmp = -1536309755, tmp)<<(tmp = -3158362800, tmp))));
+  assertEquals(-469662000.6651099, x += (tmp = -1317050880.6651099, tmp));
+  assertEquals(-812358332, x ^= ((-2832480471)>>>(2016495937)));
+  assertEquals(21, x ^= (((tmp = 1815603134.2513008, tmp)/((tmp = 147415927, tmp)%(-1059701742)))+x));
+  assertEquals(-2844409139.792712, x += (tmp = -2844409160.792712, tmp));
+  assertEquals(177070, x >>>= x);
+  assertEquals(0, x %= x);
+  assertEquals(0, x >>= x);
+  assertEquals(1459126376, x ^= (tmp = -2835840920, tmp));
+  assertEquals(1459126376, x %= (-1462864282));
+  assertEquals(0, x >>>= (tmp = 2922724319, tmp));
+  assertEquals(338995506, x ^= (338995506.6411549));
+  assertEquals(336896258, x &= (2635904967));
+  assertEquals(336634112, x -= (x&(tmp = 1659656287, tmp)));
+  assertEquals(NaN, x %= (x-x));
+  assertEquals(NaN, x /= (tmp = -674606200, tmp));
+  assertEquals(NaN, x %= ((x|(2788108542))/(x+(tmp = 600941473, tmp))));
+  assertEquals(0, x >>>= ((-1858251597.3970242)>>>x));
+  assertEquals(1951294747, x |= (tmp = 1951294747, tmp));
+  assertEquals(1951294747, x &= x);
+  assertEquals(-153190625, x |= (-1500095737));
+  assertEquals(23467367587890624, x *= x);
+  assertEquals(346531290.1813514, x /= (((((-513617734.11148167)|x)/((tmp = -2042982150.1170752, tmp)%((x%((x%x)>>>(((-1369980151)&(((922678983)%(x&(tmp = -855337708, tmp)))-((tmp = -2717183760, tmp)>>>((1939904985.4701347)%(((tmp = -2473316858, tmp)&((tmp = -599556221.9046664, tmp)>>((tmp = -6352213, tmp)/x)))&x)))))%x)))/((tmp = -1842773812.8648412, tmp)>>>(((x>>>(tmp = 499774063, tmp))<<(((tmp = -1353532660.5755146, tmp)*(-3070956509))>>(((-905883994.0188017)>>(tmp = -16637173, tmp))<<((tmp = 471668537, tmp)*((tmp = -232036004.26637793, tmp)/x)))))&(tmp = 85227224, tmp))))))>>>(x|(-2528471983)))-((tmp = 1531574803, tmp)+((x>>>x)-(2889291290.158888)))));
+  assertEquals(-94.42225749399837, x /= (((tmp = 2381634642.1432824, tmp)>>(tmp = -2637618935, tmp))|(2307200473)));
+  assertEquals(-47, x >>= (1524333345.141235));
+  assertEquals(-2.8699253616435082e-8, x /= (1637673252));
+  assertEquals(0, x |= x);
+  assertEquals(1083427040, x += ((-2012055268)<<(tmp = -2192382589.6911573, tmp)));
+  assertEquals(1083427040, x %= (x*x));
+  assertEquals(2694039776, x += ((((-1740065704.9004602)<<(-736392934))%(2781638048.424092))>>>(x&x)));
+  assertEquals(-1600927520, x |= ((tmp = 2904430054.869525, tmp)*(((1054051883.4751332)*x)*((-939020743)-(tmp = 1636935481.1834455, tmp)))));
+  assertEquals(-1600927520, x -= (x%x));
+  assertEquals(3037584978216498700, x *= (tmp = -1897390694, tmp));
+  assertEquals(372598954.1823988, x %= (tmp = 1553763703.5082102, tmp));
+  assertEquals(-1476395008, x <<= ((x>>((tmp = 282496335.49494267, tmp)^((-1948623419.6947453)|((((((tmp = -1203306995, tmp)-(-5554612.355098486))>>>(1867254951.4836824))>>x)|(-695777865))/((-59122652.19377303)<<(-609999229.7448442))))))>>(x/(tmp = -1207010654.9993455, tmp))));
+  assertEquals(-2.2540185787941605, x /= (((tmp = 1364159859.9199843, tmp)*x)>>x));
+  assertEquals(-2, x |= x);
+  assertEquals(2241824008, x *= ((3174055292.962967)>>(((-2379151623.602476)>>(tmp = -1423760236, tmp))>>(tmp = -522536019.2225733, tmp))));
+  assertEquals(-2138158385, x ^= ((x>>((((1316131966.9180691)-((x*x)>>x))>>>x)>>((-2712430284)|(((((x<<(-616185937.6090865))-(((x-(tmp = 2957048661, tmp))<<(tmp = 617564839.888214, tmp))/(x%((tmp = -447175647.9393475, tmp)<<(2203298493.460617)))))-((x&((x<<(914944265))^(((-1294901094)*((tmp = 2512344795, tmp)+((((tmp = -1227572518, tmp)%(1831277766.4920158))*((x|x)^(tmp = 2515415182.6718826, tmp)))*x)))-(961485129))))>>>(tmp = 2079018304, tmp)))>>(tmp = 734028202, tmp))^(554858721.6149715)))))-((tmp = 1312985279.5114603, tmp)^(tmp = 2450817476.179955, tmp))));
+  assertEquals(2.759030298237921, x /= (x|(tmp = -775901745.3688724, tmp)));
+  assertEquals(8, x <<= x);
+  assertEquals(NaN, x %= (((x&((1792031228.831834)>>(-1174912501)))%(((-2351757750)+(tmp = -2610099430, tmp))*(-2811655968)))*(x&(tmp = -1881632878, tmp))));
+  assertEquals(0, x &= ((x*(616116645.7508612))^(2789436828.536846)));
+  assertEquals(0, x *= x);
+  assertEquals(35097452, x ^= ((tmp = 1023684579, tmp)%(((x|((tmp = -757953041, tmp)+(772988909)))+(tmp = -2934577578, tmp))>>>((tmp = -1973224283, tmp)>>>((x*(2244818063.270375))|(x-(-716709285)))))));
+  assertEquals(0.015207441433418992, x /= (2307913014.4056892));
+  assertEquals(-5865042.942076175, x -= (5865042.957283616));
+  assertEquals(-67719.94207617454, x %= (((1464126615.2493973)+(398302030.0108756))>>>x));
+  assertEquals(4294899577, x >>>= (x<<x));
+  assertEquals(-1, x >>= (tmp = 607447902, tmp));
+  assertEquals(-1, x >>= (3081219749.9119744));
+  assertEquals(6.53694303504065e-10, x /= (tmp = -1529767040.4034374, tmp));
+  assertEquals(6.53694303504065e-10, x %= ((tmp = 899070650.7190754, tmp)&(tmp = -1101166301, tmp)));
+  assertEquals(6.53694303504065e-10, x %= (tmp = -2207346460, tmp));
+  assertEquals(NaN, x %= (((x&x)>>x)%(((-10980184)+x)&(tmp = -1473044870.4729445, tmp))));
+  assertEquals(NaN, x -= x);
+  assertEquals(-1755985426, x ^= (tmp = 2538981870, tmp));
+  assertEquals(-13842, x %= ((((-2258237411.3816605)+(-1325704332.0531585))<<((tmp = -877665450.1877053, tmp)>>(((((2420989037)+(2084279990.6278818))*(-327869571.9348242))+x)^x)))>>>x));
+  assertEquals(1, x /= x);
+  assertEquals(1, x >>= ((2241312290)^(2859250114)));
+  assertEquals(0, x >>= x);
+  assertEquals(-1615631756, x |= (-1615631756.1469975));
+  assertEquals(-1615631756, x |= x);
+  assertEquals(-627245056, x <<= ((x*(tmp = -1308330685.5971081, tmp))|(tmp = 1479586158, tmp)));
+  assertEquals(-627245056, x |= x);
+  assertEquals(1786953888, x ^= (-1340096352.1839824));
+  assertEquals(1668014353, x -= (tmp = 118939535, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(-645681, x ^= ((-1322356629)>>(tmp = 1829870283, tmp)));
+  assertEquals(-1322354688, x <<= (-794779253));
+  assertEquals(-4310084378.672725, x += (-2987729690.6727247));
+  assertEquals(-8620168757.34545, x += x);
+  assertEquals(-8720421, x |= (tmp = -748107877.6417065, tmp));
+  assertEquals(-1508858270, x ^= (1500137913));
+  assertEquals(-0.825735756765112, x /= (1827289490.1767085));
+  assertEquals(1253449509.1742642, x += (((tmp = 1253449509.9576545, tmp)-(((tmp = 2860243975, tmp)+(367947569.85976696))>>(((((530960315)>>>((((x%(tmp = -2203199228, tmp))<<(x*(((tmp = -117302283, tmp)/(x-((2579576936)%(-1225024012))))&(tmp = -2857767500.1967726, tmp))))/((x/((tmp = -166066119, tmp)<<x))|x))>>>x))|(((2771852372)>>(((tmp = -3103692094.1463976, tmp)-(tmp = 2867208546.069278, tmp))>>>(702718610.1963737)))|(tmp = 2680447361, tmp)))>>x)>>(-2006613979.051014))))^((-1665626277.9339101)/(x<<(tmp = 342268763, tmp)))));
+  assertEquals(1693336701.1742642, x += (tmp = 439887192, tmp));
+  assertEquals(0.8479581831275719, x /= ((1171383583)+(((x&x)>>>(51482548.618915915))-(tmp = -825572595.1031849, tmp))));
+  assertEquals(28, x |= ((tmp = -2355932919.6737213, tmp)>>(tmp = -2395605638, tmp)));
+  assertEquals(0, x %= x);
+  assertEquals(0, x -= x);
+  assertEquals(0, x <<= (x^((tmp = 2793423893.484949, tmp)*(1585074754.3250475))));
+  assertEquals(0, x >>= (x/(x-((957719861.9175875)&(1288527195)))));
+  assertEquals(0, x >>>= ((-1429196921.4432657)/x));
+  assertEquals(-852424225.734199, x -= (tmp = 852424225.734199, tmp));
+  assertEquals(-46674433, x |= ((tmp = -2335242963, tmp)*((2135206646.2614377)>>(tmp = 505649511.8292929, tmp))));
+  assertEquals(2944662357, x += (tmp = 2991336790, tmp));
+  assertEquals(1404, x >>>= (849155189.1503456));
+  assertEquals(-846755170, x ^= (tmp = -846753822.4471285, tmp));
+  assertEquals(52615, x >>>= ((-517068110)+x));
+  assertEquals(1475021859.9916897, x += (tmp = 1474969244.9916897, tmp));
+  assertEquals(0, x %= x);
+  assertEquals(0, x %= ((539583595.8244679)*(tmp = 1469751690.9193692, tmp)));
+  assertEquals(0, x &= (807524227.2057163));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x -= (x^((tmp = -362481588, tmp)%(2611296227))));
+  assertEquals(NaN, x *= x);
+  assertEquals(0, x >>= ((-2519875630.999908)<<x));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x += (((tmp = 2485209575, tmp)>>(tmp = 2326979823, tmp))%(x-(((-1296334640.7476478)&x)<<x))));
+  assertEquals(0, x >>= (((tmp = 1370704131, tmp)^((((tmp = 793217372.7587746, tmp)>>(((-1455696484.109328)|(((((-2186284424.5379324)<<(tmp = 3052914152.254852, tmp))-(x>>(tmp = 3121403408, tmp)))+((778194280)-(((((tmp = 2398957652, tmp)-(x+(((-2592019996.937958)>>((tmp = 1648537981, tmp)>>x))<<(-677436594))))<<(39366669.09012544))|((tmp = 3133808408.9582872, tmp)-(-2987527245.010673)))*x)))|((tmp = -2178662629, tmp)<<x)))^(((tmp = 909652440.3570575, tmp)%(-2572839902.6852217))%(-1879408081))))*(tmp = -2910988598, tmp))&(((x^x)>>(2822040993))|((x*x)^(((1072489842.6785052)|(x-(((464054192.7390214)^x)<<(tmp = -2754448095, tmp))))*((tmp = -1544182396, tmp)/(tmp = -3198554481, tmp)))))))^(tmp = 1946162396.9841106, tmp)));
+  assertEquals(371272192, x |= (((x^((x-(x/x))&(tmp = 2370429394, tmp)))-(tmp = -403692829, tmp))*(tmp = 2808636109, tmp)));
+  assertEquals(929786482, x |= ((729966239.8987448)^(x-((tmp = 120127779, tmp)^((tmp = -3088531385, tmp)>>>((x+((tmp = 2364833601, tmp)>>>(((599149090.6666714)>>(tmp = 2838821032, tmp))%(tmp = -662846011, tmp))))-(tmp = 1168491221.1813436, tmp)))))));
+  assertEquals(-681121542, x += ((-1610909505.998718)^((tmp = -957338882, tmp)>>>(tmp = 1935594133.6531684, tmp))));
+  assertEquals(-2147483648, x <<= ((tmp = 15161708, tmp)|(2453975670)));
+  assertEquals(-2147483648, x >>= x);
+  assertEquals(0, x <<= (2080486058));
+  assertEquals(0, x &= (((x&(tmp = -767821326, tmp))/((tmp = 1877040536, tmp)>>>(tmp = 2378603217.75597, tmp)))*(-1601799835)));
+  assertEquals(0, x %= (-1820240383));
+  assertEquals(1621233920, x ^= ((tmp = 820230232, tmp)*(1727283900)));
+  assertEquals(1621233920, x |= (x>>>x));
+  assertEquals(1621233931, x += ((tmp = 794966194.9011587, tmp)>>(tmp = -597737830.5450518, tmp)));
+  assertEquals(1621276543, x |= (((x^((2354444886)+(tmp = 685142845.4708651, tmp)))-(tmp = 790204976.9120214, tmp))>>>((((tmp = -2792921939, tmp)/(((((tmp = -80705524, tmp)<<x)-(((((((tmp = 1951577216.379527, tmp)>>>x)%((-529882150)>>>(tmp = -1682409624, tmp)))<<((-42043756.29025769)-(-1803729173.6855814)))/(2937202170.118023))*(tmp = -1998098798.5722106, tmp))*(tmp = -2996229463.904228, tmp)))&x)>>>(-301330643)))/(-2858859382.0050273))-(tmp = 1571854256.0740635, tmp))));
+  assertEquals(810638271, x >>>= (x/(1553632833)));
+  assertEquals(810638271, x <<= (tmp = -1467397440, tmp));
+  assertEquals(-2147483648, x <<= x);
+  assertEquals(871068871, x ^= (tmp = 3018552519, tmp));
+  assertEquals(-1073743881, x |= ((tmp = 2294122324.020989, tmp)|(tmp = -1799706842.4493146, tmp)));
+  assertEquals(-77816868, x += (((-2225296403)&x)>>(tmp = -2667103424.445239, tmp)));
+  assertEquals(-1215889, x >>= (tmp = 1876107590.8391647, tmp));
+  assertEquals(-2431778, x += x);
+  assertEquals(4292535518, x >>>= (((x>>(-1825580683))/x)%x));
+  assertEquals(4292802560, x -= (x|(1492864090)));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>= x);
+  assertEquals(0, x %= (tmp = 2173121205, tmp));
+  assertEquals(0, x *= (x>>x));
+  assertEquals(1565261471, x |= ((1565261471.323931)>>>x));
+  assertEquals(0, x -= x);
+  assertEquals(-86980804, x |= (-86980804));
+  assertEquals(-698956484, x -= (((((2754713793.1746016)*(((((-1514587465.0698888)>>(tmp = -1307050817, tmp))/(tmp = 2368054667.438519, tmp))*(-1908125943.5714772))<<(x>>>(-357164827.4932244))))+(1257487617))<<(2954979945))&(612330472)));
+  assertEquals(-1073741824, x <<= x);
+  assertEquals(54497747, x ^= (-1019244077.098908));
+  assertEquals(54501375, x |= (((tmp = 1944912427, tmp)>>>x)%x));
+  assertEquals(0, x -= x);
+  assertEquals(0, x -= x);
+  assertEquals(-0, x *= (-1748215388));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>>= (((tmp = 988769112, tmp)%(tmp = -3133658477, tmp))<<x));
+  assertEquals(0, x %= (1685221089.2950323));
+  assertEquals(0, x >>>= (x+((793467168)-(tmp = 135877882, tmp))));
+  assertEquals(0, x %= ((tmp = -2406801984, tmp)%(tmp = -987618172, tmp)));
+  assertEquals(0, x *= ((-2943444887.953456)|(tmp = -2327469738.4544783, tmp)));
+  assertEquals(0, x >>= x);
+  assertEquals(-145484729.70167828, x += (tmp = -145484729.70167828, tmp));
+  assertEquals(1140855872, x &= (x^(tmp = 3151437967.965556, tmp)));
+  assertEquals(1486808408, x += (tmp = 345952536, tmp));
+  assertEquals(107846582.36594129, x %= (-1378961825.6340587));
+  assertEquals(-642031616, x <<= (x+x));
+  assertEquals(151747770.95108718, x *= (x/(tmp = 2716379907, tmp)));
+  assertEquals(192723456, x <<= (tmp = -1731167384, tmp));
+  assertEquals(2151208003, x -= ((-2151208003)+x));
+  assertEquals(1, x /= x);
+  assertEquals(1, x |= x);
+  assertEquals(1996766603, x |= (1996766602));
+  assertEquals(895606123, x ^= (tmp = 1113972960.966081, tmp));
+  assertEquals(-1500036886, x ^= (tmp = 2482412929, tmp));
+  assertEquals(-1542644247, x ^= (x>>>((tmp = 51449105, tmp)>>>(((-2057313176)*x)/(-1768119916)))));
+  assertEquals(-1496074063273093600, x *= ((tmp = 786152274, tmp)^(387292498)));
+  assertEquals(-794329073, x %= (((tmp = -2314637675.617696, tmp)*((((x*(411053423.29070306))-(2889448433.4240828))/((-970630131)/(tmp = -2886607600.7423067, tmp)))<<(tmp = 1263617112.9362245, tmp)))|(2816980223.8209996)));
+  assertEquals(2468008436047106600, x *= (tmp = -3107035257.725115, tmp));
+  assertEquals(3040956928, x >>>= ((tmp = 1514372119.1787262, tmp)*(3169809008)));
+  assertEquals(-19, x >>= (tmp = -266966022.10604453, tmp));
+  assertEquals(-1.6505580654964654e-8, x /= ((-3143841480)>>(x-x)));
+  assertEquals(-2.2420284729165577e-7, x *= (x*((((703414102.2523813)%(tmp = 2989948152, tmp))-((-1583401827.2949386)^((tmp = -1916731338, tmp)%((331500653.3566053)|(((tmp = 29865940, tmp)+((tmp = -2294889418.6764183, tmp)<<(tmp = -1558629267.255229, tmp)))>>>(x*(x+x)))))))|((988977957)&(-2986790281)))));
+  assertEquals(0, x ^= (x/(tmp = 781117823.345541, tmp)));
+  assertEquals(NaN, x *= (((x^((((tmp = -2969290335, tmp)+(((((tmp = -175387021, tmp)&(tmp = -1080807973, tmp))<<(tmp = -2395571076.6876855, tmp))|((tmp = -1775289899.4106793, tmp)^x))|(-2963463918)))*(tmp = -1761443911, tmp))^(tmp = 847135725, tmp)))<<((146689636)<<x))%x));
+  assertEquals(0, x ^= x);
+  assertEquals(1720182184, x -= (((tmp = 3184020508, tmp)|((-489485703)+(tmp = -2644503573, tmp)))&(tmp = 2575055579.6375213, tmp)));
+  assertEquals(1720182184, x >>= (x<<(-45408034)));
+  assertEquals(5.759243187540471e+27, x *= (((x&(1456298805))+(x<<(106573181)))*((566861317.2877743)+(2262937360.3733215))));
+  assertEquals(5.759243187540471e+27, x -= (tmp = -1365873935, tmp));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>= (1960073319.3465362));
+  assertEquals(0, x <<= x);
+  assertEquals(560463904, x += ((tmp = 1844076589.9286406, tmp)&((((((-691675777.5800121)|(-745631201))|x)+(tmp = 1504458593.2843904, tmp))-x)<<x)));
+  assertEquals(-513210271, x -= (x|(1052702623.7761713)));
+  assertEquals(3781757025, x >>>= ((-1346666404.362477)*(tmp = 2798191459, tmp)));
+  assertEquals(1080100929, x &= (1122097879.882534));
+  assertEquals(1276833905.8093092, x *= ((1276833905.8093092)/x));
+  assertEquals(1276833905.8093092, x %= (1796226525.7152414));
+  assertEquals(1276833905, x <<= (((tmp = -491205007.83412814, tmp)*(tmp = 1496201476.496839, tmp))>>(x+((tmp = -854043282.114594, tmp)-((x|(tmp = -807842056, tmp))*x)))));
+  assertEquals(1276833905, x %= (((-1870099318)>>>(((tmp = -2689717222, tmp)/(248095232))/(tmp = 1036728800.5566598, tmp)))&(((((857866837)>>(tmp = 3034825801.740485, tmp))|(-1676371984))>>>(x<<x))%((-3035366571.0221004)*(1578324367.8819473)))));
+  assertEquals(1, x /= x);
+  assertEquals(2819223656.189109, x += (2819223655.189109));
+  assertEquals(-1475743640, x >>= (((tmp = 2586723314.38089, tmp)/(x&(tmp = -697978283.9961061, tmp)))<<(x%((-1167534676)>>(x^((tmp = -284763535, tmp)*((x%x)&((((tmp = 2916973220.726839, tmp)%x)/(tmp = -1338421209.0621986, tmp))|((tmp = -834710536.803335, tmp)%x)))))))));
+  assertEquals(-3267683406, x -= (tmp = 1791939766, tmp));
+  assertEquals(-2090420900700614100, x *= (639725653));
+  assertEquals(-1540353536, x %= ((-1800269105)<<((((x&(((tmp = 1135087416.3945065, tmp)^(613708290))>>x))>>(tmp = -1234604858.7683473, tmp))^(2404822882.7666225))>>>((tmp = -287205516, tmp)-((1648853730.1462333)^((x+(x%((tmp = 359176339, tmp)%((2856479172)<<(tmp = -1995209313, tmp)))))^(((tmp = 2857919171.839304, tmp)>>>(tmp = 2779498870, tmp))>>x)))))));
+  assertEquals(-2093767030, x ^= (654554250.498078));
+  assertEquals(1, x >>>= ((tmp = -166296226.12181997, tmp)^(x/x)));
+  assertEquals(-1487427474, x -= ((x<<x)|(1487427475.4063978)));
+  assertEquals(-1487427470.562726, x += ((-1226399959.8267038)/((tmp = 2172365551, tmp)<<x)));
+  assertEquals(-3457859227618939400, x *= (tmp = 2324724597.3686075, tmp));
+  assertEquals(396221312, x >>= (-1354035390));
+  assertEquals(0, x %= x);
+  assertEquals(0, x &= (tmp = 2733387603, tmp));
+  assertEquals(1485905453, x |= ((((tmp = -1321532329.304437, tmp)&((((tmp = 1817382709.4180388, tmp)%(((tmp = 2089156555.7749293, tmp)-(-1555460267))|(tmp = 717392475.9986715, tmp)))%(tmp = 1976713214, tmp))^x))>>>x)+(tmp = -2812404197.002721, tmp)));
+  assertEquals(1485905453, x |= x);
+  assertEquals(-997658264, x <<= (-1409757949.6038744));
+  assertEquals(-997657290, x -= ((-2041106361)>>(tmp = -2014750507, tmp)));
+  assertEquals(-2138512124, x &= (tmp = 2565597060, tmp));
+  assertEquals(8422400, x &= ((-2819342693.5172367)*(tmp = 1441722560, tmp)));
+  assertEquals(111816531.81703067, x -= (-103394131.81703067));
+  assertEquals(59606682.673836395, x *= ((tmp = -1451690098, tmp)/(x-(2835050651.717734))));
+  assertEquals(-119213365.34767279, x *= (x|((-2656365050)/((-66180492)+(tmp = 284225706.32323086, tmp)))));
+  assertEquals(-232839, x >>= (1694344809.435083));
+  assertEquals(-1, x >>= x);
+  assertEquals(1, x *= x);
+  assertEquals(1, x |= x);
+  assertEquals(0, x >>= (tmp = 397239268, tmp));
+  assertEquals(-1525784563, x -= (tmp = 1525784563, tmp));
+  assertEquals(-153.62740888512675, x /= (((tmp = -2040622579.5354173, tmp)*(tmp = -1149025861.549324, tmp))%(((tmp = 2981701364.0073133, tmp)*(tmp = 2993366361, tmp))|(x|(tmp = 1800299979, tmp)))));
+  assertEquals(-1671795135, x &= (-1671795135.6173766));
+  assertEquals(-4253, x |= ((((x*((1533721762.8796673)<<((tmp = 1026164775.0081646, tmp)<<x)))<<(((x-((((x>>((((((tmp = -481536070.7067797, tmp)&(tmp = 1663121016, tmp))>>>(-2974733313.5449667))+(tmp = -493019653, tmp))>>x)&(tmp = 879307404.8600142, tmp)))>>>x)%(x-(tmp = -1806412445.788453, tmp)))%x))<<(x<<(x+x)))+x))>>((tmp = -332473688.28477216, tmp)<<((tmp = 1701065928, tmp)+(((((tmp = -2407330783, tmp)+x)-((tmp = 584100783, tmp)%(tmp = -3077106506, tmp)))^x)>>x))))<<x));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>>= (1578470476.6074834));
+  assertEquals(0, x >>>= (974609751));
+  assertEquals(-120, x += (x-((tmp = -245718438.0842378, tmp)>>>(tmp = -1870354951, tmp))));
+  assertEquals(-6.134465505515781e-8, x /= (1956160645));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x *= (tmp = -399718472.70049024, tmp));
+  assertEquals(-1803198769.8413258, x += (-1803198769.8413258));
+  assertEquals(988624943, x ^= ((((tmp = 320776739.5608537, tmp)*(((tmp = -983452570.3150327, tmp)^x)&(tmp = -3181597938, tmp)))-(tmp = -1367913740.9036021, tmp))/(((tmp = -535854933.2943456, tmp)-(717666905.8122432))>>>(((((x^(tmp = 380453258.60062766, tmp))^(tmp = -1242333929, tmp))/((tmp = 1072416261, tmp)+(((2090466933)*(x*(tmp = -386283072, tmp)))|((tmp = 789259942, tmp)<<(tmp = -1475723636.1901488, tmp)))))>>>x)%((x>>(tmp = -1243048658.3818703, tmp))|((((((tmp = -619553509, tmp)|x)/(878117279.285609))|((x<<(x>>>(tmp = -749568437.7390883, tmp)))*x))/(tmp = 1674804407, tmp))-(x*(tmp = 1528620873, tmp))))))));
+  assertEquals(988625135, x |= (x>>>(tmp = 2402222006, tmp)));
+  assertEquals(988625135, x %= (-2691094165.990094));
+  assertEquals(0, x %= x);
+  assertEquals(-0, x *= (tmp = -1409904262, tmp));
+  assertEquals(-0, x /= ((1176483512.8626208)<<x));
+  assertEquals(0, x &= ((((1677892713.6240005)^(tmp = 2575724881, tmp))^(tmp = -2935655281.208194, tmp))*(216675668)));
+  assertEquals(0, x >>= (tmp = -1296960457, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x <<= (x>>(-3127984289.9112387)));
+  assertEquals(0, x %= ((tmp = 190018725.45957255, tmp)<<((x>>>x)/x)));
+  assertEquals(0, x /= (1185681972));
+  assertEquals(0, x &= ((tmp = -1285574617, tmp)>>x));
+  assertEquals(0, x >>>= ((tmp = 2498246277.2054763, tmp)+(((tmp = 924534435, tmp)&x)>>(tmp = 1379755429, tmp))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x /= (3093439341));
+  assertEquals(0, x *= (x>>>x));
+  assertEquals(0, x &= (tmp = 551328367, tmp));
+  assertEquals(-0, x /= (-3153411714.834353));
+  assertEquals(1217585288, x ^= (tmp = -3077382008.637764, tmp));
+  assertEquals(-639702017, x |= ((tmp = -640922633, tmp)%(tmp = -879654762, tmp)));
+  assertEquals(-1645297680, x <<= (tmp = 1418982820.8182912, tmp));
+  assertEquals(-1.4059558868398736, x /= (1170234212.4674253));
+  assertEquals(-2650856935.66554, x *= (1885448157));
+  assertEquals(1326259953.26931, x *= (((x>>(x|(-496195134.78045774)))+((2029515886)%(tmp = 1148955580, tmp)))/(tmp = -1760016519, tmp)));
+  assertEquals(0, x &= (((((-273334205)+(tmp = 797224093.682485, tmp))/x)>>>((((tmp = -887577414, tmp)/x)+x)%(tmp = 720417467, tmp)))^(((x-(tmp = -309071035, tmp))>>(-3123114729.33889))/x)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x %= ((tmp = -2243857462, tmp)/((((((2642220700.6673346)&x)*(tmp = 1454878837, tmp))|((-25825087.30002737)%(851535616.3479034)))<<(tmp = -697581582, tmp))%(tmp = 2248990486, tmp))));
+  assertEquals(0, x >>= (((x|(((tmp = -220437911, tmp)&((((255690498)*(((2993252642)>>>(tmp = 300426048.0338713, tmp))>>x))&((-364232989)+(x<<(-1824069275))))%(x+(tmp = 2696406059.026349, tmp))))+((tmp = 2911683270, tmp)/(tmp = 2718991915, tmp))))*(x/(((tmp = -982851060.0744538, tmp)^((-2903383954)<<((-85365803.80553412)^x)))%(1489258330.5730634))))>>>x));
+  assertEquals(0.7805921633088815, x += (((-1886920875)/(-2417294156.5304217))%(tmp = -1176793645.8923106, tmp)));
+  assertEquals(0, x <<= x);
+  assertEquals(-2215008905, x -= (2215008905));
+  assertEquals(1931542900, x &= (-215923724.72133207));
+  assertEquals(907191462, x ^= (-3133954606.357727));
+  assertEquals(453595731, x >>>= (((tmp = 2726241550, tmp)/(tmp = -332682163, tmp))*((((tmp = 2500467531, tmp)>>>(((x<<(tmp = -1847200310.4863105, tmp))/x)^x))+x)<<(191688342.22953415))));
+  assertEquals(-0.21671182880645923, x /= ((((-1169180683.1316955)%x)>>>(1650525418))^((2198033206.797462)&((-6913973.910871983)%(1758398541.8440342)))));
+  assertEquals(-375102237.1603561, x += (tmp = -375102236.9436443, tmp));
+  assertEquals(1, x &= (((84374105.89811504)|((tmp = -2480295008.926951, tmp)>>((605043461)>>(tmp = -2495122811, tmp))))>>(-2129266088)));
+  assertEquals(1, x |= x);
+  assertEquals(0.0000024171579540208214, x /= (((-2600416098)>>(-2076954196))^x));
+  assertEquals(0.0000024171579540208214, x %= (tmp = -2632420148.815531, tmp));
+  assertEquals(1809220936.0126908, x -= (-1809220936.0126884));
+  assertEquals(1682452118.2686126, x += (((2358977542)<<(x/(tmp = -2862107929, tmp)))+(x+(x%((-3101674407)/(((x*((x>>(tmp = 630458691.3736696, tmp))>>>(tmp = -852137742, tmp)))/x)-((-1875892391.1022017)&(tmp = -1027359748.9533749, tmp))))))));
+  assertEquals(1682452118, x <<= (((tmp = -80832958.07816291, tmp)>>x)%(x-((x^(x<<(tmp = -156565345, tmp)))|((tmp = -1208807363.727137, tmp)/(tmp = 2614737513.304538, tmp))))));
+  assertEquals(6572078, x >>= (-1573364824));
+  assertEquals(13144156, x += x);
+  assertEquals(1731678184, x ^= ((tmp = 593370804.9985657, tmp)|(-3124896848.53273)));
+  assertEquals(845545, x >>>= (tmp = -605637621.2299933, tmp));
+  assertEquals(-1383361088, x ^= (tmp = -1383632087, tmp));
+  assertEquals(-82545896480031520, x += ((x+(1023183845.7316296))*((((tmp = 576673669, tmp)>>(((-584800080.1625061)/(2388147521.9174623))+((((x>>>(-905032341.5830328))^(tmp = -2170356357, tmp))-x)+((136459319)+(-1799824119.689473)))))|x)&(tmp = -2688743506.0257063, tmp))));
+  assertEquals(-895206176, x |= x);
+  assertEquals(-0, x %= x);
+  assertEquals(1791306023, x ^= ((tmp = -3219480856, tmp)+(tmp = 715819582.0181161, tmp)));
+  assertEquals(1791306023, x &= x);
+  assertEquals(2725167636753240600, x *= (1521330025));
+  assertEquals(-281190679, x |= (tmp = -1422045975.798171, tmp));
+  assertEquals(-281190679, x += (x%x));
+  assertEquals(-2342097426.906673, x -= (tmp = 2060906747.906673, tmp));
+  assertEquals(-4651462701.906673, x -= (2309365275));
+  assertEquals(1878, x >>>= (2544974549.345834));
+  assertEquals(1964, x += (x&((1067649861)>>(182139255.7513579))));
+  assertEquals(2209, x += (x>>(tmp = -1775039165, tmp)));
+  assertEquals(0, x -= x);
+  assertEquals(-0, x /= (tmp = -1634697185, tmp));
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x >>>= ((tmp = 3075747652, tmp)&(tmp = 819236484, tmp)));
+  assertEquals(0, x /= ((1276203810.476657)%(-2434960500.784484)));
+  assertEquals(0, x >>>= (tmp = -503633649, tmp));
+  assertEquals(-982731931, x |= (-982731931));
+  assertEquals(-1965463862, x += x);
+  assertEquals(-0.221469672913716, x %= ((tmp = -1742292120, tmp)/x));
+  assertEquals(-0.221469672913716, x %= (-2021391941.1839576));
+  assertEquals(0, x <<= (((((tmp = -2802447851, tmp)>>((2534456072.6518855)&x))%(tmp = 2841162496.610816, tmp))<<((89341820)/(2565367990.0552235)))>>(tmp = 2700250984.4830647, tmp)));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>= ((tmp = -636189745, tmp)>>>(x/(((tmp = 2634252476, tmp)%(2026595795))>>(tmp = -2048078394.743723, tmp)))));
+  assertEquals(NaN, x %= ((x%((((x%((tmp = -2583207106, tmp)&x))|(190357769))<<(tmp = 595856931.2599536, tmp))%x))*((-2433186614.6715775)<<((2856869562.1088696)^(tmp = 1112328003, tmp)))));
+  assertEquals(1621713910, x |= (tmp = 1621713910.0282416, tmp));
+  assertEquals(3243427820, x += x);
+  assertEquals(0, x *= (x&(x-x)));
+  assertEquals(0, x >>>= (((2871235439)<<((x+((tmp = -1319445828.9659343, tmp)+(tmp = 1595655077.959171, tmp)))>>(tmp = -86333903, tmp)))-(x/(2907174373.268768))));
+  assertEquals(0, x >>= (-1091774077.2173789));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x *= (tmp = 1976023677.7015994, tmp));
+  assertEquals(NaN, x -= (-3013707698));
+  assertEquals(NaN, x += ((x+(((tmp = -3119865782.9691515, tmp)<<(1327383504.0158405))^(((-143382411.7239611)>>>((-2157016781)+(((-335815848)/x)<<(tmp = 1953515427, tmp))))&(-2715729178))))/(413738158.2334299)));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x += (-845480493));
+  assertEquals(-789816013, x |= (tmp = -789816013.129916, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= (3032573320));
+  assertEquals(47630, x ^= ((1086705488)%((x^(tmp = -1610832418, tmp))>>>(tmp = 1136352558, tmp))));
+  assertEquals(47630, x >>= (tmp = 1035320352.4269229, tmp));
+  assertEquals(47630, x >>= ((((x^x)<<(x*((((x&((-1657468419)*((tmp = -674435523, tmp)&((tmp = 2992300334, tmp)|x))))*((tmp = -489509378.31950426, tmp)*(tmp = 2276316053, tmp)))>>>x)<<x)))%(tmp = -1209988989, tmp))/(tmp = -2080515253.3541622, tmp)));
+  assertEquals(3192518951.8129544, x += (3192471321.8129544));
+  assertEquals(648116457.8129544, x %= (-2544402494));
+  assertEquals(0, x -= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>= x);
+  assertEquals(0, x *= (tmp = 30051865, tmp));
+  assertEquals(0, x ^= ((x&(((x&x)>>>(((((((x+(2319551861.0414495))>>>(tmp = -3099624461, tmp))^((((tmp = 1574312763, tmp)|x)>>>((-2723797246)&(tmp = -1993956152, tmp)))|(-1830179045)))|(((((((-2545698704.3662167)>>>x)-(((-79478653)|x)%(x+(x>>((tmp = 2386405508.2180576, tmp)/x)))))>>((((-1947911815.2808042)*((x+(368522081.2884482))-(tmp = 2452991210, tmp)))>>(343556643.1123545))>>((((tmp = 1869261547.537739, tmp)>>(3193214755))|x)&(x*(2027025120)))))<<((-1149196187)>>>(814378291.8374172)))+((((((((-160721403)/(2079201480.2186408))+((x|((((tmp = -299595483.16805863, tmp)>>>((x|((x+x)/(-2359032023.9366207)))<<(tmp = -3095108545, tmp)))>>((tmp = -1547963617.9087071, tmp)*(x>>x)))&((tmp = -1568186648.7499216, tmp)+(((2646528453)^(-2004832723.0506048))>>>(tmp = -3188715603.921877, tmp)))))+(tmp = 1578824724, tmp)))^x)^x)/(tmp = -985331362, tmp))|(tmp = 445135036, tmp))<<(tmp = -73386074.43413758, tmp)))+(((-1674995105.9837937)-(tmp = 1392915573, tmp))>>x)))%(tmp = 1215953864, tmp))&((tmp = -439264643.5238693, tmp)>>>x))+(((tmp = 2311895902, tmp)|(1604405793.6399229))&(tmp = -565192829, tmp))))-x))>>(-2455985321)));
+  assertEquals(0, x %= ((1177798817)>>(tmp = 2081394163.5420477, tmp)));
+  assertEquals(0, x >>>= ((x^(tmp = -41947528.33954811, tmp))>>(x>>>((tmp = 1367644771, tmp)+x))));
+  assertEquals(0, x %= ((x+((tmp = 163275724, tmp)<<((tmp = -514460883.3040788, tmp)+x)))|(tmp = -287112073.2482593, tmp)));
+  assertEquals(0, x &= (3067975906));
+  assertEquals(201342051, x |= (tmp = 201342051, tmp));
+  assertEquals(0, x %= (((((-2580351108.8990865)<<(tmp = 2675329316, tmp))&((1338398946)%((-1548041558)+((x>>(-1568233868.7366815))|((x>>((tmp = -1064582207, tmp)/(-1062237014)))>>(tmp = 854123209, tmp))))))<<(((989032887)*(1842748656))%(tmp = -1566983130, tmp)))-x));
+  assertEquals(-0, x /= (tmp = -828519512.617768, tmp));
+  assertEquals(0, x &= ((((1449608518)+(-1829731972))*(1828894311))*(((tmp = -1121326205.614264, tmp)^(-2057547855))<<(tmp = -2758835896, tmp))));
+  assertEquals(NaN, x %= ((tmp = -2138671333, tmp)%x));
+  assertEquals(0, x &= x);
+  assertEquals(665568613.0328879, x += (665568613.0328879));
+  assertEquals(317, x >>= (2627267349.735873));
+  assertEquals(0, x -= x);
+  assertEquals(0, x &= (((tmp = 3030611035, tmp)*(((tmp = 476143340.933007, tmp)>>(x-(2238302130.2331467)))|(x|x)))%(tmp = 320526262, tmp)));
+  assertEquals(0, x <<= (tmp = 729401206, tmp));
+  assertEquals(0, x >>>= (1721412276));
+  assertEquals(217629949.3530736, x += ((tmp = 217629949.3530736, tmp)%((-931931100.601475)%(x^(tmp = -2149340123.548764, tmp)))));
+  assertEquals(217629949.3530736, x %= (tmp = 2275384959.4243402, tmp));
+  assertEquals(0, x >>>= (1112677437.5524077));
+  assertEquals(0, x *= (500256656.7476063));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x -= x);
+  assertEquals(0, x -= x);
+  assertEquals(0, x &= (-1076968794));
+  assertEquals(0, x /= (tmp = 1774420931.0082943, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(0, x >>= x);
+  assertEquals(0, x %= (-2978890122.943079));
+  assertEquals(-0, x /= (tmp = -2954608787, tmp));
+  assertEquals(-800048201, x ^= ((tmp = -800048201.7227018, tmp)>>>((-2016227566.1480863)/(tmp = -2263395521, tmp))));
+  assertEquals(3333, x >>>= (-2038839052));
+  assertEquals(487957736.625432, x += (487954403.625432));
+  assertEquals(-1650983426, x |= (2643918270));
+  assertEquals(-1861867448, x &= (tmp = -251254199.12813115, tmp));
+  assertEquals(-7.934314690172143e-18, x %= ((((x^(-703896560.6519544))>>(tmp = -1853262409, tmp))/(tmp = -1168012152.177894, tmp))/(tmp = 837616075.1097361, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x &= (tmp = -2328150260.5399947, tmp));
+  assertEquals(-1954860020, x |= (tmp = 2340107276, tmp));
+  assertEquals(-1954860020, x >>= ((tmp = 159177341, tmp)*(x&(-705832619))));
+  assertEquals(-1954895727, x -= (x>>>((-1443742544.7183702)^((((tmp = 869581714.0137681, tmp)+x)^((x%(tmp = -1036566362.5189383, tmp))^(x%x)))>>x))));
+  assertEquals(1.0241361338078498, x /= (tmp = -1908824093.2692068, tmp));
+  assertEquals(16777216, x <<= (x*(((-1925197281)^(tmp = -1392300089.4750946, tmp))|x)));
+  assertEquals(-225882765524992, x *= (tmp = -13463662, tmp));
+  assertEquals(-1845493760, x |= x);
+  assertEquals(-1845493760, x %= (tmp = 3181618519.786825, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(NaN, x /= (x>>>x));
+  assertEquals(NaN, x %= (((((tmp = -521176477, tmp)>>(((tmp = 370693623, tmp)/(((tmp = -1181033022.4136918, tmp)>>(x|(x*(2601660441))))+(tmp = -1696992780, tmp)))|(x|(-1197454193.198036))))>>>(((2512453418.3855605)+((((((tmp = 799501914, tmp)&(((1788580469.7069902)*(((((1476778529.5109258)<<(tmp = -1873387738.3541565, tmp))-((tmp = -521988584.7945764, tmp)*(-1598785351.3914914)))&(-1899161721.8061454))&((x/x)*(690506460))))>>>((tmp = 2255896398.840741, tmp)>>((tmp = -1331486014.6180065, tmp)+(-1159698058.534132)))))*((1112115365.2633948)&((x>>((x>>(-784426389.4693215))&(-492064338.97227573)))>>x)))^((x-((tmp = 2986028023, tmp)>>(tmp = 2347380320.00517, tmp)))*(tmp = -1463851121, tmp)))*(tmp = -1059437133, tmp))%(x-(tmp = 1238739493.7636225, tmp))))^(2029235174)))*(-1923899530))>>>x));
+  assertEquals(0, x >>>= (2848792983.510682));
+  assertEquals(0, x >>= (((tmp = 3042817032.705198, tmp)>>>x)&((((tmp = -829389221, tmp)-((2669682285.8576303)+(tmp = 1812236814.3082042, tmp)))^x)%((tmp = -2401726554, tmp)^((tmp = 2464685683, tmp)|(-2685039620.224061))))));
+  assertEquals(2069649722, x |= (2069649722.311271));
+  assertEquals(NaN, x %= (((((-68757739.39282179)&(-1382816369))/(3122326124))<<(x-(-507995800.3369653)))<<(((-1962768567.343907)+((tmp = 1357057125, tmp)/x))^(tmp = 1997617124, tmp))));
+  assertEquals(NaN, x += x);
+  assertEquals(0, x >>= (26895919));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x %= (tmp = 1092448030, tmp));
+  assertEquals(0, x <<= (tmp = -477672441.46258235, tmp));
+  assertEquals(0, x /= (2113701907));
+  assertEquals(0, x >>>= x);
+  assertEquals(NaN, x /= x);
+  assertEquals(1341078673, x |= (-2953888623));
+  assertEquals(1341078673, x &= x);
+  assertEquals(0, x %= x);
+  assertEquals(414817852.151006, x -= (-414817852.151006));
+  assertEquals(1006632960, x <<= ((((((126465614.8316778)+(x-(2511803375)))+(tmp = 1620717148.352402, tmp))*x)/(tmp = -3013745105.5275207, tmp))-((tmp = -418034061.6865432, tmp)/(-300492911))));
+  assertEquals(1055624813, x |= (tmp = 921407085, tmp));
+  assertEquals(-3, x |= ((((tmp = 1382397819.7507677, tmp)+(tmp = -111851147.7289567, tmp))+x)/((tmp = 247980405.7238742, tmp)^(tmp = -592156399.8577058, tmp))));
+  assertEquals(35161, x &= (((((((-2973570544.725141)*(tmp = -1244715638, tmp))+x)<<(x/((x>>>(-2143371615.073137))/(226072236))))%((x-(tmp = 1971392936, tmp))^(tmp = 2653103658, tmp)))%((tmp = 2828319571.7066674, tmp)>>((1528970502)^((tmp = -55869558, tmp)%x))))>>(889380585.6738582)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x *= (2749718750));
+  assertEquals(0, x >>>= ((((-1633495402.6252813)*(tmp = 2943656739.1108646, tmp))+(tmp = 977432165, tmp))&((tmp = -2338132019, tmp)*(408176349.8061733))));
+  assertEquals(-1778794752, x -= (((tmp = -1391412154.5199084, tmp)-((-3172342474)|x))&(1854366052)));
+  assertEquals(-1778794752, x %= (tmp = 2024807296.6901965, tmp));
+  assertEquals(-1114410.466337204, x %= ((tmp = -240344444.24487805, tmp)%(-47661164)));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x >>= (x>>x));
+  assertEquals(0, x *= x);
+  assertEquals(0, x /= ((-3134902611)|(tmp = -3131158951, tmp)));
+  assertEquals(-0, x /= (((tmp = 1430247610.634234, tmp)&x)+((tmp = -2047191110.8623483, tmp)-((((x%((((x/(tmp = -2599234213, tmp))|(tmp = 2650380060, tmp))|x)+x))>>>x)&(-1961373866))<<x))));
+  assertEquals(-718394682, x -= ((x|(tmp = 1764417670.8577194, tmp))%(1046022988)));
+  assertEquals(3576572614, x >>>= (((tmp = 2480472883.078992, tmp)<<x)>>((2035208402.8039393)&(tmp = 492980449, tmp))));
+  assertEquals(434034142, x %= (x&((x>>>(311110449.48751545))|(-243530647))));
+  assertEquals(524703439.3065736, x += (((tmp = 1392771723.3065736, tmp)%(x&x))%(tmp = -2199704930, tmp)));
+  assertEquals(373686272, x &= (x<<((tmp = 2103372351.9456532, tmp)%(tmp = -1367109519, tmp))));
+  assertEquals(373686272, x >>= x);
+  assertEquals(-0.12245430020241108, x /= (tmp = -3051638622.5907507, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(1, x %= (3095983855));
+  assertEquals(-1454736871, x ^= (x*(tmp = -1454736872, tmp)));
+  assertEquals(-1454736866, x ^= (((724989405.7338341)|(tmp = -2834298786.384371, tmp))>>>(tmp = -2029602148.1758833, tmp)));
+  assertEquals(-1454736866, x &= x);
+  assertEquals(-197394432, x <<= (tmp = -1562128975, tmp));
+  assertEquals(251658240, x <<= (tmp = 2126510950, tmp));
+  assertEquals(3295700610.703306, x -= (tmp = -3044042370.703306, tmp));
+  assertEquals(-51152917, x |= ((949179883.1784958)|(((tmp = -2046168220, tmp)>>(x/x))/(((835064313)*(tmp = 2197600689, tmp))^(((tmp = 2717104216, tmp)&x)<<(-1402661995.3845913))))));
+  assertEquals(-1549204421, x ^= ((((tmp = -481013711, tmp)>>>((tmp = 119589341.80209589, tmp)%(-995489985.2905662)))-(635717011))^(x+(x*x))));
+  assertEquals(-1078356672.3999934, x += (470847748.6000067));
+  assertEquals(1484987268.4638166, x += (tmp = 2563343940.86381, tmp));
+  assertEquals(277020804, x &= (tmp = 2532819117, tmp));
+  assertEquals(-2097118208, x <<= (x>>>x));
+  assertEquals(-2147483648, x <<= (tmp = 761285045, tmp));
+  assertEquals(2147483648, x >>>= x);
+  assertEquals(-935909870282997800, x *= ((-2583300643)|x));
+  assertEquals(-370753566.54721737, x %= (-1084543510.4524941));
+  assertEquals(-177, x >>= (-946264747.6588805));
+  assertEquals(-416077682, x ^= (tmp = 416077761, tmp));
+  assertEquals(NaN, x %= ((((tmp = 779607408, tmp)*(((tmp = -3007128117, tmp)*(851442866.6153773))+x))&(1283388806))/(-876363553)));
+  assertEquals(NaN, x %= (x/(tmp = -1668413939.652408, tmp)));
+  assertEquals(-1726405921, x ^= (tmp = -1726405921, tmp));
+  assertEquals(-1, x >>= ((3031008213.807012)>>x));
+  assertEquals(4294967295, x >>>= ((x>>>x)&(tmp = 2788082290, tmp)));
+  assertEquals(8544111670008449000, x *= (tmp = 1989331020.0417833, tmp));
+  assertEquals(268435456, x <<= (tmp = 3121736017.2098465, tmp));
+  assertEquals(-2.1011176170964474e+26, x -= (((tmp = 1392503299, tmp)*(tmp = 1446108825.1572113, tmp))*(x^(tmp = 372776014.213725, tmp))));
+  assertEquals(0, x |= x);
+  assertEquals(0, x >>= ((-112413907.70074797)*(-702798603)));
+  assertEquals(1829518838, x |= (tmp = -2465448458, tmp));
+  assertEquals(57172463, x >>= ((tmp = 2979642955.241792, tmp)%(tmp = -2464398693.291434, tmp)));
+  assertEquals(114344926, x += x);
+  assertEquals(113279134, x &= (2397742238.6877637));
+  assertEquals(54, x >>= (1908522709.6377516));
+  assertEquals(-2.966982919573829e-7, x /= (tmp = -182003070, tmp));
+  assertEquals(0, x <<= (-1078417156));
+  assertEquals(-147831390, x ^= (((-147831390)>>>x)+x));
+  assertEquals(0, x -= x);
+  assertEquals(-242221450.44696307, x -= (tmp = 242221450.44696307, tmp));
+  assertEquals(-484442900, x <<= (((tmp = -2033947265.088614, tmp)&x)/(x^(tmp = -2893953848, tmp))));
+  assertEquals(-3227648, x <<= (x<<((tmp = -193993010, tmp)*((983187830)|(3146465242.2783365)))));
+  assertEquals(-6455296, x += x);
+  assertEquals(-1771542585, x -= (x^(tmp = -1767335879, tmp)));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x >>>= ((((tmp = -1612864670.4532743, tmp)*(tmp = 786265765.210487, tmp))*((((tmp = -893735877.3250401, tmp)*((x^(tmp = -2804782464.233885, tmp))<<x))&(x-x))^x))<<x));
+  assertEquals(0, x -= (x>>>(-1648118674.380736)));
+  assertEquals(0, x >>= ((tmp = -2706058813.0028524, tmp)>>(2745047169)));
+  assertEquals(0, x += x);
+  assertEquals(0, x %= (-898267735.137356));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>= ((265527509)/((tmp = 2190845136.7048635, tmp)+((x>>x)>>>((x%(x-x))&((((-2080184609.8989801)&((-327231633)>>>((tmp = 864849136, tmp)%(((-524363239)*(((((tmp = 2245852565.3713694, tmp)&(1918365.8978698254))>>>(tmp = -2463081769, tmp))-(((2438244059.471446)|((((-135303645.38470244)*(-861663832.2253196))%(tmp = 1273185196.0261836, tmp))|((2261539338.832875)%((320267076.2363237)+x))))>>(tmp = -2731398821, tmp)))/(tmp = -1947938611, tmp)))^x))))>>(tmp = 833666235, tmp))|x))))));
+  assertEquals(-1116704570, x ^= (-1116704570));
+  assertEquals(1379561710, x ^= (tmp = -280362968.19654894, tmp));
+  assertEquals(-1673822208, x <<= x);
+  assertEquals(-1673822208, x |= (x<<(tmp = 1389479193.9038138, tmp)));
+  assertEquals(2559712, x >>>= (-2703763734.0354066));
+  assertEquals(2593499, x ^= (x>>>((tmp = 148668150.03291285, tmp)^(tmp = -1580360304, tmp))));
+  assertEquals(2070393855, x |= (tmp = -2227002907, tmp));
+  assertEquals(304197770, x &= (tmp = 2453257354, tmp));
+  assertEquals(304197770, x <<= ((-669331453.8814087)-(x^(x^(tmp = 33804899.98928583, tmp)))));
+  assertEquals(297068, x >>= x);
+  assertEquals(Infinity, x /= (x-x));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x %= ((tmp = 1723087085, tmp)%(2859382131.304421)));
+  assertEquals(0, x %= (((tmp = 2935439763, tmp)<<(-3163992768.637094))%(tmp = 67176733, tmp)));
+  assertEquals(0, x &= (tmp = 2480771277, tmp));
+  assertEquals(0, x >>>= (x+(tmp = -3168690063, tmp)));
+  assertEquals(0, x *= ((tmp = -1915275449.1806245, tmp)>>>((tmp = -1644482094.1822858, tmp)/(tmp = -432927173, tmp))));
+  assertEquals(0, x += (((2766509428.071809)/(x/((942453848.5423365)/(((tmp = -1284574492, tmp)&((tmp = 760186450.7301528, tmp)-(2464974117.358138)))/((x/(x|(672536969)))*(x>>(-1272232579)))))))>>(x*(-3175565978))));
+  assertEquals(-1277710521, x -= (1277710521));
+  assertEquals(-1277710521, x >>= (((tmp = -2349135858, tmp)-x)-x));
+  assertEquals(-1277710521, x >>= ((tmp = 2135645051, tmp)*(tmp = -2468555366, tmp)));
+  assertEquals(-155971, x >>= (-1294859507));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x >>>= (((861078292.6597499)|(-268063679))-(((((-221864206.9494424)-(-3186868203.2201176))&(tmp = 1287132927, tmp))<<(((tmp = 1964887915, tmp)<<((25908382)^(tmp = -688293519.875164, tmp)))*(2075946055)))&(x-((x>>x)&(1395338223.7954774))))));
+  assertEquals(788002218, x -= (-788002218));
+  assertEquals(716399906, x &= (-1145868506));
+  assertEquals(145776674, x &= (-1661931477.360386));
+  assertEquals(145776674, x |= x);
+  assertEquals(-0.05255700469257692, x /= (tmp = -2773686873, tmp));
+  assertEquals(-660918434, x |= (-660918434.2915542));
+  assertEquals(1223537346, x ^= (tmp = -1871274596, tmp));
+  assertEquals(305884336, x >>= (x&x));
+  assertEquals(-1.1123775647978218e-8, x *= ((tmp = -793393031.4229445, tmp)/((tmp = -503919284, tmp)*(((((tmp = 429810625, tmp)>>>x)-((2091544148.870375)<<(((((x^x)%x)|x)/(-260773261))<<((tmp = -1323834653, tmp)&x))))*((-1231800099.3724015)+x))*((x+((-559726167)^x))>>>((-549148877)<<((((tmp = 1196115201, tmp)/((tmp = -2654658968.390111, tmp)%(tmp = -1044419580, tmp)))*(((((x>>>(733571228))+(2919762692.511447))/(-2718451983.570547))^x)+((2891533060.1804514)^((tmp = -2514488663, tmp)&x))))<<(tmp = -2526139641.6733007, tmp))))))));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x *= x);
+  assertEquals(0, x |= x);
+  assertEquals(3076984066.336236, x -= ((tmp = -3076984066.336236, tmp)+((tmp = -446575828.5155368, tmp)&x)));
+  assertEquals(1, x /= x);
+  assertEquals(1513281647.839972, x *= (1513281647.839972));
+  assertEquals(1251138155, x ^= ((tmp = 2124481052, tmp)&(2431937351.4392214)));
+  assertEquals(1, x /= x);
+  assertEquals(0, x &= (tmp = 627050040, tmp));
+  assertEquals(497153016, x ^= (497153016));
+  assertEquals(-1112801283, x |= (tmp = 2752196557, tmp));
+  assertEquals(0.5735447276296568, x /= ((((tmp = -500878794, tmp)%(tmp = -2559962372.2930336, tmp))%(2661010102))+(tmp = -1439338297, tmp)));
+  assertEquals(1.0244795995097235e-9, x /= (559840067));
+  assertEquals(0.43468811912309857, x *= (424301391));
+  assertEquals(-1972757928, x ^= (tmp = -1972757928.9227014, tmp));
+  assertEquals(-606757265, x ^= (tmp = -2923461577.264596, tmp));
+  assertEquals(-37, x >>= (((-2736561559.7474318)%(tmp = -27668972.662741184, tmp))*(2774711606)));
+  assertEquals(-1923785671, x += ((-1923785597)+x));
+  assertEquals(-3877639176, x += (tmp = -1953853505, tmp));
+  assertEquals(-4688259242, x -= ((810620066.4394455)>>(((-1474285107.459875)>>x)/(((((-570672326.4007359)>>(tmp = -3086802075, tmp))%x)>>>(((tmp = 286938819.28193486, tmp)>>>((1712478502)>>(tmp = 3045149117.796816, tmp)))<<(tmp = 750463263.292952, tmp)))&(tmp = 2055350255.5669963, tmp)))));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x <<= (1037856162.5105649));
+  assertEquals(0, x *= x);
+  assertEquals(0, x &= (997845077.4917375));
+  assertEquals(0, x *= x);
+  assertEquals(0, x *= x);
+  assertEquals(0, x <<= (((x<<x)&(57691805))>>(786927663)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x += x);
+  assertEquals(0, x &= (-2131910624.1429484));
+  assertEquals(0, x >>>= (-43787814));
+  assertEquals(-2415062021, x += (tmp = -2415062021, tmp));
+  assertEquals(-4830124042, x += x);
+  assertEquals(-186683401, x |= (tmp = 1960135383, tmp));
+  assertEquals(NaN, x *= ((tmp = -1674740173.9864025, tmp)%(((((((-432895485.7261934)-x)^x)>>>(((-1627743078.3383338)>>(179992151))<<((tmp = 911484278.0555259, tmp)|(((tmp = -3042492703, tmp)>>(((-663866035.302746)>>(((x-((440661929.50030375)>>>(tmp = 263692082, tmp)))*x)+x))/((1546004407)^(((tmp = 2023662889.1594632, tmp)*(tmp = -2456602312, tmp))+(tmp = 755602286.1810379, tmp)))))%((tmp = -336449961, tmp)|(tmp = 206780145, tmp))))))/(1068005219.1508512))<<(tmp = -474008862.6864624, tmp))/(((((((1518711056.5437899)>>>(tmp = 287418286.63085747, tmp))<<(tmp = 2823048707, tmp))^(((x<<(x^(-1600970311)))&(x>>(((tmp = 157300110.7636031, tmp)*(tmp = -3047000529, tmp))&(1743024951.3535223))))>>x))-(tmp = -2895435807, tmp))*((tmp = -314120704, tmp)&(tmp = 1759205369, tmp)))>>(tmp = 1833555960.046526, tmp)))));
+  assertEquals(NaN, x -= (tmp = 694955369, tmp));
+  assertEquals(NaN, x *= (x%x));
+  assertEquals(0, x |= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x &= x);
+  assertEquals(NaN, x /= (x+x));
+  assertEquals(NaN, x %= ((tmp = -1595988845, tmp)*((1754043345)>>>(-601631332))));
+  assertEquals(0, x >>>= (tmp = 862768754.5445609, tmp));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x *= (tmp = -1774545519, tmp));
+  assertEquals(0, x >>>= (tmp = -2492937784, tmp));
+  assertEquals(0, x %= ((((x<<(-1657262788.2028513))&((x^(tmp = -671811451, tmp))<<(-2984124996)))^(1455422699.7504625))-((-340550620)>>x)));
+  assertEquals(918278025, x ^= ((tmp = -918278027, tmp)^((tmp = 2889422870, tmp)/(tmp = -657306935.7725658, tmp))));
+  assertEquals(918278025, x %= (2603186571.0582614));
+  assertEquals(107034679.32509923, x %= (tmp = -811243345.6749008, tmp));
+  assertEquals(53517339, x >>= (x%((((x*((tmp = -983766424, tmp)^(-1881545357.8686862)))|(tmp = -1429937087, tmp))>>((x<<x)>>((((tmp = -2347470476, tmp)&x)+((x&x)<<(396061331.6476157)))*(tmp = -3136296453.209073, tmp))))>>>(((tmp = 908427836, tmp)|(tmp = 207737064, tmp))|(((1253036041)-(tmp = 2705074182, tmp))+(-431215157.82083917))))));
+  assertEquals(53477378, x &= ((((-1128036654.165636)*x)+x)>>(x>>(3080099059))));
+  assertEquals(0, x >>= (-590692293));
+  assertEquals(0, x %= (-2395850570.9700127));
+  assertEquals(0, x *= ((tmp = 1377485272, tmp)&(1129370608)));
+  assertEquals(0, x += (x>>>(x%(((((tmp = -1746827236, tmp)+((tmp = -326913490, tmp)&((-58256967)&x)))*(tmp = -1176487022.001651, tmp))>>>(-2089147643))-x))));
+  assertEquals(0, x <<= (tmp = 1073298160.2914447, tmp));
+  assertEquals(-837811832, x ^= (-837811832));
+  assertEquals(102760448, x <<= (tmp = 2833582450.4544373, tmp));
+  assertEquals(0, x &= (((((((tmp = 2595641175, tmp)*x)+(tmp = -2049260172.1025927, tmp))%((2986747823)>>(tmp = -2120598518, tmp)))&((tmp = -2742408622, tmp)&x))>>x)*((1043474247.9601482)&(tmp = 1686365779.9885998, tmp))));
+  assertEquals(0, x >>= ((tmp = 1717862848, tmp)-(tmp = 1077024446.4160957, tmp)));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x /= (-1669429787.975099));
+  assertEquals(NaN, x -= (-2299895633.4807186));
+  assertEquals(138173970, x ^= (138173970.56627905));
+  assertEquals(-2084183776, x <<= (3073345316));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x >>= (-3080556066.068573));
+  assertEquals(0, x &= ((tmp = -2587514820, tmp)*(x-((x^(1995672257))*(1125326747.2339358)))));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x >>= (tmp = 2139186585, tmp));
+  assertEquals(-1904096640, x |= ((-602301360.1919911)*(-1270444810)));
+  assertEquals(1073741824, x <<= (tmp = -1069467849, tmp));
+  assertEquals(1073741824, x ^= (x-x));
+  assertEquals(536870912, x >>>= (-1579466367.160293));
+  assertEquals(512, x >>= (972402804.3890183));
+  assertEquals(512, x &= (tmp = 2664796831, tmp));
+  assertEquals(16777216, x <<= (-2738292561));
+  assertEquals(0, x >>>= ((((1397663615.3889246)|(1117420260.6730964))-(-1173734560))<<((tmp = 1007006104.0172879, tmp)<<((tmp = -623002097, tmp)%(tmp = -35829654.379403114, tmp)))));
+  assertEquals(1200191544, x ^= (tmp = -3094775752, tmp));
+  assertEquals(71, x >>>= x);
+  assertEquals(71, x |= x);
+  assertEquals(1394763772, x += (1394763701));
+  assertEquals(-1.492717171027427, x /= ((x&(tmp = 1243787435, tmp))-(2043911970.26752)));
+  assertEquals(-1.1002448961224718e-8, x /= ((((835185744)*(((tmp = 2165818437, tmp)^(tmp = 2567417009.1166553, tmp))/x))/x)/(((63485842.39971793)^(2668248282.597389))/x)));
+  assertEquals(0, x <<= (tmp = 1598238578.637568, tmp));
+  assertEquals(0, x |= (x&((tmp = -1812945547.5373957, tmp)>>>x)));
+  assertEquals(0, x >>>= (x+(-1969679729.7299538)));
+  assertEquals(1582033662, x += (tmp = 1582033662, tmp));
+  assertEquals(1, x >>>= x);
+  assertEquals(-550748739, x += ((tmp = -550748740, tmp)/(x&((2537822642.235506)^((-2167656297)%(tmp = 1161201210, tmp))))));
+  assertEquals(-268921, x >>= (tmp = 1916069547.7381654, tmp));
+  assertEquals(-0.00021776939364231114, x /= (tmp = 1234888868, tmp));
+  assertEquals(0, x <<= (-1036375023));
+  assertEquals(0, x &= ((((x/(2398886792.27443))&(x|((-1813057854.1797302)-x)))&(x/(((tmp = 3091133731.4967556, tmp)|(3013139691.823039))<<x)))>>>(2542784636.963599)));
+  assertEquals(0, x += ((x*x)/(tmp = 347079383, tmp)));
+  assertEquals(788347904, x |= ((1462257124.6374629)*((3180592147.4065146)-(x&(1922244678)))));
+  assertEquals(2130672735, x |= (tmp = -2846986145, tmp));
+  assertEquals(-1331327970, x ^= ((656251304)-(tmp = 1489152359, tmp)));
+  assertEquals(-0.14377179742889856, x %= (((2889747597.813753)-(1730428996))/(((tmp = -1378710998, tmp)&x)|x)));
+  assertEquals(-1754612583.143772, x += ((-1754725729)^((-2285838408)>>>(1434074349))));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x &= (tmp = -1031961332, tmp));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x /= (3059476325));
+  assertEquals(NaN, x *= ((x*((((tmp = 13529540.462185979, tmp)&x)^((x<<(-1312696238.1628869))&(-2029766712.3852897)))>>x))/x));
+  assertEquals(1657339940, x ^= ((tmp = -488956817.1491232, tmp)&(tmp = -2352413900.1983714, tmp)));
+  assertEquals(-530683621952432200, x *= (tmp = -320202035.2882054, tmp));
+  assertEquals(229226258, x ^= ((tmp = -1263410990.026416, tmp)+(((-808046349)&(tmp = -1294442506, tmp))&((tmp = 1147437219, tmp)<<((tmp = -820299900, tmp)-(tmp = -1947748943.3443851, tmp))))));
+  assertEquals(7163320, x >>= (-2631307131));
+  assertEquals(-68, x |= (((-1271721343)>>x)%x));
+  assertEquals(-39956523818.38862, x *= (587595938.505715));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>>= ((x^(x+x))<<(tmp = 265212367, tmp)));
+  assertEquals(0, x |= (((x>>((tmp = 2294761023, tmp)/(x>>(2125624288))))&((-2125650113)|(tmp = 1014409884, tmp)))%(tmp = -527324757, tmp)));
+  assertEquals(0, x >>= ((tmp = 2267075595, tmp)*(-1681569641.8304193)));
+  assertEquals(0, x >>>= x);
+  assertEquals(0.5738410949707031, x -= ((tmp = -1846572645.573841, tmp)%((((((x^(((-156613905.64173532)/x)<<x))+((x|((2405109060)>>>x))^x))/(570585894.8542807))+(x&(-2544708558)))^((((tmp = -2539082152.490635, tmp)+((((-657138283)/(2204743293))-((tmp = -1422552246.565012, tmp)+x))<<(x-x)))>>(x/(x>>>(tmp = -3027022305.484394, tmp))))<<x))&((-2066650303.3258202)/(tmp = -1666842593.0050385, tmp)))));
+  assertEquals(0, x >>>= ((((tmp = 2473451837.613817, tmp)>>((2526373359.1434193)>>(x<<x)))+((tmp = -579162065, tmp)+((tmp = -3115798169.551487, tmp)-(tmp = 933004398.9618305, tmp))))&(tmp = 131167062, tmp)));
+  assertEquals(-2067675316, x ^= (-2067675316.6300585));
+  assertEquals(543772, x >>>= x);
+  assertEquals(-1073741824, x <<= x);
+  assertEquals(3221225472, x >>>= ((x*(1478586441.081221))&(tmp = -3050416829.2279186, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x *= x);
+  assertEquals(-1017771903.0298333, x -= (1017771903.0298333));
+  assertEquals(0.6404112721149928, x /= ((tmp = -144667370, tmp)^(-2849599562)));
+  assertEquals(-2410517638773644000, x -= (((tmp = 1759631550, tmp)*x)*((((tmp = -2949481475, tmp)>>>x)*x)|(tmp = -2977983804, tmp))));
+  assertEquals(-0, x %= (x+((((tmp = -1307866327.7569134, tmp)<<((x&((tmp = -2380043169.8405933, tmp)|x))>>(472992789.7639668)))|(((((x<<(tmp = -1416427232.7298179, tmp))%(-1404989679.409946))*((x/(tmp = -992416608, tmp))/(tmp = 524646495, tmp)))-(tmp = 734405570, tmp))>>x))/(1079256317.7325506))));
+  assertEquals(0, x <<= (tmp = 2459834668, tmp));
+  assertEquals(-0, x /= (tmp = -1892164840.5719755, tmp));
+  assertEquals(0, x >>= (x|(((1299844244)>>>(((tmp = -2422924469.9824634, tmp)|x)-((((1914590293.2194016)+(-3033885853.8243046))-((tmp = -1720088308, tmp)%x))<<(tmp = 2210817619, tmp))))<<x)));
+  assertEquals(0, x <<= (((tmp = 3192483902.841396, tmp)>>>(((x^(2944537154))|(tmp = -1334426566, tmp))*(((((((-2705218389)&x)+(1987320749))+(tmp = -111851605, tmp))|(2894234323))-(265580345))&x)))%(((tmp = 1431928204.6987057, tmp)&(tmp = 914901046, tmp))&(x>>>x))));
+  assertEquals(0, x >>>= (tmp = 1941940941, tmp));
+  assertEquals(0, x %= (3089014384));
+  assertEquals(0, x += ((tmp = 2948646615, tmp)*x));
+  assertEquals(-0, x /= (tmp = -1480146895, tmp));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x %= (-2995257724.158043));
+  assertEquals(NaN, x %= (tmp = 2714835455, tmp));
+  assertEquals(NaN, x /= (tmp = -311440765.98078775, tmp));
+  assertEquals(NaN, x -= (-1600234513.697098));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x <<= (-1499045929));
+  assertEquals(-0, x *= (-2491783113));
+  assertEquals(0, x ^= (x%((x>>(((1234398704.3681123)>>>x)%(x+x)))>>(402257223.4673699))));
+  assertEquals(-643225204, x ^= (((-55960194.698637486)+((((721411198)-(((tmp = 1308676208.7953796, tmp)%(2242904895))-x))>>((((tmp = 332791012, tmp)&((tmp = -2094787948, tmp)/((x/(2427791092))^(2444944499.6414557))))%(((x+(1253986263.5049214))+(((((3135584075.248715)+((tmp = -2569819028.5414333, tmp)%(440908176.1619092)))>>>(x<<((3061615025)-x)))%x)%(x+((2369612016)*((((tmp = 1173615806, tmp)*(-1910894327))&(2428053015.077821))*(-55668334.70082307))))))<<(tmp = -2129259989.0307562, tmp)))+(1579400360)))%((-3053590451.8996153)>>x)))+(x>>(x%(x^((-1772493876)^x))))));
+  assertEquals(413738663060841600, x *= x);
+  assertEquals(1581062538.4501781, x %= ((tmp = -1298397672.0300272, tmp)-((2237197923)+(tmp = -1385478459, tmp))));
+  assertEquals(755644566.8709538, x %= (tmp = -825417971.5792243, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>>= ((89330582)%(-1012731642.4855506)));
+  assertEquals(0, x >>>= x);
+  assertEquals(NaN, x %= ((x>>>((x/(tmp = -1848848941.2352903, tmp))>>>(tmp = -71862893, tmp)))&(-2385996598.2015553)));
+  assertEquals(NaN, x += (-2292484503.318904));
+  assertEquals(NaN, x *= (2961064461));
+  assertEquals(NaN, x += (x<<((2076798243.6442)/((tmp = -81541044.75366282, tmp)^((3041366498.551101)+((2126874365)/(tmp = -177610359, tmp)))))));
+  assertEquals(NaN, x %= ((x/((x/x)+x))>>>x));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x += (1171761980.678));
+  assertEquals(NaN, x += ((2355675823)<<(-390497521)));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x &= (tmp = -658428225.56619, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= (1643310725.5713737));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x <<= (-397005335.3712895));
+  assertEquals(0, x >>>= (tmp = -2804713458.166788, tmp));
+  assertEquals(0, x <<= (((((((tmp = 1879988501, tmp)%(1528081313.9360204))+(1376936736))*((((x>>>((1736268617.339198)>>>(-2598735297.4277673)))<<((((((((-2742982036)/(231867353.4549594))-(875335564))<<x)|((2241386341.742653)<<((-22024910.828409433)&(x<<x))))*(-756987803.5693252))+x)^(tmp = 1084498737, tmp)))<<(1920373881.8464394))&(2370827451.82652)))&(x^(tmp = -891503574, tmp)))<<x)>>>((-1519588625.2332087)^(483024636.2600144))));
+  assertEquals(52193878.40997505, x -= ((tmp = -341753803.40997505, tmp)%(tmp = -96519975, tmp)));
+  assertEquals(-1665844168.938803, x -= (1718038047.348778));
+  assertEquals(3.6962232549405003e-19, x /= (((((-809583468.5507183)>>>((tmp = 286797763, tmp)%((1579183142.7321532)/(1853824036.001172))))<<x)>>(((x|x)^((tmp = -2641304815, tmp)<<(x<<x)))>>(((((268338128.8300134)&(-1778318362.8509881))*(751081373.346478))<<(((525066612)>>(-1139761212))*(2949167563.299916)))<<x)))+((tmp = 664905121, tmp)*((-2208280205)*(3069462420)))));
+  assertEquals(4710721795.110161, x += (((217604832)+((1307891481.781326)-x))+(tmp = 3185225481.328835, tmp)));
+  assertEquals(0, x %= x);
+  assertEquals(0, x -= (((x>>>(x/(tmp = 46977522.46204984, tmp)))>>(-2466993199.615269))&(tmp = 14524430.287991166, tmp)));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x /= (tmp = 578120637, tmp));
+  assertEquals(-17267104, x -= (((tmp = 1515285919.495792, tmp)+(((tmp = -1364790286.7057304, tmp)+((954599071)>>((897770243.1509961)*x)))^x))>>>(566027942.1732262)));
+  assertEquals(-17267104, x &= x);
+  assertEquals(189138241, x ^= ((tmp = 1565742675.9503145, tmp)-((tmp = 1737806643, tmp)|((x*(tmp = -1382435297.5955122, tmp))*(-2820516692.153056)))));
+  assertEquals(189138241, x %= (x*(tmp = -1670678493, tmp)));
+  assertEquals(1693, x %= ((-2328713314)>>>(1623637325)));
+  assertEquals(1693, x %= ((-1019394014)*(x|x)));
+  assertEquals(3386, x += x);
+  assertEquals(9268970871604, x *= (2737439714));
+  assertEquals(-4720.120483643183, x /= (tmp = -1963714889, tmp));
+  assertEquals(-1, x >>= ((x^(((-2404688047.455056)|((1439590234.6203847)<<(tmp = -2496557617, tmp)))/((x<<((tmp = 1865549512.282249, tmp)/(((360384191.55661833)>>(tmp = -1225297117.344188, tmp))>>>(2703264010.4122753))))*(1521960888.0071676))))%(tmp = 2834001448.0508294, tmp)));
+  assertEquals(63, x >>>= (x&(-3079339174.6490154)));
+  assertEquals(0, x >>>= (1039770956.6196513));
+  assertEquals(0, x >>>= (-1074820214));
+  assertEquals(0, x >>>= (x/x));
+  assertEquals(0, x >>= ((tmp = -449117604.2811785, tmp)&x));
+  assertEquals(-0, x /= (tmp = -118266935.1241343, tmp));
+  assertEquals(2226140134, x += (tmp = 2226140134, tmp));
+  assertEquals(2068827161, x ^= ((tmp = -1950744808.846384, tmp)>>((2258661151)^((tmp = -1118176421.8650177, tmp)<<(2828634014)))));
+  assertEquals(123, x >>>= (-1779624840.0515127));
+  assertEquals(0, x >>>= (x|((tmp = -239082904, tmp)<<(tmp = 1404827607, tmp))));
+  assertEquals(0, x >>>= x);
+  assertEquals(1793109749, x ^= (tmp = -2501857547.710491, tmp));
+  assertEquals(855, x >>>= x);
+  assertEquals(0, x >>>= (-847289833));
+  assertEquals(0, x %= (-2271241045));
+  assertEquals(169648072, x ^= (((tmp = 169648072.66759944, tmp)^x)|x));
+  assertEquals(176025927479164930, x *= ((tmp = 1111997198.8803885, tmp)<<(tmp = 2913623691, tmp)));
+  assertEquals(176025926613281700, x += ((tmp = -865883245, tmp)<<(x+(-2624661650))));
+  assertEquals(3406506912, x >>>= ((x|(tmp = 2436016535, tmp))*(((tmp = -1222337225, tmp)<<((1765930268)&x))*(tmp = 1600702938, tmp))));
+  assertEquals(1.694694170868292, x %= (x/(-1597121830.794548)));
+  assertEquals(0, x >>= (tmp = -2443203089, tmp));
+  assertEquals(0, x >>>= (1323174858.2229874));
+  assertEquals(0, x &= ((tmp = 846556929.2764134, tmp)|(((1483000635.0020065)|(-3151225553))|(tmp = -229028309, tmp))));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>= ((((((-2677334787)>>>x)>>((tmp = 496077992, tmp)&((((x<<(x*(tmp = 1095163344.2352686, tmp)))+(-952017952))%((x<<((x*x)/(tmp = 2983152477, tmp)))^((tmp = -939521852.1514642, tmp)^(tmp = 143967625.83755958, tmp))))*((tmp = 551827709.8366535, tmp)>>>x))))^((-1552681253.69869)-(-1874069995)))>>>(x>>(x%(tmp = -2554673215, tmp))))|(tmp = -190693051.77664518, tmp)));
+  assertEquals(0, x /= (tmp = 427402761.37668264, tmp));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x |= (x>>>(((((-543326164.0673618)>>>(-2344090136.707964))>>>((((-563350246.6026886)/x)/(1525481037.3332934))&(tmp = -2917983401.88958, tmp)))^(-1094667845.1208413))^x)));
+  assertEquals(0, x &= (1080322749.897747));
+  assertEquals(0, x %= (tmp = -1572157280, tmp));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x %= ((377280936)|x));
+  assertEquals(708335912, x -= (tmp = -708335912, tmp));
+  assertEquals(2766937, x >>>= x);
+  assertEquals(547342779, x += (tmp = 544575842, tmp));
+  assertEquals(546273751, x -= ((x>>>(472833385.9560914))|((tmp = -1164832103.9970903, tmp)/(3147856452.1699758))));
+  assertEquals(546273751, x &= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>>= (tmp = -3181805175, tmp));
+  assertEquals(-375546685, x |= (-375546685.08261824));
+  assertEquals(1089992785780217200, x *= (tmp = -2902416209, tmp));
+  assertEquals(0, x %= x);
+  assertEquals(-1854981526, x -= ((x-x)-(-1854981526)));
+  assertEquals(-3709963052, x += x);
+  assertEquals(-316772482, x %= (tmp = -1696595285, tmp));
+  assertEquals(-316772482, x |= x);
+  assertEquals(1, x /= x);
+  assertEquals(0, x -= x);
+  assertEquals(-1418375842, x ^= (-1418375842));
+  assertEquals(-2, x >>= x);
+  assertEquals(-4, x += x);
+  assertEquals(-8388608, x &= (x<<(-350555339.30086184)));
+  assertEquals(-16777216, x += x);
+  assertEquals(-0, x %= x);
+  assertEquals(1083355129, x += (tmp = 1083355129, tmp));
+  assertEquals(0, x &= (((tmp = 389729053, tmp)-(tmp = 2944192190.0939536, tmp))/(x-(2081712461.2657034))));
+  assertEquals(0, x += x);
+  assertEquals(-3, x += ((3147270119.5831738)>>((2455837253.1801558)%((-2100649096)>>(((290236808.01408327)|(x&((2661741230.3235292)|((tmp = 1686874589.4690177, tmp)<<x))))*(x+(tmp = 2327674670, tmp)))))));
+  assertEquals(-3, x %= ((x>>(((-2962686431)%x)>>((((2438370783)-(tmp = 2667305770.4839745, tmp))>>>x)>>>x)))<<((x&(tmp = 1428498616, tmp))|((tmp = 2621728539.102742, tmp)/(-204559901)))));
+  assertEquals(2, x ^= (x|((((tmp = 1751230118.6865973, tmp)/(-867465831.207304))>>((-808143600.0912395)+(-2882191493.0506454)))^x)));
+  assertEquals(2, x %= (-2015954220.2250996));
+  assertEquals(0, x >>>= (tmp = 401373999, tmp));
+  assertEquals(0, x >>= (2371830723));
+  assertEquals(0, x >>>= ((((tmp = 2765919396, tmp)-x)-(530310269.7131671))|(tmp = -615761207.9006102, tmp)));
+  assertEquals(-145389011, x ^= (tmp = -145389011, tmp));
+  assertEquals(-145389011, x |= x);
+  assertEquals(1632929832, x &= (-2518898392));
+  assertEquals(4190540017.751949, x += (tmp = 2557610185.751949, tmp));
+  assertEquals(4980024282.153588, x += ((1841304364.1177452)%(tmp = 1051820099.7161053, tmp)));
+  assertEquals(0, x >>>= (((((1379314342.4233718)>>((-2782805860)^((x%(tmp = 1328845288, tmp))>>>(tmp = 901403219.858733, tmp))))+(x/((tmp = -3078904299, tmp)/x)))/x)|(x|(1399702815))));
+  assertEquals(-1820494882, x ^= (tmp = -1820494882.407127, tmp));
+  assertEquals(-305870376, x %= (tmp = -757312253, tmp));
+  assertEquals(-577530443, x += (x|(tmp = -1958083619.6653333, tmp)));
+  assertEquals(333541412591776260, x *= x);
+  assertEquals(-949341696, x >>= ((((1550069663)<<((x>>>(tmp = 2406565178.902887, tmp))>>>((1844746612.632984)/((tmp = 2233757197, tmp)*((-1524891464.1028347)>>(tmp = 2498623474.5616803, tmp))))))&x)<<(x&(tmp = -370379833.3884752, tmp))));
+  assertEquals(-277202090, x |= ((-762200848.8405354)-(tmp = 1749136282, tmp)));
+  assertEquals(0.13704539927239265, x /= (tmp = -2022702633.373563, tmp));
+  assertEquals(0, x -= x);
+  assertEquals(0, x %= ((132951580.19304836)-((427623236.27544415)-(1212242858))));
+  assertEquals(0, x &= ((449148576)&(-1609588210.249217)));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x -= x);
+  assertEquals(-0, x /= (tmp = -1640777090.9694843, tmp));
+  assertEquals(0, x &= (((tmp = -1923412153, tmp)>>>((x>>(tmp = 3027958119.0651507, tmp))+(60243350)))>>(tmp = -2610106062, tmp)));
+  assertEquals(0, x ^= (((-186998676)/(tmp = 2697937056, tmp))-x));
+  assertEquals(-1147950080, x |= ((2425449461)*(tmp = -2525854833, tmp)));
+  assertEquals(457688198, x ^= (2698274950.660941));
+  assertEquals(8724, x %= ((1174351031)>>>((371599047.36048746)+(3025292010))));
+  assertEquals(0, x <<= (tmp = -710011617, tmp));
+  assertEquals(0, x >>>= (1693410026));
+  assertEquals(1443005362, x ^= ((tmp = -2851961934, tmp)+((((x%x)-(tmp = 547622400, tmp))<<(((tmp = 722396486.5553623, tmp)|x)>>>((((tmp = -542268973.5080287, tmp)<<(tmp = 1347854903.771954, tmp))>>>(tmp = -889664427.7115686, tmp))&((tmp = 1549560114, tmp)*(tmp = 964918035, tmp)))))&(-2422502602.920377))));
+  assertEquals(3986573462, x -= (-2543568100));
+  assertEquals(7973146924, x += x);
+  assertEquals(-1, x >>= (-75987297));
+  assertEquals(-12, x += ((2940824338.64834)>>(tmp = 3061467355, tmp)));
+  assertEquals(-3.8229398525977614e-8, x /= (313894554));
+  assertEquals(-2.890709270374084e-17, x /= (tmp = 1322491989, tmp));
+  assertEquals(0, x |= (x-x));
+  assertEquals(0, x >>>= (tmp = -1205300664, tmp));
+  assertEquals(-0, x /= (((2869505187.6914144)>>(tmp = 1541407065, tmp))/(((-571132581)>>>(x>>x))/((x^(170373762.8793683))>>>((((tmp = -363073421.05897164, tmp)|(((tmp = -1591421637, tmp)>>(1095719702.8838692))&(636687681.9145031)))^x)^(x|x))))));
+  assertEquals(-1487828433, x ^= (-1487828433.3462324));
+  assertEquals(-0, x %= x);
+  assertEquals(1716342498, x -= ((tmp = 2578624798, tmp)^x));
+  assertEquals(1636, x >>= ((264194540)>>>(-801900756)));
+  assertEquals(0, x >>>= ((tmp = 2502688876, tmp)+((x<<(x|((-628272226.0338528)|((x<<(-2083074091))>>>(tmp = 1692123246.8418589, tmp)))))>>(1594759826.990993))));
+  assertEquals(0, x <<= (tmp = -904399643, tmp));
+  assertEquals(NaN, x /= ((x^(x-x))%((tmp = 1744962024.4882128, tmp)%x)));
+  assertEquals(NaN, x /= (-1013142883.1845908));
+  assertEquals(NaN, x /= ((tmp = 793633198, tmp)^(-2993598490.8659954)));
+  assertEquals(0, x &= (x>>((tmp = 1200937851, tmp)<<(((tmp = -2807378465, tmp)&(tmp = -143778237, tmp))|(tmp = -1200772223, tmp)))));
+  assertEquals(0, x <<= x);
+  assertEquals(88144, x |= (((((tmp = 3002723937.8560686, tmp)*(tmp = -3171720774.2612267, tmp))%(((tmp = -2586705978.7271833, tmp)%((x+(-1553704278))&(2405085526.501994)))>>((-240842053)>>>(((((tmp = -1886367228.4794896, tmp)>>>x)^(tmp = 2604098316, tmp))^(tmp = 1362808529, tmp))<<((tmp = -1062263918, tmp)|((-172718753)%(tmp = -1910172365.4882073, tmp)))))))^((1444153362)>>((x&((-1205465523.2604182)^(tmp = -2062463383, tmp)))>>(tmp = 956712476, tmp))))>>((((-1004215312)^((((-1707378612.5424936)^(tmp = 2372161553, tmp))/((tmp = 1802586581, tmp)*((2082257.1896460056)&((tmp = -1270773477, tmp)^(tmp = 942517360.3447798, tmp)))))+x))%((((666494127)^(x^x))>>>(tmp = -2592829775, tmp))+((-1601528223)+((x+(tmp = -2417034771.7409983, tmp))>>>((tmp = -730673817, tmp)*x)))))>>x)));
+  assertEquals(-2603179111.7557006, x -= ((2603267255.755627)+(x/(1200979191.2823262))));
+  assertEquals(1691788185, x >>= (tmp = 3088840032, tmp));
+  assertEquals(-168382533, x |= (tmp = -780750941.4590135, tmp));
+  assertEquals(-168382533, x >>= (60741120.48285198));
+  assertEquals(-134287365, x |= (x*(tmp = 834637940.7151251, tmp)));
+  assertEquals(-1481917089, x -= (tmp = 1347629724, tmp));
+  assertEquals(1, x >>>= x);
+  assertEquals(262144, x <<= (2680216914));
+  assertEquals(1075132032, x ^= (x-((tmp = 3220359552.3398685, tmp)^(((-434474746.6039338)|((((((((tmp = 1945689314.9683735, tmp)>>(1300022273))>>>(333705550))&x)%(588357521))-(x+(x^(((tmp = -134560382, tmp)+x)-((((994246147.7195556)-(-1506599689.7383268))%(x<<x))>>((1256426985.5269494)+(tmp = 1860295952.8232574, tmp)))))))^(((tmp = 917333220.2226384, tmp)>>x)>>>(tmp = 865898066, tmp)))%((x|(x%((tmp = -2660580370, tmp)&(tmp = 2966426022, tmp))))*x)))/(((tmp = 682585452, tmp)&(-3219368609))+((tmp = -1330253964, tmp)+((x&(2857161427))/x)))))));
+  assertEquals(274944, x &= ((2606953028.1319966)-(-1707165702)));
+  assertEquals(266752, x &= ((x<<((x+(x+(x^(-1570175484))))^x))^(x+(x<<(tmp = 90330700.84649956, tmp)))));
+  assertEquals(266752, x &= ((((x*(tmp = 2033225408, tmp))-(x-((tmp = 1507658653, tmp)/(-3016036094))))>>>((1497480588)>>(2784070758)))|(tmp = -3025904401.93921, tmp)));
+  assertEquals(-1680442631, x |= ((x/(445284843))|((tmp = 2614520057.2723284, tmp)<<x)));
+  assertEquals(40851947, x >>>= (tmp = -1577031386.938616, tmp));
+  assertEquals(2493, x >>= ((3044630989.3662357)-(-2670572992.8580284)));
+  assertEquals(-0.0000017317105653562252, x /= (-1439617017.9207587));
+  assertEquals(0, x &= (2359806567));
+  assertEquals(623768541, x ^= (623768541));
+  assertEquals(1028567149.0716183, x += (((tmp = 1307794561, tmp)%(x>>x))-(-404798608.0716183)));
+  assertEquals(-1.2971762489811298, x /= (tmp = -792927830.6471529, tmp));
+  assertEquals(-1.2971762489811298, x %= ((-2426421701.2490773)/(-689566815.3393874)));
+  assertEquals(-2147483648, x <<= x);
+  assertEquals(-2147483648, x &= (tmp = -869991477, tmp));
+  assertEquals(-268435456, x >>= (1383186659));
+  assertEquals(0, x -= x);
+  assertEquals(-2009742037, x |= (-2009742037.5389993));
+  assertEquals(-1386630820, x ^= (627864695));
+  assertEquals(-1033479103975173600, x *= (tmp = 745316697.9046186, tmp));
+  assertEquals(-1628048487, x |= (2662654361));
+  assertEquals(325551, x >>>= (340874477));
+  assertEquals(-1235730537, x ^= (tmp = 3059533880.0725217, tmp));
+  assertEquals(-1235730537, x %= (2247137328));
+  assertEquals(-220200960, x <<= ((x>>x)-x));
+  assertEquals(0, x <<= ((tmp = 337220439.90653336, tmp)|(tmp = 2901619168.375105, tmp)));
+  assertEquals(0, x >>>= ((-2114406183)/x));
+  assertEquals(0, x %= ((1425828626.3896675)/x));
+  assertEquals(0, x >>>= ((3213757494)>>>(2595550834.3436537)));
+  assertEquals(0, x <<= x);
+  assertEquals(-0, x /= ((1544519069.5634403)/((tmp = -1332146306, tmp)&(-762835430.0022461))));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>= (x|((((x*((-786272700)+x))<<x)+((tmp = -1868484904, tmp)-(tmp = -1692200376, tmp)))+(-1010450257.6674457))));
+  assertEquals(0, x -= x);
+  assertEquals(0, x ^= (x>>>(706010741)));
+  assertEquals(-964928697, x |= (-964928697));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>= ((((tmp = 1778003555.3780043, tmp)>>(x%((tmp = -766158535, tmp)^((-2681449292.8257303)%((x-(x|(tmp = 1966478387.2443752, tmp)))^(((tmp = -1848398085, tmp)&x)>>>(tmp = -2860470842, tmp)))))))%(tmp = 2315077030, tmp))^x));
+  assertEquals(0, x ^= x);
+  assertEquals(-288007757, x ^= ((tmp = 183607156.1803962, tmp)-(tmp = 471614914, tmp)));
+  assertEquals(-270573581, x |= (tmp = -849475741.9424644, tmp));
+  assertEquals(-2129929, x |= (((((1942852445)&(tmp = 1280372312, tmp))*(x*(tmp = -1601900291, tmp)))^((509080002.81080174)-(tmp = 2699498226.9164257, tmp)))>>(((-335361221)>>(tmp = 843134832, tmp))%(-35532542))));
+  assertEquals(-232622355, x ^= ((-3060885134.5375547)-(((tmp = 1965966723, tmp)-((tmp = 1248630129.6970558, tmp)<<(tmp = 1859637857.5027392, tmp)))*x)));
+  assertEquals(-52149658093200070, x *= (224181627.31264615));
+  assertEquals(-697122968, x ^= (x-(x+(tmp = 2747211186.407712, tmp))));
+  assertEquals(-2146269688, x &= ((tmp = -1466710519, tmp)^(x/(1419998975))));
+  assertEquals(-536567422, x >>= (((((tmp = -1760701688.999274, tmp)>>(-1821976334))/(((tmp = -1660849531, tmp)>>>x)-((x+((tmp = -2489545009.4327965, tmp)>>>((tmp = -267360771.39148235, tmp)^x)))*(((-1453528661)%x)>>>(((243967010.3118453)/((((((2977476024)>>>((-1630798246)<<x))&(591563895.2506002))*(((2668543723.9720144)>>>x)|(1600638279)))^x)>>(x<<(tmp = -152589389, tmp))))>>>(x|(2821305924.9225664)))))))+(618968002.8307843))%(tmp = -1005408074.368274, tmp)));
+  assertEquals(40962, x &= (114403906));
+  assertEquals(19741977727890, x *= ((-2367133915.963945)>>>(-3119344126)));
+  assertEquals(1313341440, x <<= x);
+  assertEquals(626, x >>>= ((((-333992843)%(tmp = -2742280618.6046286, tmp))>>>x)|x));
+  assertEquals(0, x <<= (2598188575));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x ^= (x%((2507288229.3233204)&(tmp = -1714553169.9276752, tmp))));
+  assertEquals(0, x /= ((633436914.3859445)>>>(tmp = 1579804050.6442273, tmp)));
+  assertEquals(0, x *= ((tmp = 1172218326, tmp)<<((tmp = -2491306095.8456626, tmp)*(((tmp = 1305371897.9753594, tmp)>>((x^(((3077992060)*x)<<(492815553.904796)))>>((652151523)|x)))%x))));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x %= (1118131711));
+  assertEquals(0, x &= ((tmp = 2734673884, tmp)|(x-((tmp = 2694578672.8975897, tmp)*(((x>>(2350811280.974167))*(1052548515))&(x^(x*(tmp = -1336287059.0982835, tmp))))))));
+  assertEquals(-2632782867.1256156, x += ((tmp = -2743992725.1256156, tmp)+(tmp = 111209858, tmp)));
+  assertEquals(-0, x %= x);
+  assertEquals(0, x >>>= (((tmp = -2050519887, tmp)^(106865302.74529803))>>(1642851915.2909596)));
+  assertEquals(-171964826, x |= (tmp = -171964826.6087358, tmp));
+  assertEquals(-2.113405951193522, x /= (tmp = 81368572.80206144, tmp));
+  assertEquals(3, x >>>= x);
+  assertEquals(0, x %= x);
+  assertEquals(-1717345907.837667, x += (-1717345907.837667));
+  assertEquals(-100964883, x |= (tmp = -109574931.80629134, tmp));
+  assertEquals(-33849857, x |= (-974111718.2433801));
+  assertEquals(1, x >>>= (tmp = -2556222849.005595, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>>= (-1796630999.4739401));
+  assertEquals(0, x >>>= x);
+  assertEquals(2031695758, x += (((x/(((tmp = -2364918403, tmp)%(x^((tmp = 277767803.6375599, tmp)>>((((tmp = 540036080, tmp)/(x|(2665298931)))/(x|((x>>(-2035456216.6165116))<<(2143184420.5651584))))^x))))&(tmp = 927798419.8784283, tmp)))-(-2031695758))>>>x));
+  assertEquals(2031695758, x |= x);
+  assertEquals(2031695758, x <<= (((x>>(x%x))|(tmp = -1164531232.7384055, tmp))*x));
+  assertEquals(124004, x >>>= x);
+  assertEquals(529846352, x += ((529722348)%((2417645298.865121)|(x>>(x>>>(x+x))))));
+  assertEquals(60067920, x &= (((tmp = -3166008541.8486233, tmp)-x)|(x%x)));
+  assertEquals(1415594240755200, x *= ((-2786707452.873729)>>(((tmp = -2369315809, tmp)*((1559868465)|(1011218835.1735028)))>>>x)));
+  assertEquals(1415595182259140, x += (941503939.9023957));
+  assertEquals(0, x <<= ((tmp = 2887184784.265529, tmp)/(-2575891671.0881453)));
+  assertEquals(0, x &= ((tmp = -1546339583, tmp)>>>(tmp = -587433830, tmp)));
+  assertEquals(0, x *= (((tmp = 1356991166.5990682, tmp)%(tmp = -284401292, tmp))*(1869973719.9757812)));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x ^= (((tmp = 92575404.43720293, tmp)>>>(263475358.17717505))%x));
+  assertEquals(0, x <<= (((561514358)*(tmp = -439584969, tmp))%((((-3005411368.7172136)+x)|(-2230472917))&x)));
+  assertEquals(0, x >>= ((x>>>x)-((x-(1630649280.510933))+x)));
+  assertEquals(0, x >>= (tmp = -1772403084.7012017, tmp));
+  assertEquals(0, x *= x);
+  assertEquals(0, x += x);
+  assertEquals(0, x &= x);
+  assertEquals(0, x >>= (tmp = 1622680387, tmp));
+  assertEquals(1033887633558225200, x -= ((-510616337)*(tmp = 2024783695, tmp)));
+  assertEquals(-2.8073538539158063e+27, x *= (tmp = -2715337492, tmp));
+  assertEquals(-2.8073538539158063e+27, x -= ((tmp = -1664804757, tmp)&((tmp = -226616419, tmp)>>>(1006711498))));
+  assertEquals(1894539615, x |= (tmp = -2400427681.1831083, tmp));
+  assertEquals(7400545, x >>= (774629608.4463601));
+  assertEquals(456756268, x += (449355723));
+  assertEquals(285771784, x &= (-1316427366));
+  assertEquals(17, x >>= ((tmp = -220509931.20787525, tmp)*(((tmp = 2518859292, tmp)+(-1477543005.1586645))>>(tmp = 3172820250.687789, tmp))));
+  assertEquals(85924262443, x *= (x*((tmp = -2856669745.965829, tmp)&(((tmp = 401420695, tmp)^(tmp = 2355371132, tmp))|(tmp = 590645330.021911, tmp)))));
+  assertEquals(1703875715, x ^= ((-2576394029.7843904)-x));
+  assertEquals(1703875715, x %= (tmp = 2234144310, tmp));
+  assertEquals(271405807, x ^= (1973569132));
+  assertEquals(1060178, x >>>= (tmp = -84823096, tmp));
+  assertEquals(8, x >>>= (tmp = 2246120561.905554, tmp));
+  assertEquals(-2846791089, x += (-2846791097));
+  assertEquals(104933962, x &= (x-(-2969030955.99584)));
+  assertEquals(489215611.96215343, x -= (-384281649.96215343));
+  assertEquals(489215611, x |= x);
+  assertEquals(1186191360, x <<= ((tmp = 774407142.993727, tmp)%x));
+  assertEquals(1186191360, x %= (1555004022));
+  assertEquals(-1697134080, x ^= (tmp = -597421568, tmp));
+  assertEquals(-1102053376, x <<= ((-927370769.4059179)^((tmp = 1093490918, tmp)>>(((-2522227493.3821955)%x)+(-2657319903)))));
+  assertEquals(1086450058, x ^= (-23991926.187098265));
+  assertEquals(1086450058, x |= x);
+  assertEquals(-1.6554590588410778, x /= (x|(x<<(x+x))));
+  assertEquals(67108863, x >>>= ((-926530233)+x));
+  assertEquals(494553310, x ^= (tmp = 512079649, tmp));
+  assertEquals(207751168, x &= (2892146720.6261826));
+  assertEquals(207751168, x &= x);
+  assertEquals(207751168, x |= x);
+  assertEquals(6340, x >>>= (((((x<<(x-((-2819638321)*((x<<x)+x))))>>x)+(tmp = 2016170261, tmp))+(tmp = 2755496043.772017, tmp))+(-841368625.1402085)));
+  assertEquals(6340, x ^= ((x/(tmp = -192734784, tmp))>>>(((-140306239)&x)-x)));
+  assertEquals(1, x /= x);
+  assertEquals(0, x >>= x);
+  assertEquals(26786600, x ^= (tmp = 26786600, tmp));
+  assertEquals(-0.014657576899542954, x /= ((-1454855938.0338)+(-372635753.3681567)));
+  assertEquals(0, x &= ((tmp = 2480635933, tmp)&(-2986584704.9165974)));
+  assertEquals(-2108639122, x += ((tmp = 2108639123.8683565, tmp)^((-881296055)/(((x<<(2026200582))|(tmp = -862495245.138771, tmp))-(-1111596494.892467)))));
+  assertEquals(1893466112, x <<= (tmp = 607974481, tmp));
+  assertEquals(1893466112, x |= x);
+  assertEquals(1133122783.997418, x += ((tmp = -760343332, tmp)-((x-(tmp = -878561823.4218843, tmp))/(tmp = -693454632.596637, tmp))));
+  assertEquals(8, x >>>= (tmp = 700339003.3919828, tmp));
+  assertEquals(4.605305035175536e-9, x /= (1737127060.8343256));
+  assertEquals(4.605305035175536e-9, x -= ((x%(897221779))>>>x));
+  assertEquals(-1864423625.5704088, x += (tmp = -1864423625.5704088, tmp));
+  assertEquals(1132240092, x <<= (1304417186.1193643));
+  assertEquals(-2088985380, x ^= (x<<x));
+  assertEquals(-4, x >>= ((tmp = 1959823884.0935726, tmp)%(-1679792398.569136)));
+  assertEquals(-268435456, x <<= ((tmp = 2586838136, tmp)|((tmp = -481716750.718518, tmp)>>>((1485826674.882607)/(tmp = -2826294011, tmp)))));
+  assertEquals(-32768, x >>= (2060648973));
+  assertEquals(1, x /= x);
+  assertEquals(-2838976297, x -= (tmp = 2838976298, tmp));
+  assertEquals(-1382985298, x <<= ((tmp = -2104305023, tmp)&x));
+  assertEquals(10, x >>>= (x+x));
+  assertEquals(10, x -= (x>>>(361588901.70779836)));
+  assertEquals(854603510, x -= (-854603500));
+  assertEquals(-557842432, x <<= (tmp = 1212985813.6094751, tmp));
+  assertEquals(-459390188241943040, x *= (tmp = 823512450.6304014, tmp));
+  assertEquals(-232800033621957060, x /= ((((((686635689)/(tmp = 2013252543, tmp))*(tmp = -1591617746.8678951, tmp))|(((tmp = -1777454093.5611362, tmp)>>>((tmp = 2680809394, tmp)^(((x>>((((((tmp = -265022244, tmp)%((tmp = -3075004537, tmp)>>(((((1427784269.5686688)^((tmp = -1095171528.911587, tmp)^(-942424985.7979553)))>>(-1279441481.1987405))*((2493620394)>>(-2769016043)))/(x&((tmp = 2059033657, tmp)%(((tmp = 1948606940.1488457, tmp)-(tmp = -2645984114.13219, tmp))^x))))))^x)^x)%(x%((((tmp = 3209433446.4551353, tmp)%(tmp = 1364430104.0424738, tmp))/(tmp = -2103044578.349498, tmp))+(tmp = -2613222750, tmp))))*(2099218034)))&(((tmp = -378500985.49700975, tmp)>>(((x+x)|(x%(((-1841907486)<<(-1220613546.194021))<<(tmp = -1260884176, tmp))))^(tmp = 1858784116, tmp)))>>>((x%x)%((x>>>(tmp = -2540799113.7667685, tmp))|x))))/((((tmp = 642072894.6455215, tmp)-(-324951103.6679399))*(tmp = 1424524615, tmp))+((x<<(tmp = -904578863.5945344, tmp))*(tmp = 49233475.435349464, tmp))))))<<(tmp = 1680210257, tmp)))+((tmp = -1516431503, tmp)>>>(-1105406695.3068116)))/(-275019361.6764543)));
+  assertEquals(192359387.42913792, x /= (-1210234846));
+  assertEquals(192359387.42913792, x %= (-2920206625.0154076));
+  assertEquals(192359387.42913803, x -= (((((((tmp = -1263203016.3258834, tmp)-(2432034005.6011124))&x)<<(1479434294))>>((tmp = -1695856315.523002, tmp)>>>(tmp = 557391345, tmp)))/(tmp = -1280240246.2501266, tmp))%((tmp = -2196489823.034029, tmp)>>(((x&((912221637.1101809)+((tmp = -3003677979.652423, tmp)>>(tmp = -716129460.1668484, tmp))))-((x+(x-(-2780610859)))>>>(-2445608016)))<<((x*(x+(x+(((-2124412727.9007604)%(tmp = -593539041.5539455, tmp))&(tmp = 2404054468.768749, tmp)))))%(x>>(tmp = -2913066344.404591, tmp)))))));
+  assertEquals(11740, x >>= (688848398.7228824));
+  assertEquals(11740, x >>= ((1545765912)*(307650529.9764147)));
+  assertEquals(23480, x += x);
+  assertEquals(0, x >>>= ((tmp = 1313078391, tmp)|x));
+  assertEquals(1726251264, x -= ((1939413887)<<(1004888744.2840619)));
+  assertEquals(765324793.5278986, x %= (960926470.4721014));
+  assertEquals(747387, x >>= ((2483010044)-(tmp = -413698190, tmp)));
+  assertEquals(1, x /= x);
+  assertEquals(3016811624, x *= (3016811624));
+  assertEquals(17408, x &= (((tmp = -991624868, tmp)<<(((63107932)/(tmp = 2659939199, tmp))|(tmp = -1968768911.3575773, tmp)))>>(((-2876822038.9910746)|(tmp = 2550230179.243425, tmp))<<((x*(x<<((x<<((tmp = -1627718523.616604, tmp)|((2154120561.254636)-(x%(x<<(1484563622.1791654))))))<<((((x^(tmp = 3016524169, tmp))<<(((x+(tmp = 1887816698.2455955, tmp))+x)-x))-(-3023329069))-x))))+x))));
+  assertEquals(0, x <<= (((1247441062.177967)/(-1717276234))+x));
+  assertEquals(0, x |= ((x%((-1648299429.4520087)>>(-137511052)))>>(tmp = 221301016.4926411, tmp)));
+  assertEquals(0, x /= ((-2598501544.913707)>>>(-2177037696)));
+  assertEquals(NaN, x %= (x>>x));
+  assertEquals(0, x &= (tmp = 1852419158, tmp));
+  assertEquals(-829029120, x |= (((2122339180)*((((((tmp = 768748914, tmp)<<((1008490427)&((1937367899.957056)-(((635094486)>>(((tmp = -795046025, tmp)*(2665104134.4455256))^(tmp = 706594584.2462804, tmp)))/(504397522)))))/(-556057788))>>((x/(tmp = -2732280594, tmp))-x))+(-1989667473))+(tmp = 2766802447.789895, tmp)))<<(((tmp = -2969169096, tmp)-x)+(tmp = 2093593159.0942125, tmp))));
+  assertEquals(0.6451933462602606, x /= ((-1284931292)<<(x<<(tmp = 1294716764, tmp))));
+  assertEquals(1515416866.520901, x *= (2348779440));
+  assertEquals(-1620606242886682600, x *= ((-993898625.5357854)&(((tmp = -571100481, tmp)/x)*((2428590177.311031)%(tmp = -2671379453, tmp)))));
+  assertEquals(-1137472828, x %= (tmp = -1195183004, tmp));
+  assertEquals(-3096634005473250000, x *= (tmp = 2722380640, tmp));
+  assertEquals(-3096634003996758500, x -= (-1476491033.833419));
+  assertEquals(-3096634000805538000, x += (3191220521.978341));
+  assertEquals(-3096634000805468000, x += ((((tmp = -3024976741, tmp)&(952616360))|((x*(-1547952311))+(x*x)))>>>(tmp = 981373323, tmp)));
+  assertEquals(-3096633998655594000, x += (2149873927));
+  assertEquals(-118812224101.54297, x %= (((2641881276.9898443)*(((502159480)^x)<<x))%((tmp = -2840045365.547772, tmp)*(((((-2297661528)>>>(x>>(-229103883.94961858)))&(((-1285047374.6746495)<<((-360045084)>>>((x-(tmp = -956123411.1260898, tmp))%x)))>>((tmp = -2375660287.5213504, tmp)+((((tmp = -2753478891, tmp)>>>(((tmp = 101438098, tmp)>>(((tmp = -2736502951, tmp)<<((tmp = -3084561882.368902, tmp)&(tmp = 1491700884, tmp)))|x))&(tmp = 1627412882.6404104, tmp)))>>>(tmp = 1039002116.6784904, tmp))<<((tmp = -2840130800, tmp)-(tmp = -740035567, tmp))))))&(tmp = -416316142, tmp))>>x))));
+  assertEquals(86, x >>>= (tmp = -293489896.5572462, tmp));
+  assertEquals(172, x += (x%((((-2635082487.364155)|((-2361650420.634912)&(-2147095650.7451198)))<<((tmp = 2258905145.9231243, tmp)%((((tmp = -1365987098.5130103, tmp)*(((((((932437391)/x)/(289270413.0780891))%(x-x))+((((2194986374.917528)>>(((((tmp = -1553805025, tmp)|x)^(((x>>(-564400586.0780811))^(tmp = 1738428582.0238137, tmp))>>(tmp = 1717774140, tmp)))&(tmp = -2789427438, tmp))%(((tmp = -1386118057, tmp)*(-2333221237.7915535))*(x>>>(((((41346648.46438944)&x)%(-478973697.6792319))|(tmp = 2108106738, tmp))/x)))))-(tmp = -133437701.64136505, tmp))>>>x))+(tmp = -1567210003, tmp))*(x+((x&x)-(2942851671)))))>>>(tmp = -446377136, tmp))*((((((tmp = 1597203255, tmp)>>>(619157171))|(-2766246629.005985))>>((tmp = 3130227370, tmp)%x))*(tmp = 2072227901.6101904, tmp))|((tmp = 1369019520, tmp)^(759659487))))))>>>x)));
+  assertEquals(1996475731, x ^= ((1456327892.2281098)|(1728022827)));
+  assertEquals(0, x %= x);
+  assertEquals(0, x &= (1323847974));
+  assertEquals(3076829073.8848357, x += (3076829073.8848357));
+  assertEquals(9569842648396755000, x *= (3110293883.2782717));
+  assertEquals(9569842646260304000, x -= (2136450372.9038036));
+  assertEquals(9.158188827418242e+37, x *= x);
+  assertEquals(0, x <<= ((x&(tmp = -2241179286, tmp))+((tmp = 2553144081, tmp)&((tmp = -1914709694, tmp)^(tmp = -1469651409.0651562, tmp)))));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x /= (2177840666.276347));
+  assertEquals(0, x %= (-690827104));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x ^= x);
+  assertEquals(-0, x /= (tmp = -803415280, tmp));
+  assertEquals(-2355576914.316743, x += (-2355576914.316743));
+  assertEquals(-833671722514674000, x *= ((3053388806.692315)-(tmp = 2699474775.081724, tmp)));
+  assertEquals(1, x /= x);
+  assertEquals(1898147684, x += ((tmp = 1898147683, tmp)|(x<<x)));
+  assertEquals(2.192324660388075, x %= ((tmp = 2630187518, tmp)/((2868794982.790862)|(490860748))));
+  assertEquals(0, x >>>= ((2751021779)/(-952522559)));
+  assertEquals(321040461, x ^= ((321040461.153594)-x));
+  assertEquals(-2.3814602031636922, x /= ((tmp = -170472190, tmp)|x));
+  assertEquals(-1, x >>= (2200125174.177402));
+  assertEquals(-2964432647.9379396, x += (-2964432646.9379396));
+  assertEquals(-370116502.93793964, x %= (tmp = -518863229, tmp));
+  assertEquals(777927355.2283959, x -= (-1148043858.1663356));
+  assertEquals(0, x *= ((tmp = 1134913539, tmp)&(((x>>>((tmp = -989822787, tmp)>>>x))%x)&(tmp = 1078636160.7313156, tmp))));
+  assertEquals(-1089245637, x ^= (3205721659.3548856));
+  assertEquals(-1192493056, x <<= (-1173291054));
+  assertEquals(78013832, x += ((tmp = 2462999944, tmp)+x));
+  assertEquals(0, x %= x);
+  assertEquals(0, x >>>= (1794908927.7409873));
+  assertEquals(1708338504, x += ((-2586628792.3484306)<<x));
+  assertEquals(12, x >>= (-545794789.3827574));
+  assertEquals(0, x &= ((2753207225)<<(((-1776581207.557251)+((tmp = -2414140402, tmp)*x))+(x<<(x|(tmp = 772358560.3022032, tmp))))));
+  assertEquals(0, x <<= ((tmp = -2755724712.152605, tmp)/((x>>(-732875466))&x)));
+  assertEquals(NaN, x *= (((tmp = 2617815318.1134562, tmp)/x)%(x|((((((-851659337.194871)<<(tmp = 2072294700, tmp))%((x+(2193880878.5566335))^((tmp = 3005338026, tmp)-(2947963290))))/x)/(x+(2091745239.4210382)))-(x>>x)))));
+  assertEquals(NaN, x /= (tmp = -427684595.0278094, tmp));
+  assertEquals(NaN, x /= (tmp = -263945678, tmp));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x -= (((x>>((x&x)-(tmp = -673697315, tmp)))>>(((1575095242.2330558)/(x-(-1816886266)))%(-1580195729)))>>>x));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x >>= (-2815518206));
+  assertEquals(0, x -= (x/(1795634670.692437)));
+  assertEquals(-2753579891, x += (tmp = -2753579891, tmp));
+  assertEquals(2.7773776150171776, x /= (tmp = -991431585, tmp));
+  assertEquals(5.554755230034355, x += x);
+  assertEquals(3.362161997528237e-9, x /= (1652137890.4758453));
+  assertEquals(3.362161997528237e-9, x %= (tmp = -10848734.527020693, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(-2978012493, x -= (x+(2978012493)));
+  assertEquals(-5.158905851797543, x /= (((x+((tmp = -2548840164, tmp)>>x))<<(x^((tmp = -533281232.7294345, tmp)&x)))&(tmp = -1502692171, tmp)));
+  assertEquals(-5.158905851797543, x %= (-3009435255.5612025));
+  assertEquals(-20971520, x <<= ((tmp = -2728812464, tmp)%(2619809573.672677)));
+  assertEquals(-1900019712, x &= (2398099552));
+  assertEquals(-1991377, x %= ((tmp = 1562364373.7334614, tmp)>>>(((x-(-946283217))<<(-2044590694))^(((tmp = 1681238509, tmp)>>(-2801649769))-x))));
+  assertEquals(1, x /= x);
+  assertEquals(1, x %= (x/(x-x)));
+  assertEquals(1.3525631913093335e-9, x /= (739336991));
+  assertEquals(0, x &= ((x&(x|(-1530424204)))<<((((tmp = -295143065.9115021, tmp)>>x)+x)<<x)));
+  assertEquals(0, x <<= (-1311017801));
+  assertEquals(-0, x /= (-667133339.1918633));
+  assertEquals(1038307283, x += (1038307283));
+  assertEquals(506985, x >>>= ((tmp = 1550624472.9157984, tmp)^x));
+  assertEquals(506985, x >>>= ((254646626)<<(tmp = 1572845412.744642, tmp)));
+  assertEquals(32447040, x <<= (tmp = -2427326042, tmp));
+  assertEquals(0, x -= (x<<((x|x)>>>x)));
+  assertEquals(0, x &= x);
+  assertEquals(0, x &= ((-484420357)|((tmp = 807540590.6132902, tmp)/(x/x))));
+  assertEquals(-890607324, x ^= ((tmp = -890607324, tmp)>>((((-2876826295)>>x)<<((tmp = 2351495148.117994, tmp)>>(tmp = 1368611893.274765, tmp)))*(tmp = 1531795251, tmp))));
+  assertEquals(-729075363, x += (x+(tmp = 1052139285, tmp)));
+  assertEquals(531550884933581760, x *= x);
+  assertEquals(1980836332, x ^= ((-746269795.2320724)-((2400458512)>>((1290672548)>>>((((1536843439.5629003)&(3185059975.158061))*(tmp = -1339249276.2667086, tmp))&x)))));
+  assertEquals(941373096, x %= ((x+(-451098412))^(tmp = 1725497732, tmp)));
+  assertEquals(-1766019323, x += (tmp = -2707392419, tmp));
+  assertEquals(2528947973, x >>>= (x^(-896237435.3809054)));
+  assertEquals(-263192576, x <<= (-866361580));
+  assertEquals(-2008, x >>= (-2608071791));
+  assertEquals(-88, x %= (((-1076807218.4792447)&((tmp = 601044863, tmp)>>((tmp = 1228976729, tmp)+((((-2711426325)*x)|x)|(x%(-2700007330.3266068))))))&(tmp = 3147972836.778858, tmp)));
+  assertEquals(1762886843, x ^= (tmp = 2532080403, tmp));
+  assertEquals(1762886843, x %= ((((((tmp = -2059247788, tmp)>>x)/x)+(x<<x))^x)>>>(-1969283040.3683646)));
+  assertEquals(4812334726.587896, x += (tmp = 3049447883.587897, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(1, x *= x);
+  assertEquals(-2150507334, x -= ((tmp = 1578221999, tmp)+(tmp = 572285336, tmp)));
+  assertEquals(-4546475858941548500, x *= ((tmp = -931533139.5546813, tmp)^(tmp = 3061503275, tmp)));
+  assertEquals(-269064192, x |= ((207217276.91936445)<<(tmp = -957353678.4997551, tmp)));
+  assertEquals(1, x /= x);
+  assertEquals(1, x <<= (((1463856021.8616743)%(x*(tmp = -2286419102, tmp)))/(-2852887593)));
+  assertEquals(2223868564.8383617, x *= (tmp = 2223868564.8383617, tmp));
+  assertEquals(918797189.9033995, x -= ((1305071374.9349623)%(x+(2211992629))));
+  assertEquals(-2212004787.4668465, x -= (tmp = 3130801977.370246, tmp));
+  assertEquals(31783, x >>= (2951958960));
+  assertEquals(31783, x ^= ((((tmp = -2441511566, tmp)&((tmp = 91427553.90168321, tmp)+((tmp = 3001737720.327718, tmp)%x)))>>>(-2263859841))>>>((2109161329)>>(tmp = -2816295136.7443414, tmp))));
+  assertEquals(4068224, x <<= (x%((tmp = -682576250.4464607, tmp)*(x/(((x-x)>>>(x&((((x<<(x<<x))>>>((((2243036981.528562)/(((-1839328916.9411087)>>(-1907748022.162144))<<(x+x)))+((tmp = 2362574171, tmp)<<(tmp = 1987834539, tmp)))|(-444329240)))|(399451601.1717081))>>x)))&(968363335.6089249))))));
+  assertEquals(0.0030991932898194294, x /= ((tmp = 1067316540.5529796, tmp)^(-2388640366)));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>>= (tmp = -393433349.1636851, tmp));
+  assertEquals(0, x *= (((x^(((1806955787.471396)<<x)^((517668047.55566347)>>>(x%(x<<(tmp = -276586733.4844558, tmp))))))%(1661242196.1472542))|x));
+  assertEquals(0, x |= (x>>x));
+  assertEquals(-155236210, x |= (tmp = -155236210.19366312, tmp));
+  assertEquals(-606392, x >>= ((tmp = -1533446042.97781, tmp)^x));
+  assertEquals(-1, x >>= (936126810));
+  assertEquals(2325115611, x -= (-2325115612));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>= (tmp = -354826623, tmp));
+  assertEquals(-0, x *= (-1232528947.7321298));
+  assertEquals(0, x |= x);
+  assertEquals(0, x <<= (((tmp = 187758893.4254812, tmp)&(x-(tmp = 648201576, tmp)))&(385106597)));
+  assertEquals(0, x >>= (tmp = 2554891961, tmp));
+  assertEquals(-1311492611.2970417, x += (-1311492611.2970417));
+  assertEquals(-688179220.3221785, x += (623313390.9748632));
+  assertEquals(1416835528, x &= (tmp = 1953739224, tmp));
+  assertEquals(-11.04719252755072, x /= (-128252995));
+  assertEquals(-6.287413042114223e-9, x /= (tmp = 1757033052.1558928, tmp));
+  assertEquals(-4231171, x |= (((((2022730885.7773404)*((-2495777565.221855)|(tmp = 274627292, tmp)))<<(-3072596920.4902725))>>>((-2215057529)+(-1134713759.4247034)))^((tmp = -1888181788, tmp)/(572025985.2748461))));
+  assertEquals(-4194305, x |= ((tmp = 167328318.038759, tmp)>>>(153800904.34551537)));
+  assertEquals(-1316525687, x -= (1312331382));
+  assertEquals(1448723245.7863903, x += (2765248932.7863903));
+  assertEquals(1.7219707102205526, x /= (tmp = 841317008, tmp));
+  assertEquals(1872027792.5217001, x *= (x|(tmp = 1087142645.6665378, tmp)));
+  assertEquals(3504488055973669400, x *= x);
+  assertEquals(-1075254784, x |= x);
+  assertEquals(-5, x >>= (((844461331.8957539)-((x&x)<<((tmp = 1443904777, tmp)+(tmp = 736164505.3670597, tmp))))-(((tmp = 1348422110, tmp)>>((tmp = -2878252514, tmp)/(-1175443113)))|((-2138724317)%(2057081133)))));
+  assertEquals(-3.038875804165675e-9, x /= (1645345292.8698258));
+  assertEquals(1.25204541454491e-18, x /= (-2427129055.274914));
+  assertEquals(-1.7151576137235622e-9, x *= (-1369884505.6247284));
+  assertEquals(1590804618, x ^= (1590804618.4910607));
+  assertEquals(5061318665300252000, x *= (x+x));
+  assertEquals(5061318665300252000, x %= ((tmp = 1102144242, tmp)*x));
+  assertEquals(-7, x >>= (2772167516.624264));
+  assertEquals(16383, x >>>= (-2979259214.5855684));
+  assertEquals(47108415435, x *= ((2944456517.839616)>>>(1041288554.5330646)));
+  assertEquals(61, x >>>= (x^(((-1305163705)<<((948566605)-x))-x)));
+  assertEquals(0, x %= x);
+  assertEquals(0, x ^= (((tmp = 1918861879.3521824, tmp)/((x%(tmp = 945292773.7188392, tmp))%(x|x)))>>x));
+  assertEquals(-0, x *= ((((x|((2810775287)|(tmp = 1265530406, tmp)))^((tmp = 3198912504.175658, tmp)-(((tmp = 1422607729.281712, tmp)<<(tmp = 2969836271.8682737, tmp))&x)))<<((tmp = 844656612, tmp)*(((((tmp = -828311659, tmp)%(((-2083870654)>>>(x^(((((933133782)-(tmp = 1033670745, tmp))-(629026895.4391923))%((-605095673.8097742)*((((-227510375.38460112)*x)+x)&(((((tmp = 472873752.68609154, tmp)^(tmp = 2815407038.712165, tmp))+((x>>>((tmp = -1331030665.3510115, tmp)>>>(2281234581)))-(x>>>x)))&(tmp = -2160840573.325921, tmp))&x))))<<(tmp = 1411888595, tmp))))|(((tmp = -915703839.0444739, tmp)/((x+(418836101.8158506))%(-1112605325.4404268)))&((-3098311830.6721926)-x))))-((49446671.477988124)*(-2522433127)))+((tmp = 443068797, tmp)>>(tmp = 418030554.97275746, tmp)))*((tmp = 38931296.738208175, tmp)+(1842742215.3282685)))))-((tmp = 1325672181.205841, tmp)^(tmp = 669284428, tmp))));
+  assertEquals(-0, x *= (tmp = 93843030, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>>= (x%((((((tmp = -107458601, tmp)>>(x*((x|((tmp = 2117286494, tmp)>>((x^(tmp = 114214295.42048478, tmp))>>>(tmp = 1032826615, tmp))))&((x*x)&(-225386977.67686415)))))^((-780566702.5911419)+(-1113319771)))|(((x^x)<<(1288064444))>>(-2292704291.619477)))>>(365125945))-((tmp = -1986270727.235776, tmp)/x))));
+  assertEquals(-0, x *= (((-18925517.67125845)|((((-1975220517)+(tmp = -1250070128.296064, tmp))+(1085931410.5895243))<<(((x|(((x*(tmp = 160207581.50536323, tmp))|(tmp = 1798744469.7958293, tmp))-x))>>>(((x+((x%x)&((((x^x)<<((tmp = 2538012074.623554, tmp)^x))*x)&x)))/(x+(tmp = -2563837407, tmp)))/(tmp = 2189564730, tmp)))/(((-1703793330.5770798)<<((176432492)|x))<<(1347017755.345185)))))<<(((tmp = -577100582.7258489, tmp)&x)/(-31246973))));
+  assertEquals(0, x >>>= x);
+  assertEquals(NaN, x %= ((x*(tmp = 1167625971, tmp))&(((tmp = -770445060, tmp)>>((339248786)^((2058689781.2387645)-((-2381162024)*(660448066)))))&x)));
+  assertEquals(NaN, x += ((3088519732.515986)-(-267270786.06493092)));
+  assertEquals(0, x &= (tmp = 2748768426.3393354, tmp));
+  assertEquals(-1109969306, x ^= ((-1109969306)>>>x));
+  assertEquals(-1109969306, x %= (tmp = 1150376563.581773, tmp));
+  assertEquals(-2058145178, x &= (-2057586057));
+  assertEquals(-850185626, x |= ((x^(tmp = 1223093422, tmp))&((-589909669)<<(2299786170))));
+  assertEquals(1489215443, x += (2339401069));
+  assertEquals(-23592960, x <<= x);
+  assertEquals(2063937322, x ^= (-2053296342.2317986));
+  assertEquals(12922122, x %= (x^((-2259987830)>>(x*(((tmp = -799867804.7716949, tmp)&(tmp = -1068744142, tmp))*(((((1091932754.8596292)-((tmp = -1778727010, tmp)>>(((tmp = 1207737073.2689717, tmp)-(x-(tmp = -1191958946, tmp)))+(-631801383.7488799))))-(-618332177))>>>(-156558558))>>>(3032101547.6262517)))))));
+  assertEquals(12922122, x &= x);
+  assertEquals(Infinity, x /= (x%x));
+  assertEquals(0, x &= (x*(-227800722.62070823)));
+  assertEquals(-865648691, x ^= (-865648691));
+  assertEquals(1, x /= (x%(tmp = 1524739353.8907173, tmp)));
+  assertEquals(16, x <<= (x<<(2335214658.789205)));
+  assertEquals(0, x &= ((tmp = 570332368.1239192, tmp)^(-2278439501)));
+  assertEquals(1881145344, x -= (((-569715735.8853142)+(2093355159))<<(tmp = 2788920949, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(NaN, x -= ((tmp = -1427789954, tmp)%((((((411038329.49866784)-x)-(x<<((-1330832247)+x)))/x)^((x*(845763550.2134092))>>(tmp = 1427987604.5938706, tmp)))>>>(1857667535))));
+  assertEquals(NaN, x /= (-313793473));
+  assertEquals(0, x >>>= (x/x));
+  assertEquals(1869358566, x -= (-1869358566));
+  assertEquals(-1901664519209545200, x += ((tmp = 944729941.3936644, tmp)*(-2012918653)));
+  assertEquals(-1901664519209545200, x += ((tmp = 1348246793, tmp)/(x&x)));
+  assertEquals(-1576791552, x &= (tmp = 2719250966.739456, tmp));
+  assertEquals(-305087899, x ^= (-2955630491.030272));
+  assertEquals(0, x ^= (x%(1575252839.559443)));
+  assertEquals(4184604407, x += ((((tmp = -244720076.17657042, tmp)|(2819320515))^((((tmp = 1222623743.9184055, tmp)*(-95662379.577173))/(x/(x+(((x-(tmp = -3024718107.6310973, tmp))^(-1494390781))&(tmp = 2284054218.8323536, tmp)))))>>>(tmp = 2090069761, tmp)))>>>(x%x)));
+  assertEquals(3148907440, x -= (((tmp = -332379100.7695112, tmp)-(-1145399547))^(((((((tmp = 3133792677.785844, tmp)+x)<<(2306999139.5799255))>>((tmp = -2051266106, tmp)*(((((x+(((-728654312.8954825)>>(x>>>(((x%x)&(-1587152364))|(((((-2114138294)&x)&(1547554688))^x)-(-1856094268)))))*(((-1135018784)&((x+(tmp = -1444020289, tmp))|x))+x)))>>x)&x)/(2449005489))<<((131073798.64314616)%(x>>>((-2592101383.2205048)^(tmp = -757096673.0381112, tmp)))))))^(2766467316.8307915))-(-2465892914.515834))-((((tmp = 234064056, tmp)^((x>>>(1622627548.7944543))+(-1750474146)))|(-1959662039.4687617))^((-1222880974)&(-2794536175.906498))))));
+  assertEquals(-1157627488, x &= (-1156639323));
+  assertEquals(-1342170624, x <<= ((x/((((1829945345.0613894)/(x*((tmp = 1278865203.0854595, tmp)/(((tmp = -2298274086.519347, tmp)+(tmp = -545203761, tmp))-(tmp = 2712195820, tmp)))))>>>((tmp = 240870798.9384452, tmp)-(tmp = -3188865300.4768195, tmp)))>>>(x%((648799266)>>>(tmp = 24460403.864815235, tmp)))))|((tmp = 232533924, tmp)|x)));
+  assertEquals(-2684341248, x += x);
+  assertEquals(1073755136, x &= (((-662718514.9245079)>>(tmp = -1915462105, tmp))+(tmp = 1478850441.8689613, tmp)));
+  assertEquals(-1073755136, x /= (x|((tmp = -1767915185, tmp)|((325827419.1430224)|(((-1343423676)|(tmp = -1929549501, tmp))|(-866933068.9585254))))));
+  assertEquals(-1073755136, x %= ((tmp = 547342356, tmp)-((tmp = 2213249646.7047653, tmp)-((((((-2463314705)^(tmp = -993331620, tmp))^(((x%x)>>(tmp = 1798026491.3658786, tmp))-(((1024072781)/(tmp = -2407354455, tmp))%(1973295010))))<<(-1966787233))^x)|(-1787730004)))));
+  assertEquals(-1073754452, x |= (tmp = 3099823788.077907, tmp));
+  assertEquals(-1540683096, x &= (-1540674632.7013893));
+  assertEquals(-1540683052, x ^= ((tmp = -126183090, tmp)>>>((-622437575.5788481)|((((tmp = -2947914022, tmp)%(((tmp = 2512586745, tmp)>>x)>>>((27238232.23677671)/(tmp = 3203958551, tmp))))/(tmp = 2906005721.402535, tmp))^((((tmp = 1763897860.737334, tmp)^(1445562340.2485332))/x)+(-2393501217.716533))))));
+  assertEquals(-1258599433, x |= (tmp = 351291767.59661686, tmp));
+  assertEquals(-1241560065, x |= (626346046.5083935));
+  assertEquals(-1241560065, x ^= ((2263372092)/((tmp = -2868907862, tmp)>>>x)));
+  assertEquals(-893685228, x -= (tmp = -347874837, tmp));
+  assertEquals(3401282068, x >>>= (x*x));
+  assertEquals(0, x %= x);
+  assertEquals(0, x >>>= x);
+  assertEquals(-2079237393, x ^= (tmp = 2215729903, tmp));
+  assertEquals(NaN, x %= ((((tmp = 3203450436, tmp)/(2867575150.6528325))&(1864945829))&((x&((((tmp = -1927086741.3438427, tmp)|x)|(-1783290909.3240588))*((-1074778499.0697656)*(x-((tmp = -848983542.8456669, tmp)^(tmp = -1324673961, tmp))))))>>(tmp = -2144580304.245896, tmp))));
+  assertEquals(-43334009, x |= (x^(-43334009.72683525)));
+  assertEquals(-43334009, x &= x);
+  assertEquals(-43334009, x %= (tmp = 1252450645.060542, tmp));
+  assertEquals(-43334009, x |= (((((((tmp = 968062202, tmp)/(x|(tmp = 2766801984, tmp)))*((2173353793.938968)>>(((tmp = -2459317247, tmp)<<(tmp = -2333601397, tmp))>>>((tmp = -578254251.8969193, tmp)*(tmp = 839964110.7893236, tmp)))))&(((1675305119)&(tmp = -929153707, tmp))*((x*x)*x)))/x)|(x/(tmp = 384740559.43867135, tmp)))%(1657362591)));
+  assertEquals(0, x -= x);
+  assertEquals(0, x %= (-1334758781.1087842));
+  assertEquals(0, x -= x);
+  assertEquals(-54, x += ((tmp = -1787151355.470972, tmp)>>((tmp = 237028977, tmp)>>(((2829473542)<<(x>>>(((((((x-(-1950724753))*(((x>>>(2807353513.6283565))<<((-583810779.1155353)>>(x*x)))>>(-1068513265)))^(x^(-696263908.5131407)))%(((tmp = -1325619399, tmp)<<((tmp = -1030194450, tmp)-x))^x))+((-2852768585.3718724)>>(tmp = -3160022361, tmp)))%(x&x))>>(tmp = 2667222702.5454206, tmp))))+((804998368.8915854)<<x)))));
+  assertEquals(-54, x %= (-1601267268.4306633));
+  assertEquals(1, x >>>= (tmp = -543199585.579128, tmp));
+  assertEquals(4.732914708226396e-10, x /= (tmp = 2112862922, tmp));
+  assertEquals(-4266932650, x -= ((((x^((((tmp = 2784618443, tmp)^(tmp = -2271260297.9010153, tmp))|((((tmp = -599752639.7516592, tmp)*(2751967680.3680997))^(tmp = -1478450055.578217, tmp))*x))-x))&((tmp = -520061982, tmp)-((tmp = 1400176711.9637299, tmp)^(((2100417541)|(x+(tmp = -674592897.0420957, tmp)))>>x))))^(tmp = -365650686.7947228, tmp))>>>((-2943521813)&(((tmp = -1888789582, tmp)>>(tmp = 700459655.488978, tmp))+(tmp = -1725725703.655931, tmp)))));
+  assertEquals(224277168, x <<= (tmp = 2885115011.8229475, tmp));
+  assertEquals(224277168, x %= (tmp = -2655345206.442777, tmp));
+  assertEquals(850395136, x <<= (x-(((((-769868538.1729524)/((tmp = -298603579, tmp)%(x^x)))+((2691475692)|(((x>>>(628995710.4745524))^(x<<(((tmp = -1046054749, tmp)|(919868171))-x)))^((-1377678789.8170452)&((3065147797)%(tmp = 2638804433, tmp))))))^(tmp = -2036295169, tmp))&(((tmp = -157844758.08476114, tmp)*(tmp = -2819601496, tmp))&((((tmp = 78921441, tmp)<<(653551762.5197772))/(1801316098))*(-1479268961.8276927))))));
+  assertEquals(1645565728, x ^= (tmp = 1353013024, tmp));
+  assertEquals(1645565728, x >>>= x);
+  assertEquals(3020513544, x += (1374947816));
+  assertEquals(0, x %= x);
+  assertEquals(0, x %= ((((((tmp = -304228072.4115715, tmp)>>>((-90523260.45975709)-(tmp = -3013349171.084838, tmp)))%((-1640997281)*((tmp = -1600634553, tmp)%((tmp = 557387864, tmp)<<((888796080.766409)|(x^((((x%(((((tmp = 1164377954.1041703, tmp)*x)|(2742407432.192806))&((tmp = 1707928950, tmp)<<(1279554132.4481683)))+(tmp = -2108725405.7752397, tmp)))%(tmp = -465060827, tmp))^((tmp = 2422773793, tmp)+x))^((((((((tmp = -1755376249, tmp)^((-267446806)^x))/(((tmp = -1808578662.4939392, tmp)+((tmp = -1997100217, tmp)+x))+(((tmp = -2469853122.411479, tmp)/x)>>(tmp = 660624616.7956645, tmp))))%((x<<((((((tmp = -1701946558, tmp)-(tmp = 133302235, tmp))>>>x)/(738231394))<<(-1060468151.4959564))&(((((-1877380837.4678264)|(tmp = 2366186363, tmp))%x)>>>(-2382914822.1745577))>>((-1874291848.9775913)<<(tmp = 2522973186, tmp)))))<<(-2672141993)))|(tmp = 732379966, tmp))%x)^x)^x))))))))%(tmp = 2385998902.7287374, tmp))*x)+(tmp = -2195749866.017106, tmp)));
+  assertEquals(401488, x ^= (((-320896627)>>>(tmp = 2812780333.9572906, tmp))&(tmp = -2088849328, tmp)));
+  assertEquals(-1661116571.0046256, x += (tmp = -1661518059.0046256, tmp));
+  assertEquals(-1616122720, x <<= x);
+  assertEquals(-1616122720, x >>= x);
+  assertEquals(-390439413, x %= (tmp = -1225683307, tmp));
+  assertEquals(-84189205, x |= ((x|(2054757858))^(((x<<(((x|x)|(((x>>>((-2938303938.1397676)<<((2993545056)^((tmp = -643895708.5427527, tmp)/((1371449825.5345795)-(1896270238.695752))))))-(tmp = 1061837650, tmp))+(x+(tmp = 3072396681, tmp))))>>(x-((((tmp = -1877865355.1550744, tmp)&x)%(-2766344937))>>>(2055121782)))))-((x<<x)|(tmp = -2742351880.1974454, tmp)))<<((-2600270279.219802)>>(-1625612979)))));
+  assertEquals(-168378410, x += x);
+  assertEquals(-168378410, x &= x);
+  assertEquals(-1534983792, x &= (-1501412943));
+  assertEquals(-1821543761, x ^= (938439487));
+  assertEquals(-1821543761, x &= (x^(((tmp = -4237854, tmp)>>x)/x)));
+  assertEquals(2358, x >>>= (2954252724.620632));
+  assertEquals(4716, x <<= ((-75522382.8757689)/((tmp = 1074334479, tmp)|((tmp = -720387522, tmp)>>(x>>>(-3085295162.6877327))))));
+  assertEquals(-1313079316, x |= (2981887904.020387));
+  assertEquals(-1957790646, x -= (644711330));
+  assertEquals(17831, x >>>= ((tmp = -2550108342, tmp)-(((tmp = 454671414.0146706, tmp)+(-661129693.9333956))>>(x>>>(((tmp = 1752959432.3473055, tmp)*(-2619510342.1812334))%(tmp = -456773274.2411971, tmp))))));
+  assertEquals(689287937.6879716, x -= ((tmp = -397126863.6879716, tmp)-(((x>>x)^(x/(-1387467129.6278908)))|((x>>((tmp = -2361114214.8413954, tmp)<<(tmp = -805670024.4717407, tmp)))<<(-2724018098)))));
+  assertEquals(1378575875.3759432, x += x);
+  assertEquals(84112428460187.8, x *= (((((2681425112.3513584)%(tmp = -1757945333, tmp))|x)>>(-1793353713.0003397))%x));
+  assertEquals(-3221, x >>= (-1976874128));
+  assertEquals(-3221, x %= (((tmp = 2318583056.834932, tmp)|((tmp = -1016115125, tmp)+((-472566636.32567954)+x)))|(tmp = 3135899138.065598, tmp)));
+  assertEquals(-6596608, x <<= x);
+  assertEquals(-1249902592, x <<= (((tmp = -2025951709.5051148, tmp)/((-465639441)<<(-2273423897.9682302)))*((tmp = -2408892408.0294642, tmp)-(tmp = 1017739741, tmp))));
+  assertEquals(73802092170444800, x *= (tmp = -59046275, tmp));
+  assertEquals(-1619001344, x <<= x);
+  assertEquals(0, x <<= (tmp = 1610670303, tmp));
+  assertEquals(-0, x *= ((((x+(tmp = 2039867675, tmp))|(tmp = 399355061, tmp))<<(1552355369.313559))^x));
+  assertEquals(0, x *= x);
+  assertEquals(0, x >>>= (((2875576018.0610805)>>x)%(tmp = -2600467554, tmp)));
+  assertEquals(2290405226.139538, x -= (-2290405226.139538));
+  assertEquals(0, x %= x);
+  assertEquals(0, x ^= (((tmp = 2542309844.485515, tmp)-x)%((-2950029429.0027323)/(tmp = 2943628481, tmp))));
+  assertEquals(0, x += x);
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>>= (tmp = 2337330038, tmp));
+  assertEquals(0, x += (x/(((292272669.0808271)&(tmp = 2923699026.224247, tmp))^(tmp = 367745855, tmp))));
+  assertEquals(0, x &= x);
+  assertEquals(0, x %= ((tmp = 1565155613.3644123, tmp)<<(-308403859.5844681)));
+  assertEquals(-1845345399.3731332, x += (tmp = -1845345399.3731332, tmp));
+  assertEquals(5158590659731951000, x *= (-2795460763.8680177));
+  assertEquals(-364664, x >>= (1837745292.5701954));
+  assertEquals(1, x /= x);
+  assertEquals(-860616114.8182092, x += ((tmp = 2076961323.1817908, tmp)+(-2937577439)));
+  assertEquals(-860616115, x ^= ((x*(tmp = 2841422442.583121, tmp))>>>((tmp = 1929082917.9039137, tmp)>>(-2602087246.7521305))));
+  assertEquals(-38387843, x |= (3114677624));
+  assertEquals(2927507837, x += (tmp = 2965895680, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(-1792887531, x *= (-1792887531));
+  assertEquals(-0, x %= ((x^x)+x));
+  assertEquals(-0, x %= (tmp = 2800752702.562547, tmp));
+  assertEquals(1384510548, x ^= (tmp = 1384510548, tmp));
+  assertEquals(42251, x >>= (1645421551.363844));
+  assertEquals(0, x >>>= (17537561));
+  assertEquals(-2076742862, x ^= (tmp = 2218224434, tmp));
+  assertEquals(-2.790313825067623, x /= (744268563.3934636));
+  assertEquals(5313538, x &= (((((tmp = -2406579239.0691676, tmp)+((-1470174628)+(((tmp = -783981599, tmp)<<(tmp = -1789801141.272646, tmp))^(((((((tmp = -844643189.5616491, tmp)&(tmp = -252337862, tmp))&(x|x))%((-3159642145.7728815)+(tmp = 2149920003.9525595, tmp)))&(x>>(1737589807.9431858)))-((((((((1610161800)<<(497024994))>>x)<<x)/x)>>>x)&x)-(757420763.2141517)))-(tmp = -3061016994.9596977, tmp)))))/(tmp = 1810041920.4089384, tmp))&(tmp = 5887654.786785364, tmp))&((tmp = 1626414403.2432103, tmp)+(x%x))));
+  assertEquals(-2147483648, x <<= (tmp = 1304102366.8011155, tmp));
+  assertEquals(-208418816, x %= (((((-2850404799)*(x+(3158771063.226051)))*(-2017465205))/(x>>x))>>(x%(tmp = 2760203322, tmp))));
+  assertEquals(-2189223477, x -= (1980804661));
+  assertEquals(-859239912, x ^= (tmp = 2974421971.3544703, tmp));
+  assertEquals(-1599850415, x ^= (tmp = -2475871671.140151, tmp));
+  assertEquals(-1600636847, x += ((((tmp = -1311002944, tmp)<<((tmp = -1137871342, tmp)<<(tmp = 115719116, tmp)))/(413107255.6242596))<<(x>>((((-1908022173)&(((-1519897333)^((x>>(x*(tmp = -2886087774.426503, tmp)))*(tmp = 530910975, tmp)))+(-2579617265.889692)))+((2518127437.127563)>>>((tmp = 481642471.56441486, tmp)>>>(792447239))))^(x<<(248857393.6819017))))));
+  assertEquals(-191, x >>= (-1591265193));
+  assertEquals(-192.27421813247196, x += ((tmp = 2627329028.207775, tmp)/(tmp = -2061914644.9523563, tmp)));
+  assertEquals(1230613220, x ^= (tmp = 3064354212.307105, tmp));
+  assertEquals(1230613220, x &= x);
+  assertEquals(1230613220, x %= (1833479205.1064768));
+  assertEquals(1230613220, x >>>= ((((1559450742.1425748)|((2151905260.956583)*(1213275165)))%(514723483.12764716))>>>x));
+  assertEquals(1230613493, x |= ((((3004939197.578903)*(tmp = -576274956, tmp))+((tmp = 1037832416.2243971, tmp)^x))>>>(tmp = 2273969109.7735467, tmp)));
+  assertEquals(2461226986, x += x);
+  assertEquals(-27981, x >>= ((692831755.8048055)^((tmp = -1593598757, tmp)%(x-((((-1470536513.882593)|((tmp = -2716394020.466401, tmp)|(tmp = 2399097686, tmp)))&x)%x)))));
+  assertEquals(-1.4660454948034359e+23, x *= (((x>>>((((((tmp = -3056016696, tmp)<<(-2882888332))*(2041143608.321916))&(((tmp = -634710040, tmp)|(tmp = -2559412457, tmp))>>(1916553549.7552106)))%((-2150969350.3643866)*x))<<((x*(tmp = 2657960438.247278, tmp))|x)))%((tmp = 526041379, tmp)*(tmp = 2514771352.4509397, tmp)))*(1219908294.8107886)));
+  assertEquals(-1.4660454948034359e+23, x -= ((1709004428)>>(((x|(-422745730.626189))%x)>>x)));
+  assertEquals(-2247766068, x %= (-3105435508));
+  assertEquals(-386845856.0649812, x -= (-1860920211.9350188));
+  assertEquals(-386846803.0649812, x -= ((((-3214465921)|((tmp = -1326329034, tmp)+(((tmp = -1203188938.9833462, tmp)%((((((-1318276502)+(x+x))^((x<<x)%(x>>>x)))+(tmp = -439689881, tmp))+((-1455448168.695214)^(x-((-388589993)>>((((940252202)^(-2218777278))|x)/(tmp = -1007511556, tmp))))))&(-140407706.28176737)))-(x/((888903270.7746506)-((tmp = -2885938478.632409, tmp)<<(((((tmp = -1750518830.270917, tmp)>>(((((((tmp = 868557365.7908674, tmp)/(tmp = -2805687195.5172157, tmp))*x)|((((((-1342484550)-((tmp = 1089284576, tmp)^(tmp = 120651272, tmp)))<<(tmp = 2230578669.4642825, tmp))-(x*x))%(x^(((tmp = -3177941534, tmp)+(x>>(-1595660968)))/(-1738933247))))>>>(tmp = 2860175623, tmp)))-(((2392690115.8475947)>>>(tmp = -1754609670.2068992, tmp))>>>(tmp = 2615573062, tmp)))-(tmp = 2590387730, tmp))^((x+((((x-(tmp = -2823664112.4548965, tmp))*(200070977))>>>(((x|((((tmp = 1361398, tmp)>>((tmp = 1649209268, tmp)%x))+x)+(x>>>(tmp = -2379989262.1245675, tmp))))|(x^((tmp = -647953298.7526417, tmp)-x)))&(tmp = -1881232501.1945808, tmp)))>>>x))%(x^(tmp = -1737853471.005935, tmp)))))>>>(427363558))>>>((tmp = -3076726422.0846386, tmp)^(-1518782569.1853383)))/x)))))))|x)>>>(1854299126)));
+  assertEquals(-386846803.0649812, x -= (x%x));
+  assertEquals(238532, x >>>= (-448890706.10774803));
+  assertEquals(232, x >>>= (-791593878));
+  assertEquals(232, x <<= (((x^((x-x)&(tmp = 1219114201, tmp)))/(tmp = -427332955, tmp))%(tmp = 1076283154, tmp)));
+  assertEquals(210, x ^= (x>>>((2975097430)>>>x)));
+  assertEquals(1, x /= x);
+  assertEquals(2317899531, x *= (2317899531));
+  assertEquals(1131786, x >>>= x);
+  assertEquals(2301667519.6379366, x += ((tmp = 193109669.63793683, tmp)+(tmp = 2107426064, tmp)));
+  assertEquals(3842614963.6379366, x += (((-1676516834)>>>(tmp = -1817478916.5658965, tmp))^(((tmp = 1122659711, tmp)>>>(tmp = -2190796437, tmp))|(tmp = -2754023244, tmp))));
+  assertEquals(-452352333, x &= x);
+  assertEquals(-863, x >>= x);
+  assertEquals(-3.777863669459606e-7, x /= (2284359827.424491));
+  assertEquals(-3.777863669459606e-7, x %= ((tmp = -2509759238, tmp)>>>x));
+  assertEquals(0, x <<= (-814314066.6614306));
+  assertEquals(0, x %= (tmp = 190720260, tmp));
+  assertEquals(2301702913, x += (2301702913));
+  assertEquals(-249158048, x >>= (tmp = -2392013853.302008, tmp));
+  assertEquals(-249158048, x >>= x);
+  assertEquals(-498316096, x += x);
+  assertEquals(-498316096, x %= (tmp = 2981330372.914731, tmp));
+  assertEquals(106616.2199211318, x *= (((((tmp = 1020104482.2766557, tmp)^((tmp = -416114189.96786, tmp)>>>(1844055704)))|(tmp = 1665418123, tmp))>>(1826111980.6564898))/(-2446724367)));
+  assertEquals(106616, x |= x);
+  assertEquals(1094927345, x -= (((-1229759420)|(741260479.7854375))-x));
+  assertEquals(8353, x >>= x);
+  assertEquals(0, x >>>= (tmp = -327942828, tmp));
+  assertEquals(-953397616.8888416, x += (tmp = -953397616.8888416, tmp));
+  assertEquals(-1906641240.7776833, x += (x+((-3033450184.9106326)>>>(tmp = 2090901325.5617187, tmp))));
+  assertEquals(-1906641240.7776833, x %= (tmp = 2584965124.3953505, tmp));
+  assertEquals(-1098907671, x |= (tmp = -1272590495, tmp));
+  assertEquals(-1.8305258600334393, x /= (600323489));
+  assertEquals(-1, x &= x);
+  assertEquals(-1, x |= ((x+x)-x));
+  assertEquals(1, x *= x);
+  assertEquals(867473898, x ^= (tmp = 867473899.0274491, tmp));
+  assertEquals(6, x >>>= (tmp = 1174763611.341228, tmp));
+  assertEquals(0, x >>= ((689882795)^(2250084531)));
+  assertEquals(0, x /= (tmp = 2545625607, tmp));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x += x);
+  assertEquals(0, x -= (x*(-1098372339.5157008)));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x -= (tmp = -1797344676.375759, tmp));
+  assertEquals(1121476698, x |= (tmp = 1121476698, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(1, x &= (-191233693));
+  assertEquals(330137888.92595553, x += (330137887.92595553));
+  assertEquals(-1792236714, x ^= (tmp = 2256609910, tmp));
+  assertEquals(269000724, x &= (316405813.62093115));
+  assertEquals(256, x >>= x);
+  assertEquals(256, x %= ((2556320341.54669)|(1066176021.2344948)));
+  assertEquals(256, x |= x);
+  assertEquals(131072, x <<= ((-1650561175.8467631)|x));
+  assertEquals(-286761951, x -= ((tmp = 287024095, tmp)-((-2293511421)&(x|x))));
+  assertEquals(-1561852927, x &= (3002663949.0989227));
+  assertEquals(-460778761, x %= (tmp = -550537083, tmp));
+  assertEquals(-3023749308.0492287, x += (tmp = -2562970547.0492287, tmp));
+  assertEquals(-481313332.04922867, x %= ((x|((tmp = -855929299, tmp)%((2181641323)%(x|(220607471.33018696)))))&x));
+  assertEquals(17510668, x &= (tmp = 363557663, tmp));
+  assertEquals(12552, x &= (3020225307));
+  assertEquals(1814655896, x |= ((x<<(((-1475967464)*(-3122830185))*x))+(x^(-2480340864.2661023))));
+  assertEquals(-3209124403525266400, x -= ((1146847590)*(tmp = 2798213497, tmp)));
+  assertEquals(-6418248807050533000, x += x);
+  assertEquals(1.1856589432073933e+28, x *= (-1847324681.313275));
+  assertEquals(-1238853292, x ^= (-1238853292));
+  assertEquals(-77428331, x >>= (x&((((2043976651.8514216)>>>x)^(x>>>(((tmp = -1785122464.9720652, tmp)%x)<<(1570073474.271266))))*x)));
+  assertEquals(2011, x >>>= x);
+  assertEquals(2011, x &= x);
+  assertEquals(0, x >>= (-2682377538));
+  assertEquals(-1.1367252770299785, x -= (((tmp = 2704334195.566802, tmp)/(2379056972))%((((-1764065164)*((((468315142.8822602)>>((x%(((tmp = 2537190513.506641, tmp)+((x&(x|((tmp = -947458639, tmp)^(2653736677.417406))))*((x<<((1243371170.1759553)>>>(((tmp = 1572208816, tmp)<<((tmp = 963855806.1090456, tmp)>>>x))%((-3078281718.7743487)*x))))^(-1154518374))))^(-2839738226.6314087)))^((-2865141241.190915)*(-2400659423.8207664))))>>((tmp = 32940590, tmp)/(tmp = 2917024064.570817, tmp)))+(((27601850)/(tmp = 3168834986, tmp))>>x)))+(tmp = 2528181032.600125, tmp))/(3162473952))));
+  assertEquals(-1697395408.7948515, x -= (1697395407.6581264));
+  assertEquals(1536992607912062500, x *= (tmp = -905500627.5781817, tmp));
+  assertEquals(102759872, x >>= (tmp = -707887133.4484048, tmp));
+  assertEquals(102759872, x %= (tmp = -1764067619.7913327, tmp));
+  assertEquals(12543, x >>>= (-144142995.1469829));
+  assertEquals(-2059555229.2592103, x += ((-2059555229.2592103)-x));
+  assertEquals(-537022593, x |= (tmp = -2770761410.407701, tmp));
+  assertEquals(23777505, x ^= (-560496738.6854918));
+  assertEquals(-64329014115772310, x *= ((tmp = -2729234369.198843, tmp)+x));
+  assertEquals(189083830, x ^= (tmp = 933619934, tmp));
+  assertEquals(189083830, x %= ((tmp = -2918083254, tmp)-(x|(x^(-2481479224.0329475)))));
+  assertEquals(378167660, x += x);
+  assertEquals(-0.45833387791900504, x /= ((tmp = 2727991875.241294, tmp)<<(tmp = 2570034571.9084663, tmp)));
+  assertEquals(0, x <<= x);
+  assertEquals(-0, x /= (tmp = -67528553.30662966, tmp));
+  assertEquals(0, x <<= (938440044.3983492));
+  assertEquals(-945479171, x ^= (tmp = -945479171, tmp));
+  assertEquals(-225632619284361200, x *= (238643670.00884593));
+  assertEquals(-0, x %= x);
+  assertEquals(-585826304, x ^= ((-1256265560)<<(tmp = 1144713549, tmp)));
+  assertEquals(-671583855, x ^= (183333265.1468178));
+  assertEquals(-484311040, x <<= x);
+  assertEquals(-3969762.62295082, x /= ((((tmp = -1164308668.931008, tmp)-x)%x)>>>(((397816647)>>(-1605343671.4070785))<<x)));
+  assertEquals(758097879, x ^= ((tmp = -2871307491, tmp)^(-2043176492.646442)));
+  assertEquals(0, x *= ((x>>(tmp = 1983292927, tmp))&(tmp = -860505131.4484091, tmp)));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x &= x);
+  assertEquals(0, x %= ((3132981707)-(-2832016477)));
+  assertEquals(0, x >>= (x<<((1830195133.0342631)>>>(tmp = -1003969250, tmp))));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x += (tmp = 273271019.87603223, tmp));
+  assertEquals(NaN, x += (625749326.1155348));
+  assertEquals(0, x >>= (tmp = -531039433.3702333, tmp));
+  assertEquals(0, x -= (((tmp = 2029464099, tmp)-(x-(tmp = -329058111.411458, tmp)))*(x<<x)));
+  assertEquals(-0, x *= ((-1112957170.5613296)|((tmp = 847344494, tmp)>>>(tmp = 2735119927, tmp))));
+  assertEquals(-0, x /= (tmp = 544636506, tmp));
+  assertEquals(0, x >>>= (x^(545093699)));
+  assertEquals(0, x %= (((tmp = -2208409647.5052004, tmp)+(3083455385.374988))+(((-482178732.7077277)*x)>>>((2661060565)*(-2125201239)))));
+  assertEquals(0, x >>>= (-212334007.34016395));
+  assertEquals(0.7004300865203454, x -= ((2032883941)/(-2902336693.0154715)));
+  assertEquals(0, x <<= (x<<((265868133.50175047)>>>(1162631094))));
+  assertEquals(604920272.4394834, x -= (-604920272.4394834));
+  assertEquals(604920272, x &= x);
+  assertEquals(0, x <<= (((-1961880051.1127694)%(tmp = 1715021796, tmp))|((tmp = 2474759639.4587016, tmp)|(243416152.55635))));
+  assertEquals(-46419074, x |= (((tmp = -518945938.5238774, tmp)%((x+(tmp = 242636408, tmp))+(-1974062910)))|(1546269242.0259726)));
+  assertEquals(-46419074, x += ((-629802130)*((tmp = -658144149, tmp)%((-905005358.5370393)>>>x))));
+  assertEquals(-46419074, x |= (x%(-1103652494)));
+  assertEquals(7892881050983985, x *= (-170035297.36469936));
+  assertEquals(1105701997.4273424, x %= ((((-490612260.0023911)>>>(tmp = 1803426906, tmp))^(x%(2725270344.2568116)))-(1010563167.8934317)));
+  assertEquals(1088619532, x &= (-2232199650));
+  assertEquals(1073807364, x &= (-888024506.5008001));
+  assertEquals(1153062254980628500, x *= x);
+  assertEquals(1153062255703627000, x -= (tmp = -722998613.897227, tmp));
+  assertEquals(-1141418584, x |= (3017232552.4814596));
+  assertEquals(-373464140, x ^= (-2914372068));
+  assertEquals(994050048, x <<= x);
+  assertEquals(0, x ^= x);
+  assertEquals(0, x &= (tmp = -3166402389, tmp));
+  assertEquals(0, x &= ((-1760842506.337213)|(tmp = 2538748127.795164, tmp)));
+  assertEquals(-0, x /= (-2635127769.808626));
+  assertEquals(0, x &= ((((tmp = 1414701581, tmp)^(((2425608769)/((x<<x)^(x-x)))^((tmp = -2641946468.737288, tmp)|(tmp = -313564549.1754241, tmp))))*(tmp = -2126027460, tmp))|(-2255015479)));
+  assertEquals(225482894, x ^= (225482894.8767246));
+  assertEquals(0, x ^= x);
+  assertEquals(306216231, x += (tmp = 306216231, tmp));
+  assertEquals(306216231, x -= ((-465875275.19848967)&((-806775661.4260025)/((((-184966089.49763203)>>>((x>>x)+((tmp = -1951107532, tmp)|x)))%x)*((2704859526.4047284)%((x*x)>>x))))));
+  assertEquals(30754, x &= (1706162402.033193));
+  assertEquals(30454.010307602264, x -= (((590456519)>>>(tmp = 2713582726.8181214, tmp))/x));
+  assertEquals(8419062, x |= ((2848886788)<<(tmp = 2993383029.402275, tmp)));
+  assertEquals(16, x >>= (tmp = -1651287021, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(-1407643485, x ^= (-1407643486));
+  assertEquals(2, x >>>= (-1126004674));
+  assertEquals(470812081, x ^= ((-2411718964)>>>x));
+  assertEquals(550443688.6407901, x += (tmp = 79631607.6407901, tmp));
+  assertEquals(3669092443.64079, x -= (-3118648755));
+  assertEquals(-625874853, x <<= (((tmp = -1640437346, tmp)/(((x*x)>>>x)<<x))/x));
+  assertEquals(-1431439050363516700, x *= (2287101077));
+  assertEquals(-1921660672, x |= ((((((((-1912249689.9978154)&(-1676922742.5343294))*(2625527768))<<((820676465)^(((x+(tmp = -852743692, tmp))&((x-((((1361714551)/(311531668))>>>(tmp = -1330495518.8175917, tmp))<<(((tmp = 1369938417.8760853, tmp)*(-1217947853.8942266))<<(-2048029668))))-(-513455284)))>>>(tmp = 1980267333.6201067, tmp))))<<(((1503464217.2901971)>>(tmp = 2258265389, tmp))>>>(1868451148)))&(x-(x^(tmp = -1565209787, tmp))))*x)<<(tmp = -2426550685, tmp)));
+  assertEquals(-1921660672, x %= (((tmp = 523950472.3315773, tmp)+(((2971865706)^x)-x))&(-1773969177)));
+  assertEquals(420176973.1169958, x += (2341837645.116996));
+  assertEquals(420176973, x >>>= (((tmp = -2485489141, tmp)<<((tmp = -2520928568.360244, tmp)+x))&(543950045.0932506)));
+  assertEquals(50, x ^= (x|((tmp = 2001660699.5898843, tmp)>>>(tmp = 1209151128, tmp))));
+  assertEquals(138212770720.96973, x *= (2764255414.4193945));
+  assertEquals(-28683, x |= (((-535647551)|x)>>((((2065261509)>>(-354214733))*x)+(-3218217378.2592907))));
+  assertEquals(1627048838, x ^= (tmp = -1627044749, tmp));
+  assertEquals(-839408795, x ^= (2903337187.480303));
+  assertEquals(-1000652427, x += (tmp = -161243632, tmp));
+  assertEquals(740237908.4196916, x += ((tmp = 1587000348, tmp)+(tmp = 153889987.41969144, tmp)));
+  assertEquals(Infinity, x /= (((((-615607376.1012697)&(57343184.023578644))+((-1967741575)|(-3082318496)))<<(((tmp = -958212971.99792, tmp)>>(tmp = 2962656321.3519197, tmp))-(x|(x*(969365195)))))<<(tmp = -1739470562.344624, tmp)));
+  assertEquals(-Infinity, x /= ((tmp = -1736849852, tmp)%x));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x %= (tmp = -226505646, tmp));
+  assertEquals(1982856549, x -= (((x+(-1982856549))%(-2274946222))>>(x%(((tmp = -1289577208.9097936, tmp)>>x)^(778147661)))));
+  assertEquals(1648018703, x ^= ((3085618856)+((tmp = 1546283467, tmp)&(((x|((-2376306530)*(((((((tmp = -2807616416, tmp)%(((((tmp = 347097983.1491085, tmp)<<x)|(((((1135380667)/(x>>>(tmp = 1679395106, tmp)))^((1277761947)<<((tmp = -1614841203.5244312, tmp)>>x)))%((tmp = 1552249234.2065845, tmp)>>>x))>>>(tmp = -1677859287, tmp)))>>>(2605907565))/(tmp = 2291657422.221277, tmp)))%(((tmp = 425501732.6666014, tmp)>>>(1327403879.455553))+x))>>((tmp = -3075752653.2474413, tmp)&(x-(tmp = -71834630, tmp))))|((((2532199449.6500597)*(-842197612.4577162))%x)>>x))*(((1220047194.5100307)<<((tmp = 1642962251, tmp)<<((-662340)>>>((tmp = -1672316631.3251066, tmp)<<((tmp = 1762690952.542441, tmp)-(x/(1904755683.3277364)))))))>>x))|(((((tmp = 1625817700.7052522, tmp)%(tmp = -2990984460, tmp))|(2395645662))-((2619930607.550086)>>x))^(tmp = 130618712, tmp)))))&((-3142462204.4628367)/(1078126534.8819227)))%(((tmp = -256343715.2267704, tmp)+x)^(tmp = 2009243755, tmp))))));
+  assertEquals(1937698223, x |= (((tmp = 866354374.7435778, tmp)+(tmp = 2751925259.3264275, tmp))%(-2252220455)));
+  assertEquals(0, x -= x);
+  assertEquals(-823946290.6515498, x -= (tmp = 823946290.6515498, tmp));
+  assertEquals(706970324, x ^= (-457174758));
+  assertEquals(32916, x &= (25740724));
+  assertEquals(0, x >>>= ((-1658933418.6445677)|(tmp = -846929510.4794133, tmp)));
+  assertEquals(0, x ^= ((-834208600)/((-1256752740)&(tmp = 1973248337.8973258, tmp))));
+  assertEquals(-1639195806, x += (-1639195806));
+  assertEquals(-1559416478, x ^= ((tmp = 1349893449.0193534, tmp)*(tmp = 2044785568.1713037, tmp)));
+  assertEquals(0, x &= ((x>>(tmp = 1720833612, tmp))/((x+(-1305879952.5854573))^x)));
+  assertEquals(-0, x *= (tmp = -1713182743, tmp));
+  assertEquals(0, x >>= x);
+  assertEquals(NaN, x /= (((x%((x>>>(((-1515761763.5499895)^(-3076528507.626539))<<(tmp = 1293944457.8983147, tmp)))<<(tmp = 276867491.8483894, tmp)))>>(tmp = -2831726496.6887417, tmp))%((((tmp = 1780632637.3666987, tmp)^x)%((208921173.18897665)>>(tmp = 633138136, tmp)))+x)));
+  assertEquals(0, x >>= (tmp = -2755513767.0561147, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(840992300.0324914, x -= ((-840992300.0324914)+x));
+  assertEquals(840992300, x &= x);
+  assertEquals(-1094140277, x ^= (2364029095));
+  assertEquals(-Infinity, x /= ((((((1257084956)<<(2009241695))>>(x+x))*x)>>>x)>>>(205318919.85870552)));
+  assertEquals(-Infinity, x -= (((x>>>(tmp = 3037168809.20163, tmp))&x)*(x&(((806151109)*x)-(tmp = -1741679480.58333, tmp)))));
+  assertEquals(400659949, x ^= (tmp = 400659949, tmp));
+  assertEquals(5, x >>= (tmp = 1175519290, tmp));
+  assertEquals(5, x |= x);
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>= ((1317772443)&(x<<x)));
+  assertEquals(-1123981819, x ^= (tmp = 3170985477, tmp));
+  assertEquals(1123864651, x ^= ((x%(((x&x)&(-2606227299.7590737))<<((tmp = -2018123078.1859496, tmp)*x)))|(x+(((((1935939774.8139446)/((-1303958190)/(2802816697.32639)))<<((2880056582)*x))+x)+x))));
+  assertEquals(1543368927, x |= (-2795691884));
+  assertEquals(NaN, x /= (x%((tmp = -1129915114, tmp)<<x)));
+  assertEquals(NaN, x += (tmp = -3045743135, tmp));
+  assertEquals(NaN, x -= (tmp = -2849555731.8207827, tmp));
+  assertEquals(NaN, x /= (((((2127485827)>>>((((tmp = 363239924, tmp)>>x)|((((tmp = -1419142286.0523334, tmp)-(x<<x))^(tmp = -1990365089.8283136, tmp))*((tmp = 2780242444.0739098, tmp)>>>(((-2336511023.342298)&x)/(tmp = 2296926221.402897, tmp)))))>>((tmp = 1378982475.6839466, tmp)>>(tmp = -816522530, tmp))))&(x^(tmp = -1668642255.0586753, tmp)))%(((tmp = 921249300.1500335, tmp)^x)*(tmp = -2228816905, tmp)))>>x));
+  assertEquals(-1460685191, x |= (tmp = 2834282105, tmp));
+  assertEquals(-1463439264, x &= (tmp = 2881860064.146755, tmp));
+  assertEquals(20.98100714963762, x /= (((3017150580.7875347)^((250499372.5339837)<<(tmp = -42767556.30788112, tmp)))|(x%(-2829281526))));
+  assertEquals(1, x /= x);
+  assertEquals(2, x += x);
+  assertEquals(8, x <<= x);
+  assertEquals(0, x >>>= ((730174750)>>>x));
+  assertEquals(0, x ^= x);
+  assertEquals(-1459637373, x ^= (2835329923.456409));
+  assertEquals(-1233115861, x ^= (511678120));
+  assertEquals(95682857, x >>>= ((tmp = 1534570885, tmp)|(tmp = -414425499.3786578, tmp)));
+  assertEquals(70254633, x &= (-1502067585));
+  assertEquals(51384749748909710, x *= (tmp = 731407276, tmp));
+  assertEquals(9390482.873469353, x %= (tmp = -592576964.7982686, tmp));
+  assertEquals(4695241, x >>>= (tmp = -1879898431.5395758, tmp));
+  assertEquals(-3129811912538149000, x += (((-727481809)^((3106908604)%x))*((((tmp = -1218123690, tmp)^(x>>((-942923806)^x)))/(x+x))>>>(-1508881888.969373))));
+  assertEquals(1596870236, x ^= (-1135673764.9721224));
+  assertEquals(0, x ^= x);
+  assertEquals(2133782410, x |= (((-2202469371)>>((tmp = 1327588406.183342, tmp)/(tmp = 253581265.7246865, tmp)))-((tmp = 2226575446.838795, tmp)^x)));
+  assertEquals(-81895217.83608055, x -= (tmp = 2215677627.8360806, tmp));
+  assertEquals(812089344, x <<= ((tmp = 882824005, tmp)/(((x>>((((((((tmp = 1211145185, tmp)/((-137817273)-(((tmp = 2165480503.1144185, tmp)-(-1840859887.1288517))*((155886014.8393339)>>((-1984526598)<<(tmp = 1331249058.3246582, tmp))))))>>(x*x))%(2830324652))%(933701061))|(1346496215))^(tmp = -988800810, tmp))+x))>>>x)<<(-2372088384))));
+  assertEquals(812089344, x <<= x);
+  assertEquals(8472, x %= ((((x|(((x%(tmp = 2772099481.664402, tmp))+(2894690616))-x))&(x&(((-715790638.6454093)>>(tmp = -1447931029, tmp))-(tmp = 1761027889, tmp))))^x)%(((tmp = 830969811, tmp)|x)|((-1102267929)-(3193018687)))));
+  assertEquals(-0.0000028559857417864914, x /= (-2966401364));
+  assertEquals(0, x >>= x);
+  assertEquals(-701800392, x += (tmp = -701800392, tmp));
+  assertEquals(2034756873, x -= (tmp = -2736557265, tmp));
+  assertEquals(-0.9475075048394501, x /= (((((82879340.27231383)+((tmp = -2876678920.653639, tmp)*(-2801097850)))<<x)>>>((x<<(((((x|x)&(tmp = -1572694766, tmp))>>(x+(x/((x-(((tmp = 1435301275, tmp)|(tmp = 983577854.212041, tmp))>>(tmp = 632633852.1644179, tmp)))+x))))>>>x)|(-850932021)))>>x))<<(-821983991)));
+  assertEquals(0, x >>= (x>>(2424003553.0883207)));
+  assertEquals(2599386349, x -= (-2599386349));
+  assertEquals(-68157441, x |= (((tmp = -1170343454.9327996, tmp)+((((tmp = 448468098, tmp)|(x>>(x>>(((x>>(((x/(x&(x<<x)))<<(2436876051.2588806))^(3010167261)))%((tmp = 2577616315.7538686, tmp)>>>(-2953152591.015912)))%((tmp = -1304628613, tmp)/(x&((x|((-2000952119)%((691146914)/((tmp = 1480966978.7766845, tmp)<<((tmp = 2644449477.392441, tmp)|(-2143869305.871568))))))+(tmp = -315254308, tmp))))))))&(-2060205555))|((-604140518.8186448)^(x*x))))%(x*((tmp = 1383244000.2807684, tmp)/(3195793656)))));
+  assertEquals(-68157441, x |= x);
+  assertEquals(-1, x >>= x);
+  assertEquals(-2147483648, x <<= x);
+  assertEquals(-1.5257198286933313, x /= (tmp = 1407521622, tmp));
+  assertEquals(1149084989.47428, x += (((tmp = 1149084991.9004865, tmp)&x)^((((((2797053000)/(x^x))*(-2829253694))>>>((tmp = -610924351, tmp)>>x))>>>(tmp = -675681012, tmp))<<(2812852729))));
+  assertEquals(0, x %= x);
+  assertEquals(0, x <<= ((tmp = -584069073, tmp)*(-2953140326)));
+  assertEquals(0, x <<= (tmp = -481515023.6404002, tmp));
+  assertEquals(-1441535370, x ^= (2853431926));
+  assertEquals(2853431926, x >>>= (((((((tmp = 2215663525.9620194, tmp)%((-1102832735.9274108)/x))>>x)&(3220898702.76322))&(((2077584946)*((x>>x)<<((tmp = 1845701049, tmp)-x)))/(tmp = 1947184202.5737212, tmp)))|(((tmp = 2976351488, tmp)^(-42517339))%((2648230244.410125)^(1520051731.31089))))/(1761635964)));
+  assertEquals(43539, x >>>= (tmp = 1361671184.7432632, tmp));
+  assertEquals(21769, x >>= ((tmp = -804932298.9572575, tmp)>>((((tmp = 1749006993.253409, tmp)+(276536978))^x)|(2698166994))));
+  assertEquals(1103025563, x |= (tmp = 1103007891, tmp));
+  assertEquals(1327594607, x += (tmp = 224569044, tmp));
+  assertEquals(1327594607, x |= x);
+  assertEquals(-478674944, x <<= (((672378508)&x)^(((-2070209708.6470091)|x)|(x>>>x))));
+  assertEquals(-478674943, x ^= ((-1832457698.6345716)>>>((tmp = -3077714019, tmp)/(1809383028))));
+  assertEquals(229129701056053250, x *= x);
+  assertEquals(1, x /= x);
+  assertEquals(2, x <<= (-1522529727));
+  assertEquals(2, x &= x);
+  assertEquals(-2016989182, x |= ((((tmp = -1267845511, tmp)*(1225350332))+((tmp = -1397690831.5717893, tmp)>>>(tmp = -2575382994, tmp)))+x));
+  assertEquals(-241, x >>= (tmp = 931869591, tmp));
+  assertEquals(-1048087547, x &= (tmp = -1048087403.1163051, tmp));
+  assertEquals(-4004486369.844599, x += (tmp = -2956398822.844599, tmp));
+  assertEquals(-4004486368.844599, x -= (((2701878498)>>x)|(x|(-1079354967))));
+  assertEquals(1, x >>= (tmp = -1583689092, tmp));
+  assertEquals(1, x *= (x>>(x%x)));
+  assertEquals(0, x %= x);
+  assertEquals(-0, x *= (-120818969));
+  assertEquals(0, x >>= ((tmp = 1794099660, tmp)/(((x&(((-321906091)^(tmp = -3009885933.8449526, tmp))&((tmp = -140917780, tmp)|(2037803173.4075825))))&x)&(tmp = -745357154, tmp))));
+  assertEquals(0, x <<= (563984257.3493614));
+  assertEquals(NaN, x %= ((((x>>(tmp = -2190891392.320677, tmp))-x)<<(462714956))<<((tmp = -84413570, tmp)|((x|(-2787022855))-((tmp = 2028532622, tmp)|(tmp = 1103757073.9178817, tmp))))));
+  assertEquals(NaN, x *= ((2137674085.3142445)|((tmp = -1054749859.2353804, tmp)%x)));
+  assertEquals(NaN, x /= (x>>>(((((tmp = 597103360.9069608, tmp)>>>(-2850217714.1866236))-((tmp = 1125150527, tmp)*x))%(tmp = -982662312, tmp))|((x/(((968656808.6069037)*(((128484784.15362918)>>x)^x))&((((x/((((tmp = 748775979, tmp)*((x-(((tmp = 709571811.9883962, tmp)%(-2083567026))%(x/(tmp = -680467505, tmp))))/((tmp = -167543858, tmp)/(tmp = -3113588783, tmp))))/x)<<(-2605415230)))>>>(tmp = 3133054172, tmp))%(tmp = -1904650393, tmp))*((x|(-1193709562))*(tmp = -1731312795.718104, tmp)))))/((tmp = -672386301, tmp)/(tmp = 808898833.4163612, tmp))))));
+  assertEquals(-9, x |= (((((tmp = 150377964.57195818, tmp)/(tmp = 2161910879.0514045, tmp))-(-2381625849))>>(-2715928517))/(((452113643)^(-2502232011))/((-3076471740)^(((tmp = 1664851172, tmp)*(((-1460011714)>>>x)<<((-2870606437)%x)))*((tmp = -2836565755.609597, tmp)-((x/(tmp = -871461415, tmp))-(2278867564))))))));
+  assertEquals(-1, x >>= x);
+  assertEquals(-1, x |= ((-1319927272)>>>(-2866709980)));
+  assertEquals(-1, x >>= ((2345179803.155703)&(-978025218.2243443)));
+  assertEquals(1, x /= x);
+  assertEquals(-260730973, x |= (tmp = -260730973, tmp));
+  assertEquals(1174405120, x <<= (2681054073));
+  assertEquals(1174405120, x &= x);
+  assertEquals(1073741824, x &= (tmp = 2017166572.7622075, tmp));
+  assertEquals(1073741824, x |= x);
+  assertEquals(168806102, x %= ((((tmp = -2939969193.950067, tmp)|((-2325174027.614815)/(-2329212715)))*(x/(((((-2927776738)/(x|x))+(x%(tmp = -3007347037.698492, tmp)))<<(-1898633380))>>(tmp = 204338085.45241892, tmp))))^x));
+  assertEquals(168806102, x %= ((-832849739.5197744)&(tmp = -141908598, tmp)));
+  assertEquals(-401033205.05225074, x -= (tmp = 569839307.0522507, tmp));
+  assertEquals(-401033205, x &= x);
+  assertEquals(-401130402, x ^= ((x*(tmp = 311418759.22436893, tmp))>>x));
+  assertEquals(793533469, x ^= (-950312893.5201888));
+  assertEquals(756, x >>>= (-1096189516));
+  assertEquals(711, x += ((tmp = -753105189, tmp)>>(599823192.5381484)));
+  assertEquals(0, x >>>= ((tmp = -2859668634.4641137, tmp)+(-1160392986.1521513)));
+  assertEquals(2427599726.176195, x -= (-2427599726.176195));
+  assertEquals(1942312465.2523103, x -= (485287260.92388475));
+  assertEquals(0, x >>>= ((tmp = -1740656456, tmp)/(tmp = 1339746799.9335847, tmp)));
+  assertEquals(0, x <<= ((-7017077.38786912)*((-699490904.4551768)^x)));
+  assertEquals(0, x <<= (tmp = 715662384, tmp));
+  assertEquals(0, x *= (x>>>(2149735450.0758677)));
+  assertEquals(NaN, x /= x);
+  assertEquals(0, x >>= ((397078885)*((851639692.8982519)-x)));
+  assertEquals(0, x &= (-2526654445));
+  assertEquals(0, x %= (-1204924598));
+  assertEquals(251639720, x ^= (x|(tmp = 251639720, tmp)));
+  assertEquals(695433573, x ^= (663539405));
+  assertEquals(-1038050104, x -= (1733483677));
+  assertEquals(0, x ^= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x &= (392107269));
+  assertEquals(0, x %= (-3084908458.241551));
+  assertEquals(0, x ^= x);
+  assertEquals(-2121660509, x ^= (tmp = -2121660509.7861986, tmp));
+  assertEquals(2285041855588855800, x *= (x|(3209046634)));
+  assertEquals(54915072, x >>>= (x%(((((x%((((tmp = -1429433339.5078833, tmp)|(tmp = 2906845137, tmp))^(3207260333))&(-848438650)))-(-2721099735))&(141851917.19978714))+x)/x)));
+  assertEquals(54915072, x &= x);
+  assertEquals(54915072, x %= (x+(1855489160)));
+  assertEquals(70078753, x ^= ((((((-1648661736)+(x%((-1421237596)+(tmp = 2053180992.3857927, tmp))))+(tmp = 38606889, tmp))<<((-241334284)%((x>>(215316122))*(tmp = 396488307, tmp))))+((tmp = -2900704565, tmp)^x))^(((1103481003.1111188)^x)-(tmp = 1304113534, tmp))));
+  assertEquals(1149501440, x <<= ((x>>(tmp = 3203172843, tmp))*(tmp = -192535531, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>= ((tmp = 2751499787, tmp)&((tmp = 2217654798, tmp)*(tmp = -2798728014, tmp))));
+  assertEquals(NaN, x /= ((((-2019592425)>>>((((-1571930240.741224)>>>((-183952981)/((((1990518443.672842)>>(((((2051371284)%(685322833.6793983))>>>(2662885938))<<(-1212029669.6675105))|((-2790877875)<<(1546643473))))<<x)-(tmp = 804296674.4579233, tmp))))-(tmp = -417759051.68770766, tmp))/((-621859758)>>>x)))&x)<<(tmp = -48558935.55320549, tmp)));
+  assertEquals(0, x <<= (x&x));
+  assertEquals(0, x *= (x%(tmp = 301196068, tmp)));
+  assertEquals(398290944, x |= (((tmp = 1904146839, tmp)+(1521017178))*(-3174245888.562067)));
+  assertEquals(1256401076, x ^= (1566464180));
+  assertEquals(149620758, x %= ((tmp = 532626355, tmp)^(tmp = -382971203, tmp)));
+  assertEquals(149620791, x |= (x>>x));
+  assertEquals(-0.07034576194938641, x /= ((tmp = -1977313182.7573922, tmp)-x));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x &= x);
+  assertEquals(0, x /= ((2182424851.139966)%(((-2768516150)+x)>>>x)));
+  assertEquals(0, x %= (-504299638.53962016));
+  assertEquals(-0, x *= (-2915134629.6909094));
+  assertEquals(0, x <<= ((tmp = 952692723.402582, tmp)%(2146335996.785011)));
+  assertEquals(230457472, x |= ((tmp = -574776101.8681948, tmp)*(683185125)));
+  assertEquals(933795934, x ^= (tmp = 974395614, tmp));
+  assertEquals(933801974, x ^= (x>>>((-148683729)*(((tmp = 2912596991.415531, tmp)^(-2883672328))/x))));
+  assertEquals(222, x >>= (-3060224682));
+  assertEquals(27, x >>>= (1429156099.1338701));
+  assertEquals(754519106, x ^= (tmp = 754519129.7281355, tmp));
+  assertEquals(188629776, x >>>= ((x>>>((1247267193)<<(tmp = -936228622, tmp)))%((tmp = 978604324.8236886, tmp)*((tmp = -3018953108, tmp)^(((tmp = 259650195, tmp)>>>(tmp = 2762928902.7901163, tmp))*(x>>((tmp = 787444263.5542864, tmp)/(x>>>(((-2039193776)<<(tmp = -1408159169, tmp))-(1238893783))))))))));
+  assertEquals(188629775.33987066, x += ((tmp = 1040520414, tmp)/((-1576237184)|((tmp = -970083705, tmp)&(((tmp = -312062761.12228274, tmp)|(1171754278.2968853))<<(-2069846597.7723892))))));
+  assertEquals(1473670, x >>>= ((tmp = 202409672, tmp)^x));
+  assertEquals(2171703268900, x *= (x>>(((tmp = 840468550, tmp)&(-3208057101.2136793))/x)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x ^= (x&((tmp = 2569871408.2405066, tmp)|((tmp = -3149374622, tmp)<<(x-(x|((tmp = -821239139.1626894, tmp)>>>x)))))));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x %= (tmp = 1926106354, tmp));
+  assertEquals(0, x >>= ((x/(-2848416))/(tmp = 2484293767, tmp)));
+  assertEquals(0, x <<= ((tmp = -2484137114, tmp)>>>(tmp = -887083772.8318355, tmp)));
+  assertEquals(0, x >>= (tmp = -2651389432, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(1041871201, x += ((tmp = 1041871201.9272791, tmp)|(x<<(-1136959830))));
+  assertEquals(651390879501530900, x *= ((tmp = 1250424964.0346212, tmp)>>x));
+  assertEquals(1965815296.245636, x %= ((2650603245.655831)+((-1610821947.8640454)>>>(((878987151.6917406)*((((784630543)%(((1448720244)>>(((tmp = 3036767847, tmp)+((tmp = 1012548422, tmp)<<(1957000200)))-x))/(x>>x)))<<((tmp = 914710268, tmp)*(((x^(1559603121))<<(tmp = 3181816736, tmp))|((-1964115655)+x))))-(-1055603890)))&(946797797.0616649)))));
+  assertEquals(1965815296.245636, x %= (tmp = -2601038357.593118, tmp));
+  assertEquals(-769384440.872302, x += (-2735199737.117938));
+  assertEquals(-769384440.872302, x %= (2193123162));
+  assertEquals(1, x /= x);
+  assertEquals(1, x -= (((x>>>(-1968465925))*((tmp = 563037904, tmp)>>((tmp = 3009534415.769578, tmp)>>((-2567240601.7038674)<<(tmp = -1258402723.4150183, tmp)))))%(3112239470.276867)));
+  assertEquals(1, x |= x);
+  assertEquals(1505461527, x ^= (tmp = 1505461526.5858076, tmp));
+  assertEquals(406553877, x &= (tmp = 2558242293, tmp));
+  assertEquals(406553877, x |= x);
+  assertEquals(-574902339, x |= ((-709809495)%(tmp = -2880884811.410611, tmp)));
+  assertEquals(-20281777.349363208, x %= (22184822.46602547));
+  assertEquals(1, x /= x);
+  assertEquals(-4360732, x ^= ((x|(tmp = 3178620274, tmp))>>(((2686286888)&(((-1107223053.8716578)/(((-2955575332.3675404)+(-2770518721))|(-2705016953.640522)))-x))^((1473641110.4633303)*((((-1466496401)<<x)+x)%(1805868749.082736))))));
+  assertEquals(-1158545408, x <<= ((((x/((-2710098221.691819)-(-2421462965.788145)))/(((((x>>>(tmp = 1994541591.1032422, tmp))+(tmp = -1276676679.9747126, tmp))&((tmp = 1764029634.2493339, tmp)+((x|(tmp = -3050446156, tmp))-((tmp = -9441859, tmp)/(((-2072420232)&x)*(-1003199889))))))+(tmp = -2443230628, tmp))*x))*((x&((((x|(747566933))*(((2039741506)>>>((tmp = -2456000554, tmp)>>>(-1566360933.7788877)))^((tmp = 960600745, tmp)/x)))&(x^(((-2649310348.777452)^((2224282875)-(tmp = -2129141087.3182096, tmp)))<<((x<<x)+((-1307892509.3874407)-(x|(tmp = -2831643528.9720087, tmp)))))))/(((tmp = -35502946, tmp)<<((tmp = 1091279222, tmp)>>(((-2686069468.8930416)-x)+(tmp = 367442353.2904701, tmp))))%(1218262628))))/x))^(-919079153.7857773)));
+  assertEquals(747, x >>>= (1229157974));
+  assertEquals(747, x |= x);
+  assertEquals(NaN, x %= (((3086718766.4715977)*((7912648.497568846)*((-2713828337.1659327)*(-176492425.4011252))))<<(tmp = -1074475173, tmp)));
+  assertEquals(0, x >>>= ((((444923201)<<x)>>>(-883391420.2142565))*((((617245412)<<x)>>>x)*(-913086143.2793813))));
+  assertEquals(1941802406, x ^= (tmp = -2353164890, tmp));
+  assertEquals(14, x >>>= (-1600311077.4571416));
+  assertEquals(-18229482703.7246, x += (((x+(-993157139.7880647))%x)*(1862419512.1781366)));
+  assertEquals(-14.531388114858734, x /= ((tmp = -1649072797.951641, tmp)<<x));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>= ((x/x)^x));
+  assertEquals(2, x ^= ((-1597416259)/(-738770020)));
+  assertEquals(0, x >>= (tmp = -387850072.74833393, tmp));
+  assertEquals(0, x >>>= ((2491085477.186817)>>(x*(((tmp = -1592498533, tmp)+(tmp = 2086841852, tmp))&(-3174019330.8288536)))));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x >>>= (tmp = -3045348659.45243, tmp));
+  assertEquals(-1208573479, x |= ((3086393817)-x));
+  assertEquals(1460649854142163500, x *= x);
+  assertEquals(1588199424, x <<= (-1902076952));
+  assertEquals(1586102272, x &= (tmp = 2139876091.9142454, tmp));
+  assertEquals(-460908552.5528109, x -= (tmp = 2047010824.552811, tmp));
+  assertEquals(-460908552.5528109, x %= (tmp = 507904117.09368753, tmp));
+  assertEquals(-460908552.5528109, x %= (2749577642.527038));
+  assertEquals(234012, x >>>= (-340465746.91275));
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x %= (tmp = -2601875531, tmp));
+  assertEquals(0, x %= (x|(tmp = 650979981.1158671, tmp)));
+  assertEquals(0, x %= (tmp = -2286020987, tmp));
+  assertEquals(0, x |= x);
+  assertEquals(0, x &= (x|((tmp = 2568101411, tmp)-(-1438002403))));
+  assertEquals(0, x >>>= (1399248574));
+  assertEquals(0, x %= (-1906670287.2043698));
+  assertEquals(0, x >>= (1019286379.6962404));
+  assertEquals(0, x |= (x/(tmp = -82583591.62643051, tmp)));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x *= (x^(1874776436)));
+  assertEquals(NaN, x -= ((-1238826797)-(-2971588236.7228813)));
+  assertEquals(0, x <<= (2064632559));
+  assertEquals(-0.5967273958864694, x += (((tmp = 1502995019, tmp)>>x)/(-2518729707)));
+  assertEquals(0, x >>>= x);
+  assertEquals(-0, x /= (-1923030890));
+  assertEquals(NaN, x %= x);
+  assertEquals(0, x >>= (tmp = 1081732779.9449487, tmp));
+  assertEquals(-820183066, x |= ((tmp = -3169007292.4721155, tmp)|(-1912588318)));
+  assertEquals(0, x -= x);
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x /= (tmp = 287181840, tmp));
+  assertEquals(0, x &= (x/((tmp = -1139766051, tmp)<<(x&(tmp = 2779004578, tmp)))));
+  assertEquals(0, x >>= (((tmp = -1816938028, tmp)+(-224851993.3139863))*(-2933829524)));
+  assertEquals(0, x |= ((((tmp = 305077929.1808746, tmp)&((x-(((((tmp = 2122810346.7475111, tmp)<<(717271979))*(tmp = 256854043.72633624, tmp))%((x+(tmp = -318657223.9992106, tmp))*((1993144830)<<(2594890698.603228))))^((((tmp = 257370667, tmp)>>>((((x^(3160746820))>>>(2049640466.8116226))>>>(2543930504.7117066))^(x-x)))^(x%(964838975)))^x)))%(x*x)))>>>x)*(tmp = -46861540, tmp)));
+  assertEquals(747575633, x ^= ((-2406502427)-(-3154078060.3794584)));
+  assertEquals(0, x *= (x%x));
+  assertEquals(0, x <<= (1313773705.3087234));
+  assertEquals(0, x >>>= ((x+x)>>>(3068164056)));
+  assertEquals(-0, x *= (tmp = -1771797797, tmp));
+  assertEquals(1784146970, x ^= (tmp = 1784146970, tmp));
+  assertEquals(1784146970, x >>>= (tmp = -2219972320.7195597, tmp));
+  assertEquals(1744830464, x <<= ((((-2769476584)-(((1798431604)>>(tmp = 1337687914.799577, tmp))>>>((-2802941943.15014)>>x)))>>>(tmp = 646033678, tmp))-x));
+  assertEquals(3044433348102455300, x *= x);
+  assertEquals(0, x >>= ((tmp = 1592076570.1900845, tmp)-((645774223.6317859)>>x)));
+  assertEquals(0, x >>= (x>>>(-3045822290.1536255)));
+  assertEquals(-0, x *= (tmp = -2450298800.986624, tmp));
+  assertEquals(0, x >>= (tmp = 1379605393, tmp));
+  assertEquals(0, x &= (((x-((((tmp = 837939461.6683749, tmp)+((((-813261853.3247359)|(x&(((-2565113940)*(tmp = -2725085381.240134, tmp))|x)))%(-1457259320))-(x+((tmp = -273947066, tmp)%((1164825698.879649)>>(1653138880.3434052))))))>>>(2823967606.411492))>>>((((((((1189235604.9646997)/(tmp = -2875620103.4002438, tmp))-(tmp = -801261493, tmp))<<(((1832556579.5095325)<<x)|((tmp = -2740330665, tmp)>>(tmp = -2352814025, tmp))))-(tmp = -1445043552.99499, tmp))&(x<<(((((445325471)*(1293047043.1808558))>>>(((1901837408.5910044)-(tmp = -2349093446.5313253, tmp))>>>(tmp = 1000847053.1861948, tmp)))*(x>>>(1771853406.6567078)))>>x)))>>>x)>>>(x^((tmp = 2813422715, tmp)-(x+(-342599947)))))))&(x>>>x))*x));
+  assertEquals(NaN, x %= ((tmp = -3027713526, tmp)-((((x%(((((x/((2711155710)^(((((x>>>x)%((1098599291.155015)^(((((tmp = 1855724377.8987885, tmp)/(x|x))*((-1963179786)*((x-((-1634717702)%x))<<x)))>>(2008859507))>>((tmp = 2635024299.7983694, tmp)^(tmp = -602049246, tmp)))))*(x>>x))&(tmp = -1925103609, tmp))*((tmp = 2106913531.2828505, tmp)%((tmp = -200970069, tmp)*(-2809001910.951446))))))%x)*((1990098169)>>((x<<(2303347904.2601404))%x)))|(2767962065.9846206))+(201589933.301661)))>>(((tmp = 1921071149.5140274, tmp)>>(1054558799.1731887))|x))*(x/((((-2833879637.345674)>>>(tmp = 2849099601, tmp))%x)+(x%(x%(((tmp = 1983018049, tmp)^(tmp = -2659637454, tmp))>>((-1335497229.6945198)-(x+(((((tmp = 1136612609.848967, tmp)%(2471741030.01762))<<(x|(((tmp = 1644081190.1972675, tmp)&(-1422527338))^(2379264356.265957))))/(tmp = 2979299484.1884174, tmp))/x)))))))))*((tmp = 1858298882, tmp)^((tmp = -547417134.9651439, tmp)*x)))));
+  assertEquals(-7664, x |= ((2286000258.825538)>>(1716389170)));
+  assertEquals(-1, x >>= x);
+  assertEquals(-1231640486.3023372, x += ((tmp = 1231640485.3023372, tmp)*x));
+  assertEquals(-2463280972.6046743, x += x);
+  assertEquals(1746, x >>>= x);
+  assertEquals(1746, x >>>= (((tmp = -562546488.0669937, tmp)*((-2475357745.8508205)&((x%(821425388.8633704))%((((-2315481592.687686)&(((tmp = 3130530521.7453523, tmp)+x)-x))^(-973033390.1773088))/x))))<<x));
+  assertEquals(1746, x %= (-1544973951.076033));
+  assertEquals(27936, x <<= (-525441532.33816123));
+  assertEquals(27936, x %= (x*((tmp = 344991423.5336287, tmp)+(-2267207281))));
+  assertEquals(27, x >>>= (tmp = 1249792906, tmp));
+  assertEquals(0, x >>>= (tmp = -1068989615, tmp));
+  assertEquals(0, x >>>= (tmp = 347969658.92579734, tmp));
+  assertEquals(-2656611892, x -= (2656611892));
+  assertEquals(1944539596, x |= (((tmp = 3000889963, tmp)-x)<<((tmp = 2917390580.5323124, tmp)^(-996041439))));
+  assertEquals(1944539596, x |= x);
+  assertEquals(-739740167.0752468, x -= ((1712009965.0752468)+(x>>((tmp = -740611560.99014, tmp)>>>((tmp = -1033267419.6253037, tmp)&(862184116.3583733))))));
+  assertEquals(-1479480334.1504936, x += x);
+  assertEquals(-4294967296.150494, x -= (x>>>((1219235492.3661718)&(3138970355.0665245))));
+  assertEquals(0, x >>= (x*x));
+  assertEquals(-0, x *= ((-2202530054.6558375)-(-676578695)));
+  assertEquals(-0, x %= (1336025846));
+  assertEquals(0, x &= x);
+  assertEquals(0, x /= (1759366510));
+  assertEquals(630007622, x |= (630007622));
+  assertEquals(-0.22460286863455903, x /= (tmp = -2804984753, tmp));
+  assertEquals(1102410276.775397, x -= (-1102410277));
+  assertEquals(1102410276.775397, x %= ((((-2569525203)&x)*(x|(-1932675298)))/((-2376634450)>>>(x>>>(tmp = 936937604.9491489, tmp)))));
+  assertEquals(33642, x >>= (3028252527));
+  assertEquals(2181106522.688034, x -= (-2181072880.688034));
+  assertEquals(-2113861630, x &= (2523921542));
+  assertEquals(-2147483646, x &= (-1996601566.9370148));
+  assertEquals(-2147483648, x &= (tmp = -665669175.1968856, tmp));
+  assertEquals(-2858673260.1367273, x -= (tmp = 711189612.1367272, tmp));
+  assertEquals(350657, x >>= (tmp = -170243892.25474262, tmp));
+  assertEquals(-0.0001405571562140975, x /= (-2494764474.7868776));
+  assertEquals(0, x ^= x);
+  assertEquals(NaN, x /= ((x&(-2041236879))*((tmp = -2182530229, tmp)^((1274197078)*x))));
+  assertEquals(0, x |= (x&(x-(1794950303))));
+  assertEquals(1222105379, x |= (tmp = 1222105379, tmp));
+  assertEquals(729884484, x ^= (tmp = 1666645607.6907792, tmp));
+  assertEquals(729884484, x %= (tmp = -2896922082, tmp));
+  assertEquals(8768, x &= ((tmp = 358940932, tmp)>>>(3159687631.3308897)));
+  assertEquals(1892384495, x |= (-2402591569));
+  assertEquals(1892470533, x += ((((x^(-2266612043))>>>(tmp = -531009952, tmp))<<(x>>>((-1365315963.5698428)>>>((x+((-3168207800.184341)-(tmp = 1776222157.609917, tmp)))+(-1588857469.3596382)))))>>>x));
+  assertEquals(143587205, x += (tmp = -1748883328, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>= (tmp = 2334880462.3195543, tmp));
+  assertEquals(0, x &= ((tmp = 1819359625.4396145, tmp)|(tmp = -1323513565, tmp)));
+  assertEquals(-1102259874, x ^= (3192707422));
+  assertEquals(2567457772588852700, x *= (-2329267202));
+  assertEquals(-16783687, x |= ((-2212476227.060922)^(378973700.78452563)));
+  assertEquals(4278183609, x >>>= ((((((((tmp = 1766363150.197206, tmp)*(-2774552871))%x)>>>((3071429820)&((((((tmp = 351068445.27642524, tmp)<<(tmp = 2646575765, tmp))^(806452682))<<((x>>>(-2217968415.505327))<<(1564726716)))|x)-(tmp = -3110814468.9023848, tmp))))+x)^x)>>>(tmp = -617705282.0788529, tmp))>>>x));
+  assertEquals(4314933530, x -= ((1032195469.789219)|(tmp = -448053861.9531791, tmp)));
+  assertEquals(9709850, x %= (((tmp = -3056286252.5853324, tmp)*x)&x));
+  assertEquals(9709850, x %= (tmp = -2596800940, tmp));
+  assertEquals(2655489828.9461126, x -= (tmp = -2645779978.9461126, tmp));
+  assertEquals(369266212, x &= (((335712316.24874604)|(tmp = 33648215, tmp))-((x/(2639848695))<<((-499681175)<<(-2490554556)))));
+  assertEquals(-2147483648, x <<= (-834465507));
+  assertEquals(1073741824, x >>>= (((tmp = 3018385473.1824775, tmp)>>(x*(-2574502558.216812)))|(((tmp = -1742844828, tmp)*(1698724455))&x)));
+  assertEquals(-270818218, x += (-1344560042));
+  assertEquals(360710144, x <<= x);
+  assertEquals(0, x <<= (tmp = 612718075, tmp));
+  assertEquals(0, x <<= x);
+  assertEquals(-0, x /= (tmp = -1922423684, tmp));
+  assertEquals(-0, x *= ((((tmp = 741806213.3264687, tmp)%(-711184803.2022421))+((tmp = -3209040938, tmp)&(525355849.044886)))&(x<<(tmp = -698610297, tmp))));
+  assertEquals(0, x <<= (-482471790));
+  assertEquals(0, x &= ((-921538707)/(tmp = -482498765.988616, tmp)));
+  assertEquals(0, x ^= (x^x));
+  assertEquals(-351721702, x ^= (-351721702.8850286));
+  assertEquals(726242219625599900, x -= ((2064820612)*x));
+  assertEquals(1452484439251199700, x += x);
+  assertEquals(2.52318299412847e-15, x %= ((((x<<((2508143285)+x))>>(-2493225905.011774))%(1867009511.0792103))/((((x<<(2542171236))>>((x|x)&(tmp = -384528563, tmp)))+((-1168755343)*(1731980691.6745195)))+(tmp = -1608066022.71164, tmp))));
+  assertEquals(79905008, x += ((((-2702081714.590131)&(x+(tmp = -1254725471.2121565, tmp)))*(3088309981))%(((tmp = 1476844981.1453142, tmp)|((((tmp = -1243556934.7291331, tmp)%x)^(-1302096154))+((660489180)/(tmp = -681535480.8642154, tmp))))^(tmp = -8410710, tmp))));
+  assertEquals(1215822204, x ^= ((-3008054900)>>>(tmp = -1990206464.460693, tmp)));
+  assertEquals(-394790532, x |= ((((-1334779133.2038574)+(tmp = -1407958866.832946, tmp))<<(1699208315))-(((x^(x%x))<<(3216443))>>(x+((((2576716374.3081336)|((tmp = 2316167191.348064, tmp)&((51086351.20208645)&((x|(tmp = -357261999, tmp))^(x/x)))))*(-45901631.10155654))*(((-439588079)>>>((-2358959768.7634916)|(1613636894.9373643)))+(((-908627176)<<x)%(x%((-1669567978)>>>((x>>(1289400876))+(tmp = 2726174270, tmp)))))))))));
+  assertEquals(-0.17717467607696327, x /= (2228255982.974148));
+  assertEquals(-1905616474, x ^= (tmp = 2389350822.851587, tmp));
+  assertEquals(-0, x %= x);
+  assertEquals(2818124981.508915, x -= (-2818124981.508915));
+  assertEquals(-1476842315, x |= x);
+  assertEquals(73408564, x &= (-3147390604.3453345));
+  assertEquals(70, x >>>= x);
+  assertEquals(1, x >>= x);
+  assertEquals(3086527319.899181, x *= (3086527319.899181));
+  assertEquals(-145, x >>= x);
+  assertEquals(-145, x %= (tmp = -2500421077.3982406, tmp));
+  assertEquals(-1, x >>= (tmp = -2970678326.712191, tmp));
+  assertEquals(-1, x %= ((tmp = -535932632.4668834, tmp)+(((-1226598339.347982)<<((tmp = 616949449, tmp)/(tmp = 2779464046, tmp)))/(214578501.67984307))));
+  assertEquals(1, x *= x);
+  assertEquals(1, x >>= ((tmp = 11080208, tmp)<<(460763913)));
+  assertEquals(-1.8406600706723492e-19, x /= ((tmp = -2334126306.1720915, tmp)*(tmp = 2327566272.5901165, tmp)));
+  assertEquals(856681434186007200, x -= ((tmp = -2286974992.8133907, tmp)*(374591518)));
+  assertEquals(3126084224, x >>>= x);
+  assertEquals(-1160460669, x |= (tmp = 181716099, tmp));
+  assertEquals(873988096, x <<= (tmp = 406702419, tmp));
+  assertEquals(0, x <<= ((tmp = 802107965.4672925, tmp)-((tmp = 1644174603, tmp)>>((tmp = 604679952, tmp)+(tmp = -515450096.51425123, tmp)))));
+  assertEquals(NaN, x %= ((x>>(tmp = 2245570378, tmp))*(tmp = 1547616585, tmp)));
+  assertEquals(NaN, x /= ((tmp = -776657947.0382309, tmp)&(tmp = 163929332.28270507, tmp)));
+  assertEquals(NaN, x *= (tmp = 243725679.78916526, tmp));
+  assertEquals(NaN, x /= (x>>x));
+  assertEquals(0, x <<= ((tmp = -1293291295.5735884, tmp)%(((((63309078)>>>x)&(x&(-2835108260.025297)))+x)>>>(-1317213424))));
+  assertEquals(0, x *= ((((tmp = -1140319441.0068483, tmp)*(tmp = 2102496185, tmp))&(-2326380427))<<(tmp = -2765904696, tmp)));
+  assertEquals(0, x /= (tmp = 2709618593, tmp));
+  assertEquals(0, x >>= (-1753085095.7670164));
+  assertEquals(1766381484, x |= (-2528585812));
+  assertEquals(1766381484, x %= (2735943476.6363373));
+  assertEquals(1766381484, x %= (x*(tmp = 2701354268, tmp)));
+  assertEquals(-2147483648, x <<= (-323840707.4949653));
+  assertEquals(4611686018427388000, x *= (x<<x));
+  assertEquals(0, x <<= (3066735113));
+  assertEquals(0, x ^= ((((x*x)^(tmp = -2182795086.39927, tmp))<<(x^(tmp = 1661144992.4371827, tmp)))<<((((-2885512572.176741)*(tmp = 609919485, tmp))|(tmp = 929399391.0790694, tmp))>>>((((((((((399048996)>>((-107976581.61751771)>>>x))|(((-1502100015)<<(tmp = -1108852531.9494338, tmp))&(x/(tmp = -3198795871.7239237, tmp))))+((-2627653357)>>x))>>>x)*(1066736757.2718519))%(tmp = 1326732482.201604, tmp))/(tmp = 2513496019.814191, tmp))>>>((1694891519)>>>(-2860217254.378931)))<<(tmp = 31345503, tmp)))));
+  assertEquals(0, x ^= (x/((-2556481161)>>>(x/(x%(x&(1302923615.7148068)))))));
+  assertEquals(NaN, x /= x);
+  assertEquals(NaN, x += (tmp = 846522031, tmp));
+  assertEquals(0, x >>= (x+(-1420249556.419045)));
+  assertEquals(0, x ^= (((x%(-1807673170))&x)-x));
+  assertEquals(-3484.311990686845, x -= ((((((-510347602.0068991)>>>x)<<((tmp = 1647999950, tmp)&(((305407727)>>((1781066601.791009)&x))<<((tmp = -998795238, tmp)%(((x/x)+x)<<(((2586995491.434947)<<x)-((((tmp = 545715607.9395425, tmp)*x)>>>x)>>>(((((2332534960.4595165)^(-3159493972.3695474))<<(tmp = 867030294, tmp))|(2950723135.753855))^(((3150916666)<<x)>>((tmp = 414988690, tmp)|((tmp = -1879594606, tmp)/(tmp = 1485647336.933429, tmp))))))))))))>>(tmp = -2676293177, tmp))%(617312699.1995015))/((((tmp = -1742121185, tmp)^((((x&x)<<(tmp = 698266916, tmp))/(-1860886248))+((-213304430)%((((((-2508973021.1333447)+(tmp = 2678876318.4903, tmp))&(tmp = -43584540, tmp))-x)^(-2251323850.4611115))-x))))>>>(tmp = 2555971284, tmp))%((((tmp = 16925106, tmp)^x)&x)|((x/((x|(tmp = -2787677257.125139, tmp))<<(-853699567)))+(tmp = -1721553520, tmp))))));
+  assertEquals(-447873933.26863855, x += (-447870448.9566479));
+  assertEquals(200591060101520900, x *= x);
+  assertEquals(200591062202483420, x -= (-2100962536));
+  assertEquals(-5.261023346568228e+24, x *= ((tmp = -419641692.6377077, tmp)>>(tmp = -224703100, tmp)));
+  assertEquals(1269498660, x |= (195756836));
+  assertEquals(1269498660, x |= x);
+  assertEquals(1269498660, x |= x);
+  assertEquals(-37.75978948486164, x /= (((tmp = -595793780, tmp)+((tmp = 2384365752, tmp)>>>(1597707155)))|((968887032)^(tmp = 2417905313.4337964, tmp))));
+  assertEquals(-37.75978948486164, x %= (tmp = -1846958365.291661, tmp));
+  assertEquals(1102319266.6421175, x += (1102319304.401907));
+  assertEquals(-1664202255175155200, x -= ((x^(tmp = 407408729, tmp))*x));
+  assertEquals(-752874653, x ^= (tmp = 314673507, tmp));
+  assertEquals(-72474761, x |= (tmp = -2538726025.8884344, tmp));
+  assertEquals(-72474761, x |= x);
+  assertEquals(-122849418, x += ((tmp = -2332080457, tmp)|(((((30496388.145492196)*(((-1654329438.451212)|(-2205923896))&(x>>(tmp = -1179784444.957002, tmp))))&(tmp = 319312118, tmp))*(651650825))|(((-2305190283)|x)>>>(-428229803)))));
+  assertEquals(994, x >>>= x);
+  assertEquals(614292, x *= (((((2565736877)/((tmp = 649009094, tmp)>>>(((x>>>(2208471260))>>(x>>>x))%x)))&(tmp = 357846438, tmp))<<(tmp = -2175355851, tmp))%x));
+  assertEquals(1792008118, x |= (tmp = 1791924774.5121183, tmp));
+  assertEquals(1246238208, x &= (tmp = 1264064009.9569638, tmp));
+  assertEquals(-88877082, x ^= (2969289190.285704));
+  assertEquals(0.044923746573582474, x /= ((tmp = -3057438043, tmp)^(-1009304907)));
+  assertEquals(0, x <<= ((-828383918)-((((x>>(734512101))*(tmp = -3108890379, tmp))-(x|((tmp = 3081370585.3127823, tmp)^((-271087194)-(x/(tmp = -2777995324.4073873, tmp))))))%x)));
+  assertEquals(1604111507.3365753, x -= (-1604111507.3365753));
+  assertEquals(-1721314970, x ^= (tmp = -956686859, tmp));
+  assertEquals(-102247425, x |= (tmp = -2535095555, tmp));
+  assertEquals(-102247425, x %= (-955423877));
+  assertEquals(1053144489850425, x *= (((tmp = 1583243590.9550207, tmp)&(1356978114.8592746))|(tmp = -10299961.622774363, tmp)));
+  assertEquals(-0.0043728190668037336, x /= ((-1196259252.435701)*(((-689529982)|(tmp = -1698518652.4373918, tmp))<<x)));
+  assertEquals(-2, x ^= (((x+(tmp = 2961627388, tmp))>>(tmp = 231666110.84104693, tmp))|x));
+  assertEquals(-1, x >>= (tmp = -83214419.92958307, tmp));
+  assertEquals(-1, x %= (-1303878209.6288595));
+  assertEquals(2944850457.5213213, x -= (tmp = -2944850458.5213213, tmp));
+  assertEquals(-1.6607884436053055, x /= (-1773164107));
+  assertEquals(-0.6607884436053055, x %= ((x>>(1240245489.8629928))%(tmp = -3044136221, tmp)));
+  assertEquals(-0, x *= ((x*x)>>>((1069542313.7656753)+x)));
+  assertEquals(0, x >>>= (tmp = -202931587.00212693, tmp));
+  assertEquals(-0, x *= (-375274420));
+  assertEquals(0, x |= ((x/(((tmp = -876417141, tmp)*(x>>>x))&(-2406962078)))<<x));
+  assertEquals(0, x &= ((tmp = -650283599.0780096, tmp)*(tmp = 513255913.34108484, tmp)));
+  assertEquals(3027255453.458466, x += (3027255453.458466));
+  assertEquals(-12568623413253943000, x *= (((x-(198689694.92141533))|x)-x));
+  assertEquals(-12568623410285185000, x -= (tmp = -2968758030.3694654, tmp));
+  assertEquals(-2008903680, x &= (3111621747.7679076));
+  assertEquals(-110045263.26583672, x += (tmp = 1898858416.7341633, tmp));
+  assertEquals(15964, x >>>= (1141042034));
+  assertEquals(31928, x += x);
+  assertEquals(0, x ^= x);
+  assertEquals(-1159866377, x |= (-1159866377));
+  assertEquals(0, x ^= x);
+  assertEquals(3072699529.4306993, x -= (tmp = -3072699529.4306993, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(-1471195029, x |= (2823772267.429641));
+  assertEquals(-4152937108, x += (-2681742079));
+  assertEquals(142030188, x |= x);
+  assertEquals(270, x >>= (tmp = 1013826483, tmp));
+  assertEquals(0, x >>>= (529670686));
+  assertEquals(-2912300367, x -= (2912300367));
+  assertEquals(2213791134963007500, x *= (x<<((((-3214746140)>>(tmp = -588929463, tmp))+((tmp = -3084290306, tmp)>>x))>>x)));
+  assertEquals(2213791133466809900, x -= (tmp = 1496197641, tmp));
+  assertEquals(69834416, x >>>= (x|(((2755815509.6323137)^(x%(((x*((((tmp = 375453453, tmp)<<(x*x))>>(tmp = -973199642, tmp))*x))>>((tmp = -356288629, tmp)>>(tmp = 2879464644, tmp)))<<((((1353647167.9291127)>>>(x/x))<<((2919449101)/(2954998123.5529594)))^x))))&((-2317273650)>>>(tmp = 34560010.71060455, tmp)))));
+  assertEquals(69834416, x >>>= (x^(-2117657680.8646245)));
+  assertEquals(2217318064, x -= ((tmp = 2035883891, tmp)<<(tmp = -1884739265, tmp)));
+  assertEquals(-1272875686, x ^= (tmp = 805889002.7165648, tmp));
+  assertEquals(-1272875686, x >>= (x&(((1750455903)*x)>>((722098015)%((tmp = 1605335626, tmp)>>(tmp = -565369634, tmp))))));
+  assertEquals(-1274351316, x -= (x>>>((tmp = 2382002632, tmp)-((tmp = -2355012843, tmp)+(1465018311.6735773)))));
+  assertEquals(-2982908522.4418216, x -= ((tmp = 1635549038.4418216, tmp)+(((1952167017.720186)&((tmp = -2284822073.1002254, tmp)>>(-1403893917)))%(tmp = 655347757, tmp))));
+  assertEquals(312, x >>>= x);
+  assertEquals(1248, x <<= (2376583906));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x *= ((((tmp = 1914053541.881434, tmp)>>>(tmp = 1583032186, tmp))>>>(-2511688231))%(tmp = -2647173031, tmp)));
+  assertEquals(0, x >>>= (tmp = -2320612994.2421227, tmp));
+  assertEquals(0, x %= (((x+(tmp = -720216298.5403998, tmp))<<(414712685))>>(tmp = 480416588, tmp)));
+  assertEquals(0, x >>= ((((3039442014.271272)<<x)%(-2402430612.9724464))&((-2141451461.3664773)%((x>>(1361764256))/((tmp = -1723952801.9320493, tmp)%(477351810.2485285))))));
+  assertEquals(-0, x /= (tmp = -1627035877, tmp));
+  assertEquals(0, x >>>= (tmp = 1745193212, tmp));
+  assertEquals(0, x >>>= (2309131575));
+  assertEquals(NaN, x %= (((x*(tmp = -1730907131.6124666, tmp))%((((1481750041)|(x>>((((x>>>(tmp = 3128156522.5936565, tmp))/(tmp = -1277222645.9880452, tmp))^(tmp = -2327254789, tmp))+x)))>>>(-1161176960))>>>(tmp = 3135906272.5466847, tmp)))*(((((-2230902834.464362)^(1822893689.8183987))+(((tmp = 1597326356, tmp)/(x&((tmp = -3044163063.587389, tmp)>>(tmp = 2844997555, tmp))))%(x^x)))>>((x|x)/x))^(2634614167.2529745))));
+  assertEquals(0, x &= (3081901595));
+  assertEquals(0, x &= (-2453019214.8914948));
+  assertEquals(0, x &= x);
+  assertEquals(0, x >>>= (-596810618.3666217));
+  assertEquals(0, x >>= (((908276623)|x)/x));
+  assertEquals(0, x ^= x);
+  assertEquals(958890056, x |= (tmp = 958890056.474458, tmp));
+  assertEquals(1325436928, x <<= (tmp = -2474326583, tmp));
+  assertEquals(711588532333838300, x *= ((-148161646.68183947)<<(tmp = -1149179108.8049204, tmp)));
+  assertEquals(0, x ^= (((2862565506)%x)/(tmp = -2865813112, tmp)));
+  assertEquals(-2064806628, x += (((tmp = -2677361175.7317276, tmp)/((817159440)>>>(tmp = 1895467706, tmp)))^(x|(tmp = -2309094859, tmp))));
+  assertEquals(-69806982479424, x *= ((x&(tmp = 2857559765.1909904, tmp))&(-3166908966.754988)));
+  assertEquals(-430255744, x %= ((((((-2968574724.119535)<<x)<<((tmp = 1603913671, tmp)%((-1495838556.661653)^(tmp = 1778219751, tmp))))*(-400364265))<<((((1607866371.235576)-(1961740136))|(1259754297))&(tmp = -1018024797.1352971, tmp)))^x));
+  assertEquals(6.828637393208647e-7, x /= (x*(tmp = 1464421, tmp)));
+  assertEquals(0, x &= x);
+  assertEquals(-0, x *= (((tmp = -2510016276, tmp)-(2088209546))<<((tmp = -1609442851.3789036, tmp)+(tmp = 1919930212, tmp))));
+  assertEquals(-0, x %= (tmp = 1965117998, tmp));
+  assertEquals(-290294792.53186846, x += ((tmp = -2361555894.5318685, tmp)%(2071261102)));
+  assertEquals(-70873, x >>= (tmp = 2206814124, tmp));
+  assertEquals(-141746, x += x);
+  assertEquals(-141733.9831459089, x -= (((tmp = -806523527, tmp)>>>(tmp = 1897214891, tmp))/x));
+  assertEquals(-141733.9831459089, x %= ((tmp = 1996295696, tmp)<<(tmp = 3124244672, tmp)));
+  assertEquals(141733.9831459089, x /= (x>>(2688555704.561076)));
+  assertEquals(3196954517.3075542, x -= (tmp = -3196812783.3244085, tmp));
+  assertEquals(-19929155, x |= (((x|x)+x)^((tmp = 391754876, tmp)-(((((((tmp = -3051902902.5100636, tmp)*(x/(1546924993)))|(tmp = 1494375949, tmp))/((((-795378522)/(tmp = 509984856, tmp))>>>(tmp = -106173186, tmp))+x))|x)|(1916921307))>>>x))));
+  assertEquals(1279271449, x &= ((tmp = 1289446971, tmp)&(tmp = 1836102619, tmp)));
+  assertEquals(17876992, x <<= (-207633461));
+  assertEquals(0, x >>= (tmp = -903885218.9406946, tmp));
+  assertEquals(0, x >>>= x);
+  assertEquals(-2999, x -= (((754533336.2183633)%(tmp = 557970276.0537136, tmp))>>(tmp = -1171045520, tmp)));
+  assertEquals(-0.000003020470363504361, x /= (tmp = 992891715.2229724, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(0.45768595820301217, x %= ((tmp = 673779031, tmp)/(tmp = -1242414872.3263657, tmp)));
+  assertEquals(-980843052.1872087, x += (tmp = -980843052.6448946, tmp));
+  assertEquals(-Infinity, x /= ((((tmp = 317747175.8024508, tmp)&(x&(((tmp = 1632953053, tmp)>>x)/x)))%x)/(3145184986)));
+  assertEquals(0, x &= (x<<x));
+  assertEquals(0, x ^= (x-((2969023660.5619783)/x)));
+  assertEquals(0, x *= x);
+  assertEquals(NaN, x %= (x/(((x-x)/((tmp = -1622970458.3812745, tmp)-(1626134522)))&((((((tmp = 1384729039.4149384, tmp)^(x%(tmp = -2736365959, tmp)))+((-1465172172)%x))>>(tmp = -1839184810.2603343, tmp))^(((tmp = 1756918419, tmp)>>>(x+(x%(tmp = -2011122996.9794662, tmp))))<<(-3026600748.902623)))*((tmp = -2040286580, tmp)>>(-2899217430.655154))))));
+  assertEquals(0, x >>>= (tmp = 2100066003.3046467, tmp));
+  assertEquals(1362012169, x ^= (tmp = 1362012169, tmp));
+  assertEquals(1476312683, x |= ((457898409)>>>(-3079768830.723079)));
+  assertEquals(1441711, x >>>= (905040778.7770994));
+  assertEquals(2078530607521, x *= x);
+  assertEquals(-208193103, x |= ((tmp = -241750000, tmp)^x));
+  assertEquals(745036378, x ^= (((tmp = -1737151062.4726632, tmp)<<x)|(tmp = -1900321813, tmp)));
+  assertEquals(1744830464, x <<= x);
+  assertEquals(212992, x >>>= ((1210741037)-(x-(x>>>((x^(-1273817997.0036907))+((2401915056.5471)%(x<<(tmp = 1696738364.277438, tmp))))))));
+  assertEquals(0.0001604311565639742, x /= (1327622418));
+  assertEquals(0, x <<= (tmp = 166631979.34529006, tmp));
+  assertEquals(0, x *= ((((tmp = 657814984, tmp)/(((-831055031)>>>(1531978379.1768064))|((tmp = 2470027754.302619, tmp)^(-223467597))))/(tmp = 1678697269.468965, tmp))&(tmp = -1756260071.4360774, tmp)));
+  assertEquals(-2049375053, x ^= (tmp = -2049375053, tmp));
+  assertEquals(-1879109889, x |= (tmp = -1963586818.0436726, tmp));
+  assertEquals(718239919, x ^= (tmp = -1523550640.1925273, tmp));
+  assertEquals(-1361085185, x |= (-1939964707));
+  assertEquals(2, x >>>= (1864136030.7395325));
+  assertEquals(0.794648722849246, x %= ((-668830999)*(((-2227700170.7193384)%(x^(x>>>x)))/(tmp = 399149892, tmp))));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x *= x);
+  assertEquals(0, x &= ((tmp = -2389008496.5948563, tmp)|((((tmp = -2635919193.905919, tmp)*((-64464127)<<(2136112830.1317358)))>>((184057979)*(-1204959085.8362718)))>>>(-442946870.3341484))));
+  assertEquals(-243793920, x -= ((tmp = 3002998032, tmp)<<((537875759)<<x)));
+  assertEquals(0, x -= x);
+  assertEquals(0, x *= ((((66852616.82442963)/((((x^x)&(2975318321.223734))+(((tmp = -1388210811.1249495, tmp)^((((-680567297.7620237)%(x-(tmp = -672906716.4672911, tmp)))-x)*(tmp = -1452125821.0132627, tmp)))*(((2770387154.5427895)%x)%x)))-x))<<((-1481832432.924325)>>(tmp = 3109693867, tmp)))>>>(x/(((((((tmp = 928294418, tmp)^(((-1018314535)/(tmp = -3167523001, tmp))%((((((tmp = -1639338126, tmp)-(tmp = -2613558829, tmp))&x)/x)%(tmp = 513624872, tmp))/((-520660667)&x))))*(2620452414))^((tmp = 2337189239.5949326, tmp)*(3200887846.7954993)))>>>((tmp = 1173330667, tmp)^x))<<x)>>(((tmp = -2475534594.982338, tmp)*x)|x)))));
+  assertEquals(0, x /= (2520915286));
+  assertEquals(0, x &= x);
+  assertEquals(0, x >>= (-1908119327));
+  assertEquals(0, x >>>= (tmp = 549007635, tmp));
+  assertEquals(0, x >>= (-994747873.8117285));
+  assertEquals(0, x <<= ((((x>>>((-3084793026.846681)%((1107295502)&(tmp = -296613957.8133817, tmp))))&((19637717.166736007)/(x+x)))+x)/(-2479724242)));
+  assertEquals(-695401420, x += (-695401420));
+  assertEquals(-695401394, x += (x>>>(tmp = 2340097307.6556053, tmp)));
+  assertEquals(-555745552, x -= (x|(-483851950.68644)));
+  assertEquals(-17825792, x <<= x);
+  assertEquals(-17825792, x >>= x);
+  assertEquals(-17, x %= ((tmp = 1799361095, tmp)|((x>>(((-1201252592)<<((((543273288)+(-2859945716.606924))*x)<<((-3030193601)<<(3081129914.9217644))))|((1471431587.981769)>>(-246180750))))|(((tmp = -2689251055.1605787, tmp)>>x)&(((2131333169)^x)-((tmp = -951555489, tmp)/x))))));
+  assertEquals(-8912896, x <<= (1146444211));
+  assertEquals(2854567584, x += (tmp = 2863480480, tmp));
+  assertEquals(426232502.24151134, x %= (1214167540.8792443));
+  assertEquals(1806802048, x ^= (-2368317898));
+  assertEquals(432537600, x <<= (tmp = 2831272652.589364, tmp));
+  assertEquals(432537600, x %= (((1713810619.3880467)-x)&((-2853023009.553296)&(tmp = -3158798098.3355417, tmp))));
+  assertEquals(-509804066, x += (tmp = -942341666, tmp));
+  assertEquals(-509804066, x %= (-732349220));
+  assertEquals(259900185710132350, x *= x);
+  assertEquals(711598501.7021885, x %= ((tmp = 2020395586.2280731, tmp)-(tmp = 3031459563.1386633, tmp)));
+  assertEquals(711598503.0618857, x += ((tmp = 967558548.4141241, tmp)/x));
+  assertEquals(711598503, x &= x);
+  assertEquals(711598503, x ^= (((((1609355669.1963444)+((((tmp = -2660082403.258437, tmp)+(tmp = -235367868, tmp))&(x/x))*((-2595932186.69466)|((tmp = -3039202860, tmp)<<x))))>>>(-951354869))-((tmp = -691482949.6335375, tmp)/(tmp = -1735502400, tmp)))/(tmp = 798440377, tmp)));
+  assertEquals(558262613882868500, x *= (784519095.4299527));
+  assertEquals(558262611968479000, x -= ((((tmp = 1039039153.4026555, tmp)/(-3138845051.6240187))*(tmp = 633557994, tmp))&(1981507217)));
+  assertEquals(1170427648, x |= ((x>>((((-1086327124)%((tmp = -1818798806.368613, tmp)^(tmp = 2183576654.9959817, tmp)))>>x)&((((((tmp = 1315985464.0330539, tmp)&(2774283689.333836))%x)*((2722693772.8994813)&(tmp = -2720671984.945404, tmp)))^(tmp = -76808019, tmp))<<((tmp = 685037799.2336662, tmp)^((tmp = 1057250849, tmp)&(tmp = 1469205111.2989025, tmp))))))+(x*(((tmp = 448288818.47173154, tmp)-(-2527606231))-((8387088.402292728)>>x)))));
+  assertEquals(558, x >>>= (tmp = 2732701109, tmp));
+  assertEquals(558, x &= x);
+  assertEquals(-0.00015855057024653912, x /= ((x+(((tmp = -1963815633, tmp)-(x>>x))-((x|x)>>x)))/x));
+  assertEquals(1.3458861596445712e-13, x /= (-1178038492.4116466));
+  assertEquals(0, x <<= (-104550232));
+  assertEquals(0, x >>>= (x>>(tmp = -255275244.12613606, tmp)));
+  assertEquals(0, x >>= x);
+  assertEquals(375, x |= ((1576819294.6991196)>>>(-2570246122)));
+  assertEquals(96000, x <<= ((2252913843.0150948)>>>(-49239716)));
+  assertEquals(6144000, x <<= ((((tmp = -2478967279, tmp)&((x%((tmp = -1705332610.8018858, tmp)+(x+(tmp = 590766349, tmp))))<<(tmp = 1759375933, tmp)))+(-2024465658.849834))&(1564539207.3650014)));
+  assertEquals(-1149239296, x <<= (1862803657.7241006));
+  assertEquals(-9, x >>= (((tmp = 463306384.05696774, tmp)^x)|((x>>((((-2098070856.799663)<<((-2054870274.9012866)<<(((-2582579691)/(829257170.0266814))<<(((((tmp = -1753535573.7074275, tmp)<<((x>>(-197886116))%((2487188445)%(tmp = 2465391564.873364, tmp))))&(((tmp = -500069832, tmp)&(tmp = 3016637032, tmp))&((tmp = 2525942628, tmp)|((((-920996215)|x)^((((tmp = -687548533.419106, tmp)&(1423222636.058937))<<((tmp = -1096532228, tmp)>>((((tmp = -3124481449.2740726, tmp)^(tmp = 2724328271.808975, tmp))>>x)*x)))+(-1661789589.5808442)))+(((x*(tmp = -1224371664.9549093, tmp))^((tmp = 3202970043, tmp)^x))/(tmp = 131494054.58501709, tmp))))))|(((tmp = -1654136720, tmp)<<x)>>((1652979932.362416)-(tmp = -863732721, tmp))))^(-113307998)))))^(-90820449.91417909))*((tmp = 641519890, tmp)-((((x<<(tmp = 2349936514.071881, tmp))*(2324420443.587892))^x)%(x<<((tmp = -1838473742, tmp)/(((-3154172718.4274178)-x)+x)))))))|(x>>>((tmp = 2096024376.4308293, tmp)<<x)))));
+  assertEquals(81, x *= x);
+  assertEquals(81, x &= x);
+  assertEquals(81, x %= (tmp = 2223962994, tmp));
+  assertEquals(81, x ^= ((x/(((-1606183420.099584)|(-1242175583))&(((x|((tmp = 828718431.3311573, tmp)/(x>>x)))+(((-2207542725.4531174)^(x*x))*(tmp = 551575809.955105, tmp)))/x)))&((x>>x)&x)));
+  assertEquals(81, x %= (tmp = 279598358.6976975, tmp));
+  assertEquals(101.72338484518858, x -= (((tmp = 2452584495.44003, tmp)%((-1181192721)+(((x>>(((x&x)^x)+((x>>>((x+(-2472793823.57181))/(((2854104951)>>(-1208718359.6554642))>>>(1089411895.694705))))/(x|(-2821482890.1780205)))))^(-1786654551))/(-29404242.70557475))))/(((-4352531)<<((-1227287545)<<x))%(-2558589438))));
+  assertEquals(101.72338484518858, x %= (-943645643));
+  assertEquals(0, x -= x);
+  assertEquals(0, x >>>= (-2440404084));
+  assertEquals(0, x >>= (tmp = 1029680958.405923, tmp));
+  assertEquals(0, x >>>= (1213820208.7204895));
+  assertEquals(-0, x /= (tmp = -103093683, tmp));
+  assertEquals(0, x >>>= (-2098144813));
+  assertEquals(-0, x /= (((-3087283334)+(((tmp = -3129028112.6859293, tmp)%(tmp = 2413829931.1605015, tmp))-(2578195237.8071446)))|x));
+  assertEquals(-15, x |= ((((-178926550.92823577)>>>(-965071271))^((tmp = -484633724.7237625, tmp)-(tmp = 473098919.1486404, tmp)))>>((-2264998310.203265)%(tmp = -499034672, tmp))));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x >>= (((-3207915976.698118)<<(tmp = 2347058630, tmp))|(tmp = -2396250098.559627, tmp)));
+  assertEquals(NaN, x %= x);
+  assertEquals(NaN, x *= (621843222));
+  assertEquals(0, x >>= (((-2409032228.7238913)*x)-(tmp = -887793239, tmp)));
+  assertEquals(NaN, x /= x);
+  assertEquals(1193017666, x ^= (tmp = 1193017666, tmp));
+  assertEquals(3.5844761899682753, x /= (tmp = 332829011.206393, tmp));
+  assertEquals(-888572929, x |= (((tmp = 1032409228, tmp)+(tmp = -1920982163.7853453, tmp))+x));
+  assertEquals(-1817051951333455600, x *= (((-1506265102)^(tmp = -775881816, tmp))-(tmp = -32116372.59181881, tmp)));
+  assertEquals(-1638479616, x |= x);
+  assertEquals(-114489, x %= (((tmp = -247137297.37866855, tmp)>>>((((((-322805409)-x)^x)>>((((((((x>>>(tmp = -900610424.7148039, tmp))/(-1155208489.6240904))|((-2874045803)|(tmp = 3050499811, tmp)))+(x/((tmp = -613902712, tmp)^((-982142626.2892077)*((((tmp = -3201753245.6026397, tmp)|((1739238762.0423079)^x))/(243217629.47237313))^((tmp = -11944405.987132788, tmp)/(tmp = 2054031985.633406, tmp)))))))*(tmp = 2696108952.450961, tmp))*x)>>>(tmp = 3058430643.0660386, tmp))>>(x<<x)))>>(-984468302.7450335))%((tmp = 1302320585.246251, tmp)>>>x)))%(tmp = -2436842285.8208156, tmp)));
+  assertEquals(2047, x >>>= (2380161237));
+  assertEquals(0, x >>= x);
+  assertEquals(0, x &= (tmp = 980821012.975836, tmp));
+  assertEquals(-1090535537, x -= ((-3064511503.1214876)&((tmp = -2598316939.163751, tmp)<<((tmp = -969452391.8925576, tmp)*x))));
+  assertEquals(-2181071074, x += x);
+  assertEquals(1, x >>>= ((2902525386.449062)>>x));
+  assertEquals(1, x += (x&(tmp = -2643758684.6636515, tmp)));
+  assertEquals(1, x %= ((tmp = -2646526891.7004848, tmp)/x));
+  assertEquals(448735695.7888887, x -= (tmp = -448735694.7888887, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(1, x >>= ((-480385726)<<(2641021142)));
+  assertEquals(1, x %= (375099107.9200462));
+  assertEquals(1, x >>= (((x&((tmp = -2402469116.9903326, tmp)%(tmp = -2862459555.860298, tmp)))*(tmp = -2834162871.0586414, tmp))%(((x>>>(tmp = 721589907.5073895, tmp))*(x^x))%(((tmp = 2844611489.231776, tmp)^((983556913)&(906035409.6693488)))^(x>>>(1239322375))))));
+  assertEquals(268435456, x <<= (tmp = 178807644.80966163, tmp));
+  assertEquals(44, x %= ((tmp = 2527026779.081539, tmp)>>>(2736129559)));
+  assertEquals(88, x += x);
+  assertEquals(0, x >>>= x);
+  assertEquals(0, x -= x);
+  assertEquals(-1523121602, x |= (2771845694));
+  assertEquals(-2, x >>= x);
+  assertEquals(-4, x += x);
+  assertEquals(-256, x <<= (((2522793132.8616533)>>(tmp = 77232772.94058788, tmp))+(3118669244.49152)));
+  assertEquals(4294967040, x >>>= x);
+  assertEquals(-256, x &= x);
+  assertEquals(1278370155.835435, x -= (-1278370411.835435));
+  assertEquals(-3.488228054921667, x /= (tmp = -366481243.6881058, tmp));
+  assertEquals(1.162742684973889, x /= ((x|(((((2404819175.562809)*(tmp = -2524589506, tmp))&(tmp = -675727145, tmp))>>>(x*x))&((-413250006)<<(tmp = 2408322715, tmp))))|((2940367603)>>>x)));
+  assertEquals(0, x >>>= ((2513665793)-(tmp = 1249857454.3367786, tmp)));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x ^= x);
+  assertEquals(1989998348.6336238, x -= (-1989998348.6336238));
+  assertEquals(903237918.986834, x %= (1086760429.6467898));
+  assertEquals(-4.4185765232981975, x /= (-204418304));
+  assertEquals(1471621914, x ^= (tmp = -1471621914.1771696, tmp));
+  assertEquals(1471621914, x |= ((((((x<<(tmp = -2676407394.536844, tmp))%(((343324258)+(x/(x>>(((-221193011)>>>x)|x))))>>(((-2737713893)^((tmp = -49214797.00735545, tmp)+((-2818106123.172874)/(tmp = -2361786565.3028684, tmp))))<<(1859353297.6355076))))*(tmp = -751970685, tmp))|((tmp = 2502717391.425871, tmp)/(tmp = -2647169430, tmp)))*((tmp = -1647567294, tmp)&(((tmp = 1819557651, tmp)/x)>>((((-3073469753)/x)-(((tmp = -1973810496.6407511, tmp)&((x-(x+(tmp = -2986851659, tmp)))>>>(tmp = -2226975699, tmp)))|(418770782.142766)))<<x))))*(((((tmp = 125466732, tmp)/((((1453655756.398259)|(((874792086.7064595)-(194880772.91499102))>>>x))%(x<<(tmp = -1445557137, tmp)))<<x))>>>(tmp = -1953751906, tmp))/((tmp = -2140573172.2979035, tmp)*((-108581964)^x)))|(-481484013.0393069))));
+  assertEquals(1454179065, x += ((tmp = 947147038.2829313, tmp)|(tmp = -154822975.3629098, tmp)));
+  assertEquals(1, x /= x);
+  assertEquals(1, x %= ((((((tmp = -2262250297.991866, tmp)-(tmp = 481953960, tmp))/(1629215187.6020458))|(2515244216))>>>((tmp = -3040594752.2184515, tmp)-(tmp = -1116041279, tmp)))^(((-182133502)-(1065160192.6609197))+(((((-1850040207)^(tmp = -1570328610, tmp))^(tmp = 20542725.09256518, tmp))*x)|(2386866629)))));
+  assertEquals(1, x &= (2889186303));
+  assertEquals(0, x >>= (((-1323093107.050538)>>(x%x))-(((((((-1736522840)+(tmp = -2623890690.8318863, tmp))*(959395040.5565329))*(233734920))<<((x+(x%((tmp = -2370717284.4370327, tmp)%(tmp = 2109311949, tmp))))-(tmp = -1005532894, tmp)))|(861703605))>>>((2399820772)/x))));
+  assertEquals(0, x >>= x);
+  assertEquals(57233408, x |= ((tmp = 2655923764.4179816, tmp)*(-1353634624.3025436)));
+  assertEquals(997939728, x |= (980552208.9005274));
+  assertEquals(1859642592476610800, x *= (1863481872));
+  assertEquals(-977190656, x <<= x);
+  assertEquals(4.378357529141239e+26, x *= ((((x/(((tmp = 2429520991, tmp)/(x/(tmp = 784592802, tmp)))-(tmp = -2704781982, tmp)))*(tmp = -2161015768.2322354, tmp))&((((-3164868762)>>(tmp = 2390893153.32907, tmp))^x)>>(-2422626718.322538)))*(tmp = 278291869, tmp)));
+  assertEquals(4.378357529141239e+26, x -= (1710777896.992369));
+  assertEquals(0, x &= (((((tmp = -2532956158.400033, tmp)|((2195255831.279001)|(1051047432)))|(-1628591858))|(tmp = -2042607521.947963, tmp))>>((-1471225208)/(((-133621318)>>(1980416325.7358408))*((1741069593.1036062)-(x|(2133911581.991011)))))));
+  assertEquals(-0, x /= (-656083507));
+  assertEquals(NaN, x += ((tmp = -1071410982.2789869, tmp)%x));
+  assertEquals(NaN, x *= (tmp = -1513535145.3146675, tmp));
+  assertEquals(0, x >>= ((2831245247.5267224)>>(x<<((x+(((3068824580.7922907)|(1708295544.275714))*((tmp = -1662930228.1170444, tmp)-(((tmp = 1979994889, tmp)<<(tmp = -1826911988, tmp))&((x/(x<<(1909384611.043981)))+(1958052414.7139997))))))<<(tmp = 2481909816.56558, tmp)))));
+  assertEquals(0, x *= (((tmp = -2979739958.1614842, tmp)&x)+x));
+  assertEquals(-0, x *= ((-332769864.50313234)^x));
+  assertEquals(0, x >>= ((((689018886.1436445)+(tmp = -2819546038.620694, tmp))|(((tmp = -1459669934.9066005, tmp)|x)/x))<<(((tmp = 2640360389, tmp)/((x%((-1947492547.9056122)%((1487212416.2083092)-(-1751984129))))^x))%(tmp = 2666842881, tmp))));
+  assertEquals(-1801321460, x |= (tmp = 2493645836, tmp));
+  assertEquals(-1801321460, x %= (2400405136));
+  assertEquals(-2905399858195810300, x *= (tmp = 1612926911, tmp));
+  assertEquals(-2905399858195810300, x -= (x>>(tmp = 1603910263.9593458, tmp)));
+  assertEquals(-238798848, x &= ((tmp = -2638646212.767516, tmp)/(((tmp = 1755616291.436998, tmp)>>>(tmp = 1083349775, tmp))-(x%(((tmp = 1728859105.53634, tmp)^(1931522619.0403612))/(tmp = 712460587.0025489, tmp))))));
+  assertEquals(-2363873607.2302856, x += (-2125074759.230286));
+  assertEquals(1712665, x &= (((117229515)>>>(((1707090894.1915488)>>>((-1696008695)>>(((-1045367326.7522249)<<(tmp = -209334716, tmp))-x)))|(-1707909786.080653)))%(1260761349.172689)));
+  assertEquals(1073741824, x <<= (tmp = -289437762.34742975, tmp));
+  assertEquals(1073741824, x &= (tmp = 2079141140, tmp));
+  assertEquals(0, x <<= ((x^(-3139646716.1615124))-(((-362323071.74237394)|(tmp = 2989896849, tmp))*(tmp = -218217991, tmp))));
+  assertEquals(0, x &= (tmp = -1476835288.425903, tmp));
+  assertEquals(0, x >>>= (tmp = 61945262.70868635, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(-2735263498.7189775, x -= (2735263498.7189775));
+  assertEquals(-1182289920, x <<= (x+x));
+  assertEquals(-1182289580, x ^= ((2858446263.2258)>>>(2387398039.6273785)));
+  assertEquals(696693056, x &= ((2178665823)*(-51848583)));
+  assertEquals(1652555776, x <<= (((tmp = 2943916975, tmp)-((-1544273901)>>(-1671503106.2896929)))|x));
+  assertEquals(6455296, x >>>= (tmp = 1492638248.675439, tmp));
+  assertEquals(2097152, x &= (((x|x)*(2873891571.7000637))^((2165264807)+(tmp = 451721563, tmp))));
+  assertEquals(2097152, x %= (tmp = 1089484582.1455994, tmp));
+  assertEquals(2097152, x <<= x);
+  assertEquals(2097152, x &= ((tmp = 119096343.4032247, tmp)^((-1947874541)*x)));
+  assertEquals(0, x &= (tmp = 2363070677, tmp));
+  assertEquals(0, x &= ((tmp = -1897325383, tmp)>>>((2368480527)>>>((tmp = 1837528979, tmp)*(-1838904077)))));
+  assertEquals(-1898659416, x ^= (-1898659416.1125412));
+  assertEquals(-725506048, x <<= x);
+  assertEquals(1392943104, x <<= (295287938.9104482));
+  assertEquals(-63620329, x ^= ((tmp = -3175925826.5573816, tmp)-(tmp = 2474613927, tmp)));
+  assertEquals(-1135111726, x -= ((tmp = -1133259081, tmp)^(((tmp = -742228219, tmp)>>((-7801909.587711811)%((tmp = -642758873, tmp)+(tmp = 2893927824.6036444, tmp))))^((tmp = -2145465178.9142997, tmp)+x))));
+  assertEquals(0, x ^= x);
+  assertEquals(660714589, x |= (660714589));
+  assertEquals(660714676, x ^= ((-376720042.8047826)>>>(2196220344)));
+  assertEquals(660714676, x |= ((((((((x<<(-1140465568))-(tmp = -1648489774.1573918, tmp))%(((tmp = -2955505390.573639, tmp)*x)<<((((tmp = -1769375963, tmp)*(tmp = -440619797, tmp))&((tmp = 1904284066, tmp)%(-2420852665.0629807)))+(-324601009.2063596))))>>(tmp = 2317210783.9757776, tmp))^((tmp = 750057067.4541628, tmp)^(tmp = -1391814244.7286487, tmp)))>>((344544658.6054913)%((tmp = -1508630423.218488, tmp)&(tmp = 1918909238.2974637, tmp))))>>((-647746783.685822)&(tmp = 2444858958.3595476, tmp)))&x));
+  assertEquals(-962337195, x ^= (tmp = -507358495.30825853, tmp));
+  assertEquals(-182008925.58535767, x %= (tmp = -195082067.35366058, tmp));
+  assertEquals(502070, x >>>= (tmp = 1459732237.1447744, tmp));
+  assertEquals(-2391009930.7235765, x -= (tmp = 2391512000.7235765, tmp));
+  assertEquals(1568669696, x <<= x);
+  assertEquals(0, x <<= (tmp = -571056688.2717848, tmp));
+  assertEquals(1770376226, x ^= (tmp = 1770376226.0584736, tmp));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x &= ((((x<<x)>>>x)|x)|(((tmp = -2141573723, tmp)^x)|(64299956))));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x &= x);
+  assertEquals(0, x <<= (1106060336.7362857));
+  assertEquals(-0, x /= (x|(tmp = 2760823963, tmp)));
+  assertEquals(0, x <<= ((-2436225757)|(-1800598694.4062433)));
+  assertEquals(0, x >>>= ((-728332508.9870625)<<x));
+  assertEquals(-173377680, x ^= ((tmp = -173377680, tmp)%(tmp = -2843994892, tmp)));
+  assertEquals(-173377680, x |= ((((-819217898)&(tmp = -1321650255, tmp))&(x+((x^x)<<((1700753064)>>((((((-1038799327)>>((782275464)^x))-(tmp = -2113814317.8539028, tmp))>>(2143804838))&x)-((2970418921)/(-3073015285.6587048)))))))&((-1759593079.4077306)%((1699128805)-((tmp = -467193967, tmp)&(((2225788267.3466334)*(((2687946762.5504274)+x)>>>x))<<(-1853556066.880512)))))));
+  assertEquals(-0.5520657226957338, x /= ((tmp = -755493878, tmp)&(tmp = 918108389, tmp)));
+  assertEquals(0.30477656217556287, x *= x);
+  assertEquals(0, x &= ((tmp = -2746007517, tmp)<<(2749629340)));
+  assertEquals(0, x ^= ((x%(tmp = 1683077876, tmp))%(-162706778)));
+  assertEquals(0, x *= (tmp = 10203423, tmp));
+  assertEquals(119043212.1461842, x += (tmp = 119043212.1461842, tmp));
+  assertEquals(587202560, x <<= (tmp = 658697910.7051642, tmp));
+  assertEquals(-138689730, x |= (x-(tmp = 1296317634.5661907, tmp)));
+  assertEquals(-138663011, x -= ((-1751010109.5506423)>>(152829872)));
+  assertEquals(-138663011, x %= (-1266200468));
+  assertEquals(-138663011, x &= (x|((tmp = -571277275.622529, tmp)<<x)));
+  assertEquals(-138663011, x >>= ((971259905.1265712)*(tmp = 2203764981, tmp)));
+  assertEquals(-138663011, x %= (-904715829));
+  assertEquals(-138663011, x |= ((tmp = -2823047885.283391, tmp)>>>(((tmp = 533217000, tmp)|(650754598.7836078))|(-1475565890))));
+  assertEquals(-1610612736, x <<= x);
+  assertEquals(-1610612736, x &= x);
+  assertEquals(163840, x >>>= (-188885010));
+  assertEquals(-1224224814, x |= (tmp = 3070742482, tmp));
+  assertEquals(1498726395213334500, x *= x);
+  assertEquals(1723591210, x |= ((tmp = 615164458, tmp)|x));
+  assertEquals(1721910480, x ^= (x>>>x));
+  assertEquals(4505284605.764313, x -= (tmp = -2783374125.7643127, tmp));
+  assertEquals(-9504912393868483000, x *= (((tmp = 2896651872, tmp)<<(-2896385692.9017262))&(((((tmp = -2081179810.20238, tmp)|(tmp = -2484863999, tmp))>>((tmp = 1560885110.2665749, tmp)/(((tmp = 934324123.4289343, tmp)<<((tmp = -1591614157.0496385, tmp)+x))/(((x%(((tmp = 1672629986.8055913, tmp)%x)>>(tmp = 2116315086.2559657, tmp)))/(((-2687682697.5806303)>>x)/(-2034391222.5029132)))%(x-((((((tmp = 2598594967, tmp)/(((((((2950032233)%x)/x)^(tmp = -2126753451.3732262, tmp))<<(tmp = -3019113473, tmp))+(tmp = -2021220129.2320697, tmp))%((((-587645875.4666483)>>(((((x+x)+x)&(tmp = 533801785, tmp))|x)-((tmp = -2224808495.678903, tmp)/(1501942300))))>>>(-2558947646))>>((2798508249.020792)>>>x))))>>>((1060584557)/((((((((x&x)|(1426725365))>>>(tmp = 1500508838, tmp))>>(-1328705938))*((tmp = -2288009425.598777, tmp)>>>(((2586897285.9759064)%((-1605651559.2122297)>>>(tmp = 1936736684.4887302, tmp)))+((tmp = 2316261040, tmp)^(570340750.353874)))))&(x^((tmp = -2266524143, tmp)-(tmp = 2358520476, tmp))))+(tmp = 1449254900.9222453, tmp))%((-100598196)%((tmp = -2985318242.153491, tmp)>>((620722274.4565848)>>(871118975)))))))<<x)*(tmp = -1287065606.4143271, tmp))>>>(1038059916.2438471)))))))+((x/(-276990308.1264961))&(tmp = 2471016351.2195315, tmp)))|(((((tmp = -1288792769.3210807, tmp)+((tmp = -641817194, tmp)*(x<<(((-1933817364)>>(((tmp = 2084673536, tmp)|x)&x))&(tmp = -2752464480, tmp)))))%((796026752)*x))+(((tmp = -3083359669, tmp)|x)-((715303522)|(tmp = 181297266, tmp))))*(-1691520182.3207517)))));
+  assertEquals(0, x <<= (-2322389800));
+  assertEquals(0, x *= (tmp = 3188682235, tmp));
+  assertEquals(0, x |= (x>>>((tmp = -2729325231.8288336, tmp)^((-393497076.96012783)*(x/(tmp = -2198942459.9466457, tmp))))));
+  assertEquals(0, x ^= x);
+  assertEquals(0, x %= (2835024997.4447937));
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>= (tmp = 1109824126, tmp));
+  assertEquals(0, x <<= (3013043386));
+  assertEquals(206825782.74659085, x -= (-206825782.74659085));
+  assertEquals(-645346761227699500, x *= (-3120243292));
+  assertEquals(6825462, x >>= ((tmp = 1457908135, tmp)<<x));
+  assertEquals(-612366097.9189918, x -= (619191559.9189918));
+  assertEquals(-612306090.9189918, x -= ((2328676543.893506)>>x));
+  assertEquals(0, x ^= (x>>(((x>>>(1856200611.2269292))&(tmp = 2003217473, tmp))%((((((-107135673)+(((3062079356.170611)<<(tmp = -676928983, tmp))>>((tmp = -1487074941.2638814, tmp)|((-1601614031)/(1317006144.5025365)))))+x)*(((1163301641)>>>(448796567))/((x%((tmp = 72293197.34410787, tmp)+(-2304112723)))/((455610361)%(-2799431520)))))>>>(-217305041.09432888))<<(x-(tmp = -2168353649, tmp))))));
+  assertEquals(0, x >>= x);
+  assertEquals(-Infinity, x -= (((-1651597599.8950624)+(1780404320))/x));
+  assertEquals(0, x <<= (tmp = 2246420272.4321294, tmp));
+  assertEquals(0, x *= ((2793605382)-(tmp = -272299011, tmp)));
+  assertEquals(0, x *= x);
+  assertEquals(0, x <<= x);
+  assertEquals(0, x >>= (tmp = 2556413090, tmp));
+  assertEquals(0, x >>= ((tmp = -1784710085, tmp)%x));
+  assertEquals(0, x %= (tmp = -1929880813, tmp));
+  assertEquals(0, x *= (2586983368));
+  assertEquals(0, x &= x);
+  assertEquals(0, x <<= (-2144588807));
+  assertEquals(0, x ^= ((x<<(((((((-596537598)+((x-(((((((tmp = -3179604796, tmp)/((tmp = 1156725365.3543215, tmp)>>>(tmp = -2762144319, tmp)))%(x<<x))&((tmp = 1750241928.1271567, tmp)&(x/((tmp = 1781306819, tmp)|x))))+((((2893068644)/((tmp = -576164593.9720252, tmp)<<((2724671.48995471)&(tmp = -573132475, tmp))))%(tmp = -1355625108, tmp))&(tmp = -302869512.5880568, tmp)))+x)<<x))>>((tmp = -2569172808, tmp)/x)))^x)-(tmp = -1174006275.2213159, tmp))&x)&(((((((-2303274799)>>(tmp = -814839320, tmp))/(tmp = 183887306.09810615, tmp))>>(((tmp = 1054106394.3704875, tmp)|x)>>>x))-(x-(tmp = 1313696830, tmp)))-((tmp = 2373274399.0742035, tmp)|((((tmp = -3163779539.4902935, tmp)*(tmp = -3056125181.726942, tmp))&(((x^(x^(x/((tmp = -576441696.6015451, tmp)<<(tmp = -26223719.920306206, tmp)))))>>(tmp = -2332835940, tmp))|((-146303509.41093707)&(tmp = -2676964025, tmp))))/((((x*(tmp = 1059918020, tmp))|((((2341797349)|(tmp = -744763805.1381104, tmp))<<x)+((2991320875.552578)^(2920702604.701831))))^(-1721756138))^(((tmp = -2794367554, tmp)>>((-2671235923.2097874)<<(x&((((tmp = -621472314.0859051, tmp)-(((x*x)+x)>>>((tmp = 1834038956, tmp)+x)))*x)^(tmp = -2090567586.321468, tmp)))))<<(321395210))))))>>>(tmp = -1207661719, tmp)))+(-2877264053.3805156)))/(x%(tmp = -2226991657.709366, tmp))));
+  assertEquals(0, x *= (tmp = 986904991.061398, tmp));
+  assertEquals(0, x -= (x%(650819306.6671969)));
+  assertEquals(0, x >>>= (905893666.2871252));
+  assertEquals(0, x += (((tmp = 2501942710.4804144, tmp)&x)/((tmp = -851080399.1751502, tmp)-(-1168623992))));
+  assertEquals(-0, x *= (tmp = -2014577821.4554045, tmp));
+  assertEquals(0, x &= (tmp = 1995246018, tmp));
+  assertEquals(0, x %= (1724355237.7031958));
+  assertEquals(-954696411, x += (((-2825222201)+(((1662353496.1795506)>>>(x-x))|(tmp = 225015046, tmp)))^(x&x)));
+  assertEquals(-2158427339993389800, x *= (2260852052.1539803));
+  assertEquals(19559, x >>>= (-862409169.4978967));
+  assertEquals(-0.000012241163878671237, x /= (x^(tmp = 2697144215.160239, tmp)));
+  assertEquals(0, x -= x);
+  assertEquals(1448177644, x |= (tmp = 1448177644.624848, tmp));
+  assertEquals(1448177644, x %= (((-1497553637.4976408)+(402228446))<<x));
+  assertEquals(2304640553, x -= (-856462909));
+  assertEquals(152436736, x &= ((766686903)*(((tmp = 660964683.1744609, tmp)|((((tmp = 297369746, tmp)-(x+((tmp = -2677127146, tmp)/x)))>>(((((((x%(x<<x))-(((((529254728)|((x|(-1407086127.6088922))&(tmp = -1968465008.5000398, tmp)))/(x%x))&((((-2761805265.92574)-x)*(x^(tmp = 110730179, tmp)))%((177220657.06030762)*(((2532585190.671373)/x)+(-1465143151)))))<<((tmp = -3008848338, tmp)<<(-2475597073))))|((-192996756.38619018)|((((1445996780)|(x>>>((((tmp = -2482370545.791443, tmp)*(tmp = -270543594, tmp))^x)*((1346780586)/(tmp = -625613363.885356, tmp)))))-(x<<(x/(-562307527))))&(-125701272))))*((x&x)%(tmp = 752963070, tmp)))>>>(tmp = 17419750.79086232, tmp))*x)^(x^((-157821212.04674292)-(tmp = 503849221.598824, tmp)))))-(tmp = 1479418449, tmp)))>>>((((((-78138548.2193842)<<(((2319032860.806689)-(tmp = -1564963892.5137577, tmp))>>>(-73673322.28957987)))<<((1797573493.3467085)*x))>>(tmp = 759994997, tmp))>>>(-1066441220))&(((((((tmp = 1972048857, tmp)*(((x&((-1347017320.0747669)>>>x))*(-2332716925.705054))%(-376976019.24362826)))>>>((tmp = -466479974, tmp)+x))&(-2282789473.3675604))|(((((((((269205423.7510414)-(tmp = 21919626.105656862, tmp))*((x-(tmp = -378670528, tmp))>>(tmp = -1045706598, tmp)))>>(tmp = -3062647341.234485, tmp))>>>x)|(tmp = -285399599.9386575, tmp))%(tmp = 2731214562, tmp))|((((tmp = 837093165.3438574, tmp)|(tmp = -2956931321, tmp))+((1871874558.3292787)<<((x|((tmp = -3169147427, tmp)%(((x^x)%(1479885041))%((1769991217)%(tmp = -1899472458, tmp)))))*(tmp = -837098563.71806, tmp))))>>(tmp = -1866722748, tmp)))-(2037734340.8345597)))>>((tmp = -1262019180.5332131, tmp)+(x*(1274173993.9800131))))*(tmp = 2336989321.855402, tmp))))));
+  assertEquals(4, x >>= (tmp = -2577728327, tmp));
+  assertEquals(16, x *= (x<<((2622323372.580596)*(tmp = -1947643367, tmp))));
+  assertEquals(33554432, x <<= (tmp = -2938370507, tmp));
+  assertEquals(-2399497018.987414, x -= (tmp = 2433051450.987414, tmp));
+  assertEquals(1, x /= x);
+  assertEquals(2, x <<= x);
+  assertEquals(0, x >>= (x&x));
+  assertEquals(0, x <<= x);
+}
+f();
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
index a8a3213..ee6083a 100644
--- a/test/mjsunit/object-define-property.js
+++ b/test/mjsunit/object-define-property.js
@@ -30,28 +30,34 @@
 // Flags: --allow-natives-syntax
 
 // Check that an exception is thrown when null is passed as object.
+var exception = false;
 try {
   Object.defineProperty(null, null, null);
-  assertTrue(false);
 } catch (e) {
+  exception = true;
   assertTrue(/called on non-object/.test(e));
 }
+assertTrue(exception);
 
 // Check that an exception is thrown when undefined is passed as object.
+exception = false;
 try {
   Object.defineProperty(undefined, undefined, undefined);
-  assertTrue(false);
 } catch (e) {
+  exception = true;
   assertTrue(/called on non-object/.test(e));
 }
+assertTrue(exception);
 
 // Check that an exception is thrown when non-object is passed as object.
+exception = false;
 try {
   Object.defineProperty(0, "foo", undefined);
-  assertTrue(false);
 } catch (e) {
+  exception = true;
   assertTrue(/called on non-object/.test(e));
 }
+assertTrue(exception);
 
 // Object.
 var obj1 = {};
@@ -695,12 +701,14 @@
 // Make sure we can redefine with -0.
 Object.defineProperty(obj5, 'minuszero', descMinusZero);
 
+exception = false;
 try {
   Object.defineProperty(obj5, 'minuszero', descPlusZero);
-  assertUnreachable();
 } catch (e) {
+  exception = true;
   assertTrue(/Cannot redefine property/.test(e));
 }
+assertTrue(exception);
 
 
 Object.defineProperty(obj5, 'pluszero', descPlusZero);
@@ -708,12 +716,14 @@
 // Make sure we can redefine with +0.
 Object.defineProperty(obj5, 'pluszero', descPlusZero);
 
+exception = false;
 try {
   Object.defineProperty(obj5, 'pluszero', descMinusZero);
-  assertUnreachable();
 } catch (e) {
+  exception = true;
   assertTrue(/Cannot redefine property/.test(e));
 }
+assertTrue(exception);
 
 
 var obj6 = {};
@@ -761,13 +771,15 @@
 
 // Ensure that we can't change the descriptor of a
 // non configurable property.
+exception = false;
 try {
   var descAccessor = { get: function() { return 0; } };
   Object.defineProperty(obj6, '2', descAccessor);
-  assertUnreachable();
 } catch (e) {
+  exception = true;
   assertTrue(/Cannot redefine property/.test(e));
 }
+assertTrue(exception);
 
 Object.defineProperty(obj6, '2', descElementNonWritable);
 desc = Object.getOwnPropertyDescriptor(obj6, '2');
@@ -858,13 +870,15 @@
 
 // Ensure that we can't change the descriptor of a
 // non configurable property.
+exception = false;
 try {
   var descAccessor = { get: function() { return 0; } };
   Object.defineProperty(arr, '2', descAccessor);
-  assertUnreachable();
 } catch (e) {
+  exception = true;
   assertTrue(/Cannot redefine property/.test(e));
 }
+assertTrue(exception);
 
 Object.defineProperty(arr, '2', descElementNonWritable);
 desc = Object.getOwnPropertyDescriptor(arr, '2');
@@ -1031,3 +1045,12 @@
 testDefineProperty(o, 'p',
   { enumerable : false, configurable : false },
   { get: undefined, set: setter1, enumerable : false, configurable : false });
+
+
+// Regression test: Ensure that growing dictionaries are not ignored.
+o = {};
+for (var i = 0; i < 1000; i++) {
+  // Non-enumerable property forces dictionary mode.
+  Object.defineProperty(o, i, {value: i, enumerable: false});
+}
+assertEquals(999, o[999]);
\ No newline at end of file
diff --git a/test/mjsunit/object-freeze.js b/test/mjsunit/object-freeze.js
index 3eefffd..c3a9278 100644
--- a/test/mjsunit/object-freeze.js
+++ b/test/mjsunit/object-freeze.js
@@ -32,21 +32,25 @@
 // Test that we throw an error if an object is not passed as argument.
 var non_objects = new Array(undefined, null, 1, -1, 0, 42.43);
 for (var key in non_objects) {
+  var exception = false;
   try {
     Object.freeze(non_objects[key]);
-    assertUnreachable();
   } catch(e) {
+    exception = true;
     assertTrue(/Object.freeze called on non-object/.test(e));
   }
+  assertTrue(exception);
 }
 
 for (var key in non_objects) {
+  exception = false;
   try {
     Object.isFrozen(non_objects[key]);
-    assertUnreachable();
   } catch(e) {
+    exception = true;
     assertTrue(/Object.isFrozen called on non-object/.test(e));
   }
+  assertTrue(exception);
 }
 
 // Test normal data properties.
diff --git a/test/mjsunit/object-literal.js b/test/mjsunit/object-literal.js
index 397d670..3d0b33b 100644
--- a/test/mjsunit/object-literal.js
+++ b/test/mjsunit/object-literal.js
@@ -105,7 +105,7 @@
 assertFalse(a.a.c === b.a.c);
 
 
-// Test keywords valid as property names in initializers and dot-access.
+// Test keywords are valid as property names in initializers and dot-access.
 var keywords = [
   "break",
   "case",
@@ -124,7 +124,6 @@
   "if",
   "in",
   "instanceof",
-  "native",
   "new",
   "null",
   "return",
@@ -137,15 +136,18 @@
   "var",
   "void",
   "while",
-  "with",
+  "with"
 ];
 
 function testKeywordProperty(keyword) {
+  var exception = false;
   try {
     // Sanity check that what we get is a keyword.
     eval("var " + keyword + " = 42;");
-    assertUnreachable("Not a keyword: " + keyword);
-  } catch (e) { }
+  } catch (e) {
+    exception = true;
+  }
+  assertTrue(exception);
 
   // Simple property, read and write.
   var x = eval("({" + keyword + ": 42})");
@@ -187,4 +189,4 @@
 
 for (var i = 0; i < keywords.length; i++) {
   testKeywordProperty(keywords[i]);
-}
\ No newline at end of file
+}
diff --git a/test/mjsunit/object-seal.js b/test/mjsunit/object-seal.js
index fb9bb92..f21baed 100644
--- a/test/mjsunit/object-seal.js
+++ b/test/mjsunit/object-seal.js
@@ -32,21 +32,25 @@
 // Test that we throw an error if an object is not passed as argument.
 var non_objects = new Array(undefined, null, 1, -1, 0, 42.43);
 for (var key in non_objects) {
+  var exception = false;
   try {
     Object.seal(non_objects[key]);
-    assertUnreachable();
   } catch(e) {
+    exception = true;
     assertTrue(/Object.seal called on non-object/.test(e));
   }
+  assertTrue(exception);
 }
 
 for (var key in non_objects) {
+  exception = false;
   try {
     Object.isSealed(non_objects[key]);
-    assertUnreachable();
   } catch(e) {
+    exception = true;
     assertTrue(/Object.isSealed called on non-object/.test(e));
   }
+  assertTrue(exception);
 }
 
 // Test normal data properties.
diff --git a/test/mjsunit/polymorph-arrays.js b/test/mjsunit/polymorph-arrays.js
new file mode 100644
index 0000000..ff0c433
--- /dev/null
+++ b/test/mjsunit/polymorph-arrays.js
@@ -0,0 +1,177 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+function init_array(a) {
+  for (var i = 0; i < 10; ++i ){
+    a[i] = i;
+  }
+}
+
+function init_sparse_array(a) {
+  for (var i = 0; i < 10; ++i ){
+    a[i] = i;
+  }
+  a[5000000] = 256;
+  assertTrue(%HasDictionaryElements(a));
+}
+
+function testPolymorphicLoads() {
+  function make_polymorphic_load_function() {
+    function load(a, i) {
+      return a[i];
+    }
+
+    var object_array = new Object;
+    var sparse_object_array = new Object;
+    var js_array = new Array(10);
+    var sparse_js_array = new Array(5000001);
+
+    init_array(object_array);
+    init_array(js_array);
+    init_sparse_array(sparse_object_array);
+    init_sparse_array(sparse_js_array);
+
+    assertEquals(1, load(object_array, 1));
+    assertEquals(1, load(js_array, 1));
+    assertEquals(1, load(sparse_object_array, 1));
+    assertEquals(1, load(sparse_js_array, 1));
+
+    return load;
+  }
+
+  var object_array = new Object;
+  var sparse_object_array = new Object;
+  var js_array = new Array(10);
+  var sparse_js_array = new Array(5000001);
+
+  init_array(object_array);
+  init_array(js_array);
+  init_sparse_array(sparse_object_array);
+  init_sparse_array(sparse_js_array);
+
+  load = make_polymorphic_load_function();
+  assertEquals(undefined, load(js_array, new Object()));
+  load = make_polymorphic_load_function();
+  assertEquals(undefined, load(object_array, new Object()));
+  load = make_polymorphic_load_function();
+  assertEquals(undefined, load(sparse_js_array, new Object()));
+  load = make_polymorphic_load_function();
+  assertEquals(undefined, load(sparse_object_array, new Object()));
+
+  // Try with crankshaft.
+  load = make_polymorphic_load_function();
+  %OptimizeFunctionOnNextCall(load);
+  assertEquals(1, load(object_array, 1));
+  assertEquals(1, load(js_array, 1));
+  assertEquals(1, load(sparse_object_array, 1));
+  assertEquals(1, load(sparse_js_array, 1));
+
+  load = make_polymorphic_load_function();
+  %OptimizeFunctionOnNextCall(load);
+  assertEquals(undefined, load(js_array, new Object()));
+  load = make_polymorphic_load_function();
+  %OptimizeFunctionOnNextCall(load);
+  assertEquals(undefined, load(object_array, new Object()));
+  load = make_polymorphic_load_function();
+  %OptimizeFunctionOnNextCall(load);
+  assertEquals(undefined, load(sparse_js_array, new Object()));
+  load = make_polymorphic_load_function();
+  %OptimizeFunctionOnNextCall(load);
+  assertEquals(undefined, load(sparse_object_array, new Object()));
+}
+
+function testPolymorphicStores() {
+  function make_polymorphic_store_function() {
+    function store(a, i, val) {
+      a[i] = val;
+    }
+
+    var object_array = new Object;
+    var sparse_object_array = new Object;
+    var js_array = new Array(10);
+    var sparse_js_array = new Array(5000001);
+
+    init_array(object_array);
+    init_array(js_array);
+    init_sparse_array(sparse_object_array);
+    init_sparse_array(sparse_js_array);
+
+    store(object_array, 1, 256);
+    store(js_array, 1, 256);
+    store(sparse_object_array, 1, 256);
+    store(sparse_js_array, 1, 256);
+
+    return store;
+  }
+
+  var object_array = new Object;
+  var sparse_object_array = new Object;
+  var js_array = new Array(10);
+  var sparse_js_array = new Array(5000001);
+
+  init_array(object_array);
+  init_array(js_array);
+  init_sparse_array(sparse_object_array);
+  init_sparse_array(sparse_js_array);
+
+  store = make_polymorphic_store_function();
+  store(object_array, 2, 257);
+  store = make_polymorphic_store_function();
+  store(js_array, 2, 257);
+  store = make_polymorphic_store_function();
+  store(sparse_object_array, 2, 257);
+  store = make_polymorphic_store_function();
+  store(sparse_js_array, 2, 257);
+
+  assertEquals(257, object_array[2]);
+  assertEquals(257, js_array[2]);
+  assertEquals(257, sparse_js_array[2]);
+  assertEquals(257, sparse_object_array[2]);
+
+  // Now try Crankshaft optimized polymorphic stores
+  store = make_polymorphic_store_function();
+  %OptimizeFunctionOnNextCall(store);
+  store(object_array, 3, 258);
+  store = make_polymorphic_store_function();
+  %OptimizeFunctionOnNextCall(store);
+  store(js_array, 3, 258);
+  store = make_polymorphic_store_function();
+  %OptimizeFunctionOnNextCall(store);
+  store(sparse_object_array, 3, 258);
+  store = make_polymorphic_store_function();
+  %OptimizeFunctionOnNextCall(store);
+  store(sparse_js_array, 3, 258);
+
+  assertEquals(258, object_array[3]);
+  assertEquals(258, js_array[3]);
+  assertEquals(258, sparse_js_array[3]);
+  assertEquals(258, sparse_object_array[3]);
+}
+
+testPolymorphicLoads();
+testPolymorphicStores();
diff --git a/test/mjsunit/property-load-across-eval.js b/test/mjsunit/property-load-across-eval.js
index 5419cc7..98b621e 100644
--- a/test/mjsunit/property-load-across-eval.js
+++ b/test/mjsunit/property-load-across-eval.js
@@ -45,19 +45,21 @@
     assertEquals(2, y);
     assertEquals('global', global_function());
     assertEquals('local', local_function());
+    var exception = false;
     try {
       const_uninitialized();
-      assertUnreachable();
     } catch(e) {
-      // Ignore.
+      exception = true;
     }
+    assertTrue(exception);
     assertEquals('const_global', const_initialized());
+    exception = false;
     try {
       local_const_uninitialized();
-      assertUnreachable();
     } catch(e) {
-      // Ignore.
+      exception = true;
     }
+    assertTrue(exception);
     assertEquals('const_local', local_const_initialized());
     function g() {
       assertEquals(1, x);
@@ -65,19 +67,21 @@
       assertEquals(2, y);
       assertEquals('global', global_function());
       assertEquals('local', local_function());
+      var exception = false;
       try {
         const_uninitialized();
-        assertUnreachable();
       } catch(e) {
-        // Ignore.
+        exception = true;
       }
+      assertTrue(exception);
       assertEquals('const_global', const_initialized());
+      exception = false;
       try {
         local_const_uninitialized();
-        assertUnreachable();
       } catch(e) {
-        // Ignore.
+        exception = true;
       }
+      assertTrue(exception);
       assertEquals('const_local', local_const_initialized());
     }
     g();
diff --git a/test/mjsunit/regexp-call-as-function.js b/test/mjsunit/regexp-call-as-function.js
index 4cbe7f9..add81ac 100644
--- a/test/mjsunit/regexp-call-as-function.js
+++ b/test/mjsunit/regexp-call-as-function.js
@@ -33,4 +33,4 @@
 var subject = "xyzabcde";
 var expected = 'abc,b,c';
 assertEquals(expected, String(regexp.exec(subject)));
-assertEquals(expected, String(regexp(subject)));
+assertThrows(function(){ regexp(subject); });
diff --git a/test/mjsunit/regress/regress-1118.js b/test/mjsunit/regress/regress-1118.js
index 86b8981..7e0461d 100644
--- a/test/mjsunit/regress/regress-1118.js
+++ b/test/mjsunit/regress/regress-1118.js
@@ -55,8 +55,6 @@
     while (%GetOptimizationStatus(h) == 2) {
       for (var j = 0; j < 100; j++) g();
     }
-    assertTrue(%GetOptimizationStatus(h) == 1 ||
-               %GetOptimizationStatus(h) == 3);
     g();
   }
 }
diff --git a/test/mjsunit/regress/regress-1119.js b/test/mjsunit/regress/regress-1119.js
index 484893c..16b2e4f 100644
--- a/test/mjsunit/regress/regress-1119.js
+++ b/test/mjsunit/regress/regress-1119.js
@@ -38,7 +38,6 @@
 var exception;
 try {
   eval("try { } catch (e) { var y = false; }");
-  assertUnreachable();
 } catch (e) {
   exception = e;
 }
diff --git a/test/mjsunit/regress/regress-1130.js b/test/mjsunit/regress/regress-1130.js
index 188f3f9..07d5e3d 100644
--- a/test/mjsunit/regress/regress-1130.js
+++ b/test/mjsunit/regress/regress-1130.js
@@ -30,9 +30,11 @@
 
 Object.prototype.__defineGetter__(0, function() { throw 42; } );
 
+var exception = false;
 try {
   eval("(function() { const x; var x })")();
-  assertUnreachable();
 } catch (e) {
+  exception = true;
   assertTrue(e instanceof TypeError);
 }
+assertTrue(exception);
diff --git a/test/mjsunit/regress/regress-1132.js b/test/mjsunit/regress/regress-1132.js
index 4423ecd..3314db8 100644
--- a/test/mjsunit/regress/regress-1132.js
+++ b/test/mjsunit/regress/regress-1132.js
@@ -41,8 +41,10 @@
   }
 }
 
+var exception = false;
 try {
   test();
-  assertUnreachable();
 } catch (e) {
+  exception = true;
 }
+assertTrue(exception);
diff --git a/test/mjsunit/regress/regress-1160.js b/test/mjsunit/regress/regress-1160.js
index 8e6e29b..10d3bc3 100644
--- a/test/mjsunit/regress/regress-1160.js
+++ b/test/mjsunit/regress/regress-1160.js
@@ -32,15 +32,10 @@
 // when keyed store on the array does not work as expected because of
 // the setter on its prototype.
 
-try {
-  var N = 100;
-  var array = Array(N);
-  for (var i = 0; i < N; ++i) {
-    array[i] = i;
-  }
-  Array.prototype.__defineSetter__(32, function() { });
-  // The next line throws. We should make it work even with changed
-  // prototype. See http://code.google.com/p/v8/issues/detail?id=1161
-  array.join(",");
-  assertUnreachable();
-} catch (e) { }
+var N = 10;
+var array = Array(N);
+for (var i = 0; i < N; ++i) {
+  array[i] = i;
+}
+Array.prototype.__defineSetter__(2, function() { });
+assertEquals("0,1,2,3,4,5,6,7,8,9", array.join(","));
diff --git a/test/mjsunit/regress/regress-1170.js b/test/mjsunit/regress/regress-1170.js
index 8a5a9cf..95684c5 100644
--- a/test/mjsunit/regress/regress-1170.js
+++ b/test/mjsunit/regress/regress-1170.js
@@ -30,37 +30,43 @@
 __proto__.__defineSetter__("a", function(v) { setter_value = v; });
 eval("var a = 1");
 assertEquals(1, setter_value);
-assertFalse(hasOwnProperty("a"));
+assertFalse(this.hasOwnProperty("a"));
 
 eval("with({}) { eval('var a = 2') }");
 assertEquals(2, setter_value);
-assertFalse(hasOwnProperty("a"));
+assertFalse(this.hasOwnProperty("a"));
 
 // Function declarations are treated specially to match Safari. We do
 // not call setters for them.
 eval("function a() {}");
-assertTrue(hasOwnProperty("a"));
+assertTrue(this.hasOwnProperty("a"));
 
-__proto__.__defineSetter__("b", function(v) {   assertUnreachable(); });
+__proto__.__defineSetter__("b", function(v) { assertUnreachable(); });
+var exception = false;
 try {
   eval("const b = 23");
-  assertUnreachable();
 } catch(e) {
+  exception = true;
   assertTrue(/TypeError/.test(e));
 }
+assertTrue(exception);
+
+exception = false;
 try {
   eval("with({}) { eval('const b = 23') }");
-  assertUnreachable();
 } catch(e) {
+  exception = true;
   assertTrue(/TypeError/.test(e));
 }
+assertTrue(exception);
 
 __proto__.__defineSetter__("c", function(v) { throw 42; });
+exception = false;
 try {
   eval("var c = 1");
-  assertUnreachable();
 } catch(e) {
+  exception = true;
   assertEquals(42, e);
-  assertFalse(hasOwnProperty("c"));
+  assertFalse(this.hasOwnProperty("c"));
 }
-
+assertTrue(exception);
diff --git a/test/mjsunit/regress/regress-1172-bis.js b/test/mjsunit/regress/regress-1172-bis.js
index e8d5c81..01b637c 100644
--- a/test/mjsunit/regress/regress-1172-bis.js
+++ b/test/mjsunit/regress/regress-1172-bis.js
@@ -29,9 +29,11 @@
 // are properly treated.
 
 Object.prototype.__defineGetter__(0, function() { throw 42; });
+var exception = false;
 try {
   Object[0]();
-  assertUnreachable();
 } catch(e) {
+  exception = true;
   assertEquals(42, e);
 }
+assertTrue(exception);
diff --git a/test/mjsunit/regress/regress-124.js b/test/mjsunit/regress/regress-124.js
index 0b3aae5..1197467 100644
--- a/test/mjsunit/regress/regress-124.js
+++ b/test/mjsunit/regress/regress-124.js
@@ -26,26 +26,26 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 assertEquals("[object global]", this.toString());
-assertEquals("[object global]", toString());
+assertEquals("[object Undefined]", toString());
 
 assertEquals("[object global]", eval("this.toString()"));
-assertEquals("[object global]", eval("toString()"));
+assertEquals("[object Undefined]", eval("toString()"));
 
 assertEquals("[object global]", eval("var f; this.toString()"));
-assertEquals("[object global]", eval("var f; toString()"));
+assertEquals("[object Undefined]", eval("var f; toString()"));
 
 
 function F(f) {
   assertEquals("[object global]", this.toString());
-  assertEquals("[object global]", toString());
+  assertEquals("[object Undefined]", toString());
 
   assertEquals("[object global]", eval("this.toString()"));
-  assertEquals("[object global]", eval("toString()"));
+  assertEquals("[object Undefined]", eval("toString()"));
 
   assertEquals("[object global]", eval("var f; this.toString()"));
-  assertEquals("[object global]", eval("var f; toString()"));
+  assertEquals("[object Undefined]", eval("var f; toString()"));
 
-  assertEquals("[object global]", eval("f()"));
+  assertEquals("[object Undefined]", eval("f()"));
 
   // Receiver should be the arguments object here.
   assertEquals("[object Arguments]", eval("arguments[0]()"));
diff --git a/test/mjsunit/regress/regress-1246.js b/test/mjsunit/regress/regress-1246.js
new file mode 100644
index 0000000..f3dbec6
--- /dev/null
+++ b/test/mjsunit/regress/regress-1246.js
@@ -0,0 +1,83 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This regression tests the behaviour of the parseInt function when
+// the given radix is not a SMI.
+
+// Flags: --allow-natives-syntax
+
+var nonSmi10 = Math.log(Math.exp(10));
+var nonSmi16 = Math.log(Math.exp(16));
+
+assertTrue(!%_IsSmi(nonSmi10) && nonSmi10 == 10);
+assertTrue(!%_IsSmi(nonSmi16) && nonSmi16 == 16);
+
+// Giving these values as the radix argument triggers radix detection.
+var radix_detect = [0, -0, NaN, Infinity, -Infinity, undefined, null,
+                    "0", "-0", "a"];
+
+// These values will result in an integer radix outside of the valid range.
+var radix_invalid = [1, 37, -2, "-2", "37"];
+
+// These values will trigger decimal parsing.
+var radix10 = [10, 10.1, "10", "10.1", nonSmi10];
+
+// These values will trigger hexadecimal parsing.
+var radix16 = [16, 16.1, 0x10, "0X10", nonSmi16];
+
+for (var i = 0; i < radix_detect.length; i++) {
+  var radix = radix_detect[i];
+  assertEquals(NaN, parseInt("", radix));
+  assertEquals(23, parseInt("23", radix));
+  assertEquals(0xaf, parseInt("0xaf", radix));
+  assertEquals(NaN, parseInt("af", radix));
+}
+
+for (var i = 0; i < radix_invalid.length; i++) {
+  var radix = radix_invalid[i];
+  assertEquals(NaN, parseInt("", radix));
+  assertEquals(NaN, parseInt("23", radix));
+  assertEquals(NaN, parseInt("0xaf", radix));
+  assertEquals(NaN, parseInt("af", radix));
+}
+
+for (var i = 0; i < radix10.length; i++) {
+  var radix = radix10[i];
+  assertEquals(NaN, parseInt("", radix));
+  assertEquals(23, parseInt("23", radix));
+  assertEquals(0, parseInt("0xaf", radix));
+  assertEquals(NaN, parseInt("af", radix));
+}
+
+for (var i = 0; i < radix16.length; i++) {
+  var radix = radix16[i];
+  assertEquals(NaN, parseInt("", radix));
+  assertEquals(0x23, parseInt("23", radix));
+  assertEquals(0xaf, parseInt("0xaf", radix));
+  assertEquals(0xaf, parseInt("af", radix));
+}
+
diff --git a/test/mjsunit/regress/regress-1327557.js b/test/mjsunit/regress/regress-1327557.js
index bdf4277..cd8f08f 100644
--- a/test/mjsunit/regress/regress-1327557.js
+++ b/test/mjsunit/regress/regress-1327557.js
@@ -28,9 +28,11 @@
 var x = { valueOf: function() { throw "x"; } };
 var y = { valueOf: function() { throw "y"; } };
 
+var exception = false;
 try {
   x * -y;
-  assertUnreachable("Didn't throw an exception");
 } catch (e) {
+  exception = true;
   assertEquals("y", e);
 }
+assertTrue(exception);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1355.js
similarity index 80%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1355.js
index edbcb19..de9364a 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1355.js
@@ -25,12 +25,20 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Test that an exception is not thrown when trying to set a value for
+// a property that has only a defined getter, except when in strict mode.
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+var foo = Object.defineProperty({}, "bar", {
+ get: function () {
+      return 10;
+    }
+  });
+
+assertDoesNotThrow("foo.bar = 20");
+
+function shouldThrow() {
+  'use strict';
+  foo.bar = 20;
 }
 
-test();
+assertThrows("shouldThrow()");
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1360.js
similarity index 81%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1360.js
index edbcb19..bebad28 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1360.js
@@ -25,12 +25,15 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Check the receiver for the sort and replace functions to
+// Array.prototype.sort and String.prototype.replace.
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+var global = this;
+function strict() { "use strict"; assertEquals(void 0, this); }
+function non_strict() { assertEquals(global, this); }
 
-test();
+[1,2,3].sort(strict);
+[1,2,3].sort(non_strict);
+
+"axc".replace("x", strict);
+"axc".replace("x", non_strict);
diff --git a/test/mjsunit/regress/regress-1365.js b/test/mjsunit/regress/regress-1365.js
new file mode 100644
index 0000000..59290f9
--- /dev/null
+++ b/test/mjsunit/regress/regress-1365.js
@@ -0,0 +1,82 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1365
+
+// Check that builtin methods are passed undefined as the receiver
+// when called as functions through variables.
+
+// Flags: --allow-natives-syntax
+
+// Global variable.
+var valueOf = Object.prototype.valueOf;
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+function callGlobalValueOf() { valueOf(); }
+function callGlobalHasOwnProperty() { valueOf(); }
+
+assertEquals(Object.prototype, Object.prototype.valueOf());
+assertThrows(callGlobalValueOf);
+assertThrows(callGlobalHasOwnProperty);
+
+%OptimizeFunctionOnNextCall(Object.prototype.valueOf);
+Object.prototype.valueOf();
+
+assertEquals(Object.prototype, Object.prototype.valueOf());
+assertThrows(callGlobalValueOf);
+assertThrows(callGlobalHasOwnProperty);
+
+function CheckExceptionCallLocal() {
+  var valueOf = Object.prototype.valueOf;
+  var hasOwnProperty = Object.prototype.hasOwnProperty;
+  var exception = false;
+  try { valueOf(); } catch(e) { exception = true; }
+  assertTrue(exception);
+  exception = false;
+  try { hasOwnProperty(); } catch(e) { exception = true; }
+  assertTrue(exception);
+}
+CheckExceptionCallLocal();
+
+function CheckExceptionCallParameter(f) {
+  var exception = false;
+  try { f(); } catch(e) { exception = true; }
+  assertTrue(exception);
+}
+CheckExceptionCallParameter(Object.prototype.valueOf);
+CheckExceptionCallParameter(Object.prototype.hasOwnProperty);
+
+function CheckPotentiallyShadowedByEval() {
+  var exception = false;
+  try {
+    eval("hasOwnProperty('x')");
+  } catch(e) {
+    exception = true;
+  }
+  assertTrue(exception);
+}
+CheckPotentiallyShadowedByEval();
diff --git a/test/mjsunit/bugs/bug-1412.js b/test/mjsunit/regress/regress-1412.js
similarity index 66%
copy from test/mjsunit/bugs/bug-1412.js
copy to test/mjsunit/regress/regress-1412.js
index 8e700d5..b043f19 100644
--- a/test/mjsunit/bugs/bug-1412.js
+++ b/test/mjsunit/regress/regress-1412.js
@@ -25,10 +25,35 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-function f() { "use strict"; print(this); }
+// Test that the apply with arguments optimization passes values
+// unchanged to strict-mode functions and builtins.
 
-function g() { assertEquals(void 0, f.apply(undefined, arguments)); }
+// Flags: --allow-natives-syntax
 
-for (var i = 0; i < 10; i++) g();
-%OptimizeFunctionOnNextCall(g);
-g();
+function strict() { "use strict"; return this; }
+
+function test_strict() {
+  assertEquals(void 0, strict.apply(undefined, arguments));
+  assertEquals(42, strict.apply(42, arguments));
+  assertEquals("asdf", strict.apply("asdf", arguments));
+}
+
+for (var i = 0; i < 10; i++) test_strict();
+%OptimizeFunctionOnNextCall(test_strict);
+test_strict();
+
+function test_builtin(receiver) {
+  Object.prototype.valueOf.apply(receiver, arguments);
+}
+
+for (var i = 0; i < 10; i++) test_builtin(this);
+%OptimizeFunctionOnNextCall(test_builtin);
+test_builtin(this);
+
+var exception = false;
+try {
+  test_builtin(undefined);
+} catch(e) {
+  exception = true;
+}
+assertTrue(exception);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1423.js
similarity index 67%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1423.js
index edbcb19..b0d0ca3 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1423.js
@@ -25,12 +25,41 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --allow-natives-syntax
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+// Test that the Lithium environment iterator does stop iteration early.
+"use strict";
+
+function f0() {
+  return f1('literal', true);
 }
 
-test();
+function f1(x, y) {
+  return f2(x, y);
+}
+
+// Because it's strict, f2 has an environment containing only the constants
+// undefined, 'literal', and false.  Bug 1423 would cause environment
+// iteration to stop early.
+//
+// Bug manifests as UNREACHABLE code (due to an unallocated register) in
+// debug builds.
+function f2(x, y) {
+  if (y) {
+    if (f3(x, 'other-literal')) {
+      return 0;
+    } else {
+      return 1;
+    }
+  } else {
+    return 2;
+  }
+}
+
+function f3(x, y) {
+  return x === y;
+}
+
+for (var i = 0; i < 5; ++i) f0();
+%OptimizeFunctionOnNextCall(f0);
+assertEquals(1, f0());
diff --git a/test/mjsunit/regress/regress-1436.js b/test/mjsunit/regress/regress-1436.js
new file mode 100644
index 0000000..390ccee
--- /dev/null
+++ b/test/mjsunit/regress/regress-1436.js
@@ -0,0 +1,79 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that reduce and reduceRight call the callback function with
+// undefined as the receiver (which for non-strict functions is
+// transformed to the global object).
+
+// Check receiver for reduce and reduceRight.
+
+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); }
+
+[2, 3].reduce(non_strict);
+[2, 3].reduce(strict);
+[2, 3].reduceRight(non_strict);
+[2, 3].reduceRight(strict);
+
+
+// Check the receiver for callbacks in other array methods.
+[2, 3].every(non_strict);
+[2, 3].every(non_strict, undefined);
+[2, 3].every(non_strict, null);
+[2, 3].every(strict);
+[2, 3].every(strict, undefined);
+[2, 3].every(strict_null, null);
+
+[2, 3].filter(non_strict);
+[2, 3].filter(non_strict, undefined);
+[2, 3].filter(non_strict, null);
+[2, 3].filter(strict);
+[2, 3].filter(strict, undefined);
+[2, 3].filter(strict_null, null);
+
+[2, 3].forEach(non_strict);
+[2, 3].forEach(non_strict, undefined);
+[2, 3].forEach(non_strict, null);
+[2, 3].forEach(strict);
+[2, 3].forEach(strict, undefined);
+[2, 3].forEach(strict_null, null);
+
+[2, 3].map(non_strict);
+[2, 3].map(non_strict, undefined);
+[2, 3].map(non_strict, null);
+[2, 3].map(strict);
+[2, 3].map(strict, undefined);
+[2, 3].map(strict_null, null);
+
+[2, 3].some(non_strict);
+[2, 3].some(non_strict, undefined);
+[2, 3].some(non_strict, null);
+[2, 3].some(strict);
+[2, 3].some(strict, undefined);
+[2, 3].some(strict_null, null);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1447.js
similarity index 88%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1447.js
index edbcb19..3c64929 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1447.js
@@ -25,12 +25,5 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
+[0].forEach(function(){ Object.freeze(Array.prototype.forEach); });
+[0].every(function(){ Object.seal(Array.prototype.every); });
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1513.js
similarity index 78%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1513.js
index edbcb19..06c5edf 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1513.js
@@ -25,12 +25,20 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Deleting a mapped arguments property and adding it via
+// Object.defineProperty should not crash.
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+function testcase() {
+  return (function (a, b, c) {
+      delete arguments[0];
+      Object.defineProperty(arguments, "0", {
+              value: 10,
+              writable: false,
+              enumerable: false,
+              configurable: false
+            });
+      assertEquals(10, arguments[0]);
+    }(0, 1, 2));
 }
 
-test();
+testcase();
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1521.js
similarity index 78%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1521.js
index edbcb19..3149f05 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1521.js
@@ -24,13 +24,25 @@
 // 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
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+// Optimized variable access inside through a catch context should work.
+function test(x) {
+  try {
+    throw new Error();
+  } catch (e) {
+    var y = {f: 1};
+    var f = function () {
+      var z = y;
+      var g = function () {
+        if (y.f === z.f) return x;
+      };
+      %OptimizeFunctionOnNextCall(g);
+      return g;
+    }
+    assertEquals(3, f()());
+  }
 }
 
-test();
+test(3);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1528.js
similarity index 79%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1528.js
index edbcb19..2eb6be1 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1528.js
@@ -25,12 +25,16 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// With (or catch) scopes nested inside catch scopes should look at the
+// first outer non-catch scope to decide which closure to use when
+// allocating the new context.
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+// Code below should not assert or crash.
+try {
+  fail;
+} catch (e) {
+  with({}) {  // With scope inside catch scope.
+    // Dynamic declaration forces runtime lookup to observe the context chain.
+    eval('const x = 7');
+  }
 }
-
-test();
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1529.js
similarity index 88%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1529.js
index edbcb19..212d7b3 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1529.js
@@ -25,12 +25,11 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// See: http://code.google.com/p/v8/issues/detail?id=1529
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
+try {
+  Error.prepareStackTrace = function (error, stackTrace) {
+    stackTrace.some();
+  };
+  x;
+} catch (e) {}
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1531.js
similarity index 70%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1531.js
index edbcb19..09e61a6 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1531.js
@@ -25,12 +25,25 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Regression test for computing elements keys of arguments object.  Should
+// not crash or assert.
+function test(x) {
+  arguments[10] = 0;
+  var arr = [];
+  for (var p in arguments) arr.push(p);
+  return arr;
+}
+assertEquals(["0", "10"], test(0));
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+// Regression test for lookup after delete of a dictionary-mode arguments
+// backing store.  Should not crash or assert.
+function test1(x, y, z) {
+  // Put into dictionary mode.
+  arguments.__defineGetter__("5", function () { return 0; });
+  // Delete a property from the dictionary.
+  delete arguments[5];
+  // Look up a property in the dictionary.
+  return arguments[2];
 }
 
-test();
+assertEquals(void 0, test1(0));
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1560.js
similarity index 64%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1560.js
index edbcb19..a0aa7e6 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1560.js
@@ -25,12 +25,44 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --allow-natives-syntax --expose-gc
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+function mkCOWArray() {
+  var a = [''];
+  assertEquals('', a[0]);
+  return a;
 }
 
-test();
+function mkArray() {
+  var a = [];
+  a[0] = '';
+  return a;
+}
+
+function mkNumberDictionary() {
+  var a = new Array();
+  a[0] = '';
+  a[100000] = '';
+  return a;
+}
+
+function write(a, i) { a[i] = "bazinga!"; }
+
+function test(factories, w) {
+  factories.forEach(function(f) { w(f(), 0); });
+  factories.forEach(function(f) { w(f(), 0); });
+      %OptimizeFunctionOnNextCall(w);
+  factories.forEach(function(f) { w(f(), 0); });
+}
+
+// Monomorphic case.
+for (var i = 0; i < 5; i++) write(mkArray(), 0);
+%OptimizeFunctionOnNextCall(write);
+write(mkCOWArray(), 0);
+var failure = mkCOWArray();
+
+// Cleanup, then polymorphic case.
+%DeoptimizeFunction(write);
+gc();
+test([mkArray, mkNumberDictionary], write);
+test([mkArray, mkNumberDictionary, mkCOWArray], write);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1583.js
similarity index 66%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1583.js
index edbcb19..c4a344c 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1583.js
@@ -25,12 +25,33 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --allow-natives-syntax
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+// Regression test for a bug in recompilation of anonymous functions inside
+// catch.  We would incorrectly hoist them outside the catch in some cases.
+function f() {
+  try {
+    throw 0;
+  } catch (e) {
+    try {
+      var x = { a: 'hest' };
+      x.m = function (e) { return x.a; };
+    } catch (e) {
+    }
+  }
+  return x;
 }
 
-test();
+var o = f();
+assertEquals('hest', o.m());
+assertEquals('hest', o.m());
+assertEquals('hest', o.m());
+%OptimizeFunctionOnNextCall(o.m);
+assertEquals('hest', o.m());
+
+// Fixing the bug above introduced (revealed?) an inconsistency in named
+// getters and setters.  The property name was also treated as a function
+// name.
+var global = 'horse';
+var p = { get global() { return global; }};
+assertEquals('horse', p.global);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-1647.js
similarity index 83%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-1647.js
index edbcb19..ab6608c 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-1647.js
@@ -25,12 +25,18 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --allow-natives-syntax
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+// Test for correct deoptimization in named function expressions.
 
-test();
+var t = { foo: function() {} };
+
+var f = (function bar() {
+ t.foo();
+ assertEquals("function", typeof bar);
+});
+
+for (var i = 0; i < 10; i++) f();
+%OptimizeFunctionOnNextCall(f);
+t.number = 2;
+f();
diff --git a/test/mjsunit/regress/regress-244.js b/test/mjsunit/regress/regress-244.js
index dc5336f..7503b15 100644
--- a/test/mjsunit/regress/regress-244.js
+++ b/test/mjsunit/regress/regress-244.js
@@ -54,13 +54,14 @@
   }
   for (var i = 0; i < kIllegalEncoded.length; i++) {
     var value = kIllegalEncoded[i];
-    var threw = false;
+    var exception = false;
     try {
       decodeURI(value);
-      assertUnreachable(value);
     } catch (e) {
+      exception = true;
       assertInstanceof(e, URIError);
     }
+    assertTrue(exception);
   }
 }
 
diff --git a/test/mjsunit/regress/regress-485.js b/test/mjsunit/regress/regress-485.js
index e5182b3..f26e0eb 100755
--- a/test/mjsunit/regress/regress-485.js
+++ b/test/mjsunit/regress/regress-485.js
@@ -34,11 +34,6 @@
 var global2 = (function(){return this;})();
 assertEquals(global, global2, "direct call to local function returns global");
 
-var builtin = Object.prototype.valueOf;  // Builtin function that returns this.
-
-assertEquals(global, builtin(), "Direct call to builtin");
-
-
 // Builtin that depends on value of this to compute result.
 var builtin2 = Object.prototype.toString;
 
diff --git a/test/mjsunit/regress/regress-603.js b/test/mjsunit/regress/regress-603.js
index 7d4c322..f9344ee 100644
--- a/test/mjsunit/regress/regress-603.js
+++ b/test/mjsunit/regress/regress-603.js
@@ -29,21 +29,36 @@
 // not mess up the stack.
 // http://code.google.com/p/v8/issues/detail?id=603
 
-function test0() {
-  var re = /b../;
+var re = /b../;
+assertThrows(function() {
   return re('abcdefghijklm') + 'z';
-}
-assertEquals('bcdz', test0());
+});
 
 var re1 = /c../;
 re1.call = Function.prototype.call;
-var test1 = re1.call(null, 'abcdefghijklm') + 'z';
-assertEquals('cdez', test1);
+assertThrows(function() {
+  re1.call(null, 'abcdefghijklm') + 'z';
+});
 
 var re2 = /d../;
-var test2 = Function.prototype.call.call(re2, null, 'abcdefghijklm') + 'z';
-assertEquals('defz', test2);
+assertThrows(function() {
+  Function.prototype.call.call(re2, null, 'abcdefghijklm') + 'z';
+});
 
 var re3 = /e../;
-var test3 = Function.prototype.call.apply(re3, [null, 'abcdefghijklm']) + 'z';
-assertEquals('efgz', test3);
+assertThrows(function() {
+  Function.prototype.call.apply(
+      re3, [null, 'abcdefghijklm']) + 'z';
+});
+
+var re4 = /f../;
+assertThrows(function() {
+  Function.prototype.apply.call(
+      re4, null, ['abcdefghijklm']) + 'z';
+});
+
+var re5 = /g../;
+assertThrows(function() {
+  Function.prototype.apply.apply(
+      re4, [null, ['abcdefghijklm']]) + 'z';
+});
diff --git a/test/mjsunit/regress/regress-70066.js b/test/mjsunit/regress/regress-70066.js
index b8386a7..01c2f4f 100644
--- a/test/mjsunit/regress/regress-70066.js
+++ b/test/mjsunit/regress/regress-70066.js
@@ -57,21 +57,18 @@
 assertEquals(0, x, "test2");  // Global x is undisturbed.
 
 
-// Delete on an argument.  This hits the same code paths as test5 because
-// 'with' forces all parameters to be indirected through the arguments
-// object.
+// Delete on a parameter.
 function test3(value) {
   var status;
   with ({}) { status = delete value; }
   return value + ":" + status;
 }
 
-assertEquals("undefined:true", test3(3), "test3");
+assertEquals("3:false", test3(3), "test3");
 assertEquals(0, x, "test3");  // Global x is undisturbed.
 
 
-// Delete on an argument from an outer context.  This hits the same code
-// path as test2.
+// Delete on a parameter found in an outer context.
 function test4(value) {
   function f() {
     with ({}) { return delete value; }
@@ -84,15 +81,14 @@
 assertEquals(0, x, "test4");  // Global x is undisturbed.
 
 
-// Delete on an argument found in the arguments object.  Such properties are
-// normally DONT_DELETE in JavaScript but deletion is allowed by V8.
+// Delete on a parameter, arguments object should be unaffected.
 function test5(value) {
   var status;
   with ({}) { status = delete value; }
   return arguments[0] + ":" + status;
 }
 
-assertEquals("undefined:true", test5(5), "test5");
+assertEquals("5:false", test5(5), "test5");
 assertEquals(0, x, "test5");  // Global x is undisturbed.
 
 function test6(value) {
@@ -103,7 +99,7 @@
   return arguments[0] + ":" + status;
 }
 
-assertEquals("undefined:true", test6(6), "test6");
+assertEquals("6:false", test6(6), "test6");
 assertEquals(0, x, "test6");  // Global x is undisturbed.
 
 
diff --git a/test/mjsunit/regress/regress-752.js b/test/mjsunit/regress/regress-752.js
index 1142a1f..d38870e 100644
--- a/test/mjsunit/regress/regress-752.js
+++ b/test/mjsunit/regress/regress-752.js
@@ -33,4 +33,4 @@
   return value === 42 ? new Boolean(false) : value;
 }
 
-assertEquals(JSON.stringify([42], replacer), "[false]");
+assertEquals("[false]", JSON.stringify([42], replacer));
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-794.js
similarity index 88%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-794.js
index edbcb19..409b2ef 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-794.js
@@ -25,12 +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.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Test the a bound function does not have a prototype.
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
+function foo() {}
+assertFalse("prototype" in foo.bind());
diff --git a/test/mjsunit/regress/regress-798.js b/test/mjsunit/regress/regress-798.js
index 423c883..ffee5da 100644
--- a/test/mjsunit/regress/regress-798.js
+++ b/test/mjsunit/regress/regress-798.js
@@ -106,4 +106,3 @@
 xx.a = 1;
 xx.b = 1;
 xx.c = 1;
-
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-84234.js
similarity index 72%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-84234.js
index edbcb19..6377fb3 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-84234.js
@@ -25,12 +25,31 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --expose-gc --noopt
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+var gTestcases = new Array();
+
+function TestCase(n, d, e, a) {
+  gTestcases[gTc++] = this;
+  for ( gTc=0; gTc < gTestcases.length; gTc++ );
 }
 
-test();
+for ( var i = 0x0530; i <= 0x058F; i++ ) {
+  new TestCase("15.5.4.11-6",
+               eval("var s = new String(String.fromCharCode(i)); s.toLowerCase().charCodeAt(0)"));
+}
+var gTc= 0;
+
+
+for (var j = 0; j < 10; j++) {
+  test();
+  function test() {
+    for ( 0; gTc < gTestcases.length; gTc++ ) {
+      var MYOBJECT = new MyObject();
+    }
+    gc();
+  }
+  function MyObject( n ) {
+    this.__proto__ = Number.prototype;
+  }
+}
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-88591.js
similarity index 72%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-88591.js
index edbcb19..e42570a 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-88591.js
@@ -25,12 +25,18 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Regression test for a crash.  A data property in the global object's
+// prototype shadowed by a setter in the global object's prototype's
+// prototype would crash or assert when seen by Runtime_DeclareContextSlot.
+var called = false;
+Object.prototype.__defineSetter__('x', function(x) { called = true; });
+Object.prototype.__defineGetter__('x', function () { return 0; });
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+this.__proto__ = { x: 1 };
 
-test();
+try { fail; } catch (e) { eval('const x = 2'); }
+
+var o = Object.getOwnPropertyDescriptor(this, 'x');
+assertFalse(called);
+assertEquals(2, o.value);
+assertEquals(false, o.writable);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-88858.js
similarity index 66%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-88858.js
index edbcb19..ba33f87 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-88858.js
@@ -25,12 +25,41 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --expose-gc
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
+// Verify that JSObject::PreventExtensions works for arguments objects.
 
-test();
+try {
+    function make_watcher(name) { }
+    var o, p;
+    function f(flag) {
+        if (flag) {
+            o = arguments;
+        } else {
+            p = arguments;
+            o.watch(0, (arguments-1901)('o'));
+            p.watch(0, make_watcher('p'));
+            p.unwatch(0);
+            o.unwatch(0);
+            p[0] = 4;
+            assertEq(flag, 4);
+        }
+    }
+    f(true);
+    f(false);
+    reportCompare(true, true);
+} catch(exc1) { }
+
+try {
+    function __noSuchMethod__() {
+       if (anonymous == "1")
+           return NaN;
+       return __construct__;
+    }
+    f.p = function() { };
+    Object.freeze(p);
+    new new freeze().p;
+    reportCompare(0, 0, "ok");
+} catch(exc2) { }
+
+gc();
diff --git a/test/mjsunit/regress/regress-892742.js b/test/mjsunit/regress/regress-892742.js
index a60395e..78a57b2 100644
--- a/test/mjsunit/regress/regress-892742.js
+++ b/test/mjsunit/regress/regress-892742.js
@@ -26,25 +26,23 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 function f() {
-  return/* useless*/1;
+  return/* Counts as non-line-terminating whitespace */1;
 };
 
-
-// According to ECMA-262, this comment should actually be parsed as a
-// line terminator making g() return undefined, but this is not the
-// way it's handled by Spidermonkey or KJS.
+// According to ECMA-262, this comment should be parsed as a
+// line terminator making g() return undefined.
 function g() {
-  return/* useless
-         */2;
+  return/* Counts as line-terminator whitespace.
+          */2;
 };
 
 function h() {
-  return// meaningful
+  return// Comment doesn't include line-terminator at end.
       3;
 };
 
 
 assertEquals(1, f());
-assertEquals(2, g());
-assertTrue(typeof h() == 'undefined', 'h');
+assertEquals(undefined, g());
+assertEquals(undefined, h());
 
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-91120.js
similarity index 73%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-91120.js
index edbcb19..117acac 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-91120.js
@@ -25,12 +25,24 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// We intend that the function declaration for g inside catch is hoisted to
+// function f's scope.  Invoke it before try/catch, in the try block, in the
+// catch block, after try/catch, and outside f, and verify that it has
+// access to the proper binding of x.
+var x = 'global';
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+function f() {
+  var x = 'function';
+  assertEquals('function', g());
+  try {
+    assertEquals('function', g());
+    throw 'catch';
+  } catch (x) {
+    function g() { return x; }
+    assertEquals('function', g());
+  }
+  assertEquals('function', g());
+  return g;
 }
 
-test();
+assertEquals('function', f()());
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-91787.js
similarity index 86%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-91787.js
index edbcb19..96310d0 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-91787.js
@@ -25,12 +25,11 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Unterminated non-ASCII string literals in JSON code were not
+// detected correctly.
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
+// Shouldn't crash (due to stack overflow).
+// Should throw due to invalid syntax.
+assertThrows(function() {
+  JSON.parse('"\x80unterminated');
+});
diff --git a/test/mjsunit/bugs/bug-1412.js b/test/mjsunit/regress/regress-98773.js
similarity index 82%
rename from test/mjsunit/bugs/bug-1412.js
rename to test/mjsunit/regress/regress-98773.js
index 8e700d5..eb24eb5 100644
--- a/test/mjsunit/bugs/bug-1412.js
+++ b/test/mjsunit/regress/regress-98773.js
@@ -25,10 +25,15 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-function f() { "use strict"; print(this); }
+// Calling Array.sort on an external array is not supposed to crash.
 
-function g() { assertEquals(void 0, f.apply(undefined, arguments)); }
+var array = new Int16Array(23);
+array[7] = 7; array[9] = 9;
+assertEquals(23, array.length);
+assertEquals(7, array[7]);
+assertEquals(9, array[9]);
 
-for (var i = 0; i < 10; i++) g();
-%OptimizeFunctionOnNextCall(g);
-g();
+Array.prototype.sort.call(array);
+assertEquals(23, array.length);
+assertEquals(7, array[21]);
+assertEquals(9, array[22]);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-99167.js
similarity index 88%
rename from test/mjsunit/override-eval-with-non-function.js
rename to test/mjsunit/regress/regress-99167.js
index edbcb19..5053ae5 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-99167.js
@@ -25,12 +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.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --expose-gc --max-new-space-size=1024
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
-}
-
-test();
+eval("function Node() { this.a = 1; this.a = 3; }");
+new Node;
+for (var i = 0; i < 4; ++i) gc();
+for (var i = 0; i < 100000; ++i) new Node;
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-arguments-gc.js
similarity index 88%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-arguments-gc.js
index edbcb19..baa4e16 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-arguments-gc.js
@@ -25,12 +25,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
+// Flags: --expose-gc --nocleanup_code_caches_at_gc
 
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+function f(x) {
+  gc();
+  arguments[0] = {};
 }
 
-test();
+f(1);
+f(1);
+f(1);
diff --git a/test/mjsunit/override-eval-with-non-function.js b/test/mjsunit/regress/regress-crbug-87478.js
similarity index 84%
copy from test/mjsunit/override-eval-with-non-function.js
copy to test/mjsunit/regress/regress-crbug-87478.js
index edbcb19..115b3fd 100644
--- a/test/mjsunit/override-eval-with-non-function.js
+++ b/test/mjsunit/regress/regress-crbug-87478.js
@@ -25,12 +25,12 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// When 'eval' is overridden with a non-function object we should
-// check whether the object is callable.
-
-function test() {
-  eval = /foo/;
-  assertEquals(["foo"], eval("foobar"));
+// Check that arguments access ICs correctly handle non-JSObject
+// receivers.
+function f(array) { return array[0]; }
+function args(a) { return arguments; }
+// Put the keyed load in f into the keyed-load-arguments state.
+for (var i = 0; i < 10; i++) {
+  f(args(1));
 }
-
-test();
+f('123');
diff --git a/test/mjsunit/strict-mode-eval.js b/test/mjsunit/strict-mode-eval.js
index 018ed9e..391daaa 100644
--- a/test/mjsunit/strict-mode-eval.js
+++ b/test/mjsunit/strict-mode-eval.js
@@ -42,36 +42,44 @@
 eval_alias(code4);
 
 function strict1() {
+  var exception = false;
   try {
     eval(code1);
-    assertUnreachable("did not throw exception");
   } catch (e) {
+    exception = true;
     assertInstanceof(e, SyntaxError);
   }
+  assertTrue(exception);
 
   function strict2() {
+    var exception = false;
     try {
       eval(code2);
-      assertUnreachable("did not throw exception");
     } catch (e) {
+      exception = true;
       assertInstanceof(e, SyntaxError);
     }
+    assertTrue(exception);
 
     function strict3() {
+      var exception = false;
       try {
         eval(code3);
-        assertUnreachable("did not throw exception");
       } catch (e) {
+        exception = true;
         assertInstanceof(e, SyntaxError);
       }
+      assertTrue(exception);
 
       function strict4() {
+        var exception = false;
         try {
           eval(code4);
-          assertUnreachable("did not throw exception");
         } catch (e) {
+          exception = true;
           assertInstanceof(e, SyntaxError);
         }
+        assertTrue(exception);
       }
       strict4();
     }
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
index 2d676b4..30234ba 100644
--- a/test/mjsunit/strict-mode.js
+++ b/test/mjsunit/strict-mode.js
@@ -67,6 +67,9 @@
   with ({}) {};
 })();
 
+// Incorrectly place 'use strict' directive.
+assertThrows("function foo (x) 'use strict'; {}", SyntaxError);
+
 // 'use strict' in non-directive position.
 (function UseStrictNonDirective() {
   void(0);
@@ -319,14 +322,8 @@
            +arguments, -arguments, ~arguments, !arguments];
 })();
 
-// 7.6.1.2 Future Reserved Words
-var future_reserved_words = [
-  "class",
-  "enum",
-  "export",
-  "extends",
-  "import",
-  "super",
+// 7.6.1.2 Future Reserved Words in strict mode
+var future_strict_reserved_words = [
   "implements",
   "interface",
   "let",
@@ -337,14 +334,17 @@
   "static",
   "yield" ];
 
-function testFutureReservedWord(word) {
+function testFutureStrictReservedWord(word) {
   // Simple use of each reserved word
   CheckStrictMode("var " + word + " = 1;", SyntaxError);
+  CheckStrictMode("typeof (" + word + ");", SyntaxError);
 
   // object literal properties
   eval("var x = { " + word + " : 42 };");
   eval("var x = { get " + word + " () {} };");
   eval("var x = { set " + word + " (value) {} };");
+  eval("var x = { get " + word + " () { 'use strict'; } };");
+  eval("var x = { set " + word + " (value) { 'use strict'; } };");
 
   // object literal with string literal property names
   eval("var x = { '" + word + "' : 42 };");
@@ -364,7 +364,6 @@
 
   // Function names and arguments when the body is strict
   assertThrows("function " + word + " () { 'use strict'; }", SyntaxError);
-  assertThrows("function foo (" + word + ")  'use strict'; {}", SyntaxError);
   assertThrows("function foo (" + word + ", " + word + ") { 'use strict'; }",
                SyntaxError);
   assertThrows("function foo (a, " + word + ") { 'use strict'; }", SyntaxError);
@@ -374,17 +373,14 @@
   assertThrows("var foo = function (" + word + ") { 'use strict'; }",
                SyntaxError);
 
-  // get/set when the body is strict
-  eval("var x = { get " + word + " () { 'use strict'; } };");
-  eval("var x = { set " + word + " (value) { 'use strict'; } };");
-  assertThrows("var x = { get foo(" + word + ") { 'use strict'; } };",
-               SyntaxError);
+  // setter parameter when the body is strict
+  CheckStrictMode("var x = { set foo(" + word + ") {} };", SyntaxError);
   assertThrows("var x = { set foo(" + word + ") { 'use strict'; } };",
                SyntaxError);
 }
 
-for (var i = 0; i < future_reserved_words.length; i++) {
-  testFutureReservedWord(future_reserved_words[i]);
+for (var i = 0; i < future_strict_reserved_words.length; i++) {
+  testFutureStrictReservedWord(future_strict_reserved_words[i]);
 }
 
 function testAssignToUndefined(test, should_throw) {
@@ -842,12 +838,14 @@
   }
 
   for (var i = 0; i < 10; i ++) {
+    var exception = false;
     try {
       strict(o, name);
-      assertUnreachable();
     } catch(e) {
+      exception = true;
       assertInstanceof(e, TypeError);
     }
+    assertTrue(exception);
   }
 })();
 
diff --git a/test/mjsunit/testcfg.py b/test/mjsunit/testcfg.py
index f7b6d4d..7c6311b 100644
--- a/test/mjsunit/testcfg.py
+++ b/test/mjsunit/testcfg.py
@@ -127,13 +127,15 @@
     third_party = [current_path + ['third_party', t] for t in self.Ls(join(self.root, 'third_party'))]
     tools = [current_path + ['tools', t] for t in self.Ls(join(self.root, 'tools'))]
     compiler = [current_path + ['compiler', t] for t in self.Ls(join(self.root, 'compiler'))]
+    harmony = [current_path + ['harmony', t] for t in self.Ls(join(self.root, 'harmony'))]
     mjsunit.sort()
     regress.sort()
     bugs.sort()
     third_party.sort()
     tools.sort()
     compiler.sort()
-    all_tests = mjsunit + regress + bugs + third_party + tools + compiler
+    harmony.sort()
+    all_tests = mjsunit + regress + bugs + third_party + tools + compiler + harmony
     result = []
     for test in all_tests:
       if self.Contains(path, test):
diff --git a/test/mjsunit/tools/profile_view.js b/test/mjsunit/tools/profile_view.js
index 7f60119..d62205b 100644
--- a/test/mjsunit/tools/profile_view.js
+++ b/test/mjsunit/tools/profile_view.js
@@ -26,7 +26,8 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Load source code files from <project root>/tools.
-// Files: tools/consarray.js tools/profile.js tools/profile_view.js
+// Files: tools/codemap.js tools/consarray.js tools/profile.js
+// Files: tools/profile_view.js
 
 
 function createNode(name, time, opt_parent) {
diff --git a/test/mjsunit/typeof.js b/test/mjsunit/typeof.js
index 39dec72..8aa0ab1 100644
--- a/test/mjsunit/typeof.js
+++ b/test/mjsunit/typeof.js
@@ -25,14 +25,13 @@
 // (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 type of a regular expression should be 'function', including in
+// The type of a regular expression should be 'object', including in
 // the context of string equality comparisons.
 
 var r = new RegExp;
-assertEquals('function', typeof r);
-assertTrue(typeof r == 'function');
+assertEquals('object', typeof r);
+assertTrue(typeof r == 'object');
+assertFalse(typeof r == 'function');
 
 function test(x, y) { return x == y; }
-assertFalse(test('object', typeof r));
-
-assertFalse(typeof r == 'object');
+assertTrue(test('object', typeof r));
diff --git a/test/mjsunit/unbox-double-arrays.js b/test/mjsunit/unbox-double-arrays.js
new file mode 100644
index 0000000..351765e
--- /dev/null
+++ b/test/mjsunit/unbox-double-arrays.js
@@ -0,0 +1,468 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test dictionary -> double elements -> dictionary elements round trip
+
+// Flags: --allow-natives-syntax --unbox-double-arrays --expose-gc
+var large_array_size = 100000;
+var approx_dict_to_elements_threshold = 75000;
+
+var name = 0;
+
+function expected_array_value(i) {
+  if ((i % 2) == 0) {
+    return i;
+  } else {
+    return i + 0.5;
+  }
+}
+
+function force_to_fast_double_array(a) {
+  a[large_array_size - 2] = 1;
+  for (var i= 0; i < approx_dict_to_elements_threshold; ++i ) {
+    a[i] = expected_array_value(i);
+  }
+  assertTrue(%HasFastDoubleElements(a));
+}
+
+function make_object_like_array(size) {
+  obj = new Object();
+  obj.length = size;
+  return obj;
+}
+
+function testOneArrayType(allocator) {
+  var large_array = new allocator(large_array_size);
+  force_to_fast_double_array(large_array);
+  var six = 6;
+
+  for (var i= 0; i < approx_dict_to_elements_threshold; i += 501 ) {
+    assertEquals(expected_array_value(i), large_array[i]);
+  }
+
+  // This function has a constant and won't get inlined.
+  function computed_6() {
+    return six;
+  }
+
+  // Multiple versions of the test function makes sure that IC/Crankshaft state
+  // doesn't get reused.
+  function test_various_loads(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    assertEquals(value_5, a[5]);
+    assertEquals(value_6, a[6]);
+    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    assertEquals(value_7, a[7]);
+    assertEquals(undefined, a[large_array_size-1]);
+    assertEquals(undefined, a[-1]);
+    assertEquals(large_array_size, a.length);
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  function test_various_loads2(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    assertEquals(value_5, a[5]);
+    assertEquals(value_6, a[6]);
+    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    assertEquals(value_7, a[7]);
+    assertEquals(undefined, a[large_array_size-1]);
+    assertEquals(undefined, a[-1]);
+    assertEquals(large_array_size, a.length);
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  function test_various_loads3(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    assertEquals(value_5, a[5]);
+    assertEquals(value_6, a[6]);
+    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    assertEquals(value_7, a[7]);
+    assertEquals(undefined, a[large_array_size-1]);
+    assertEquals(undefined, a[-1]);
+    assertEquals(large_array_size, a.length);
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  function test_various_loads4(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    assertEquals(value_5, a[5]);
+    assertEquals(value_6, a[6]);
+    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    assertEquals(value_7, a[7]);
+    assertEquals(undefined, a[large_array_size-1]);
+    assertEquals(undefined, a[-1]);
+    assertEquals(large_array_size, a.length);
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  function test_various_loads5(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    assertEquals(value_5, a[5]);
+    assertEquals(value_6, a[6]);
+    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    assertEquals(value_7, a[7]);
+    assertEquals(undefined, a[large_array_size-1]);
+    assertEquals(undefined, a[-1]);
+    assertEquals(large_array_size, a.length);
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  function test_various_loads6(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    assertEquals(value_5, a[5]);
+    assertEquals(value_6, a[6]);
+    assertEquals(value_6, a[computed_6()]); // Test non-constant key
+    assertEquals(value_7, a[7]);
+    assertEquals(undefined, a[large_array_size-1]);
+    assertEquals(undefined, a[-1]);
+    assertEquals(large_array_size, a.length);
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  function test_various_stores(a, value_5, value_6, value_7) {
+    assertTrue(%HasFastDoubleElements(a));
+    a[5] = value_5;
+    a[computed_6()] = value_6;
+    a[7] = value_7;
+    assertTrue(%HasFastDoubleElements(a));
+  }
+
+  // Test double and integer values
+  test_various_loads(large_array,
+                     expected_array_value(5),
+                     expected_array_value(6),
+                     expected_array_value(7));
+  test_various_loads(large_array,
+                     expected_array_value(5),
+                     expected_array_value(6),
+                     expected_array_value(7));
+  test_various_loads(large_array,
+                     expected_array_value(5),
+                     expected_array_value(6),
+                     expected_array_value(7));
+  %OptimizeFunctionOnNextCall(test_various_loads);
+  test_various_loads(large_array,
+                     expected_array_value(5),
+                     expected_array_value(6),
+                     expected_array_value(7));
+
+  // Test NaN values
+  test_various_stores(large_array, NaN, -NaN, expected_array_value(7));
+
+  test_various_loads2(large_array,
+                      NaN,
+                      -NaN,
+                      expected_array_value(7));
+  test_various_loads2(large_array,
+                      NaN,
+                      -NaN,
+                      expected_array_value(7));
+  test_various_loads2(large_array,
+                      NaN,
+                      -NaN,
+                      expected_array_value(7));
+  %OptimizeFunctionOnNextCall(test_various_loads2);
+  test_various_loads2(large_array,
+                      NaN,
+                      -NaN,
+                      expected_array_value(7));
+
+  // Test Infinity values
+  test_various_stores(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+
+  test_various_loads3(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+  test_various_loads3(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+  test_various_loads3(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+  %OptimizeFunctionOnNextCall(test_various_loads3);
+  test_various_loads3(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+
+  // Test the hole for the default runtime implementation.
+  delete large_array[5];
+  delete large_array[6];
+  test_various_loads4(large_array,
+                      undefined,
+                      undefined,
+                      expected_array_value(7));
+
+  // Test the keyed load IC implementation when the value is the hole.
+  test_various_stores(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+  test_various_loads5(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+  test_various_loads5(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+  delete large_array[5];
+  delete large_array[6];
+  test_various_loads5(large_array,
+                      undefined,
+                      undefined,
+                      expected_array_value(7));
+  test_various_loads5(large_array,
+                      undefined,
+                      undefined,
+                      expected_array_value(7));
+
+  // Make sure Crankshaft code handles the hole correctly (bailout)
+  test_various_stores(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+  test_various_loads6(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+  test_various_loads6(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+  %OptimizeFunctionOnNextCall(test_various_loads6);
+  test_various_loads6(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+
+  delete large_array[5];
+  delete large_array[6];
+  test_various_loads6(large_array,
+                      undefined,
+                      undefined,
+                      expected_array_value(7));
+
+  // Test stores for non-NaN.
+  %OptimizeFunctionOnNextCall(test_various_stores);
+  test_various_stores(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+
+  test_various_stores(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+
+  test_various_loads6(large_array,
+                      expected_array_value(5),
+                      expected_array_value(6),
+                      expected_array_value(7));
+
+  // Test NaN behavior for stores.
+  test_various_stores(large_array,
+                      NaN,
+                      -NaN,
+                      expected_array_value(7));
+
+  test_various_stores(large_array,
+                      NaN,
+                      -NaN,
+                      expected_array_value(7));
+
+  test_various_loads6(large_array,
+                      NaN,
+                      -NaN,
+                      expected_array_value(7));
+
+  // Test Infinity behavior for stores.
+  test_various_stores(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+
+  test_various_stores(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+
+  test_various_loads6(large_array,
+                      Infinity,
+                      -Infinity,
+                      expected_array_value(7));
+
+  assertTrue(%GetOptimizationStatus(test_various_stores) != 2);
+
+  // Make sure that we haven't converted from fast double.
+  assertTrue(%HasFastDoubleElements(large_array));
+}
+
+testOneArrayType(make_object_like_array);
+testOneArrayType(Array);
+
+var large_array = new Array(large_array_size);
+force_to_fast_double_array(large_array);
+assertTrue(%HasFastDoubleElements(large_array));
+
+// Cause the array to grow beyond it's JSArray length. This will double the
+// size of the capacity and force the array into "slow" dictionary case.
+large_array[5] = Infinity;
+large_array[large_array_size+10001] = 50;
+assertTrue(%HasDictionaryElements(large_array));
+assertEquals(50, large_array[large_array_size+10001]);
+assertEquals(large_array_size+10002, large_array.length);
+assertEquals(Infinity, large_array[5]);
+assertEquals(undefined, large_array[large_array_size-1]);
+assertEquals(undefined, large_array[-1]);
+assertEquals(large_array_size+10002, large_array.length);
+
+// Test dictionary -> double elements -> fast elements.
+var large_array2 = new Array(large_array_size);
+force_to_fast_double_array(large_array2);
+delete large_array2[5];
+
+// Convert back to fast elements and make sure the contents of the array are
+// unchanged.
+large_array2[25] = new Object();
+assertTrue(%HasFastElements(large_array2));
+for (var i= 0; i < approx_dict_to_elements_threshold; i += 500 ) {
+  if (i != 25 && i != 5) {
+    assertEquals(expected_array_value(i), large_array2[i]);
+  }
+}
+assertEquals(undefined, large_array2[5]);
+assertEquals(undefined, large_array2[large_array_size-1]);
+assertEquals(undefined, large_array2[-1]);
+assertEquals(large_array_size, large_array2.length);
+
+// Make sure it's possible to change the array's length and that array is still
+// intact after the resize.
+var large_array3 = new Array(large_array_size);
+force_to_fast_double_array(large_array3);
+large_array3.length = 60000;
+assertEquals(60000, large_array3.length);
+assertEquals(undefined, large_array3[60000]);
+assertTrue(%HasFastDoubleElements(large_array3));
+assertEquals(expected_array_value(5), large_array3[5]);
+assertEquals(expected_array_value(6), large_array3[6]);
+assertEquals(expected_array_value(7), large_array3[7]);
+assertEquals(expected_array_value(large_array3.length-1),
+             large_array3[large_array3.length-1]);
+assertEquals(undefined, large_array3[large_array_size-1]);
+assertEquals(undefined, large_array3[-1]);
+gc();
+
+for (var i= 0; i < large_array3.length; i += 501 ) {
+  assertEquals(expected_array_value(i), large_array3[i]);
+}
+
+large_array3.length = 25;
+assertEquals(25, large_array3.length);
+assertTrue(%HasFastDoubleElements(large_array3));
+assertEquals(undefined, large_array3[25]);
+assertEquals(expected_array_value(5), large_array3[5]);
+assertEquals(expected_array_value(6), large_array3[6]);
+assertEquals(expected_array_value(7), large_array3[7]);
+assertEquals(expected_array_value(large_array3.length-1),
+             large_array3[large_array3.length-1]);
+assertEquals(undefined, large_array3[large_array_size-1]);
+assertEquals(undefined, large_array3[-1]);
+gc();
+
+for (var i= 0; i < large_array3.length; ++i) {
+  assertEquals(expected_array_value(i), large_array3[i]);
+}
+
+large_array3.length = 100;
+assertEquals(100, large_array3.length);
+large_array3[95] = 95;
+assertTrue(%HasFastDoubleElements(large_array3));
+assertEquals(undefined, large_array3[100]);
+assertEquals(95, large_array3[95]);
+assertEquals(expected_array_value(5), large_array3[5]);
+assertEquals(expected_array_value(6), large_array3[6]);
+assertEquals(expected_array_value(7), large_array3[7]);
+assertEquals(undefined, large_array3[large_array3.length-1]);
+assertEquals(undefined, large_array3[large_array_size-1]);
+assertEquals(undefined, large_array3[-1]);
+gc();
+
+// Test apply on arrays backed by double elements.
+function called_by_apply(arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
+  assertEquals(expected_array_value(0), arg0);
+  assertEquals(NaN, arg1);
+  assertEquals(-NaN, arg2);
+  assertEquals(Infinity, arg3);
+  assertEquals(-Infinity, arg4);
+  assertEquals(expected_array_value(5), arg5);
+}
+
+large_array3[1] = NaN;
+large_array3[2] = -NaN;
+large_array3[3] = Infinity;
+large_array3[4] = -Infinity;
+
+function call_apply() {
+  assertTrue(%HasFastDoubleElements(large_array3));
+  called_by_apply.apply({}, large_array3);
+}
+
+call_apply();
+call_apply();
+call_apply();
+%OptimizeFunctionOnNextCall(call_apply);
+call_apply();
+call_apply();
+call_apply();
+
+function test_for_in() {
+  // Due to previous tests, keys 0..25 and 95 should be present.
+  next_expected = 0;
+  assertTrue(%HasFastDoubleElements(large_array3));
+  for (x in large_array3) {
+    assertTrue(next_expected++ == x);
+    if (next_expected == 25) {
+      next_expected = 95;
+    }
+  }
+  assertTrue(next_expected == 96);
+}
+
+test_for_in();
+test_for_in();
+test_for_in();
+%OptimizeFunctionOnNextCall(test_for_in);
+test_for_in();
+test_for_in();
+test_for_in();
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index e281e67..c62d770 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -206,6 +206,10 @@
 # This section is for tests that fail in both V8 and JSC.  Thus they
 # have been determined to be incompatible between Mozilla and V8/JSC.
 
+# Fail because it calls builtins as functions and do not expect the
+# builtin to have undefined as the receiver.
+ecma/String/15.5.4.6-2: FAIL_OK
+
 # Fail because of toLowerCase and toUpperCase conversion.
 ecma/String/15.5.4.11-2: FAIL_OK
 ecma/String/15.5.4.11-5: FAIL_OK
@@ -325,11 +329,6 @@
 js1_5/Regress/regress-320119: FAIL_OK
 
 
-# We do not recognize a multiline comment as newline character.
-# We are compatible with JSC.
-ecma_3/LexicalConventions/7.4-01: FAIL_OK
-
-
 # No support for toSource().
 js1_5/Regress/regress-248444: FAIL_OK
 js1_5/Regress/regress-313967-01: FAIL_OK
@@ -432,6 +431,14 @@
 js1_2/regexp/string_split: FAIL_OK
 
 
+# RegExps are not callable.
+js1_2/regexp/simple_form: FAIL_OK
+js1_2/regexp/regress-6359: FAIL_OK
+js1_2/regexp/regress-9141: FAIL_OK
+js1_5/Regress/regress-224956: FAIL_OK
+js1_5/Regress/regress-325925: FAIL_OK
+ecma_2/RegExp/regress-001: FAIL_OK
+
 # We do not check for bad surrogate pairs when quoting strings.
 js1_5/Regress/regress-315974: FAIL_OK
 
@@ -459,10 +466,6 @@
 js1_5/extensions/regress-452178: FAIL_OK
 
 
-# 'native' *is* a keyword in V8.
-js1_5/Regress/regress-240317: FAIL_OK
-
-
 # Requires Mozilla-specific strict mode or options() function.
 ecma_3/Object/8.6.1-01: FAIL_OK
 js1_5/Exceptions/regress-315147: FAIL_OK
@@ -528,6 +531,12 @@
 js1_5/LexicalConventions/regress-343675: FAIL_OK
 
 
+# Tests if future reserved keywords of ECMA-262, edition 3 emit warnings. We
+# implement the edition 5 behaviour and fail on use of edition 5 future reserved
+# keywords as identifiers.
+js1_5/Regress/regress-240317: FAIL_OK
+
+
 # Unsupported list comprehensions: [ ... for ... ] and for each.
 js1_5/Regress/regress-352009: FAIL_OK
 js1_5/Regress/regress-349648: FAIL_OK
@@ -587,25 +596,6 @@
 js1_5/Array/regress-350256-02: FAIL
 
 
-# This fails because 'delete arguments[i]' does not disconnect the
-# argument from the arguments array.  See issue #900066.
-ecma_3/Function/regress-137181: FAIL
-
-
-# 'export' and 'import' are not keywords in V8.
-ecma_2/Exceptions/lexical-010: FAIL
-ecma_2/Exceptions/lexical-022: FAIL
-
-
-# Requires Mozilla-specific strict mode.
-ecma_2/Exceptions/lexical-011: FAIL
-ecma_2/Exceptions/lexical-014: FAIL
-ecma_2/Exceptions/lexical-016: FAIL
-ecma_2/Exceptions/lexical-021: FAIL
-ecma_2/LexicalConventions/keywords-001: FAIL
-js1_5/Regress/regress-306633: FAIL
-
-
 # This test seems designed to fail (it produces a 700Mbyte string).
 # We fail on out of memory.  The important thing is not to crash.
 js1_5/Regress/regress-303213: FAIL || TIMEOUT if $mode == debug
@@ -675,7 +665,6 @@
 js1_5/extensions/regress-352094: FAIL_OK
 js1_5/extensions/regress-352261: FAIL_OK
 js1_5/extensions/regress-352281: FAIL_OK
-js1_5/extensions/regress-352372: FAIL_OK
 js1_5/extensions/regress-352455: FAIL_OK
 js1_5/extensions/regress-352604: FAIL_OK
 js1_5/extensions/regress-353214: FAIL_OK
diff --git a/test/preparser/strict-identifiers.pyt b/test/preparser/strict-identifiers.pyt
index a0f4612..72808e2 100644
--- a/test/preparser/strict-identifiers.pyt
+++ b/test/preparser/strict-identifiers.pyt
@@ -164,6 +164,20 @@
   x = {get $id() {}, set $id(value) {}};
 """)
 
+identifier_name_source = """
+  var x = {$id: 42};
+  x = {get $id() {}, set $id(value) {}};
+  x.$id = 42;
+  function foo() { "use strict;" }
+  x = {$id: 42};
+  x = {get $id() {}, set $id(value) {}};
+  x.$id = 42;
+"""
+
+identifier_name = Template("identifier_name-$id", identifier_name_source)
+identifier_name_strict = StrictTemplate("identifier_name_strict-$id",
+                                        identifier_name_source)
+
 # ----------------------------------------------------------------------
 # Run tests
 
@@ -189,8 +203,12 @@
 # Reserved words just throw the same exception in all cases
 # (with "const" being special, as usual).
 for reserved_word in reserved_words + strict_reserved_words:
-  message = "strict_reserved_word"
-  if (reserved_word == "const"): message = "unexpected_token"
+  if (reserved_word in strict_reserved_words):
+    message = "strict_reserved_word"
+  elif (reserved_word == "const"):
+    message = "unexpected_token"
+  else:
+    message = "reserved_word"
   arg_name_own({"id":reserved_word}, message)
   arg_name_nested({"id":reserved_word}, message)
   setter_arg({"id": reserved_word}, message)
@@ -205,5 +223,11 @@
   postfix_var({"id":reserved_word, "op":"++", "opname":"inc"}, message)
   postfix_var({"id":reserved_word, "op":"--", "opname":"dec"}, message)
   read_var({"id": reserved_word}, message)
+  identifier_name({"id": reserved_word}, None);
+  identifier_name_strict({"id": reserved_word}, None);
 
 
+# Future reserved words in strict mode behave like normal identifiers
+# in a non strict context.
+for reserved_word in strict_reserved_words:
+  non_strict_use({"id": id}, None)
diff --git a/test/sputnik/README b/test/sputnik/README
index 50d721f..3656634 100644
--- a/test/sputnik/README
+++ b/test/sputnik/README
@@ -1,6 +1,6 @@
 To run the sputniktests you must check out the test suite from
 googlecode.com.  The test expectations are currently relative to
-version 94. To get the tests run the following command within
+version 97. To get the tests run the following command within
 v8/test/sputnik/
 
-  svn co http://sputniktests.googlecode.com/svn/trunk/ -r94 sputniktests
+  svn co http://sputniktests.googlecode.com/svn/trunk/ -r97 sputniktests
diff --git a/test/sputnik/sputnik.status b/test/sputnik/sputnik.status
index f322840..82d8a61 100644
--- a/test/sputnik/sputnik.status
+++ b/test/sputnik/sputnik.status
@@ -28,15 +28,16 @@
 prefix sputnik
 def FAIL_OK = FAIL, OKAY
 
-##################### DELIBERATE INCOMPATIBILITIES #####################
+############################### BUGS ###################################
 
-# 900066: Deleting elements in .arguments should disconnect the
-# element from the actual arguments.  Implementing this is nontrivial
-# and we have no indication that anything on the web depends on this
-# feature.
-S13_A13_T1: FAIL_OK
-S13_A13_T2: FAIL_OK
-S13_A13_T3: FAIL_OK
+# A bound function should fail on access to 'caller' and 'arguments'.
+S15.3.4.5_A1: FAIL
+S15.3.4.5_A2: FAIL
+
+# '__proto__' should be treated as a normal property in JSON.
+S15.12.2_A1: FAIL
+
+##################### DELIBERATE INCOMPATIBILITIES #####################
 
 # This tests precision of trignometric functions.  We're slightly off
 # from the implementation in libc (~ 1e-17) but it's not clear if we
@@ -48,12 +49,9 @@
 # We allow calls to regexp exec() with no arguments to fail for
 # compatibility reasons.
 S15.10.6.2_A1_T16: FAIL_OK
+S15.10.6.2_A12: FAIL_OK
 S15.10.6.3_A1_T16: FAIL_OK
 
-# We allow regexps to be called as functions for compatibility reasons.
-S15.10.7_A1_T1: FAIL_OK
-S15.10.7_A1_T2: FAIL_OK
-
 # We are silent in some regexp cases where the spec wants us to give
 # errors, for compatibility.
 S15.10.2.11_A1_T2: FAIL
@@ -101,22 +99,14 @@
 S7.8.4_A4.3_T5: FAIL_OK
 S7.8.4_A7.2_T5: FAIL_OK
 
-# We allow some keywords to be used as identifiers
-S7.5.3_A1.26: FAIL_OK
+# We allow some keywords to be used as identifiers.
+S7.5.3_A1.15: FAIL_OK
 S7.5.3_A1.18: FAIL_OK
-S7.5.3_A1.27: FAIL_OK
-S7.5.3_A1.5: FAIL_OK
-S7.5.3_A1.9: FAIL_OK
-S7.5.3_A1.10: FAIL_OK
-S7.5.3_A1.11: FAIL_OK
-# native
-S7.5.3_A1.20: FAIL_OK
 S7.5.3_A1.21: FAIL_OK
 S7.5.3_A1.22: FAIL_OK
 S7.5.3_A1.23: FAIL_OK
-S7.5.3_A1.15: FAIL_OK
 S7.5.3_A1.24: FAIL_OK
-S7.5.3_A1.16: FAIL_OK
+S7.5.3_A1.26: FAIL_OK
 
 # This checks for non-262 behavior
 S12.6.4_A14_T1: PASS || FAIL_OK
@@ -146,16 +136,8 @@
 S12.6.4_D1: PASS || FAIL_OK
 
 # We allow function declarations within statements
-S12.5_A9_T1: FAIL_OK
-S12.5_A9_T2: FAIL_OK
-# S12.6.2_A13_T3: FAIL_OK
-# S12.5_A9_T3: FAIL_OK
-# S12.6.1_A13_T3: FAIL_OK
-S12.1_A1: FAIL_OK
 S12.6.2_A13_T1: FAIL_OK
 S12.6.2_A13_T2: FAIL_OK
-S12.6.1_A13_T1: FAIL_OK
-S12.6.1_A13_T2: FAIL_OK
 S12.6.4_A13_T1: FAIL_OK
 S12.6.4_A13_T2: FAIL_OK
 #S12.6.4_A13_T3: FAIL_OK
@@ -179,6 +161,23 @@
 S9.9_A1: FAIL_OK
 S9.9_A2: FAIL_OK
 
+# Calls builtins without an explicit receiver which means that
+# undefined is passed to the builtin. The tests expect the global
+# object to be passed which was true in ES3 but not in ES5.
+S11.1.1_A2: FAIL_OK
+S15.5.4.4_A1_T3: FAIL_OK
+S15.5.4.5_A1_T3: FAIL_OK
+S15.5.4.6_A1_T3: FAIL_OK
+S15.5.4.7_A1_T3: FAIL_OK
+S15.5.4.8_A1_T3: FAIL_OK
+S15.5.4.9_A1_T3: FAIL_OK
+S15.5.4.10_A1_T3: FAIL_OK
+S15.5.4.11_A1_T3: FAIL_OK
+S15.5.4.12_A1_T3: FAIL_OK
+S15.5.4.13_A1_T3: FAIL_OK
+S15.5.4.14_A1_T3: FAIL_OK
+S15.5.4.15_A1_T3: FAIL_OK
+
 ##################### SKIPPED TESTS #####################
 
 # These tests take a looong time to run in debug mode.
@@ -244,12 +243,6 @@
 S15.9.5.8_A1_T2: FAIL_OK
 S15.9.5.9_A1_T2: FAIL_OK
 
-# Regexps have type "function", not "object".
-S11.4.3_A3.6: FAIL_OK
-S15.10.7_A3_T2: FAIL_OK
-S15.10.7_A3_T1: FAIL_OK
-
-
 [ $arch == arm ]
 
 # BUG(3251225): Tests that timeout with --nocrankshaft.
diff --git a/test/test262/README b/test/test262/README
index 6d9e56e..ea6b4a7 100644
--- a/test/test262/README
+++ b/test/test262/README
@@ -4,11 +4,11 @@
 
   http://hg.ecmascript.org/tests/test262
 
-at revision 62 as 'data' in this directory.  Using later version
+at revision 128 as 'data' in this directory.  Using later version
 may be possible but the tests are only known to pass (and indeed run)
 with that revision.
 
-hg clone -r 62 http://hg.ecmascript.org/tests/test262 data
+hg clone -r 128 http://hg.ecmascript.org/tests/test262 data
 
 If you do update to a newer revision you may have to change the test
 harness adapter code since it uses internal functionality from the
diff --git a/test/test262/harness-adapt.js b/test/test262/harness-adapt.js
index bc10a9d..52b5de7 100644
--- a/test/test262/harness-adapt.js
+++ b/test/test262/harness-adapt.js
@@ -43,7 +43,7 @@
   }
 
   Test262Error.prototype.toString = function() {
-    return this.result + " " + error;
+    return this.result + " " + this.error;
   }
 
   function registerTest(test) {
diff --git a/test/test262/test262.status b/test/test262/test262.status
index 754984d..8cee210 100644
--- a/test/test262/test262.status
+++ b/test/test262/test262.status
@@ -46,24 +46,12 @@
 # Unanalyzed failures which may be bugs or deliberate differences
 #
 
-# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
-#      Names in UTF8: class (class)
-7.6-30: FAIL
-# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
-#      Names in UTF8: extends (extends)
-7.6-31: FAIL
-# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
-#      Names in UTF8: \u0065\u006e\u0075\u006d (enum)
-7.6-32: FAIL
-# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
-#      Names in UTF8: \u0073uper (super)
-7.6-33: FAIL
-# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
-#      Names in UTF8: expor\u0074 (export)
-7.6-35: FAIL
-# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
-#      Names in UTF8: \u0069\u006d\u0070\u006f\u0072\u0074 (import)
-7.6-36: FAIL
+# Bug? Strict Mode - TypeError is thrown when changing the value of a Value
+#      Property of the Global Object under strict mode (NaN)
+10.2.1.1.3-4-16-s: FAIL
+# Bug? Strict Mode - TypeError is thrown when changing the value of a Value
+#      Property of the Global Object under strict mode (undefined)
+10.2.1.1.3-4-18-s: FAIL
 # Invalid test: https://bugs.ecmascript.org/show_bug.cgi?id=76
 10.4.2-2-c-1: FAIL
 # BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
@@ -93,6 +81,12 @@
 # BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
 #      enforced when using Less-than-or-equal operator: valueOf <= valueOf
 11.8.3-5: FAIL
+# Bug? simple assignment throws TypeError if LeftHandSide is a readonly property
+#      in strict mode (Global.undefined)
+11.13.1-4-27-s: FAIL
+# Bug? simple assignment throws TypeError if LeftHandSide is a readonly property
+#      in strict mode (Global.Infinity)
+11.13.1-4-3-s: FAIL
 # BUG: Global.NaN is a data property with default attribute values
 15.1.1.1-0: FAIL
 # BUG: Global.Infinity is a data property with default attribute values
@@ -123,35 +117,6 @@
 # BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
 #      for properties on built-ins (RegExp.prototype.multiline)
 15.2.3.3-4-215: FAIL
-# Bug? Object.create - 'set' property of one property in 'Properties'
-#      is not present (8.10.5 step 8)
-# V8 throws.
-15.2.3.5-4-267: FAIL
-# Bug? Object.create - 'set' property of one property in 'Properties'
-#      is undefined (8.10.5 step 8.b)
-# V8 throws.
-15.2.3.5-4-292: FAIL
-# Bug? Object.defineProperty - 'set' property in 'Attributes' is not
-#      present (8.10.5 step 8)
-# V8 throws.
-15.2.3.6-3-236: FAIL
-# Bug? Object.defineProperty - 'set' property in 'Attributes' is own
-#      accessor property without a get function (8.10.5 step 8.a)
-# V8 throws.
-15.2.3.6-3-245: FAIL
-# Bug? Object.defineProperty - 'set' property in 'Attributes' is own
-#      accessor property(without a get function) that overrides an inherited
-#      accessor property (8.10.5 step 8.a)
-# V8 throws.
-15.2.3.6-3-246: FAIL
-# Bug? Object.defineProperty - 'set' property in 'Attributes' is an
-#      inherited accessor property without a get function (8.10.5 step 8.a)
-# V8 throws.
-15.2.3.6-3-247: FAIL
-# Bug? Object.defineProperty - value of 'set' property in 'Attributes'
-#      is undefined (8.10.5 step 8.b)
-# V8 throws.
-15.2.3.6-3-261: FAIL
 # Bug? Object.defineProperty - Update [[Enumerable]] attribute of 'name'
 #      property to true successfully when [[Enumerable]] attribute of 'name'
 #      is false and [[Configurable]] attribute of 'name' is true,  the 'desc'
@@ -464,11 +429,6 @@
 #      values of 'name' (15.4.5.1 step 4.c)
 15.2.3.6-4-209: FAIL
 # Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-#      property, 'name' is accessor property and assignment to the accessor
-#      property, fails to convert accessor property from accessor property to
-#      data property (15.4.5.1 step 4.c)
-15.2.3.6-4-243-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
 #      property, name is accessor property and 'desc' is accessor descriptor,
 #      test updating the [[Enumerable]] attribute value of 'name' (15.4.5.1 step
 #      4.c)
@@ -493,18 +453,6 @@
 #      (15.4.5.1 step 4.e.ii)
 15.2.3.6-4-276: FAIL
 # Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is own property which is defined in both
-#      [[ParameterMap]] of 'O' and 'O', and is deleted afterwards, and 'desc' is
-#      data descriptor, test 'name' is redefined in 'O' with all correct
-#      attribute values (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.6-4-289-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is own property which is defined in both
-#      [[ParameterMap]] of 'O' and 'O', is deleted afterwards, and 'desc' is
-#      accessor descriptor, test 'name' is redefined in 'O' with all correct
-#      attribute values (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.6-4-290-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
 #      formal parameters, 'name' is own accessor property of 'O' which is also
 #      defined in [[ParameterMap]] of 'O', and 'desc' is accessor descriptor,
 #      test updating multiple attribute values of 'name' (10.6
@@ -516,6 +464,19 @@
 #      step 3)
 15.2.3.6-4-291: FAIL
 # Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+#      formal parameters, 'name' is own property of 'O' which is also defined in
+#      [[ParameterMap]] of 'O', and 'desc' is data descriptor, test updating
+#      multiple attribute values of 'name' (10.6 [[DefineOwnProperty]] step 3
+#      and 5.b)
+15.2.3.6-4-292-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+#      formal parameters, 'name' is own data property of 'O' which is also
+#      defined in [[ParameterMap]] of 'O', test TypeError is thrown when
+#      updating the [[Value]] attribute value of 'name' which is defined as
+#      unwritable and non-configurable (10.6 [[DefineOwnProperty]] step 4 and
+#      step 5b)
+15.2.3.6-4-293-2: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
 #      formal parameters, 'name' is own data property of 'O' which is also
 #      defined in [[ParameterMap]] of 'O', test TypeError is not thrown when
 #      updating the [[Value]] attribute value of 'name' which is defined as
@@ -523,39 +484,44 @@
 #      5.b)
 15.2.3.6-4-293-3: FAIL
 # Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is own accessor property of 'O' which is also
+#      formal parameters, 'name' is own data property of 'O' which is also
 #      defined in [[ParameterMap]] of 'O', test TypeError is thrown when
-#      updating the [[Get]] attribute value of 'name' which is defined as
-#      non-configurable (10.6 [[DefineOwnProperty]] step 4 and step 5a)
-15.2.3.6-4-297-1: FAIL
+#      updating the [[Writable]] attribute value of 'name' which is defined as
+#      non-configurable (10.6 [[DefineOwnProperty]] step 4 and 5b)
+15.2.3.6-4-294-1: FAIL
 # Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is own accessor property of 'O' which is also
-#      defined in [[ParameterMap]] of 'O', test TypeError is thrown when
-#      updating the [[Set]] attribute value of 'name' which is defined as
-#      non-configurable (10.6 [[DefineOwnProperty]] steps 4 and 5a)
-15.2.3.6-4-298-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is own accessor property of 'O' which is also
+#      formal parameters, 'name' is own data property of 'O' which is also
 #      defined in [[ParameterMap]] of 'O', test TypeError is thrown when
 #      updating the [[Enumerable]] attribute value of 'name' which is defined as
-#      non-configurable (10.6 [[DefineOwnProperty]] steps 4 and 5a)
-15.2.3.6-4-299-1: FAIL
+#      non-configurable (10.6 [[DefineOwnProperty]] step 4 and step 5b)
+15.2.3.6-4-295-1: FAIL
 # Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is an index named property of 'O', and 'desc'
-#      is data descriptor, test 'name' is defined in 'O' with all correct
-#      attribute values (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.6-4-301-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is an index named property of 'O' but not
-#      defined in [[ParameterMap]] of 'O', and 'desc' is accessor descriptor,
-#      test 'name' is defined in 'O' with all correct attribute values (10.6
-#      [[DefineOwnProperty]] step 3 and step 5a)
-15.2.3.6-4-302-1: FAIL
+#      formal parameters, 'name' is own data property of 'O' which is also
+#      defined in [[ParameterMap]] of 'O', test TypeError is thrown when
+#      updating the [[Configurable]] attribute value of 'name' which is defined
+#      as non-configurable (10.6 [[DefineOwnProperty]] step 4 and step 5b)
+15.2.3.6-4-296-1: FAIL
 # Bug? Object.defineProperty - 'O' is an Arguments object, 'name' is an index
 #      named accessor property of 'O' but not defined in [[ParameterMap]] of
 #      'O', and 'desc' is accessor descriptor, test updating multiple attribute
 #      values of 'name' (10.6 [[DefineOwnProperty]] step 3)
 15.2.3.6-4-303: FAIL
+# Bug? ES5 Attributes - indexed property 'P' with attributes [[Writable]]: true,
+#      [[Enumerable]]: true, [[Configurable]]: false is writable using simple
+#      assignment, 'O' is an Arguments object
+15.2.3.6-4-333-11: FAIL
+# Bug? ES5 Attributes - Updating indexed data property 'P' whose attributes are
+#      [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true to an
+#      accessor property, 'A' is an Array object (8.12.9 - step 9.b.i)
+15.2.3.6-4-360-1: FAIL
+# Bug? ES5 Attributes - Updating indexed data property 'P' whose attributes are
+#      [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true to an
+#      accessor property, 'O' is an Arguments object (8.12.9 - step 9.b.i)
+15.2.3.6-4-360-6: FAIL
+# Bug? ES5 Attributes - Updating indexed data property 'P' whose attributes are
+#      [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true to an
+#      accessor property, 'O' is the global object (8.12.9 - step 9.b.i)
+15.2.3.6-4-360-7: FAIL
 # Bug? ES5 Attributes - [[Value]] attribute of data property is the activex host
 #      object
 15.2.3.6-4-401: FAIL
@@ -575,17 +541,6 @@
 #      prototype has a property with the same name and [[Writable]] set to
 #      false(Function.prototype.bind)
 15.2.3.6-4-420: FAIL
-# Bug? ES5 Attributes - Fail to add property into object (Number instance)
-15.2.3.6-4-581: FAIL
-# Bug? ES5 Attributes - Fail to update value of property into of [[Proptotype]]
-#      internal property (JSON)
-15.2.3.6-4-586: FAIL
-# Bug? ES5 Attributes - Fail to update value of property of [[Proptotype]]
-#      internal property (Object.create)
-15.2.3.6-4-591: FAIL
-# Bug? ES5 Attributes - Fail to update value of property into of [[Proptotype]]
-#      internal property (Function.prototype.bind)
-15.2.3.6-4-596: FAIL
 # Bug? ES5 Attributes - all attributes in Array.prototype.indexOf are correct
 15.2.3.6-4-612: FAIL
 # Bug? ES5 Attributes - all attributes in Object.lastIndexOf are correct
@@ -611,20 +566,6 @@
 15.2.3.6-4-623: FAIL
 # Bug? ES5 Attributes - all attributes in Date.prototype.toJSON are correct
 15.2.3.6-4-624: FAIL
-# Bug? Object.defineProperties - argument 'Properties' is an Error object
-#      props.description = obj1;
-15.2.3.7-2-15: FAIL
-# Bug? Object.defineProperties - 'Properties' is an Error object which
-#      implements its own [[Get]] method to get enumerable own property
-#      props.description = obj1;
-15.2.3.7-5-a-16: FAIL
-# Bug? Object.defineProperties - 'set' property of 'descObj' is not present
-#      (8.10.5 step 8)
-15.2.3.7-5-b-227: FAIL
-# Bug? Object.defineProperties - 'descObj' is an Error object which implements
-#      its own [[Get]] method to get 'set' property (8.10.5 step 8.a)
-#      descObj.description = { value: 11 };
-15.2.3.7-5-b-248: FAIL
 # Bug? Object.defineProperties - 'O' is an Array, test the length property of
 #      'O' is own data property (15.4.5.1 step 1)
 15.2.3.7-6-a-112: FAIL
@@ -922,23 +863,48 @@
 #      'desc' is accessor descriptor, test updating multiple attribute values of
 #      'P' (10.6 [[DefineOwnProperty]] step 3)
 15.2.3.7-6-a-280: FAIL
+# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
+#      property of 'O' which is also defined in [[ParameterMap]] of 'O', and
+#      'desc' is data descriptor, test updating multiple attribute values of 'P'
+#      (10.6 [[DefineOwnProperty]] step 3)
+15.2.3.7-6-a-281: FAIL
+# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
+#      property of 'O' which is also defined in [[ParameterMap]] of 'O', test
+#      TypeError is thrown when updating the [[Value]] attribute value of 'P'
+#      whose writable and configurable attributes are false (10.6
+#      [[DefineOwnProperty]] step 4)
+15.2.3.7-6-a-282: FAIL
+# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
+#      property of 'O' which is also defined in [[ParameterMap]] of 'O', test
+#      TypeError is thrown when updating the [[Writable]] attribute value of 'P'
+#      which is defined as non-configurable (10.6 [[DefineOwnProperty]] step 4)
+15.2.3.7-6-a-283: FAIL
+# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
+#      property of 'O' which is also defined in [[ParameterMap]] of 'O', test
+#      TypeError is thrown when updating the [[Enumerable]] attribute value of
+#      'P' which is defined as non-configurable (10.6 [[DefineOwnProperty]] step
+#      4)
+15.2.3.7-6-a-284: FAIL
+# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
+#      property of 'O' which is also defined in [[ParameterMap]] of 'O', test
+#      TypeError is thrown when updating the [[Configurable]] attribute value of
+#      'P' which is defined as non-configurable (10.6 [[DefineOwnProperty]] step
+#      4)
+15.2.3.7-6-a-285: FAIL
 # Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is an array
 #      index named accessor property of 'O' but not defined in [[ParameterMap]]
 #      of 'O', and 'desc' is accessor descriptor, test updating multiple
 #      attribute values of 'P' (10.6 [[DefineOwnProperty]] step 3)
 15.2.3.7-6-a-292: FAIL
-# Bug? Object.prototype.toString - '[object Undefined]' will be returned when
-#      'this' value is undefined
-15.2.4.2-1-1: FAIL
-# Bug? Object.prototype.toString - '[object Undefined]' will be returned when
-#      'this' value is undefined
-15.2.4.2-1-2: FAIL
-# Bug? Object.prototype.toString - '[object Null]' will be returned when 'this'
-#      value is null
-15.2.4.2-2-1: FAIL
-# Bug? Object.prototype.toString - '[object Null]' will be returned when 'this'
-#      value is null
-15.2.4.2-2-2: FAIL
+# Bug? Strict Mode - 'this' value is a string which cannot be converted to
+#      wrapper objects when the function is called with an array of arguments
+15.3.4.3-1-s: FAIL
+# Bug? Strict Mode - 'this' value is a number which cannot be converted to
+#      wrapper objects when the function is called with an array of arguments
+15.3.4.3-2-s: FAIL
+# Bug? Strict Mode - 'this' value is a boolean which cannot be converted to
+#      wrapper objects when the function is called with an array of arguments
+15.3.4.3-3-s: FAIL
 # Bug? Function.prototype.bind - [[Get]] attribute of 'caller' property in 'F'
 #      is thrower
 15.3.4.5-20-2: FAIL
@@ -951,16 +917,6 @@
 # Bug? Function.prototype.bind - [[Set]] attribute of 'arguments' property in
 #      'F' is thrower
 15.3.4.5-21-3: FAIL
-# Bug? Array.prototype.concat will concat an Array when index property
-#      (read-only) exists in Array.prototype (Step 5.c.i)
-15.4.4.4-5-c-i-1: FAIL
-# Bug? Array.prototype.indexOf applied to undefined throws a TypeError
-15.4.4.14-1-1: FAIL
-# Bug? Array.prototype.indexOf applied to null throws a TypeError
-15.4.4.14-1-2: FAIL
-# Bug? Array.prototype.indexOf - side effects produced by step 1 are visible
-#      when an exception occurs
-15.4.4.14-5-28: FAIL
 # Bug? Array.prototype.indexOf - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.14-9-a-19: FAIL
@@ -983,13 +939,6 @@
 # Bug? Array.prototype.indexOf - terminates iteration on unhandled exception on
 #      an Array
 15.4.4.14-9-b-i-30: FAIL
-# Bug? Array.prototype.lastIndexOf applied to undefined throws a TypeError
-15.4.4.15-1-1: FAIL
-# Bug? Array.prototype.lastIndexOf applied to null throws a TypeError
-15.4.4.15-1-2: FAIL
-# Bug? Array.prototype.lastIndexOf - side effects produced by step 1 are visible
-#      when an exception occurs
-15.4.4.15-5-28: FAIL
 # Bug? Array.prototype.lastIndexOf - deleting property of prototype causes
 #      prototype index property not to be visited on an Array
 15.4.4.15-8-a-14: FAIL
@@ -1011,6 +960,12 @@
 # Bug? Array.prototype.lastIndexOf terminates iteration on unhandled exception
 #      on an Array
 15.4.4.15-8-b-i-30: FAIL
+# Bug? Array.prototype.every applied to boolean primitive
+15.4.4.16-1-3: FAIL
+# Bug? Array.prototype.every applied to number primitive
+15.4.4.16-1-5: FAIL
+# Bug? Array.prototype.every applied to string primitive
+15.4.4.16-1-7: FAIL
 # Bug? Array.prototype.every - side effects produced by step 2 are visible when
 #      an exception occurs
 15.4.4.16-4-8: FAIL
@@ -1048,6 +1003,12 @@
 # Bug? Array.prototype.every - element changed by getter on previous iterations
 #      is observed on an Array
 15.4.4.16-7-c-i-28: FAIL
+# Bug? Array.prototype.some applied to boolean primitive
+15.4.4.17-1-3: FAIL
+# Bug? Array.prototype.some applied to number primitive
+15.4.4.17-1-5: FAIL
+# Bug? Array.prototype.some applied to applied to string primitive
+15.4.4.17-1-7: FAIL
 # Bug? Array.prototype.some - side effects produced by step 2 are visible when
 #      an exception occurs
 15.4.4.17-4-8: FAIL
@@ -1085,6 +1046,12 @@
 # Bug? Array.prototype.some - element changed by getter on previous iterations
 #      is observed on an Array
 15.4.4.17-7-c-i-28: FAIL
+# Bug? Array.prototype.forEach applied to boolean primitive
+15.4.4.18-1-3: FAIL
+# Bug? Array.prototype.forEach applied to number primitive
+15.4.4.18-1-5: FAIL
+# Bug? Array.prototype.forEach applied to string primitive
+15.4.4.18-1-7: FAIL
 # Bug? Array.prototype.forEach - side effects produced by step 2 are visible
 #      when an exception occurs
 15.4.4.18-4-8: FAIL
@@ -1122,9 +1089,12 @@
 # Bug? Array.prototype.forEach - element changed by getter on previous
 #      iterations is observed on an Array
 15.4.4.18-7-c-i-28: FAIL
-# Bug? Array.prototype.map - applied to Array-like object, 'length' is an own
-#      data property that overrides an inherited accessor property
-15.4.4.19-2-5: FAIL
+# Bug? Array.prototype.map - applied to boolean primitive
+15.4.4.19-1-3: FAIL
+# Bug? Array.prototype.map - applied to number primitive
+15.4.4.19-1-5: FAIL
+# Bug? Array.prototype.map - applied to string primitive
+15.4.4.19-1-7: FAIL
 # Bug? Array.prototype.map - Side effects produced by step 2 are visible when an
 #      exception occurs
 15.4.4.19-4-8: FAIL
@@ -1162,33 +1132,12 @@
 # Bug? Array.prototype.map - element changed by getter on previous iterations is
 #      observed on an Array
 15.4.4.19-8-c-i-28: FAIL
-# Bug? Array.prototype.filter - value of 'length' is a number (value is
-#      negative)
-15.4.4.20-3-7: FAIL
-# Bug? Array.prototype.filter - value of 'length' is a number (value is
-#      Infinity)
-# V8 timeout
-15.4.4.20-3-8: SKIP
-# Bug? Array.prototype.filter - 'length' is a string containing a negative
-#      number
-15.4.4.20-3-12: FAIL
-# Bug? Array.prototype.filter - 'length' is a string containing a decimal number
-15.4.4.20-3-13: FAIL
-# Bug? Array.prototype.filter - 'length' is a string containing +/-Infinity
-15.4.4.20-3-14: SKIP
-# Bug? Array.prototype.filter - value of 'length' is a positive non-integer,
-#      ensure truncation occurs in the proper direction
-# V8 timeout
-15.4.4.20-3-24: FAIL
-# Bug? Array.prototype.filter - value of 'length' is a negative non-integer,
-#      ensure truncation occurs in the proper direction
-15.4.4.20-3-25: FAIL
-# Bug? Array.prototype.filter - value of 'length' is boundary value (2^32)
-# V8 timeout
-15.4.4.20-3-28: SKIP
-# Bug? Array.prototype.filter - value of 'length' is boundary value (2^32 + 1)
-# V8 timeout
-15.4.4.20-3-29: SKIP
+# Bug? Array.prototype.filter applied to boolean primitive
+15.4.4.20-1-3: FAIL
+# Bug? Array.prototype.filter applied to number primitive
+15.4.4.20-1-5: FAIL
+# Bug? Array.prototype.filter applied to string primitive
+15.4.4.20-1-7: FAIL
 # Bug? Array.prototype.filter - side effects produced by step 2 are visible when
 #      an exception occurs
 15.4.4.20-4-8: FAIL
@@ -1207,9 +1156,6 @@
 # Bug? Array.prototype.filter - properties can be added to prototype after
 #      current position are visited on an Array-like object
 15.4.4.20-9-b-6: FAIL
-# Bug? Array.prototype.filter - properties can be added to prototype after
-#      current position are visited on an Array
-15.4.4.20-9-b-7: FAIL
 # Bug? Array.prototype.filter - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.20-9-b-16: FAIL
@@ -1241,33 +1187,12 @@
 # Bug? Array.prototype.filter - element changed by getter on previous iterations
 #      is observed on an Array
 15.4.4.20-9-c-i-28: FAIL
-# Bug? Array.prototype.reduce - value of 'length' is a number (value is
-#      negative)
-15.4.4.21-3-7: FAIL
-# Bug? Array.prototype.reduce - value of 'length' is a number (value is
-#      Infinity)
-# V8 timeout.
-15.4.4.21-3-8: SKIP
-# Bug? Array.prototype.reduce - 'length' is a string containing a negative
-#      number
-15.4.4.21-3-12: FAIL
-# Bug? Array.prototype.reduce - 'length' is a string containing a decimal number
-15.4.4.21-3-13: FAIL
-# Bug? Array.prototype.reduce - 'length' is a string containing +/-Infinity
-# V8 timeout.
-15.4.4.21-3-14: SKIP
-# Bug? Array.prototype.reduce - value of 'length' is a positive non-integer,
-#      ensure truncation occurs in the proper direction
-15.4.4.21-3-24: FAIL
-# Bug? Array.prototype.reduce - value of 'length' is a negative non-integer,
-#      ensure truncation occurs in the proper direction
-15.4.4.21-3-25: FAIL
-# Bug? Array.prototype.reduce - value of 'length' is boundary value (2^32)
-# V8 timeout.
-15.4.4.21-3-28: SKIP
-# Bug? Array.prototype.reduce - value of 'length' is boundary value (2^32 + 1)
-# V8 timeout.
-15.4.4.21-3-29: SKIP
+# Bug? Array.prototype.reduce applied to boolean primitive
+15.4.4.21-1-3: FAIL
+# Bug? Array.prototype.reduce applied to number primitive
+15.4.4.21-1-5: FAIL
+# Bug? Array.prototype.reduce applied to string primitive
+15.4.4.21-1-7: FAIL
 # Bug? Array.prototype.reduce - side effects produced by step 2 are visible when
 #      an exception occurs
 15.4.4.21-4-8: FAIL
@@ -1289,36 +1214,12 @@
 # Bug? Array.prototype.reduce - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.21-9-b-29: FAIL
-# Bug? Array.prototype.reduceRight - value of 'length' is a number (value is
-#      negative)
-15.4.4.22-3-7: FAIL
-# Bug? Array.prototype.reduceRight - value of 'length' is a number (value is
-#      Infinity)
-# V8 timeout.
-15.4.4.22-3-8: SKIP
-# Bug? Array.prototype.reduceRight - value of 'length' is a string containing a
-#      negative number
-15.4.4.22-3-12: FAIL
-# Bug? Array.prototype.reduceRight - value of 'length' is a string containing a
-#      decimal number
-15.4.4.22-3-13: FAIL
-# Bug? Array.prototype.reduceRight - value of 'length' is a string containing
-#      +/-Infinity
-# V8 timeout.
-15.4.4.22-3-14: SKIP
-# Bug? Array.prototype.reduceRight - value of 'length' is a positive
-#      non-integer, ensure truncation occurs in the proper direction
-15.4.4.22-3-24: FAIL
-# Bug? Array.prototype.reduceRight - value of 'length' is a negative
-#      non-integer, ensure truncation occurs in the proper direction
-15.4.4.22-3-25: FAIL
-# Bug? Array.prototype.reduceRight - value of 'length' is boundary value (2^32)
-# V8 timeout.
-15.4.4.22-3-28: SKIP
-# Bug? Array.prototype.reduceRight - value of 'length' is boundary value (2^32 +
-#      1)
-# V8 timeout.
-15.4.4.22-3-29: SKIP
+# Bug? Array.prototype.reduceRight applied to boolean primitive
+15.4.4.22-1-3: FAIL
+# Bug? Array.prototype.reduceRight applied to number primitive
+15.4.4.22-1-5: FAIL
+# Bug? Array.prototype.reduceRight applied to string primitive
+15.4.4.22-1-7: FAIL
 # Bug? Array.prototype.reduceRight - side effects produced by step 2 are visible
 #      when an exception occurs
 15.4.4.22-4-8: FAIL
@@ -1378,10 +1279,6 @@
 # Bug? Array.prototype.reduceRight - modifications to length will change number
 #      of iterations
 15.4.4.22-9-9: FAIL
-# Bug? String.prototype.trim throws TypeError when string is undefined
-15.5.4.20-1-1: FAIL
-# Bug? String.prototype.trim throws TypeError when string is null
-15.5.4.20-1-2: FAIL
 # Bug? String.prototype.trim - 'S' is a string with all WhiteSpace
 15.5.4.20-3-2: FAIL
 # Bug? String.prototype.trim - 'S' is a string with all union of WhiteSpace and
@@ -1404,9 +1301,6 @@
 # Bug? String.prototype.trim handles whitepace and lineterminators
 #      (\\uFEFF\\uFEFF)
 15.5.4.20-4-34: FAIL
-# Bug? Date Time String Format - specified default values will be set for all
-#      optional fields(MM, DD, mm, ss and time zone) when they are absent
-15.9.1.15-1: FAIL
 # Bug? Date.prototype.toISOString - RangeError is thrown when value of date is
 #      Date(1970, 0, -99999999, 0, 0, 0, -1), the time zone is UTC(0)
 15.9.5.43-0-8: FAIL
diff --git a/tools/codemap.js b/tools/codemap.js
index 71a99cc..dec494a 100644
--- a/tools/codemap.js
+++ b/tools/codemap.js
@@ -211,6 +211,14 @@
 
 
 /**
+ * Returns an array of pairs of all dynamic code entries and their addresses.
+ */
+CodeMap.prototype.getAllDynamicEntriesWithAddresses = function() {
+  return this.dynamics_.exportKeysAndValues();
+};
+
+
+/**
  * Returns an array of all static code entries.
  */
 CodeMap.prototype.getAllStaticEntries = function() {
diff --git a/tools/gcmole/gcmole.lua b/tools/gcmole/gcmole.lua
index 4afc66d..f8d3b62 100644
--- a/tools/gcmole/gcmole.lua
+++ b/tools/gcmole/gcmole.lua
@@ -97,8 +97,6 @@
       .. (plugin_args or "")
       .. " -triple " .. triple
       .. " -D" .. arch_define
-      .. " -DENABLE_VMSTATE_TRACKING"
-      .. " -DENABLE_LOGGING_AND_PROFILING"
       .. " -DENABLE_DEBUGGER_SUPPORT"
       .. " -Isrc"
 end
diff --git a/tools/gdb-v8-support.py b/tools/gdb-v8-support.py
new file mode 100644
index 0000000..0aa1d49
--- /dev/null
+++ b/tools/gdb-v8-support.py
@@ -0,0 +1,154 @@
+# Copyright 2011 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+kSmiTag = 0
+kSmiTagSize = 1
+kSmiTagMask = (1 << kSmiTagSize) - 1
+
+
+kHeapObjectTag = 1
+kHeapObjectTagSize = 2
+kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1
+
+
+kFailureTag = 3
+kFailureTagSize = 2
+kFailureTagMask = (1 << kFailureTagSize) - 1
+
+
+kSmiShiftSize32 = 0
+kSmiValueSize32 = 31
+kSmiShiftBits32 = kSmiTagSize + kSmiShiftSize32
+
+
+kSmiShiftSize64 = 31
+kSmiValueSize64 = 32
+kSmiShiftBits64 = kSmiTagSize + kSmiShiftSize64
+
+
+kAllBits = 0xFFFFFFFF
+kTopBit32 = 0x80000000
+kTopBit64 = 0x8000000000000000
+
+
+t_u32 = gdb.lookup_type('unsigned int')
+t_u64 = gdb.lookup_type('unsigned long long')
+
+
+def has_smi_tag(v):
+  return v & kSmiTagMask == kSmiTag
+
+
+def has_failure_tag(v):
+  return v & kFailureTagMask == kFailureTag
+
+
+def has_heap_object_tag(v):
+  return v & kHeapObjectTagMask == kHeapObjectTag
+
+
+def raw_heap_object(v):
+  return v - kHeapObjectTag
+
+
+def smi_to_int_32(v):
+  v = v & kAllBits
+  if (v & kTopBit32) == kTopBit32:
+    return ((v & kAllBits) >> kSmiShiftBits32) - 2147483648
+  else:
+    return (v & kAllBits) >> kSmiShiftBits32
+
+
+def smi_to_int_64(v):
+  return (v >> kSmiShiftBits64)
+
+
+def decode_v8_value(v, bitness):
+  base_str = 'v8[%x]' % v
+  if has_smi_tag(v):
+    if bitness == 32:
+      return base_str + (" SMI(%d)" % smi_to_int_32(v))
+    else:
+      return base_str + (" SMI(%d)" % smi_to_int_64(v))
+  elif has_failure_tag(v):
+    return base_str + " (failure)"
+  elif has_heap_object_tag(v):
+    return base_str + (" H(0x%x)" % raw_heap_object(v))
+  else:
+    return base_str
+
+
+class V8ValuePrinter(object):
+  "Print a v8value."
+  def __init__(self, val):
+    self.val = val
+  def to_string(self):
+    if self.val.type.sizeof == 4:
+      v_u32 = self.val.cast(t_u32)
+      return decode_v8_value(int(v_u32), 32)
+    elif self.val.type.sizeof == 8:
+      v_u64 = self.val.cast(t_u64)
+      return decode_v8_value(int(v_u64), 64)
+    else:
+      return 'v8value?'
+  def display_hint(self):
+    return 'v8value'
+
+
+def v8_pretty_printers(val):
+  lookup_tag = val.type.tag
+  if lookup_tag == None:
+    return None
+  elif lookup_tag == 'v8value':
+    return V8ValuePrinter(val)
+  return None
+gdb.pretty_printers.append(v8_pretty_printers)
+
+
+def v8_to_int(v):
+  if v.type.sizeof == 4:
+    return int(v.cast(t_u32))
+  elif v.type.sizeof == 8:
+    return int(v.cast(t_u64))
+  else:
+    return '?'
+
+  
+def v8_get_value(vstring):
+  v = gdb.parse_and_eval(vstring)
+  return v8_to_int(v)
+
+
+class V8PrintObject (gdb.Command):
+  """Prints a v8 object."""
+  def __init__ (self):
+    super (V8PrintObject, self).__init__ ("v8print", gdb.COMMAND_DATA)
+  def invoke (self, arg, from_tty):
+    v = v8_get_value(arg)
+    gdb.execute('call __gdb_print_v8_object(%d)' % v)
+V8PrintObject()
diff --git a/tools/grokdump.py b/tools/grokdump.py
index 15d09f4..468e7cc 100755
--- a/tools/grokdump.py
+++ b/tools/grokdump.py
@@ -291,6 +291,7 @@
     self.exception = None
     self.exception_context = None
     self.memory_list = None
+    self.memory_list64 = None
     self.thread_map = {}
     for d in directories:
       DebugPrint(d)
@@ -311,16 +312,17 @@
           self.thread_map[thread.id] = thread
       elif d.stream_type == MD_MEMORY_LIST_STREAM:
         print >>sys.stderr, "Warning: not a full minidump"
-        ml = MINIDUMP_MEMORY_LIST.Read(self.minidump, d.location.rva)
-        DebugPrint(ml)
-        for m in ml.ranges:
-          DebugPrint(m)
-      elif d.stream_type == MD_MEMORY_64_LIST_STREAM:
         assert self.memory_list is None
-        self.memory_list = MINIDUMP_MEMORY_LIST64.Read(
+        self.memory_list = MINIDUMP_MEMORY_LIST.Read(
           self.minidump, d.location.rva)
         assert ctypes.sizeof(self.memory_list) == d.location.data_size
         DebugPrint(self.memory_list)
+      elif d.stream_type == MD_MEMORY_64_LIST_STREAM:
+        assert self.memory_list64 is None
+        self.memory_list64 = MINIDUMP_MEMORY_LIST64.Read(
+          self.minidump, d.location.rva)
+        assert ctypes.sizeof(self.memory_list64) == d.location.data_size
+        DebugPrint(self.memory_list64)
 
   def IsValidAddress(self, address):
     return self.FindLocation(address) is not None
@@ -338,12 +340,16 @@
     return self.minidump[location:location + size]
 
   def FindLocation(self, address):
-    # TODO(vitalyr): only works for full minidumps (...64 structure variants).
     offset = 0
-    for r in self.memory_list.ranges:
-      if r.start <= address < r.start + r.size:
-        return self.memory_list.base_rva + offset + address - r.start
+    if self.memory_list64 is not None:
+      for r in self.memory_list64.ranges:
+        if r.start <= address < r.start + r.size:
+          return self.memory_list64.base_rva + offset + address - r.start
       offset += r.size
+    if self.memory_list is not None:
+      for r in self.memory_list.ranges:
+        if r.start <= address < r.start + r.memory.data_size:
+          return r.memory.rva + address - r.start
     return None
 
   def GetDisasmLines(self, address, size):
@@ -373,62 +379,64 @@
 # };
 # static P p;
 INSTANCE_TYPES = {
-  64: "SYMBOL_TYPE",
-  68: "ASCII_SYMBOL_TYPE",
-  65: "CONS_SYMBOL_TYPE",
-  69: "CONS_ASCII_SYMBOL_TYPE",
-  66: "EXTERNAL_SYMBOL_TYPE",
-  74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE",
-  70: "EXTERNAL_ASCII_SYMBOL_TYPE",
-  0: "STRING_TYPE",
-  4: "ASCII_STRING_TYPE",
-  1: "CONS_STRING_TYPE",
-  5: "CONS_ASCII_STRING_TYPE",
-  2: "EXTERNAL_STRING_TYPE",
-  10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE",
-  6: "EXTERNAL_ASCII_STRING_TYPE",
-  6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE",
-  128: "MAP_TYPE",
-  129: "CODE_TYPE",
-  130: "ODDBALL_TYPE",
-  131: "JS_GLOBAL_PROPERTY_CELL_TYPE",
-  132: "HEAP_NUMBER_TYPE",
-  134: "JS_PROXY_TYPE",
-  133: "FOREIGN_TYPE",
-  135: "BYTE_ARRAY_TYPE",
-  136: "EXTERNAL_BYTE_ARRAY_TYPE",
-  137: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE",
-  138: "EXTERNAL_SHORT_ARRAY_TYPE",
-  139: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE",
-  140: "EXTERNAL_INT_ARRAY_TYPE",
-  141: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE",
-  142: "EXTERNAL_FLOAT_ARRAY_TYPE",
-  144: "EXTERNAL_PIXEL_ARRAY_TYPE",
-  145: "FILLER_TYPE",
-  146: "ACCESSOR_INFO_TYPE",
-  147: "ACCESS_CHECK_INFO_TYPE",
-  148: "INTERCEPTOR_INFO_TYPE",
-  149: "CALL_HANDLER_INFO_TYPE",
-  150: "FUNCTION_TEMPLATE_INFO_TYPE",
-  151: "OBJECT_TEMPLATE_INFO_TYPE",
-  152: "SIGNATURE_INFO_TYPE",
-  153: "TYPE_SWITCH_INFO_TYPE",
-  154: "SCRIPT_TYPE",
-  155: "CODE_CACHE_TYPE",
-  158: "FIXED_ARRAY_TYPE",
-  159: "SHARED_FUNCTION_INFO_TYPE",
-  160: "JS_MESSAGE_OBJECT_TYPE",
-  161: "JS_VALUE_TYPE",
-  162: "JS_OBJECT_TYPE",
-  163: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
-  164: "JS_GLOBAL_OBJECT_TYPE",
-  165: "JS_BUILTINS_OBJECT_TYPE",
-  166: "JS_GLOBAL_PROXY_TYPE",
-  167: "JS_ARRAY_TYPE",
-  168: "JS_REGEXP_TYPE",
-  169: "JS_FUNCTION_TYPE",
-  156: "DEBUG_INFO_TYPE",
-  157: "BREAK_POINT_INFO_TYPE",
+64: "SYMBOL_TYPE",
+68: "ASCII_SYMBOL_TYPE",
+65: "CONS_SYMBOL_TYPE",
+69: "CONS_ASCII_SYMBOL_TYPE",
+66: "EXTERNAL_SYMBOL_TYPE",
+74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE",
+70: "EXTERNAL_ASCII_SYMBOL_TYPE",
+0: "STRING_TYPE",
+4: "ASCII_STRING_TYPE",
+1: "CONS_STRING_TYPE",
+5: "CONS_ASCII_STRING_TYPE",
+2: "EXTERNAL_STRING_TYPE",
+10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE",
+6: "EXTERNAL_ASCII_STRING_TYPE",
+6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE",
+128: "MAP_TYPE",
+129: "CODE_TYPE",
+130: "ODDBALL_TYPE",
+131: "JS_GLOBAL_PROPERTY_CELL_TYPE",
+132: "HEAP_NUMBER_TYPE",
+133: "FOREIGN_TYPE",
+134: "BYTE_ARRAY_TYPE",
+135: "EXTERNAL_BYTE_ARRAY_TYPE",
+136: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE",
+137: "EXTERNAL_SHORT_ARRAY_TYPE",
+138: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE",
+139: "EXTERNAL_INT_ARRAY_TYPE",
+140: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE",
+141: "EXTERNAL_FLOAT_ARRAY_TYPE",
+143: "EXTERNAL_PIXEL_ARRAY_TYPE",
+145: "FILLER_TYPE",
+146: "ACCESSOR_INFO_TYPE",
+147: "ACCESS_CHECK_INFO_TYPE",
+148: "INTERCEPTOR_INFO_TYPE",
+149: "CALL_HANDLER_INFO_TYPE",
+150: "FUNCTION_TEMPLATE_INFO_TYPE",
+151: "OBJECT_TEMPLATE_INFO_TYPE",
+152: "SIGNATURE_INFO_TYPE",
+153: "TYPE_SWITCH_INFO_TYPE",
+154: "SCRIPT_TYPE",
+155: "CODE_CACHE_TYPE",
+156: "POLYMORPHIC_CODE_CACHE_TYPE",
+159: "FIXED_ARRAY_TYPE",
+160: "SHARED_FUNCTION_INFO_TYPE",
+161: "JS_MESSAGE_OBJECT_TYPE",
+162: "JS_VALUE_TYPE",
+163: "JS_OBJECT_TYPE",
+164: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
+165: "JS_GLOBAL_OBJECT_TYPE",
+166: "JS_BUILTINS_OBJECT_TYPE",
+167: "JS_GLOBAL_PROXY_TYPE",
+168: "JS_ARRAY_TYPE",
+169: "JS_PROXY_TYPE",
+170: "JS_REGEXP_TYPE",
+171: "JS_FUNCTION_TYPE",
+172: "JS_FUNCTION_PROXY_TYPE",
+157: "DEBUG_INFO_TYPE",
+158: "BREAK_POINT_INFO_TYPE",
 }
 
 
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 7ad8b91..2650483 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -30,7 +30,7 @@
     'use_system_v8%': 0,
     'msvs_use_common_release': 0,
     'gcc_version%': 'unknown',
-    'v8_compress_startup_data%': 'false',
+    'v8_compress_startup_data%': 'off',
     'v8_target_arch%': '<(target_arch)',
 
     # Setting 'v8_can_use_unaligned_accesses' to 'true' will allow the code
@@ -62,10 +62,7 @@
     ['use_system_v8==0', {
       'target_defaults': {
         'defines': [
-          'ENABLE_LOGGING_AND_PROFILING',
           'ENABLE_DEBUGGER_SUPPORT',
-          'ENABLE_VMSTATE_TRACKING',
-          'V8_FAST_TLS',
         ],
         'conditions': [
           ['OS!="mac"', {
@@ -232,6 +229,7 @@
       'targets': [
         {
           'target_name': 'v8',
+          'toolsets': ['host', 'target'],
           'conditions': [
             ['v8_use_snapshot=="true"', {
               'dependencies': ['v8_snapshot'],
@@ -281,9 +279,16 @@
         {
           'target_name': 'v8_snapshot',
           'type': '<(library)',
+          'toolsets': ['host', 'target'],
           'conditions': [
             ['component=="shared_library"', {
               'conditions': [
+                # The ARM assembler assumes the host is 32 bits, so force building
+                # 32-bit host tools.
+                ['v8_target_arch=="arm" and host_arch=="x64" and _toolset=="host"', {
+                  'cflags': ['-m32'],
+                  'ldflags': ['-m32'],
+                }],
                 ['OS=="win"', {
                   'defines': [
                     'BUILDING_V8_SHARED',
@@ -525,7 +530,6 @@
             '../../src/inspector.h',
             '../../src/interpreter-irregexp.cc',
             '../../src/interpreter-irregexp.h',
-            '../../src/json-parser.cc',
             '../../src/json-parser.h',
             '../../src/jsregexp.cc',
             '../../src/jsregexp.h',
@@ -639,10 +643,13 @@
             '../../src/v8.cc',
             '../../src/v8.h',
             '../../src/v8checks.h',
+            '../../src/v8conversions.cc',
+            '../../src/v8conversions.h',
             '../../src/v8globals.h',
             '../../src/v8memory.h',
             '../../src/v8threads.cc',
             '../../src/v8threads.h',
+            '../../src/v8utils.cc',
             '../../src/v8utils.h',
             '../../src/variables.cc',
             '../../src/variables.h',
@@ -902,6 +909,7 @@
                 '../../tools/js2c.py',
                 '<@(_outputs)',
                 'CORE',
+                '<(v8_compress_startup_data)',
                 '<@(library_files)'
               ],
             },
@@ -919,6 +927,7 @@
                 '../../tools/js2c.py',
                 '<@(_outputs)',
                 'EXPERIMENTAL',
+                '<(v8_compress_startup_data)',
                 '<@(experimental_library_files)'
               ],
             },
@@ -953,6 +962,7 @@
         {
           'target_name': 'v8_shell',
           'type': 'executable',
+          'toolsets': ['host'],
           'dependencies': [
             'v8'
           ],
@@ -964,6 +974,12 @@
               # This could be gotten by not setting chromium_code, if that's OK.
               'defines': ['_CRT_SECURE_NO_WARNINGS'],
             }],
+            # The ARM assembler assumes the host is 32 bits, so force building
+            # 32-bit host tools.
+            ['v8_target_arch=="arm" and host_arch=="x64" and _toolset=="host"', {
+              'cflags': ['-m32'],
+              'ldflags': ['-m32'],
+            }],
             ['v8_compress_startup_data=="bz2"', {
               'libraries': [
                 '-lbz2',
@@ -976,6 +992,7 @@
         {
           'target_name': 'v8',
           'type': 'settings',
+          'toolsets': ['host', 'target'],
           'link_settings': {
             'libraries': [
               '-lv8',
@@ -985,6 +1002,7 @@
         {
           'target_name': 'v8_shell',
           'type': 'none',
+          'toolsets': ['host'],
           'dependencies': [
             'v8'
           ],
diff --git a/tools/js2c.py b/tools/js2c.py
index 8211ec5..a2ea8ea 100644
--- a/tools/js2c.py
+++ b/tools/js2c.py
@@ -33,15 +33,22 @@
 
 import os, re, sys, string
 import jsmin
+import bz2
 
 
-def ToCArray(lines):
+def ToCAsciiArray(lines):
   result = []
   for chr in lines:
     value = ord(chr)
     assert value < 128
     result.append(str(value))
-  result.append("0")
+  return ", ".join(result)
+
+
+def ToCArray(lines):
+  result = []
+  for chr in lines:
+    result.append(str(ord(chr)))
   return ", ".join(result)
 
 
@@ -87,8 +94,8 @@
     return string
 
 
-EVAL_PATTERN = re.compile(r'\beval\s*\(');
-WITH_PATTERN = re.compile(r'\bwith\s*\(');
+EVAL_PATTERN = re.compile(r'\beval\s*\(')
+WITH_PATTERN = re.compile(r'\bwith\s*\(')
 
 
 def Validate(lines, file):
@@ -212,11 +219,14 @@
 
 #include "v8.h"
 #include "natives.h"
+#include "utils.h"
 
 namespace v8 {
 namespace internal {
 
-%(source_lines)s\
+  static const byte sources[] = { %(sources_data)s };
+
+%(raw_sources_declaration)s\
 
   template <>
   int NativesCollection<%(type)s>::GetBuiltinsCount() {
@@ -235,8 +245,13 @@
   }
 
   template <>
-  Vector<const char> NativesCollection<%(type)s>::GetScriptSource(int index) {
-%(get_script_source_cases)s\
+  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\
     return Vector<const char>("", 0);
   }
 
@@ -246,27 +261,43 @@
     return Vector<const char>("", 0);
   }
 
+  template <>
+  Vector<const byte> NativesCollection<%(type)s>::GetScriptsSource() {
+    return Vector<const byte>(sources, %(total_length)i);
+  }
+
+  template <>
+  void NativesCollection<%(type)s>::SetRawScriptsSource(Vector<const char> raw_source) {
+    ASSERT(%(raw_total_length)i == raw_source.length());
+    raw_sources = raw_source.start();
+  }
+
 }  // internal
 }  // v8
 """
 
 
-SOURCE_DECLARATION = """\
-  static const char %(id)s[] = { %(data)s };
+RAW_SOURCES_COMPRESSION_DECLARATION = """\
+  static const char* raw_sources = NULL;
 """
 
 
-GET_DEBUGGER_INDEX_CASE = """\
+RAW_SOURCES_DECLARATION = """\
+  static const char* raw_sources = reinterpret_cast<const char*>(sources);
+"""
+
+
+GET_INDEX_CASE = """\
     if (strcmp(name, "%(id)s") == 0) return %(i)i;
 """
 
 
-GET_DEBUGGER_SCRIPT_SOURCE_CASE = """\
-    if (index == %(i)i) return Vector<const char>(%(id)s, %(length)i);
+GET_RAW_SCRIPT_SOURCE_CASE = """\
+    if (index == %(i)i) return Vector<const char>(raw_sources + %(offset)i, %(raw_length)i);
 """
 
 
-GET_DEBUGGER_SCRIPT_NAME_CASE = """\
+GET_SCRIPT_NAME_CASE = """\
     if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i);
 """
 
@@ -283,11 +314,10 @@
     else:
       modules.append(s)
 
-  # Build source code lines
-  source_lines = [ ]
-
   minifier = jsmin.JavaScriptMinifier()
 
+  module_offset = 0
+  all_sources = []
   for module in modules:
     filename = str(module)
     debugger = filename.endswith('-debugger.js')
@@ -296,49 +326,46 @@
     lines = ExpandMacros(lines, macros)
     Validate(lines, filename)
     lines = minifier.JSMinify(lines)
-    data = ToCArray(lines)
     id = (os.path.split(filename)[1])[:-3]
     if debugger: id = id[:-9]
+    raw_length = len(lines)
     if debugger:
-      debugger_ids.append((id, len(lines)))
+      debugger_ids.append((id, raw_length, module_offset))
     else:
-      ids.append((id, len(lines)))
-    source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data })
+      ids.append((id, raw_length, module_offset))
+    all_sources.append(lines)
+    module_offset += raw_length
+  total_length = raw_total_length = module_offset
+
+  if env['COMPRESSION'] == 'off':
+    raw_sources_declaration = RAW_SOURCES_DECLARATION
+    sources_data = ToCAsciiArray("".join(all_sources))
+  else:
+    raw_sources_declaration = RAW_SOURCES_COMPRESSION_DECLARATION
+    if env['COMPRESSION'] == 'bz2':
+      all_sources = bz2.compress("".join(all_sources))
+    total_length = len(all_sources)
+    sources_data = ToCArray(all_sources)
 
   # Build debugger support functions
   get_index_cases = [ ]
-  get_script_source_cases = [ ]
+  get_raw_script_source_cases = [ ]
   get_script_name_cases = [ ]
 
   i = 0
-  for (id, length) in debugger_ids:
+  for (id, raw_length, module_offset) in debugger_ids + ids:
     native_name = "native %s.js" % id
-    get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i })
-    get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % {
-      'id': id,
-      'length': length,
-      'i': i
-    })
-    get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % {
-      'name': native_name,
-      'length': len(native_name),
-      'i': i
-    });
-    i = i + 1
-
-  for (id, length) in ids:
-    native_name = "native %s.js" % id
-    get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i })
-    get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % {
-      'id': id,
-      'length': length,
-      'i': i
-    })
-    get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % {
-      'name': native_name,
-      'length': len(native_name),
-      'i': i
-    });
+    get_index_cases.append(GET_INDEX_CASE % { 'id': id, 'i': i })
+    get_raw_script_source_cases.append(GET_RAW_SCRIPT_SOURCE_CASE % {
+        'offset': module_offset,
+        'raw_length': raw_length,
+        'i': i
+        })
+    get_script_name_cases.append(GET_SCRIPT_NAME_CASE % {
+        'name': native_name,
+        'length': len(native_name),
+        'i': i
+        })
     i = i + 1
 
   # Emit result
@@ -346,9 +373,12 @@
   output.write(HEADER_TEMPLATE % {
     'builtin_count': len(ids) + len(debugger_ids),
     'debugger_count': len(debugger_ids),
-    'source_lines': "\n".join(source_lines),
+    'sources_data': sources_data,
+    'raw_sources_declaration': raw_sources_declaration,
+    'raw_total_length': raw_total_length,
+    'total_length': total_length,
     'get_index_cases': "".join(get_index_cases),
-    'get_script_source_cases': "".join(get_script_source_cases),
+    'get_raw_script_source_cases': "".join(get_raw_script_source_cases),
     'get_script_name_cases': "".join(get_script_name_cases),
     'type': env['TYPE']
   })
@@ -357,8 +387,9 @@
 def main():
   natives = sys.argv[1]
   type = sys.argv[2]
-  source_files = sys.argv[3:]
-  JS2C(source_files, [natives], { 'TYPE': type })
+  compression = sys.argv[3]
+  source_files = sys.argv[4:]
+  JS2C(source_files, [natives], { 'TYPE': type, 'COMPRESSION': compression })
 
 if __name__ == "__main__":
   main()
diff --git a/tools/linux-tick-processor b/tools/linux-tick-processor
index 9789697..0b0a1fb 100755
--- a/tools/linux-tick-processor
+++ b/tools/linux-tick-processor
@@ -8,12 +8,10 @@
 [ "$D8_PATH" ] || D8_PATH=$tools_path/..
 d8_exec=$D8_PATH/d8
 
-if [ "$1" = "--no-build" ]; then
-  shift
-else
-# compile d8 if it doesn't exist, assuming this script
-# resides in the repository.
-  [ -x $d8_exec ] || scons -j4 -C $D8_PATH -Y $tools_path/.. d8
+if [ ! -x $d8_exec ]; then
+  echo "d8 shell not found in $D8_PATH"
+  echo "To build, execute 'scons <flags> d8' from the V8 directory"
+  exit 1
 fi
 
 
diff --git a/tools/ll_prof.py b/tools/ll_prof.py
index 798b574..58cbb95 100755
--- a/tools/ll_prof.py
+++ b/tools/ll_prof.py
@@ -631,10 +631,10 @@
   def ReadMmap(self, header, offset):
     mmap_info = PERF_MMAP_EVENT_BODY_DESC.Read(self.trace,
                                                offset + self.header_size)
-    # Read null-padded filename.
+    # Read null-terminated filename.
     filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info):
-                          offset + header.size].rstrip(chr(0))
-    mmap_info.filename = filename
+                          offset + header.size]
+    mmap_info.filename = filename[:filename.find(chr(0))]
     return mmap_info
 
   def ReadSample(self, header, offset):
diff --git a/tools/profile.js b/tools/profile.js
index c9c9437..10a07f8 100644
--- a/tools/profile.js
+++ b/tools/profile.js
@@ -162,8 +162,16 @@
     // Function object has been overwritten with a new one.
     func.name = name;
   }
-  var entry = new Profile.DynamicFuncCodeEntry(size, type, func, state);
-  this.codeMap_.addCode(start, entry);
+  var entry = this.codeMap_.findDynamicEntryByStartAddress(start);
+  if (entry) {
+    if (entry.size === size && entry.func === func) {
+      // Entry state has changed.
+      entry.state = state;
+    }
+  } else {
+    entry = new Profile.DynamicFuncCodeEntry(size, type, func, state);
+    this.codeMap_.addCode(start, entry);
+  }
   return entry;
 };
 
@@ -374,6 +382,31 @@
 
 
 /**
+ * Cleans up function entries that are not referenced by code entries.
+ */
+Profile.prototype.cleanUpFuncEntries = function() {
+  var referencedFuncEntries = [];
+  var entries = this.codeMap_.getAllDynamicEntriesWithAddresses();
+  for (var i = 0, l = entries.length; i < l; ++i) {
+    if (entries[i][1].constructor === Profile.FunctionEntry) {
+      entries[i][1].used = false;
+    }
+  }
+  for (var i = 0, l = entries.length; i < l; ++i) {
+    if ("func" in entries[i][1]) {
+      entries[i][1].func.used = true;
+    }
+  }
+  for (var i = 0, l = entries.length; i < l; ++i) {
+    if (entries[i][1].constructor === Profile.FunctionEntry &&
+        !entries[i][1].used) {
+      this.codeMap_.deleteCode(entries[i][0]);
+    }
+  }
+};
+
+
+/**
  * Creates a dynamic code entry.
  *
  * @param {number} size Code size.
@@ -408,6 +441,11 @@
 };
 
 
+Profile.DynamicCodeEntry.prototype.toString = function() {
+  return this.getName() + ': ' + this.size.toString(16);
+};
+
+
 /**
  * Creates a dynamic code entry.
  *
@@ -448,6 +486,11 @@
 };
 
 
+Profile.DynamicFuncCodeEntry.prototype.toString = function() {
+  return this.getName() + ': ' + this.size.toString(16);
+};
+
+
 /**
  * Creates a shared function object entry.
  *
@@ -473,6 +516,7 @@
   return name;
 };
 
+Profile.FunctionEntry.prototype.toString = CodeMap.CodeEntry.prototype.toString;
 
 /**
  * Constructs a call graph.
diff --git a/tools/splaytree.js b/tools/splaytree.js
index 1c9aab9..d272a9e 100644
--- a/tools/splaytree.js
+++ b/tools/splaytree.js
@@ -191,6 +191,17 @@
 
 
 /**
+ * @return {Array<*>} An array containing all the values of tree's nodes paired
+ *     with keys.
+ */
+SplayTree.prototype.exportKeysAndValues = function() {
+  var result = [];
+  this.traverse_(function(node) { result.push([node.key, node.value]); });
+  return result;
+};
+
+
+/**
  * @return {Array<*>} An array containing all the values of tree's nodes.
  */
 SplayTree.prototype.exportValues = function() {
diff --git a/tools/stats-viewer.py b/tools/stats-viewer.py
index 05cb762..ab8e287 100755
--- a/tools/stats-viewer.py
+++ b/tools/stats-viewer.py
@@ -104,10 +104,12 @@
         sys.exit(1)
       maps_file = open(maps_name, "r")
       try:
-        m = re.search(r"/dev/shm/\S*", maps_file.read())
-        if m is not None and os.path.exists(m.group(0)):
-          self.data_name = m.group(0)
-        else:
+        self.data_name = None
+        for m in re.finditer(r"/dev/shm/\S*", maps_file.read()):
+          if os.path.exists(m.group(0)):
+            self.data_name = m.group(0)
+            break
+        if self.data_name is None:
           print "Can't find counter file in maps for PID %s." % self.data_name
           sys.exit(1)
       finally:
@@ -414,7 +416,8 @@
   individual counters contained in the file."""
 
   _HEADER_SIZE = 4 * 4
-  _NAME_SIZE = 32
+  _COUNTER_NAME_SIZE = 64
+  _THREAD_NAME_SIZE = 32
 
   def __init__(self, data):
     """Create a new instance.
@@ -426,22 +429,23 @@
     self.max_counters = data.IntAt(8)
     self.max_threads = data.IntAt(12)
     self.counter_names_offset = \
-        self._HEADER_SIZE + self.max_threads * (self._NAME_SIZE + 2 * 4)
+        self._HEADER_SIZE + self.max_threads * (self._THREAD_NAME_SIZE + 2 * 4)
     self.counter_values_offset = \
-        self.counter_names_offset + self.max_counters * self._NAME_SIZE
+        self.counter_names_offset + self.max_counters * self._COUNTER_NAME_SIZE
 
   def CountersInUse(self):
     """Return the number of counters in active use."""
     for i in xrange(self.max_counters):
-      if self.data.ByteAt(self.counter_names_offset + i * self._NAME_SIZE) == 0:
+      name_offset = self.counter_names_offset + i * self._COUNTER_NAME_SIZE
+      if self.data.ByteAt(name_offset) == 0:
         return i
     return self.max_counters
 
   def Counter(self, i):
     """Return the i'th counter."""
-    return ChromeCounter(self.data,
-                         self.counter_names_offset + i * self._NAME_SIZE,
-                         self.counter_values_offset + i * self.max_threads * 4)
+    name_offset = self.counter_names_offset + i * self._COUNTER_NAME_SIZE
+    value_offset = self.counter_values_offset + i * self.max_threads * 4
+    return ChromeCounter(self.data, name_offset, value_offset)
 
 
 def Main(data_file, name_filter):
diff --git a/tools/test.py b/tools/test.py
index cb2428c..ec21ffe 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -1272,6 +1272,11 @@
       options.special_command += " --crankshaft"
     else:
       options.special_command = "@--crankshaft"
+  if options.shell == "d8":
+    if options.special_command:
+      options.special_command += " --test"
+    else:
+      options.special_command = "@--test"
   if options.noprof:
     options.scons_flags.append("prof=off")
     options.scons_flags.append("profilingsupport=off")
@@ -1437,7 +1442,8 @@
         'system': utils.GuessOS(),
         'arch': options.arch,
         'simulator': options.simulator,
-        'crankshaft': options.crankshaft
+        'crankshaft': options.crankshaft,
+        'isolates': options.isolates
       }
       test_list = root.ListTests([], path, context, mode, [])
       unclassified_tests += test_list
diff --git a/tools/tickprocessor.js b/tools/tickprocessor.js
index 9d6bfb6..5f57835 100644
--- a/tools/tickprocessor.js
+++ b/tools/tickprocessor.js
@@ -169,17 +169,12 @@
           processor: this.processHeapSampleBegin },
       'heap-sample-end': { parsers: [null, null],
           processor: this.processHeapSampleEnd },
-      'heap-js-prod-item': { parsers: [null, 'var-args'],
-          processor: this.processJSProducer },
       // Ignored events.
       'profiler': null,
       'function-creation': null,
       'function-move': null,
       'function-delete': null,
-      'heap-sample-stats': null,
       'heap-sample-item': null,
-      'heap-js-cons-item': null,
-      'heap-js-ret-item': null,
       // Obsolete row types.
       'code-allocate': null,
       'begin-code-region': null,
@@ -401,17 +396,6 @@
 };
 
 
-TickProcessor.prototype.processJSProducer = function(constructor, stack) {
-  if (!this.currentProducerProfile_) return;
-  if (stack.length == 0) return;
-  var first = stack.shift();
-  var processedStack =
-      this.profile_.resolveAndFilterFuncs_(this.processStack(first, 0, stack));
-  processedStack.unshift(constructor);
-  this.currentProducerProfile_.addPath(processedStack);
-};
-
-
 TickProcessor.prototype.printStatistics = function() {
   print('Statistical profiling result from ' + this.lastLogFileName_ +
         ', (' + this.ticks_.total +
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
deleted file mode 100644
index adb6409..0000000
--- a/tools/v8.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,2764 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 45;
-	objects = {
-
-/* Begin PBXAggregateTarget section */
-		7BF891930E73098D000BAF8A /* All */ = {
-			isa = PBXAggregateTarget;
-			buildConfigurationList = 7BF8919F0E7309BE000BAF8A /* Build configuration list for PBXAggregateTarget "All" */;
-			buildPhases = (
-			);
-			dependencies = (
-				89EED40D12B69A0A0075BE1C /* PBXTargetDependency */,
-				7BF891970E73099F000BAF8A /* PBXTargetDependency */,
-				7BF891990E73099F000BAF8A /* PBXTargetDependency */,
-				893988100F2A3647007D5254 /* PBXTargetDependency */,
-				896FD03E0E78D731003DFB6A /* PBXTargetDependency */,
-				896FD0400E78D735003DFB6A /* PBXTargetDependency */,
-				8938A29912D63A680080CDDE /* PBXTargetDependency */,
-				8938A29712D63A680080CDDE /* PBXTargetDependency */,
-				8938A29512D63A680080CDDE /* PBXTargetDependency */,
-			);
-			name = All;
-			productName = All;
-		};
-/* End PBXAggregateTarget section */
-
-/* Begin PBXBuildFile section */
-		58DA027E136ECC87007399A4 /* experimental-libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 58DA027D136ECC87007399A4 /* experimental-libraries.cc */; };
-		58DA027F136ECC87007399A4 /* experimental-libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 58DA027D136ECC87007399A4 /* experimental-libraries.cc */; };
-		58DA0280136ECC87007399A4 /* experimental-libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 58DA027D136ECC87007399A4 /* experimental-libraries.cc */; };
-		8900116C0E71CA2300F91F35 /* libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8900116B0E71CA2300F91F35 /* libraries.cc */; };
-		890A13FE0EE9C47F00E49346 /* interpreter-irregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C660EE4665300B48DEB /* interpreter-irregexp.cc */; };
-		890A14010EE9C4B000E49346 /* regexp-macro-assembler-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C700EE466D000B48DEB /* regexp-macro-assembler-arm.cc */; };
-		890A14020EE9C4B400E49346 /* regexp-macro-assembler-irregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C750EE466D000B48DEB /* regexp-macro-assembler-irregexp.cc */; };
-		890A14030EE9C4B500E49346 /* regexp-macro-assembler-tracer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C770EE466D000B48DEB /* regexp-macro-assembler-tracer.cc */; };
-		890A14040EE9C4B700E49346 /* regexp-macro-assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C790EE466D000B48DEB /* regexp-macro-assembler.cc */; };
-		8924315C12F8539900906AB2 /* lithium-gap-resolver-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8924315A12F8539900906AB2 /* lithium-gap-resolver-x64.cc */; };
-		8938A2A312D63B630080CDDE /* lithium-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8938A2A212D63B630080CDDE /* lithium-x64.cc */; };
-		893988070F2A35FA007D5254 /* libv8.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8970F2F00E719FB2006AE7B5 /* libv8.a */; };
-		8939880D0F2A362A007D5254 /* d8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C920EE46A1700B48DEB /* d8.cc */; };
-		893988160F2A3688007D5254 /* d8-debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893988150F2A3686007D5254 /* d8-debug.cc */; };
-		893988330F2A3B8F007D5254 /* d8-js.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893988320F2A3B8B007D5254 /* d8-js.cc */; };
-		893A72240F7B101400303DD2 /* platform-posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893A72230F7B0FF200303DD2 /* platform-posix.cc */; };
-		893A72250F7B101B00303DD2 /* platform-posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893A72230F7B0FF200303DD2 /* platform-posix.cc */; };
-		893CCE640E71D83700357A03 /* code-stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1110E719B8F00D62E90 /* code-stubs.cc */; };
-		893E24A812B14B3D0083370F /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248612B14B3D0083370F /* bignum-dtoa.cc */; };
-		893E24A912B14B3D0083370F /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248812B14B3D0083370F /* bignum.cc */; };
-		893E24AA12B14B3D0083370F /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248A12B14B3D0083370F /* cached-powers.cc */; };
-		893E24AB12B14B3D0083370F /* deoptimizer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248B12B14B3D0083370F /* deoptimizer.cc */; };
-		893E24AC12B14B3D0083370F /* hydrogen-instructions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248D12B14B3D0083370F /* hydrogen-instructions.cc */; };
-		893E24AD12B14B3D0083370F /* hydrogen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248F12B14B3D0083370F /* hydrogen.cc */; };
-		893E24AE12B14B3D0083370F /* lithium-allocator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249312B14B3D0083370F /* lithium-allocator.cc */; };
-		893E24AF12B14B3D0083370F /* preparse-data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249512B14B3D0083370F /* preparse-data.cc */; };
-		893E24B112B14B3D0083370F /* preparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249812B14B3D0083370F /* preparser.cc */; };
-		893E24B212B14B3D0083370F /* runtime-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249A12B14B3D0083370F /* runtime-profiler.cc */; };
-		893E24B312B14B3D0083370F /* safepoint-table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249C12B14B3D0083370F /* safepoint-table.cc */; };
-		893E24B412B14B3D0083370F /* scanner-base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249E12B14B3D0083370F /* scanner-base.cc */; };
-		893E24B512B14B3D0083370F /* string-search.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24A112B14B3D0083370F /* string-search.cc */; };
-		893E24B612B14B3D0083370F /* strtod.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24A312B14B3D0083370F /* strtod.cc */; };
-		893E24B712B14B3D0083370F /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248612B14B3D0083370F /* bignum-dtoa.cc */; };
-		893E24B812B14B3D0083370F /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248812B14B3D0083370F /* bignum.cc */; };
-		893E24B912B14B3D0083370F /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248A12B14B3D0083370F /* cached-powers.cc */; };
-		893E24BA12B14B3D0083370F /* deoptimizer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248B12B14B3D0083370F /* deoptimizer.cc */; };
-		893E24BB12B14B3D0083370F /* hydrogen-instructions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248D12B14B3D0083370F /* hydrogen-instructions.cc */; };
-		893E24BC12B14B3D0083370F /* hydrogen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248F12B14B3D0083370F /* hydrogen.cc */; };
-		893E24BD12B14B3D0083370F /* lithium-allocator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249312B14B3D0083370F /* lithium-allocator.cc */; };
-		893E24BE12B14B3D0083370F /* preparse-data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249512B14B3D0083370F /* preparse-data.cc */; };
-		893E24C012B14B3D0083370F /* preparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249812B14B3D0083370F /* preparser.cc */; };
-		893E24C112B14B3D0083370F /* runtime-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249A12B14B3D0083370F /* runtime-profiler.cc */; };
-		893E24C212B14B3D0083370F /* safepoint-table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249C12B14B3D0083370F /* safepoint-table.cc */; };
-		893E24C312B14B3D0083370F /* scanner-base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249E12B14B3D0083370F /* scanner-base.cc */; };
-		893E24C412B14B3D0083370F /* string-search.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24A112B14B3D0083370F /* string-search.cc */; };
-		893E24C512B14B3D0083370F /* strtod.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24A312B14B3D0083370F /* strtod.cc */; };
-		893E24CC12B14B520083370F /* deoptimizer-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24C612B14B510083370F /* deoptimizer-arm.cc */; };
-		893E24CD12B14B520083370F /* lithium-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24C712B14B510083370F /* lithium-arm.cc */; };
-		893E24CE12B14B520083370F /* lithium-codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24C912B14B520083370F /* lithium-codegen-arm.cc */; };
-		893E24D512B14B8A0083370F /* deoptimizer-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24D012B14B8A0083370F /* deoptimizer-ia32.cc */; };
-		893E24D612B14B8A0083370F /* lithium-codegen-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24D112B14B8A0083370F /* lithium-codegen-ia32.cc */; };
-		893E24D712B14B8A0083370F /* lithium-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24D312B14B8A0083370F /* lithium-ia32.cc */; };
-		893E24DC12B14B9F0083370F /* externalize-string-extension.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24D812B14B9F0083370F /* externalize-string-extension.cc */; };
-		893E24DD12B14B9F0083370F /* gc-extension.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24DA12B14B9F0083370F /* gc-extension.cc */; };
-		893E24DE12B14B9F0083370F /* externalize-string-extension.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24D812B14B9F0083370F /* externalize-string-extension.cc */; };
-		893E24DF12B14B9F0083370F /* gc-extension.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24DA12B14B9F0083370F /* gc-extension.cc */; };
-		8944AD100F1D4D500028D560 /* regexp-stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */; };
-		8944AD110F1D4D570028D560 /* regexp-stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */; };
-		894599A30F5D8729008DA8FB /* debug-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8956B6CD0F5D86570033B5A2 /* debug-agent.cc */; };
-		8946827512C26EB700C914BC /* objects-printer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8946827412C26EB700C914BC /* objects-printer.cc */; };
-		8946827612C26EB700C914BC /* objects-printer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8946827412C26EB700C914BC /* objects-printer.cc */; };
-		89495E480E79FC23001F68C3 /* compilation-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89495E460E79FC23001F68C3 /* compilation-cache.cc */; };
-		89495E490E79FC23001F68C3 /* compilation-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89495E460E79FC23001F68C3 /* compilation-cache.cc */; };
-		894A59E912D777E80000766D /* lithium.cc in Sources */ = {isa = PBXBuildFile; fileRef = 894A59E712D777E80000766D /* lithium.cc */; };
-		894A59EA12D777E80000766D /* lithium.cc in Sources */ = {isa = PBXBuildFile; fileRef = 894A59E712D777E80000766D /* lithium.cc */; };
-		894A59EB12D777E80000766D /* lithium.cc in Sources */ = {isa = PBXBuildFile; fileRef = 894A59E712D777E80000766D /* lithium.cc */; };
-		8956922A12D4ED240072C313 /* objects-visiting.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2D1E9711212F27B00187A52 /* objects-visiting.cc */; };
-		8956922B12D4ED240072C313 /* accessors.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F60E719B8F00D62E90 /* accessors.cc */; };
-		8956922C12D4ED240072C313 /* allocation.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F80E719B8F00D62E90 /* allocation.cc */; };
-		8956922D12D4ED240072C313 /* api.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0FA0E719B8F00D62E90 /* api.cc */; };
-		8956922F12D4ED240072C313 /* assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1030E719B8F00D62E90 /* assembler.cc */; };
-		8956923012D4ED240072C313 /* ast.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1050E719B8F00D62E90 /* ast.cc */; };
-		8956923112D4ED240072C313 /* bootstrapper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1070E719B8F00D62E90 /* bootstrapper.cc */; };
-		8956923312D4ED240072C313 /* builtins.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10B0E719B8F00D62E90 /* builtins.cc */; };
-		8956923412D4ED240072C313 /* checks.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10F0E719B8F00D62E90 /* checks.cc */; };
-		8956923512D4ED240072C313 /* circular-queue.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B370F114FF62D007CDAF4 /* circular-queue.cc */; };
-		8956923612D4ED240072C313 /* code-stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1110E719B8F00D62E90 /* code-stubs.cc */; };
-		8956923812D4ED240072C313 /* codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1170E719B8F00D62E90 /* codegen.cc */; };
-		8956923912D4ED240072C313 /* compilation-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89495E460E79FC23001F68C3 /* compilation-cache.cc */; };
-		8956923A12D4ED240072C313 /* compiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1190E719B8F00D62E90 /* compiler.cc */; };
-		8956923B12D4ED240072C313 /* contexts.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11C0E719B8F00D62E90 /* contexts.cc */; };
-		8956923C12D4ED240072C313 /* conversions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11F0E719B8F00D62E90 /* conversions.cc */; };
-		8956923D12D4ED240072C313 /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */; };
-		8956923E12D4ED240072C313 /* counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1210E719B8F00D62E90 /* counters.cc */; };
-		8956924012D4ED240072C313 /* cpu-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B37241152CEA0007CDAF4 /* cpu-profiler.cc */; };
-		8956924112D4ED240072C313 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
-		8956924212D4ED240072C313 /* dateparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1260E719B8F00D62E90 /* dateparser.cc */; };
-		8956924312D4ED240072C313 /* debug-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8956B6CD0F5D86570033B5A2 /* debug-agent.cc */; };
-		8956924512D4ED240072C313 /* dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD5120165460046BF9F /* dtoa.cc */; };
-		8956924612D4ED240072C313 /* debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1280E719B8F00D62E90 /* debug.cc */; };
-		8956924812D4ED240072C313 /* disassembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12D0E719B8F00D62E90 /* disassembler.cc */; };
-		8956924912D4ED240072C313 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
-		8956924A12D4ED240072C313 /* execution.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1300E719B8F00D62E90 /* execution.cc */; };
-		8956924B12D4ED240072C313 /* factory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1320E719B8F00D62E90 /* factory.cc */; };
-		8956924C12D4ED240072C313 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
-		8956924D12D4ED240072C313 /* flags.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1350E719B8F00D62E90 /* flags.cc */; };
-		8956924E12D4ED240072C313 /* frame-element.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8981F5FE1010500F00D1520E /* frame-element.cc */; };
-		8956925012D4ED240072C313 /* frames.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13C0E719B8F00D62E90 /* frames.cc */; };
-		8956925212D4ED240072C313 /* full-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */; };
-		8956925312D4ED240072C313 /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
-		8956925412D4ED240072C313 /* global-handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13E0E719B8F00D62E90 /* global-handles.cc */; };
-		8956925512D4ED240072C313 /* handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1420E719B8F00D62E90 /* handles.cc */; };
-		8956925612D4ED240072C313 /* hashmap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1440E719B8F00D62E90 /* hashmap.cc */; };
-		8956925712D4ED240072C313 /* heap-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */; };
-		8956925812D4ED240072C313 /* heap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1470E719B8F00D62E90 /* heap.cc */; };
-		8956925912D4ED240072C313 /* ic-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14A0E719B8F00D62E90 /* ic-ia32.cc */; };
-		8956925A12D4ED240072C313 /* ic.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14C0E719B8F00D62E90 /* ic.cc */; };
-		8956925B12D4ED240072C313 /* interpreter-irregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C660EE4665300B48DEB /* interpreter-irregexp.cc */; };
-		8956925C12D4ED240072C313 /* jsregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14E0E719B8F00D62E90 /* jsregexp.cc */; };
-		8956926012D4ED240072C313 /* libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8900116B0E71CA2300F91F35 /* libraries.cc */; };
-		8956926112D4ED240072C313 /* liveedit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA91175B2D200C4CD55 /* liveedit.cc */; };
-		8956926212D4ED240072C313 /* log-utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F4B7B870FCC877A00DC4117 /* log-utils.cc */; };
-		8956926312D4ED240072C313 /* log.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1520E719B8F00D62E90 /* log.cc */; };
-		8956926512D4ED240072C313 /* mark-compact.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1590E719B8F00D62E90 /* mark-compact.cc */; };
-		8956926612D4ED240072C313 /* messages.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF15C0E719B8F00D62E90 /* messages.cc */; };
-		8956926712D4ED240072C313 /* objects-debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1600E719B8F00D62E90 /* objects-debug.cc */; };
-		8956926812D4ED240072C313 /* objects.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1620E719B8F00D62E90 /* objects.cc */; };
-		8956926A12D4ED240072C313 /* parser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1640E719B8F00D62E90 /* parser.cc */; };
-		8956926B12D4ED240072C313 /* platform-macos.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1670E719B8F00D62E90 /* platform-macos.cc */; };
-		8956926C12D4ED240072C313 /* platform-posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893A72230F7B0FF200303DD2 /* platform-posix.cc */; };
-		8956926D12D4ED240072C313 /* prettyprinter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16B0E719B8F00D62E90 /* prettyprinter.cc */; };
-		8956926E12D4ED240072C313 /* profile-generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F73E3AF114E61A100F84A5A /* profile-generator.cc */; };
-		8956926F12D4ED240072C313 /* property.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16D0E719B8F00D62E90 /* property.cc */; };
-		8956927112D4ED240072C313 /* regexp-macro-assembler-irregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C750EE466D000B48DEB /* regexp-macro-assembler-irregexp.cc */; };
-		8956927212D4ED240072C313 /* regexp-macro-assembler-tracer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C770EE466D000B48DEB /* regexp-macro-assembler-tracer.cc */; };
-		8956927312D4ED240072C313 /* regexp-macro-assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C790EE466D000B48DEB /* regexp-macro-assembler.cc */; };
-		8956927412D4ED240072C313 /* regexp-stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */; };
-		8956927712D4ED240072C313 /* rewriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16F0E719B8F00D62E90 /* rewriter.cc */; };
-		8956927812D4ED240072C313 /* runtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1710E719B8F00D62E90 /* runtime.cc */; };
-		8956927912D4ED240072C313 /* scanner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner.cc */; };
-		8956927A12D4ED240072C313 /* scopeinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1760E719B8F00D62E90 /* scopeinfo.cc */; };
-		8956927B12D4ED240072C313 /* scopes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1780E719B8F00D62E90 /* scopes.cc */; };
-		8956927C12D4ED240072C313 /* serialize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF17A0E719B8F00D62E90 /* serialize.cc */; };
-		8956927D12D4ED240072C313 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
-		8956927E12D4ED240072C313 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
-		8956927F12D4ED240072C313 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
-		8956928012D4ED240072C313 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
-		8956928212D4ED240072C313 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
-		8956928312D4ED240072C313 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
-		8956928512D4ED240072C313 /* type-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BAE1175B2D200C4CD55 /* type-info.cc */; };
-		8956928612D4ED240072C313 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
-		8956928712D4ED240072C313 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
-		8956928812D4ED240072C313 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
-		8956928912D4ED240072C313 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
-		8956928A12D4ED240072C313 /* v8threads.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19D0E719B8F00D62E90 /* v8threads.cc */; };
-		8956928B12D4ED240072C313 /* variables.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19F0E719B8F00D62E90 /* variables.cc */; };
-		8956928C12D4ED240072C313 /* version.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF32F0FAA0ED200136CF6 /* version.cc */; };
-		8956929012D4ED240072C313 /* zone.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1A20E719B8F00D62E90 /* zone.cc */; };
-		8956929212D4ED240072C313 /* bignum-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248612B14B3D0083370F /* bignum-dtoa.cc */; };
-		8956929312D4ED240072C313 /* bignum.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248812B14B3D0083370F /* bignum.cc */; };
-		8956929412D4ED240072C313 /* cached-powers.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248A12B14B3D0083370F /* cached-powers.cc */; };
-		8956929512D4ED240072C313 /* deoptimizer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248B12B14B3D0083370F /* deoptimizer.cc */; };
-		8956929612D4ED240072C313 /* hydrogen-instructions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248D12B14B3D0083370F /* hydrogen-instructions.cc */; };
-		8956929712D4ED240072C313 /* hydrogen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248F12B14B3D0083370F /* hydrogen.cc */; };
-		8956929812D4ED240072C313 /* lithium-allocator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249312B14B3D0083370F /* lithium-allocator.cc */; };
-		8956929912D4ED240072C313 /* preparse-data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249512B14B3D0083370F /* preparse-data.cc */; };
-		8956929A12D4ED240072C313 /* preparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249812B14B3D0083370F /* preparser.cc */; };
-		8956929B12D4ED240072C313 /* runtime-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249A12B14B3D0083370F /* runtime-profiler.cc */; };
-		8956929C12D4ED240072C313 /* safepoint-table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249C12B14B3D0083370F /* safepoint-table.cc */; };
-		8956929D12D4ED240072C313 /* scanner-base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249E12B14B3D0083370F /* scanner-base.cc */; };
-		8956929E12D4ED240072C313 /* string-search.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24A112B14B3D0083370F /* string-search.cc */; };
-		8956929F12D4ED240072C313 /* strtod.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24A312B14B3D0083370F /* strtod.cc */; };
-		895692A312D4ED240072C313 /* externalize-string-extension.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24D812B14B9F0083370F /* externalize-string-extension.cc */; };
-		895692A412D4ED240072C313 /* gc-extension.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E24DA12B14B9F0083370F /* gc-extension.cc */; };
-		895692A512D4ED240072C313 /* objects-printer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8946827412C26EB700C914BC /* objects-printer.cc */; };
-		8956B6CF0F5D86730033B5A2 /* debug-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8956B6CD0F5D86570033B5A2 /* debug-agent.cc */; };
-		895D5B531334212D00254083 /* isolate.cc in Sources */ = {isa = PBXBuildFile; fileRef = 895D5B521334212D00254083 /* isolate.cc */; };
-		895D5B541334212D00254083 /* isolate.cc in Sources */ = {isa = PBXBuildFile; fileRef = 895D5B521334212D00254083 /* isolate.cc */; };
-		895D5B551334212D00254083 /* isolate.cc in Sources */ = {isa = PBXBuildFile; fileRef = 895D5B521334212D00254083 /* isolate.cc */; };
-		895FA753107FFED3006F39D4 /* constants-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 895FA748107FFE73006F39D4 /* constants-arm.cc */; };
-		896FA1E5130F93D300042054 /* lithium-gap-resolver-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 896FA1E3130F93D300042054 /* lithium-gap-resolver-arm.cc */; };
-		896FD03A0E78D717003DFB6A /* libv8-arm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 89F23C870E78D5B2006B2466 /* libv8-arm.a */; };
-		897C77D012B68E3D000767A8 /* d8-debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893988150F2A3686007D5254 /* d8-debug.cc */; };
-		897C77D112B68E3D000767A8 /* d8-js.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893988320F2A3B8B007D5254 /* d8-js.cc */; };
-		897C77D212B68E3D000767A8 /* d8-posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89FB0E360F8E531900B04B3C /* d8-posix.cc */; };
-		897C77D312B68E3D000767A8 /* d8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C920EE46A1700B48DEB /* d8.cc */; };
-		897C77DD12B68E6E000767A8 /* libv8-arm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 89F23C870E78D5B2006B2466 /* libv8-arm.a */; };
-		897F767F0E71B690007ACF34 /* shell.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1B50E719C0900D62E90 /* shell.cc */; settings = {COMPILER_FLAGS = "-I../include"; }; };
-		897F76850E71B6B1007ACF34 /* libv8.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8970F2F00E719FB2006AE7B5 /* libv8.a */; };
-		8981F6001010501900D1520E /* frame-element.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8981F5FE1010500F00D1520E /* frame-element.cc */; };
-		8981F6011010502800D1520E /* frame-element.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8981F5FE1010500F00D1520E /* frame-element.cc */; };
-		898BD20E0EF6CC930068B00A /* debug-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 898BD20D0EF6CC850068B00A /* debug-ia32.cc */; };
-		898BD20F0EF6CC9A0068B00A /* debug-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 898BD20C0EF6CC850068B00A /* debug-arm.cc */; };
-		89A15C7B0EE466EB00B48DEB /* regexp-macro-assembler-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C720EE466D000B48DEB /* regexp-macro-assembler-ia32.cc */; };
-		89A15C810EE4674900B48DEB /* regexp-macro-assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C790EE466D000B48DEB /* regexp-macro-assembler.cc */; };
-		89A15C830EE4675E00B48DEB /* regexp-macro-assembler-irregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C750EE466D000B48DEB /* regexp-macro-assembler-irregexp.cc */; };
-		89A15C850EE4678B00B48DEB /* interpreter-irregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C660EE4665300B48DEB /* interpreter-irregexp.cc */; };
-		89A15C8A0EE467D100B48DEB /* regexp-macro-assembler-tracer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C770EE466D000B48DEB /* regexp-macro-assembler-tracer.cc */; };
-		89A88DEC0E71A5FF0043BA31 /* accessors.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F60E719B8F00D62E90 /* accessors.cc */; };
-		89A88DED0E71A6000043BA31 /* allocation.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F80E719B8F00D62E90 /* allocation.cc */; };
-		89A88DEE0E71A6010043BA31 /* api.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0FA0E719B8F00D62E90 /* api.cc */; };
-		89A88DEF0E71A60A0043BA31 /* assembler-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1010E719B8F00D62E90 /* assembler-ia32.cc */; };
-		89A88DF00E71A60A0043BA31 /* assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1030E719B8F00D62E90 /* assembler.cc */; };
-		89A88DF10E71A60B0043BA31 /* ast.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1050E719B8F00D62E90 /* ast.cc */; };
-		89A88DF20E71A60C0043BA31 /* bootstrapper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1070E719B8F00D62E90 /* bootstrapper.cc */; };
-		89A88DF40E71A6160043BA31 /* builtins-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10A0E719B8F00D62E90 /* builtins-ia32.cc */; };
-		89A88DF50E71A6170043BA31 /* builtins.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10B0E719B8F00D62E90 /* builtins.cc */; };
-		89A88DF60E71A61C0043BA31 /* checks.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10F0E719B8F00D62E90 /* checks.cc */; };
-		89A88DF70E71A6240043BA31 /* codegen-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1150E719B8F00D62E90 /* codegen-ia32.cc */; };
-		89A88DF80E71A6260043BA31 /* codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1170E719B8F00D62E90 /* codegen.cc */; };
-		89A88DF90E71A6430043BA31 /* compiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1190E719B8F00D62E90 /* compiler.cc */; };
-		89A88DFA0E71A6440043BA31 /* contexts.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11C0E719B8F00D62E90 /* contexts.cc */; };
-		89A88DFB0E71A6440043BA31 /* conversions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11F0E719B8F00D62E90 /* conversions.cc */; };
-		89A88DFC0E71A6460043BA31 /* counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1210E719B8F00D62E90 /* counters.cc */; };
-		89A88DFD0E71A6470043BA31 /* cpu-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1240E719B8F00D62E90 /* cpu-ia32.cc */; };
-		89A88DFE0E71A6480043BA31 /* dateparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1260E719B8F00D62E90 /* dateparser.cc */; };
-		89A88DFF0E71A6530043BA31 /* debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1280E719B8F00D62E90 /* debug.cc */; };
-		89A88E000E71A6540043BA31 /* disasm-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12B0E719B8F00D62E90 /* disasm-ia32.cc */; };
-		89A88E010E71A6550043BA31 /* disassembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12D0E719B8F00D62E90 /* disassembler.cc */; };
-		89A88E030E71A65B0043BA31 /* execution.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1300E719B8F00D62E90 /* execution.cc */; };
-		89A88E040E71A65D0043BA31 /* factory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1320E719B8F00D62E90 /* factory.cc */; };
-		89A88E050E71A65D0043BA31 /* flags.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1350E719B8F00D62E90 /* flags.cc */; };
-		89A88E060E71A6600043BA31 /* frames-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1390E719B8F00D62E90 /* frames-ia32.cc */; };
-		89A88E070E71A6610043BA31 /* frames.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13C0E719B8F00D62E90 /* frames.cc */; };
-		89A88E080E71A6620043BA31 /* global-handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13E0E719B8F00D62E90 /* global-handles.cc */; };
-		89A88E090E71A6640043BA31 /* handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1420E719B8F00D62E90 /* handles.cc */; };
-		89A88E0A0E71A6650043BA31 /* hashmap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1440E719B8F00D62E90 /* hashmap.cc */; };
-		89A88E0B0E71A66C0043BA31 /* heap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1470E719B8F00D62E90 /* heap.cc */; };
-		89A88E0C0E71A66D0043BA31 /* ic-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14A0E719B8F00D62E90 /* ic-ia32.cc */; };
-		89A88E0D0E71A66E0043BA31 /* ic.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14C0E719B8F00D62E90 /* ic.cc */; };
-		89A88E0E0E71A66F0043BA31 /* jsregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14E0E719B8F00D62E90 /* jsregexp.cc */; };
-		89A88E0F0E71A6740043BA31 /* log.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1520E719B8F00D62E90 /* log.cc */; };
-		89A88E100E71A6770043BA31 /* macro-assembler-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1560E719B8F00D62E90 /* macro-assembler-ia32.cc */; };
-		89A88E110E71A6780043BA31 /* mark-compact.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1590E719B8F00D62E90 /* mark-compact.cc */; };
-		89A88E120E71A67A0043BA31 /* messages.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF15C0E719B8F00D62E90 /* messages.cc */; };
-		89A88E130E71A6860043BA31 /* objects-debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1600E719B8F00D62E90 /* objects-debug.cc */; };
-		89A88E140E71A6870043BA31 /* objects.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1620E719B8F00D62E90 /* objects.cc */; };
-		89A88E150E71A68C0043BA31 /* parser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1640E719B8F00D62E90 /* parser.cc */; };
-		89A88E160E71A68E0043BA31 /* platform-macos.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1670E719B8F00D62E90 /* platform-macos.cc */; };
-		89A88E170E71A6950043BA31 /* prettyprinter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16B0E719B8F00D62E90 /* prettyprinter.cc */; };
-		89A88E180E71A6960043BA31 /* property.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16D0E719B8F00D62E90 /* property.cc */; };
-		89A88E190E71A6970043BA31 /* rewriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16F0E719B8F00D62E90 /* rewriter.cc */; };
-		89A88E1A0E71A69B0043BA31 /* runtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1710E719B8F00D62E90 /* runtime.cc */; };
-		89A88E1B0E71A69D0043BA31 /* scanner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner.cc */; };
-		89A88E1C0E71A69E0043BA31 /* scopeinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1760E719B8F00D62E90 /* scopeinfo.cc */; };
-		89A88E1D0E71A6A00043BA31 /* scopes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1780E719B8F00D62E90 /* scopes.cc */; };
-		89A88E1E0E71A6A30043BA31 /* serialize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF17A0E719B8F00D62E90 /* serialize.cc */; };
-		89A88E1F0E71A6B40043BA31 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
-		89A88E200E71A6B60043BA31 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
-		89A88E210E71A6B70043BA31 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
-		89A88E220E71A6BC0043BA31 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
-		89A88E230E71A6BE0043BA31 /* stub-cache-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18B0E719B8F00D62E90 /* stub-cache-ia32.cc */; };
-		89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
-		89A88E250E71A6C20043BA31 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
-		89A88E270E71A6CB0043BA31 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
-		89A88E290E71A6CE0043BA31 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
-		89A88E2A0E71A6D00043BA31 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
-		89A88E2B0E71A6D10043BA31 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
-		89A88E2C0E71A6D20043BA31 /* v8threads.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19D0E719B8F00D62E90 /* v8threads.cc */; };
-		89A88E2D0E71A6D50043BA31 /* variables.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19F0E719B8F00D62E90 /* variables.cc */; };
-		89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1A20E719B8F00D62E90 /* zone.cc */; };
-		89B91B9B12D4EF95002FF4BC /* assembler-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B7C12D4EF95002FF4BC /* assembler-x64.cc */; };
-		89B91B9C12D4EF95002FF4BC /* builtins-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B7E12D4EF95002FF4BC /* builtins-x64.cc */; };
-		89B91B9D12D4EF95002FF4BC /* code-stubs-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B7F12D4EF95002FF4BC /* code-stubs-x64.cc */; };
-		89B91B9E12D4EF95002FF4BC /* codegen-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8212D4EF95002FF4BC /* codegen-x64.cc */; };
-		89B91B9F12D4EF95002FF4BC /* cpu-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8412D4EF95002FF4BC /* cpu-x64.cc */; };
-		89B91BA012D4EF95002FF4BC /* debug-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8512D4EF95002FF4BC /* debug-x64.cc */; };
-		89B91BA112D4EF95002FF4BC /* deoptimizer-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8612D4EF95002FF4BC /* deoptimizer-x64.cc */; };
-		89B91BA212D4EF95002FF4BC /* disasm-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8712D4EF95002FF4BC /* disasm-x64.cc */; };
-		89B91BA312D4EF95002FF4BC /* frames-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8812D4EF95002FF4BC /* frames-x64.cc */; };
-		89B91BA412D4EF95002FF4BC /* full-codegen-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8A12D4EF95002FF4BC /* full-codegen-x64.cc */; };
-		89B91BA512D4EF95002FF4BC /* ic-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8B12D4EF95002FF4BC /* ic-x64.cc */; };
-		89B91BA712D4EF95002FF4BC /* macro-assembler-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B8F12D4EF95002FF4BC /* macro-assembler-x64.cc */; };
-		89B91BA812D4EF95002FF4BC /* regexp-macro-assembler-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B9112D4EF95002FF4BC /* regexp-macro-assembler-x64.cc */; };
-		89B91BAA12D4EF95002FF4BC /* simulator-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B9612D4EF95002FF4BC /* simulator-x64.cc */; };
-		89B91BAB12D4EF95002FF4BC /* stub-cache-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89B91B9812D4EF95002FF4BC /* stub-cache-x64.cc */; };
-		89B91BB812D4F02A002FF4BC /* shell.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1B50E719C0900D62E90 /* shell.cc */; settings = {COMPILER_FLAGS = "-I../include"; }; };
-		89B91BC512D4F02A002FF4BC /* d8-debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893988150F2A3686007D5254 /* d8-debug.cc */; };
-		89B91BC612D4F02A002FF4BC /* d8-js.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893988320F2A3B8B007D5254 /* d8-js.cc */; };
-		89B91BC712D4F02A002FF4BC /* d8-posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89FB0E360F8E531900B04B3C /* d8-posix.cc */; };
-		89B91BC812D4F02A002FF4BC /* d8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89A15C920EE46A1700B48DEB /* d8.cc */; };
-		89B91BFA12D4F1AA002FF4BC /* libv8-x64.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 895692AA12D4ED240072C313 /* libv8-x64.a */; };
-		89B91BFB12D4F1BB002FF4BC /* libv8-x64.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 895692AA12D4ED240072C313 /* libv8-x64.a */; };
-		89B933AF0FAA0F9600201304 /* version.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF32F0FAA0ED200136CF6 /* version.cc */; };
-		89B933B00FAA0F9D00201304 /* version.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF32F0FAA0ED200136CF6 /* version.cc */; };
-		89D7DDD512E8DDCF001E2B82 /* lithium-gap-resolver-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89D7DDD312E8DDCF001E2B82 /* lithium-gap-resolver-ia32.cc */; };
-		89D7DDDA12E8DE09001E2B82 /* gdb-jit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89D7DDD612E8DE09001E2B82 /* gdb-jit.cc */; };
-		89D7DDDB12E8DE09001E2B82 /* inspector.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89D7DDD812E8DE09001E2B82 /* inspector.cc */; };
-		89D7DDDC12E8DE09001E2B82 /* gdb-jit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89D7DDD612E8DE09001E2B82 /* gdb-jit.cc */; };
-		89D7DDDD12E8DE09001E2B82 /* inspector.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89D7DDD812E8DE09001E2B82 /* inspector.cc */; };
-		89D7DDDE12E8DE09001E2B82 /* gdb-jit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89D7DDD612E8DE09001E2B82 /* gdb-jit.cc */; };
-		89D7DDDF12E8DE09001E2B82 /* inspector.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89D7DDD812E8DE09001E2B82 /* inspector.cc */; };
-		89F23C3F0E78D5B2006B2466 /* accessors.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F60E719B8F00D62E90 /* accessors.cc */; };
-		89F23C400E78D5B2006B2466 /* allocation.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F80E719B8F00D62E90 /* allocation.cc */; };
-		89F23C410E78D5B2006B2466 /* api.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0FA0E719B8F00D62E90 /* api.cc */; };
-		89F23C430E78D5B2006B2466 /* assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1030E719B8F00D62E90 /* assembler.cc */; };
-		89F23C440E78D5B2006B2466 /* ast.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1050E719B8F00D62E90 /* ast.cc */; };
-		89F23C450E78D5B2006B2466 /* bootstrapper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1070E719B8F00D62E90 /* bootstrapper.cc */; };
-		89F23C470E78D5B2006B2466 /* builtins.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10B0E719B8F00D62E90 /* builtins.cc */; };
-		89F23C480E78D5B2006B2466 /* checks.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10F0E719B8F00D62E90 /* checks.cc */; };
-		89F23C490E78D5B2006B2466 /* code-stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1110E719B8F00D62E90 /* code-stubs.cc */; };
-		89F23C4B0E78D5B2006B2466 /* codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1170E719B8F00D62E90 /* codegen.cc */; };
-		89F23C4C0E78D5B2006B2466 /* compiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1190E719B8F00D62E90 /* compiler.cc */; };
-		89F23C4D0E78D5B2006B2466 /* contexts.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11C0E719B8F00D62E90 /* contexts.cc */; };
-		89F23C4E0E78D5B2006B2466 /* conversions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11F0E719B8F00D62E90 /* conversions.cc */; };
-		89F23C4F0E78D5B2006B2466 /* counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1210E719B8F00D62E90 /* counters.cc */; };
-		89F23C510E78D5B2006B2466 /* dateparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1260E719B8F00D62E90 /* dateparser.cc */; };
-		89F23C520E78D5B2006B2466 /* debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1280E719B8F00D62E90 /* debug.cc */; };
-		89F23C540E78D5B2006B2466 /* disassembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12D0E719B8F00D62E90 /* disassembler.cc */; };
-		89F23C560E78D5B2006B2466 /* execution.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1300E719B8F00D62E90 /* execution.cc */; };
-		89F23C570E78D5B2006B2466 /* factory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1320E719B8F00D62E90 /* factory.cc */; };
-		89F23C580E78D5B2006B2466 /* flags.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1350E719B8F00D62E90 /* flags.cc */; };
-		89F23C5A0E78D5B2006B2466 /* frames.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13C0E719B8F00D62E90 /* frames.cc */; };
-		89F23C5B0E78D5B2006B2466 /* global-handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13E0E719B8F00D62E90 /* global-handles.cc */; };
-		89F23C5C0E78D5B2006B2466 /* handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1420E719B8F00D62E90 /* handles.cc */; };
-		89F23C5D0E78D5B2006B2466 /* hashmap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1440E719B8F00D62E90 /* hashmap.cc */; };
-		89F23C5E0E78D5B2006B2466 /* heap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1470E719B8F00D62E90 /* heap.cc */; };
-		89F23C600E78D5B2006B2466 /* ic.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14C0E719B8F00D62E90 /* ic.cc */; };
-		89F23C610E78D5B2006B2466 /* jsregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14E0E719B8F00D62E90 /* jsregexp.cc */; };
-		89F23C620E78D5B2006B2466 /* libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8900116B0E71CA2300F91F35 /* libraries.cc */; };
-		89F23C630E78D5B2006B2466 /* log.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1520E719B8F00D62E90 /* log.cc */; };
-		89F23C650E78D5B2006B2466 /* mark-compact.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1590E719B8F00D62E90 /* mark-compact.cc */; };
-		89F23C660E78D5B2006B2466 /* messages.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF15C0E719B8F00D62E90 /* messages.cc */; };
-		89F23C670E78D5B2006B2466 /* objects-debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1600E719B8F00D62E90 /* objects-debug.cc */; };
-		89F23C680E78D5B2006B2466 /* objects.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1620E719B8F00D62E90 /* objects.cc */; };
-		89F23C690E78D5B2006B2466 /* parser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1640E719B8F00D62E90 /* parser.cc */; };
-		89F23C6A0E78D5B2006B2466 /* platform-macos.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1670E719B8F00D62E90 /* platform-macos.cc */; };
-		89F23C6B0E78D5B2006B2466 /* prettyprinter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16B0E719B8F00D62E90 /* prettyprinter.cc */; };
-		89F23C6C0E78D5B2006B2466 /* property.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16D0E719B8F00D62E90 /* property.cc */; };
-		89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16F0E719B8F00D62E90 /* rewriter.cc */; };
-		89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1710E719B8F00D62E90 /* runtime.cc */; };
-		89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner.cc */; };
-		89F23C700E78D5B2006B2466 /* scopeinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1760E719B8F00D62E90 /* scopeinfo.cc */; };
-		89F23C710E78D5B2006B2466 /* scopes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1780E719B8F00D62E90 /* scopes.cc */; };
-		89F23C720E78D5B2006B2466 /* serialize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF17A0E719B8F00D62E90 /* serialize.cc */; };
-		89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
-		89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
-		89F23C750E78D5B2006B2466 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
-		89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
-		89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
-		89F23C790E78D5B2006B2466 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
-		89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
-		89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
-		89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
-		89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
-		89F23C800E78D5B2006B2466 /* v8threads.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19D0E719B8F00D62E90 /* v8threads.cc */; };
-		89F23C810E78D5B2006B2466 /* variables.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19F0E719B8F00D62E90 /* variables.cc */; };
-		89F23C820E78D5B2006B2466 /* zone.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1A20E719B8F00D62E90 /* zone.cc */; };
-		89F23C8E0E78D5B6006B2466 /* shell.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1B50E719C0900D62E90 /* shell.cc */; settings = {COMPILER_FLAGS = "-I../include"; }; };
-		89F23C970E78D5E3006B2466 /* assembler-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0FE0E719B8F00D62E90 /* assembler-arm.cc */; };
-		89F23C980E78D5E7006B2466 /* builtins-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1090E719B8F00D62E90 /* builtins-arm.cc */; };
-		89F23C990E78D5E9006B2466 /* codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1140E719B8F00D62E90 /* codegen-arm.cc */; };
-		89F23C9A0E78D5EC006B2466 /* cpu-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1230E719B8F00D62E90 /* cpu-arm.cc */; };
-		89F23C9B0E78D5EE006B2466 /* disasm-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12A0E719B8F00D62E90 /* disasm-arm.cc */; };
-		89F23C9C0E78D5F1006B2466 /* frames-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1370E719B8F00D62E90 /* frames-arm.cc */; };
-		89F23C9D0E78D5FB006B2466 /* ic-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1490E719B8F00D62E90 /* ic-arm.cc */; };
-		89F23C9E0E78D5FD006B2466 /* macro-assembler-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1540E719B8F00D62E90 /* macro-assembler-arm.cc */; };
-		89F23C9F0E78D604006B2466 /* simulator-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF17D0E719B8F00D62E90 /* simulator-arm.cc */; };
-		89F23CA00E78D609006B2466 /* stub-cache-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */; };
-		89F3605B12DCDF6400ACF8A6 /* lithium-codegen-x64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89F3605A12DCDF6400ACF8A6 /* lithium-codegen-x64.cc */; };
-		89FB0E3A0F8E533F00B04B3C /* d8-posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89FB0E360F8E531900B04B3C /* d8-posix.cc */; };
-		9F11D9A0105AF0A300EBE5B2 /* heap-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */; };
-		9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */; };
-		9F2B3711114FF62D007CDAF4 /* circular-queue.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B370F114FF62D007CDAF4 /* circular-queue.cc */; };
-		9F2B3712114FF62D007CDAF4 /* circular-queue.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B370F114FF62D007CDAF4 /* circular-queue.cc */; };
-		9F2B37261152CEA0007CDAF4 /* cpu-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B37241152CEA0007CDAF4 /* cpu-profiler.cc */; };
-		9F2B37271152CEA0007CDAF4 /* cpu-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B37241152CEA0007CDAF4 /* cpu-profiler.cc */; };
-		9F4B7B890FCC877A00DC4117 /* log-utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F4B7B870FCC877A00DC4117 /* log-utils.cc */; };
-		9F4B7B8A0FCC877A00DC4117 /* log-utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F4B7B870FCC877A00DC4117 /* log-utils.cc */; };
-		9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F73E3AF114E61A100F84A5A /* profile-generator.cc */; };
-		9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F73E3AF114E61A100F84A5A /* profile-generator.cc */; };
-		9F92FAA90F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
-		9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
-		9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
-		9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
-		9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
-		9FA38BB71175B2D200C4CD55 /* full-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */; };
-		9FA38BB81175B2D200C4CD55 /* liveedit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA91175B2D200C4CD55 /* liveedit.cc */; };
-		9FA38BB91175B2D200C4CD55 /* type-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BAE1175B2D200C4CD55 /* type-info.cc */; };
-		9FA38BBA1175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
-		9FA38BBB1175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
-		9FA38BBC1175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
-		9FA38BBE1175B2D200C4CD55 /* full-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */; };
-		9FA38BBF1175B2D200C4CD55 /* liveedit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA91175B2D200C4CD55 /* liveedit.cc */; };
-		9FA38BC01175B2D200C4CD55 /* type-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BAE1175B2D200C4CD55 /* type-info.cc */; };
-		9FA38BC51175B2E500C4CD55 /* full-codegen-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */; };
-		9FA38BCF1175B30400C4CD55 /* full-codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */; };
-		C2BD4BD7120165460046BF9F /* dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD5120165460046BF9F /* dtoa.cc */; };
-		C2BD4BDB120165A70046BF9F /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */; };
-		C2BD4BE4120166180046BF9F /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */; };
-		C2BD4BE51201661F0046BF9F /* dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD5120165460046BF9F /* dtoa.cc */; };
-		C2D1E9731212F2BC00187A52 /* objects-visiting.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2D1E9711212F27B00187A52 /* objects-visiting.cc */; };
-		C2D1E9741212F2CF00187A52 /* objects-visiting.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2D1E9711212F27B00187A52 /* objects-visiting.cc */; };
-		C68081AD1225120B001EAFE4 /* code-stubs-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = C68081AB1225120B001EAFE4 /* code-stubs-arm.cc */; };
-		C68081B112251239001EAFE4 /* code-stubs-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = C68081B012251239001EAFE4 /* code-stubs-ia32.cc */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
-		7BF891960E73099F000BAF8A /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 8970F2EF0E719FB2006AE7B5;
-			remoteInfo = v8;
-		};
-		7BF891980E73099F000BAF8A /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 897F76790E71B4CC007ACF34;
-			remoteInfo = v8_shell;
-		};
-		8938A29412D63A680080CDDE /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 89B91BC012D4F02A002FF4BC;
-			remoteInfo = "d8_shell-x64";
-		};
-		8938A29612D63A680080CDDE /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 89B91BB412D4F02A002FF4BC;
-			remoteInfo = "v8_shell-x64";
-		};
-		8938A29812D63A680080CDDE /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 8956922712D4ED240072C313;
-			remoteInfo = "v8-x64";
-		};
-		893988020F2A35FA007D5254 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 8970F2EF0E719FB2006AE7B5;
-			remoteInfo = v8;
-		};
-		8939880F0F2A3647007D5254 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 893987FE0F2A35FA007D5254;
-			remoteInfo = d8_shell;
-		};
-		896FD03B0E78D71F003DFB6A /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 89F23C3C0E78D5B2006B2466;
-			remoteInfo = "v8-arm";
-		};
-		896FD03D0E78D731003DFB6A /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 89F23C3C0E78D5B2006B2466;
-			remoteInfo = "v8-arm";
-		};
-		896FD03F0E78D735003DFB6A /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 89F23C880E78D5B6006B2466;
-			remoteInfo = "v8_shell-arm";
-		};
-		897C77DB12B68E5D000767A8 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 89F23C3C0E78D5B2006B2466;
-			remoteInfo = "v8-arm";
-		};
-		897F76820E71B6AC007ACF34 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 8970F2EF0E719FB2006AE7B5;
-			remoteInfo = v8;
-		};
-		89B91BD012D4F036002FF4BC /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 8956922712D4ED240072C313;
-			remoteInfo = "v8-x64";
-		};
-		89B91BFC12D4F1BF002FF4BC /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 8956922712D4ED240072C313;
-			remoteInfo = "v8-x64";
-		};
-		89EED40C12B69A0A0075BE1C /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 897C77CB12B68E3D000767A8;
-			remoteInfo = "d8_shell-arm";
-		};
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXFileReference section */
-		22A76C900FF259E600FDC694 /* log-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "log-inl.h"; sourceTree = "<group>"; };
-		58DA027D136ECC87007399A4 /* experimental-libraries.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "experimental-libraries.cc"; sourceTree = "<group>"; };
-		8900116B0E71CA2300F91F35 /* libraries.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = libraries.cc; sourceTree = "<group>"; };
-		891C92FD1334226000FF4757 /* lithium-allocator-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "lithium-allocator-inl.h"; sourceTree = "<group>"; };
-		891C92FE133422EB00FF4757 /* isolate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = isolate.h; sourceTree = "<group>"; };
-		8924315A12F8539900906AB2 /* lithium-gap-resolver-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-gap-resolver-x64.cc"; path = "x64/lithium-gap-resolver-x64.cc"; sourceTree = "<group>"; };
-		8924315B12F8539900906AB2 /* lithium-gap-resolver-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-gap-resolver-x64.h"; path = "x64/lithium-gap-resolver-x64.h"; sourceTree = "<group>"; };
-		8938A2A212D63B630080CDDE /* lithium-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-x64.cc"; path = "x64/lithium-x64.cc"; sourceTree = "<group>"; };
-		893986D40F29020C007D5254 /* apiutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = apiutils.h; sourceTree = "<group>"; };
-		8939880B0F2A35FA007D5254 /* d8 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = d8; sourceTree = BUILT_PRODUCTS_DIR; };
-		893988150F2A3686007D5254 /* d8-debug.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-debug.cc"; path = "../src/d8-debug.cc"; sourceTree = "<group>"; };
-		893988320F2A3B8B007D5254 /* d8-js.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "d8-js.cc"; sourceTree = "<group>"; };
-		893A72230F7B0FF200303DD2 /* platform-posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "platform-posix.cc"; sourceTree = "<group>"; };
-		893A722A0F7B4A3200303DD2 /* dateparser-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "dateparser-inl.h"; sourceTree = "<group>"; };
-		893A72320F7B4AD700303DD2 /* d8-debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "d8-debug.h"; path = "../src/d8-debug.h"; sourceTree = "<group>"; };
-		893E248112B14AD40083370F /* v8-preparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-preparser.h"; sourceTree = "<group>"; };
-		893E248212B14AD40083370F /* v8-testing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-testing.h"; sourceTree = "<group>"; };
-		893E248312B14AD40083370F /* v8stdint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8stdint.h; sourceTree = "<group>"; };
-		893E248412B14B3D0083370F /* ast-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ast-inl.h"; sourceTree = "<group>"; };
-		893E248512B14B3D0083370F /* atomicops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atomicops.h; sourceTree = "<group>"; };
-		893E248612B14B3D0083370F /* bignum-dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "bignum-dtoa.cc"; sourceTree = "<group>"; };
-		893E248712B14B3D0083370F /* bignum-dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "bignum-dtoa.h"; sourceTree = "<group>"; };
-		893E248812B14B3D0083370F /* bignum.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bignum.cc; sourceTree = "<group>"; };
-		893E248912B14B3D0083370F /* bignum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bignum.h; sourceTree = "<group>"; };
-		893E248A12B14B3D0083370F /* cached-powers.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "cached-powers.cc"; sourceTree = "<group>"; };
-		893E248B12B14B3D0083370F /* deoptimizer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = deoptimizer.cc; sourceTree = "<group>"; };
-		893E248C12B14B3D0083370F /* deoptimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deoptimizer.h; sourceTree = "<group>"; };
-		893E248D12B14B3D0083370F /* hydrogen-instructions.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "hydrogen-instructions.cc"; sourceTree = "<group>"; };
-		893E248E12B14B3D0083370F /* hydrogen-instructions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "hydrogen-instructions.h"; sourceTree = "<group>"; };
-		893E248F12B14B3D0083370F /* hydrogen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hydrogen.cc; sourceTree = "<group>"; };
-		893E249012B14B3D0083370F /* hydrogen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hydrogen.h; sourceTree = "<group>"; };
-		893E249312B14B3D0083370F /* lithium-allocator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "lithium-allocator.cc"; sourceTree = "<group>"; };
-		893E249412B14B3D0083370F /* lithium-allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "lithium-allocator.h"; sourceTree = "<group>"; };
-		893E249512B14B3D0083370F /* preparse-data.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "preparse-data.cc"; sourceTree = "<group>"; };
-		893E249612B14B3D0083370F /* preparse-data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "preparse-data.h"; sourceTree = "<group>"; };
-		893E249812B14B3D0083370F /* preparser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = preparser.cc; sourceTree = "<group>"; };
-		893E249912B14B3D0083370F /* preparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = preparser.h; sourceTree = "<group>"; };
-		893E249A12B14B3D0083370F /* runtime-profiler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "runtime-profiler.cc"; sourceTree = "<group>"; };
-		893E249B12B14B3D0083370F /* runtime-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "runtime-profiler.h"; sourceTree = "<group>"; };
-		893E249C12B14B3D0083370F /* safepoint-table.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "safepoint-table.cc"; sourceTree = "<group>"; };
-		893E249D12B14B3D0083370F /* safepoint-table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "safepoint-table.h"; sourceTree = "<group>"; };
-		893E249E12B14B3D0083370F /* scanner-base.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "scanner-base.cc"; sourceTree = "<group>"; };
-		893E249F12B14B3D0083370F /* scanner-base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "scanner-base.h"; sourceTree = "<group>"; };
-		893E24A012B14B3D0083370F /* simulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simulator.h; sourceTree = "<group>"; };
-		893E24A112B14B3D0083370F /* string-search.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "string-search.cc"; sourceTree = "<group>"; };
-		893E24A212B14B3D0083370F /* string-search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "string-search.h"; sourceTree = "<group>"; };
-		893E24A312B14B3D0083370F /* strtod.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = strtod.cc; sourceTree = "<group>"; };
-		893E24A412B14B3D0083370F /* strtod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strtod.h; sourceTree = "<group>"; };
-		893E24A512B14B3D0083370F /* v8checks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8checks.h; sourceTree = "<group>"; };
-		893E24A612B14B3D0083370F /* v8globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8globals.h; sourceTree = "<group>"; };
-		893E24A712B14B3D0083370F /* v8utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8utils.h; sourceTree = "<group>"; };
-		893E24C612B14B510083370F /* deoptimizer-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "deoptimizer-arm.cc"; path = "arm/deoptimizer-arm.cc"; sourceTree = "<group>"; };
-		893E24C712B14B510083370F /* lithium-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-arm.cc"; path = "arm/lithium-arm.cc"; sourceTree = "<group>"; };
-		893E24C812B14B510083370F /* lithium-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-arm.h"; path = "arm/lithium-arm.h"; sourceTree = "<group>"; };
-		893E24C912B14B520083370F /* lithium-codegen-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-codegen-arm.cc"; path = "arm/lithium-codegen-arm.cc"; sourceTree = "<group>"; };
-		893E24CA12B14B520083370F /* lithium-codegen-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-codegen-arm.h"; path = "arm/lithium-codegen-arm.h"; sourceTree = "<group>"; };
-		893E24CF12B14B780083370F /* atomicops_internals_x86_macosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atomicops_internals_x86_macosx.h; sourceTree = "<group>"; };
-		893E24D012B14B8A0083370F /* deoptimizer-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "deoptimizer-ia32.cc"; path = "ia32/deoptimizer-ia32.cc"; sourceTree = "<group>"; };
-		893E24D112B14B8A0083370F /* lithium-codegen-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-codegen-ia32.cc"; path = "ia32/lithium-codegen-ia32.cc"; sourceTree = "<group>"; };
-		893E24D212B14B8A0083370F /* lithium-codegen-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-codegen-ia32.h"; path = "ia32/lithium-codegen-ia32.h"; sourceTree = "<group>"; };
-		893E24D312B14B8A0083370F /* lithium-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-ia32.cc"; path = "ia32/lithium-ia32.cc"; sourceTree = "<group>"; };
-		893E24D412B14B8A0083370F /* lithium-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-ia32.h"; path = "ia32/lithium-ia32.h"; sourceTree = "<group>"; };
-		893E24D812B14B9F0083370F /* externalize-string-extension.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "externalize-string-extension.cc"; path = "extensions/externalize-string-extension.cc"; sourceTree = "<group>"; };
-		893E24D912B14B9F0083370F /* externalize-string-extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "externalize-string-extension.h"; path = "extensions/externalize-string-extension.h"; sourceTree = "<group>"; };
-		893E24DA12B14B9F0083370F /* gc-extension.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gc-extension.cc"; path = "extensions/gc-extension.cc"; sourceTree = "<group>"; };
-		893E24DB12B14B9F0083370F /* gc-extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "gc-extension.h"; path = "extensions/gc-extension.h"; sourceTree = "<group>"; };
-		8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "regexp-stack.cc"; sourceTree = "<group>"; };
-		8944AD0F0F1D4D3A0028D560 /* regexp-stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "regexp-stack.h"; sourceTree = "<group>"; };
-		8946827412C26EB700C914BC /* objects-printer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "objects-printer.cc"; sourceTree = "<group>"; };
-		89471C7F0EB23EE400B6874B /* flag-definitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "flag-definitions.h"; sourceTree = "<group>"; };
-		89495E460E79FC23001F68C3 /* compilation-cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "compilation-cache.cc"; sourceTree = "<group>"; };
-		89495E470E79FC23001F68C3 /* compilation-cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "compilation-cache.h"; sourceTree = "<group>"; };
-		894A59E712D777E80000766D /* lithium.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lithium.cc; sourceTree = "<group>"; };
-		894A59E812D777E80000766D /* lithium.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lithium.h; sourceTree = "<group>"; };
-		895692AA12D4ED240072C313 /* libv8-x64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libv8-x64.a"; sourceTree = BUILT_PRODUCTS_DIR; };
-		8956B6CD0F5D86570033B5A2 /* debug-agent.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "debug-agent.cc"; sourceTree = "<group>"; };
-		8956B6CE0F5D86570033B5A2 /* debug-agent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "debug-agent.h"; sourceTree = "<group>"; };
-		895D5B4C1334210400254083 /* allocation-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "allocation-inl.h"; sourceTree = "<group>"; };
-		895D5B521334212D00254083 /* isolate.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = isolate.cc; sourceTree = "<group>"; };
-		895FA748107FFE73006F39D4 /* constants-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "constants-arm.cc"; path = "arm/constants-arm.cc"; sourceTree = "<group>"; };
-		8964482B0E9C00F700E7C516 /* codegen-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "codegen-ia32.h"; path = "ia32/codegen-ia32.h"; sourceTree = "<group>"; };
-		896448BC0E9D530500E7C516 /* codegen-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "codegen-arm.h"; path = "arm/codegen-arm.h"; sourceTree = "<group>"; };
-		896FA1E3130F93D300042054 /* lithium-gap-resolver-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-gap-resolver-arm.cc"; path = "arm/lithium-gap-resolver-arm.cc"; sourceTree = "<group>"; };
-		896FA1E4130F93D300042054 /* lithium-gap-resolver-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-gap-resolver-arm.h"; path = "arm/lithium-gap-resolver-arm.h"; sourceTree = "<group>"; };
-		8970F2F00E719FB2006AE7B5 /* libv8.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libv8.a; sourceTree = BUILT_PRODUCTS_DIR; };
-		897C77D912B68E3D000767A8 /* d8-arm */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "d8-arm"; sourceTree = BUILT_PRODUCTS_DIR; };
-		897F767A0E71B4CC007ACF34 /* v8_shell */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = v8_shell; sourceTree = BUILT_PRODUCTS_DIR; };
-		897FF0D40E719A8500D62E90 /* v8-debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-debug.h"; sourceTree = "<group>"; };
-		897FF0D50E719A8500D62E90 /* v8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8.h; sourceTree = "<group>"; };
-		897FF0F60E719B8F00D62E90 /* accessors.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = accessors.cc; sourceTree = "<group>"; };
-		897FF0F70E719B8F00D62E90 /* accessors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = accessors.h; sourceTree = "<group>"; };
-		897FF0F80E719B8F00D62E90 /* allocation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = allocation.cc; sourceTree = "<group>"; };
-		897FF0F90E719B8F00D62E90 /* allocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = allocation.h; sourceTree = "<group>"; };
-		897FF0FA0E719B8F00D62E90 /* api.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = api.cc; sourceTree = "<group>"; };
-		897FF0FB0E719B8F00D62E90 /* api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = api.h; sourceTree = "<group>"; };
-		897FF0FC0E719B8F00D62E90 /* arguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arguments.h; sourceTree = "<group>"; };
-		897FF0FD0E719B8F00D62E90 /* assembler-arm-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-arm-inl.h"; path = "arm/assembler-arm-inl.h"; sourceTree = "<group>"; };
-		897FF0FE0E719B8F00D62E90 /* assembler-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "assembler-arm.cc"; path = "arm/assembler-arm.cc"; sourceTree = "<group>"; };
-		897FF0FF0E719B8F00D62E90 /* assembler-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-arm.h"; path = "arm/assembler-arm.h"; sourceTree = "<group>"; };
-		897FF1000E719B8F00D62E90 /* assembler-ia32-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-ia32-inl.h"; path = "ia32/assembler-ia32-inl.h"; sourceTree = "<group>"; };
-		897FF1010E719B8F00D62E90 /* assembler-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "assembler-ia32.cc"; path = "ia32/assembler-ia32.cc"; sourceTree = "<group>"; };
-		897FF1020E719B8F00D62E90 /* assembler-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-ia32.h"; path = "ia32/assembler-ia32.h"; sourceTree = "<group>"; };
-		897FF1030E719B8F00D62E90 /* assembler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = assembler.cc; sourceTree = "<group>"; };
-		897FF1040E719B8F00D62E90 /* assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = assembler.h; sourceTree = "<group>"; };
-		897FF1050E719B8F00D62E90 /* ast.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ast.cc; sourceTree = "<group>"; };
-		897FF1060E719B8F00D62E90 /* ast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ast.h; sourceTree = "<group>"; };
-		897FF1070E719B8F00D62E90 /* bootstrapper.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bootstrapper.cc; sourceTree = "<group>"; };
-		897FF1080E719B8F00D62E90 /* bootstrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootstrapper.h; sourceTree = "<group>"; };
-		897FF1090E719B8F00D62E90 /* builtins-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "builtins-arm.cc"; path = "arm/builtins-arm.cc"; sourceTree = "<group>"; };
-		897FF10A0E719B8F00D62E90 /* builtins-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "builtins-ia32.cc"; path = "ia32/builtins-ia32.cc"; sourceTree = "<group>"; };
-		897FF10B0E719B8F00D62E90 /* builtins.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtins.cc; sourceTree = "<group>"; };
-		897FF10C0E719B8F00D62E90 /* builtins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = builtins.h; sourceTree = "<group>"; };
-		897FF10D0E719B8F00D62E90 /* char-predicates-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "char-predicates-inl.h"; sourceTree = "<group>"; };
-		897FF10E0E719B8F00D62E90 /* char-predicates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "char-predicates.h"; sourceTree = "<group>"; };
-		897FF10F0E719B8F00D62E90 /* checks.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = checks.cc; sourceTree = "<group>"; };
-		897FF1100E719B8F00D62E90 /* checks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = checks.h; sourceTree = "<group>"; };
-		897FF1110E719B8F00D62E90 /* code-stubs.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "code-stubs.cc"; sourceTree = "<group>"; };
-		897FF1120E719B8F00D62E90 /* code-stubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "code-stubs.h"; sourceTree = "<group>"; };
-		897FF1130E719B8F00D62E90 /* code.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = code.h; sourceTree = "<group>"; };
-		897FF1140E719B8F00D62E90 /* codegen-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "codegen-arm.cc"; path = "arm/codegen-arm.cc"; sourceTree = "<group>"; };
-		897FF1150E719B8F00D62E90 /* codegen-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "codegen-ia32.cc"; path = "ia32/codegen-ia32.cc"; sourceTree = "<group>"; };
-		897FF1170E719B8F00D62E90 /* codegen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = codegen.cc; sourceTree = "<group>"; };
-		897FF1180E719B8F00D62E90 /* codegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = codegen.h; sourceTree = "<group>"; };
-		897FF1190E719B8F00D62E90 /* compiler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = compiler.cc; sourceTree = "<group>"; };
-		897FF11A0E719B8F00D62E90 /* compiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compiler.h; sourceTree = "<group>"; };
-		897FF11B0E719B8F00D62E90 /* constants-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "constants-arm.h"; path = "arm/constants-arm.h"; sourceTree = "<group>"; };
-		897FF11C0E719B8F00D62E90 /* contexts.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = contexts.cc; sourceTree = "<group>"; };
-		897FF11D0E719B8F00D62E90 /* contexts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = contexts.h; sourceTree = "<group>"; };
-		897FF11E0E719B8F00D62E90 /* conversions-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "conversions-inl.h"; sourceTree = "<group>"; };
-		897FF11F0E719B8F00D62E90 /* conversions.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conversions.cc; sourceTree = "<group>"; };
-		897FF1200E719B8F00D62E90 /* conversions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conversions.h; sourceTree = "<group>"; };
-		897FF1210E719B8F00D62E90 /* counters.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = counters.cc; sourceTree = "<group>"; };
-		897FF1220E719B8F00D62E90 /* counters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = counters.h; sourceTree = "<group>"; };
-		897FF1230E719B8F00D62E90 /* cpu-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "cpu-arm.cc"; path = "arm/cpu-arm.cc"; sourceTree = "<group>"; };
-		897FF1240E719B8F00D62E90 /* cpu-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "cpu-ia32.cc"; path = "ia32/cpu-ia32.cc"; sourceTree = "<group>"; };
-		897FF1250E719B8F00D62E90 /* cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu.h; sourceTree = "<group>"; };
-		897FF1260E719B8F00D62E90 /* dateparser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dateparser.cc; sourceTree = "<group>"; };
-		897FF1270E719B8F00D62E90 /* dateparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dateparser.h; sourceTree = "<group>"; };
-		897FF1280E719B8F00D62E90 /* debug.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cc; sourceTree = "<group>"; };
-		897FF1290E719B8F00D62E90 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
-		897FF12A0E719B8F00D62E90 /* disasm-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "disasm-arm.cc"; path = "arm/disasm-arm.cc"; sourceTree = "<group>"; };
-		897FF12B0E719B8F00D62E90 /* disasm-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "disasm-ia32.cc"; path = "ia32/disasm-ia32.cc"; sourceTree = "<group>"; };
-		897FF12C0E719B8F00D62E90 /* disasm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = disasm.h; sourceTree = "<group>"; };
-		897FF12D0E719B8F00D62E90 /* disassembler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = disassembler.cc; sourceTree = "<group>"; };
-		897FF12E0E719B8F00D62E90 /* disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = disassembler.h; sourceTree = "<group>"; };
-		897FF1300E719B8F00D62E90 /* execution.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = execution.cc; sourceTree = "<group>"; };
-		897FF1310E719B8F00D62E90 /* execution.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = execution.h; sourceTree = "<group>"; };
-		897FF1320E719B8F00D62E90 /* factory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = factory.cc; sourceTree = "<group>"; };
-		897FF1330E719B8F00D62E90 /* factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = factory.h; sourceTree = "<group>"; };
-		897FF1350E719B8F00D62E90 /* flags.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = flags.cc; sourceTree = "<group>"; };
-		897FF1360E719B8F00D62E90 /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flags.h; sourceTree = "<group>"; };
-		897FF1370E719B8F00D62E90 /* frames-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "frames-arm.cc"; path = "arm/frames-arm.cc"; sourceTree = "<group>"; };
-		897FF1380E719B8F00D62E90 /* frames-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "frames-arm.h"; path = "arm/frames-arm.h"; sourceTree = "<group>"; };
-		897FF1390E719B8F00D62E90 /* frames-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "frames-ia32.cc"; path = "ia32/frames-ia32.cc"; sourceTree = "<group>"; };
-		897FF13A0E719B8F00D62E90 /* frames-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "frames-ia32.h"; path = "ia32/frames-ia32.h"; sourceTree = "<group>"; };
-		897FF13B0E719B8F00D62E90 /* frames-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "frames-inl.h"; sourceTree = "<group>"; };
-		897FF13C0E719B8F00D62E90 /* frames.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = frames.cc; sourceTree = "<group>"; };
-		897FF13D0E719B8F00D62E90 /* frames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = frames.h; sourceTree = "<group>"; };
-		897FF13E0E719B8F00D62E90 /* global-handles.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "global-handles.cc"; sourceTree = "<group>"; };
-		897FF13F0E719B8F00D62E90 /* global-handles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "global-handles.h"; sourceTree = "<group>"; };
-		897FF1400E719B8F00D62E90 /* globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = globals.h; sourceTree = "<group>"; };
-		897FF1410E719B8F00D62E90 /* handles-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "handles-inl.h"; sourceTree = "<group>"; };
-		897FF1420E719B8F00D62E90 /* handles.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = handles.cc; sourceTree = "<group>"; };
-		897FF1430E719B8F00D62E90 /* handles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = handles.h; sourceTree = "<group>"; };
-		897FF1440E719B8F00D62E90 /* hashmap.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hashmap.cc; sourceTree = "<group>"; };
-		897FF1450E719B8F00D62E90 /* hashmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hashmap.h; sourceTree = "<group>"; };
-		897FF1460E719B8F00D62E90 /* heap-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "heap-inl.h"; sourceTree = "<group>"; };
-		897FF1470E719B8F00D62E90 /* heap.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = heap.cc; sourceTree = "<group>"; };
-		897FF1480E719B8F00D62E90 /* heap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = heap.h; sourceTree = "<group>"; };
-		897FF1490E719B8F00D62E90 /* ic-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ic-arm.cc"; path = "arm/ic-arm.cc"; sourceTree = "<group>"; };
-		897FF14A0E719B8F00D62E90 /* ic-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ic-ia32.cc"; path = "ia32/ic-ia32.cc"; sourceTree = "<group>"; };
-		897FF14B0E719B8F00D62E90 /* ic-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ic-inl.h"; sourceTree = "<group>"; };
-		897FF14C0E719B8F00D62E90 /* ic.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ic.cc; sourceTree = "<group>"; };
-		897FF14D0E719B8F00D62E90 /* ic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ic.h; sourceTree = "<group>"; };
-		897FF14E0E719B8F00D62E90 /* jsregexp.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsregexp.cc; sourceTree = "<group>"; };
-		897FF14F0E719B8F00D62E90 /* jsregexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jsregexp.h; sourceTree = "<group>"; };
-		897FF1500E719B8F00D62E90 /* list-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "list-inl.h"; sourceTree = "<group>"; };
-		897FF1510E719B8F00D62E90 /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = "<group>"; };
-		897FF1520E719B8F00D62E90 /* log.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = log.cc; sourceTree = "<group>"; };
-		897FF1530E719B8F00D62E90 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = "<group>"; };
-		897FF1540E719B8F00D62E90 /* macro-assembler-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "macro-assembler-arm.cc"; path = "arm/macro-assembler-arm.cc"; sourceTree = "<group>"; };
-		897FF1550E719B8F00D62E90 /* macro-assembler-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "macro-assembler-arm.h"; path = "arm/macro-assembler-arm.h"; sourceTree = "<group>"; };
-		897FF1560E719B8F00D62E90 /* macro-assembler-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "macro-assembler-ia32.cc"; path = "ia32/macro-assembler-ia32.cc"; sourceTree = "<group>"; };
-		897FF1570E719B8F00D62E90 /* macro-assembler-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "macro-assembler-ia32.h"; path = "ia32/macro-assembler-ia32.h"; sourceTree = "<group>"; };
-		897FF1580E719B8F00D62E90 /* macro-assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "macro-assembler.h"; sourceTree = "<group>"; };
-		897FF1590E719B8F00D62E90 /* mark-compact.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "mark-compact.cc"; sourceTree = "<group>"; };
-		897FF15A0E719B8F00D62E90 /* mark-compact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mark-compact.h"; sourceTree = "<group>"; };
-		897FF15B0E719B8F00D62E90 /* v8memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8memory.h; sourceTree = "<group>"; };
-		897FF15C0E719B8F00D62E90 /* messages.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = messages.cc; sourceTree = "<group>"; };
-		897FF15D0E719B8F00D62E90 /* messages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messages.h; sourceTree = "<group>"; };
-		897FF15E0E719B8F00D62E90 /* mksnapshot.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mksnapshot.cc; sourceTree = "<group>"; };
-		897FF15F0E719B8F00D62E90 /* natives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = natives.h; sourceTree = "<group>"; };
-		897FF1600E719B8F00D62E90 /* objects-debug.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "objects-debug.cc"; sourceTree = "<group>"; };
-		897FF1610E719B8F00D62E90 /* objects-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "objects-inl.h"; sourceTree = "<group>"; };
-		897FF1620E719B8F00D62E90 /* objects.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objects.cc; sourceTree = "<group>"; };
-		897FF1630E719B8F00D62E90 /* objects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = objects.h; sourceTree = "<group>"; };
-		897FF1640E719B8F00D62E90 /* parser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cc; sourceTree = "<group>"; };
-		897FF1650E719B8F00D62E90 /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = "<group>"; };
-		897FF1660E719B8F00D62E90 /* platform-linux.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "platform-linux.cc"; sourceTree = "<group>"; };
-		897FF1670E719B8F00D62E90 /* platform-macos.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "platform-macos.cc"; sourceTree = "<group>"; };
-		897FF1680E719B8F00D62E90 /* platform-nullos.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "platform-nullos.cc"; sourceTree = "<group>"; };
-		897FF1690E719B8F00D62E90 /* platform-win32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "platform-win32.cc"; sourceTree = "<group>"; };
-		897FF16A0E719B8F00D62E90 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform.h; sourceTree = "<group>"; };
-		897FF16B0E719B8F00D62E90 /* prettyprinter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prettyprinter.cc; sourceTree = "<group>"; };
-		897FF16C0E719B8F00D62E90 /* prettyprinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prettyprinter.h; sourceTree = "<group>"; };
-		897FF16D0E719B8F00D62E90 /* property.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = property.cc; sourceTree = "<group>"; };
-		897FF16E0E719B8F00D62E90 /* property.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = property.h; sourceTree = "<group>"; };
-		897FF16F0E719B8F00D62E90 /* rewriter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rewriter.cc; sourceTree = "<group>"; };
-		897FF1700E719B8F00D62E90 /* rewriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rewriter.h; sourceTree = "<group>"; };
-		897FF1710E719B8F00D62E90 /* runtime.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = runtime.cc; sourceTree = "<group>"; };
-		897FF1720E719B8F00D62E90 /* runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = runtime.h; sourceTree = "<group>"; };
-		897FF1730E719B8F00D62E90 /* scanner.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scanner.cc; sourceTree = "<group>"; };
-		897FF1740E719B8F00D62E90 /* scanner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scanner.h; sourceTree = "<group>"; };
-		897FF1750E719B8F00D62E90 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
-		897FF1760E719B8F00D62E90 /* scopeinfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scopeinfo.cc; sourceTree = "<group>"; };
-		897FF1770E719B8F00D62E90 /* scopeinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scopeinfo.h; sourceTree = "<group>"; };
-		897FF1780E719B8F00D62E90 /* scopes.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scopes.cc; sourceTree = "<group>"; };
-		897FF1790E719B8F00D62E90 /* scopes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scopes.h; sourceTree = "<group>"; };
-		897FF17A0E719B8F00D62E90 /* serialize.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = serialize.cc; sourceTree = "<group>"; };
-		897FF17B0E719B8F00D62E90 /* serialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = serialize.h; sourceTree = "<group>"; };
-		897FF17C0E719B8F00D62E90 /* shell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shell.h; sourceTree = "<group>"; };
-		897FF17D0E719B8F00D62E90 /* simulator-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "simulator-arm.cc"; path = "arm/simulator-arm.cc"; sourceTree = "<group>"; };
-		897FF17E0E719B8F00D62E90 /* simulator-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "simulator-arm.h"; path = "arm/simulator-arm.h"; sourceTree = "<group>"; };
-		897FF17F0E719B8F00D62E90 /* simulator-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "simulator-ia32.cc"; path = "ia32/simulator-ia32.cc"; sourceTree = "<group>"; };
-		897FF1800E719B8F00D62E90 /* simulator-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "simulator-ia32.h"; path = "ia32/simulator-ia32.h"; sourceTree = "<group>"; };
-		897FF1810E719B8F00D62E90 /* smart-pointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "smart-pointer.h"; sourceTree = "<group>"; };
-		897FF1820E719B8F00D62E90 /* snapshot-common.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "snapshot-common.cc"; sourceTree = "<group>"; };
-		897FF1830E719B8F00D62E90 /* snapshot-empty.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "snapshot-empty.cc"; sourceTree = "<group>"; };
-		897FF1840E719B8F00D62E90 /* snapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = snapshot.h; sourceTree = "<group>"; };
-		897FF1850E719B8F00D62E90 /* spaces-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spaces-inl.h"; sourceTree = "<group>"; };
-		897FF1860E719B8F00D62E90 /* spaces.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spaces.cc; sourceTree = "<group>"; };
-		897FF1870E719B8F00D62E90 /* spaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spaces.h; sourceTree = "<group>"; };
-		897FF1880E719B8F00D62E90 /* string-stream.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "string-stream.cc"; sourceTree = "<group>"; };
-		897FF1890E719B8F00D62E90 /* string-stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "string-stream.h"; sourceTree = "<group>"; };
-		897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "stub-cache-arm.cc"; path = "arm/stub-cache-arm.cc"; sourceTree = "<group>"; };
-		897FF18B0E719B8F00D62E90 /* stub-cache-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "stub-cache-ia32.cc"; path = "ia32/stub-cache-ia32.cc"; sourceTree = "<group>"; };
-		897FF18C0E719B8F00D62E90 /* stub-cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "stub-cache.cc"; sourceTree = "<group>"; };
-		897FF18D0E719B8F00D62E90 /* stub-cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "stub-cache.h"; sourceTree = "<group>"; };
-		897FF18E0E719B8F00D62E90 /* token.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = token.cc; sourceTree = "<group>"; };
-		897FF18F0E719B8F00D62E90 /* token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = token.h; sourceTree = "<group>"; };
-		897FF1920E719B8F00D62E90 /* unicode-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unicode-inl.h"; sourceTree = "<group>"; };
-		897FF1930E719B8F00D62E90 /* unicode.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unicode.cc; sourceTree = "<group>"; };
-		897FF1940E719B8F00D62E90 /* unicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unicode.h; sourceTree = "<group>"; };
-		897FF1970E719B8F00D62E90 /* utils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utils.cc; sourceTree = "<group>"; };
-		897FF1980E719B8F00D62E90 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; };
-		897FF1990E719B8F00D62E90 /* v8-counters.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "v8-counters.cc"; sourceTree = "<group>"; };
-		897FF19A0E719B8F00D62E90 /* v8-counters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-counters.h"; sourceTree = "<group>"; };
-		897FF19B0E719B8F00D62E90 /* v8.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v8.cc; sourceTree = "<group>"; };
-		897FF19C0E719B8F00D62E90 /* v8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8.h; sourceTree = "<group>"; };
-		897FF19D0E719B8F00D62E90 /* v8threads.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v8threads.cc; sourceTree = "<group>"; };
-		897FF19E0E719B8F00D62E90 /* v8threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8threads.h; sourceTree = "<group>"; };
-		897FF19F0E719B8F00D62E90 /* variables.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = variables.cc; sourceTree = "<group>"; };
-		897FF1A00E719B8F00D62E90 /* variables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = variables.h; sourceTree = "<group>"; };
-		897FF1A10E719B8F00D62E90 /* zone-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "zone-inl.h"; sourceTree = "<group>"; };
-		897FF1A20E719B8F00D62E90 /* zone.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = zone.cc; sourceTree = "<group>"; };
-		897FF1A30E719B8F00D62E90 /* zone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zone.h; sourceTree = "<group>"; };
-		897FF1A60E719BC100D62E90 /* apinatives.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = apinatives.js; sourceTree = "<group>"; };
-		897FF1A70E719BC100D62E90 /* array.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = array.js; sourceTree = "<group>"; };
-		897FF1AA0E719BC100D62E90 /* math.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = math.js; sourceTree = "<group>"; };
-		897FF1AB0E719BC100D62E90 /* messages.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = messages.js; sourceTree = "<group>"; };
-		897FF1AE0E719BC100D62E90 /* runtime.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = runtime.js; sourceTree = "<group>"; };
-		897FF1AF0E719BC100D62E90 /* string.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = string.js; sourceTree = "<group>"; };
-		897FF1B00E719BC100D62E90 /* uri.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = uri.js; sourceTree = "<group>"; };
-		897FF1B10E719BC100D62E90 /* v8natives.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = v8natives.js; sourceTree = "<group>"; };
-		897FF1B50E719C0900D62E90 /* shell.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shell.cc; sourceTree = "<group>"; };
-		897FF1B60E719C2300D62E90 /* js2c.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = js2c.py; sourceTree = "<group>"; };
-		897FF1B70E719C2E00D62E90 /* macros.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = macros.py; path = ../src/macros.py; sourceTree = "<group>"; };
-		897FF32F0FAA0ED200136CF6 /* version.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = version.cc; sourceTree = "<group>"; };
-		897FF3300FAA0ED200136CF6 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
-		8981F5FE1010500F00D1520E /* frame-element.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "frame-element.cc"; sourceTree = "<group>"; };
-		8981F5FF1010500F00D1520E /* frame-element.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "frame-element.h"; sourceTree = "<group>"; };
-		898BD20C0EF6CC850068B00A /* debug-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "debug-arm.cc"; path = "arm/debug-arm.cc"; sourceTree = "<group>"; };
-		898BD20D0EF6CC850068B00A /* debug-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "debug-ia32.cc"; path = "ia32/debug-ia32.cc"; sourceTree = "<group>"; };
-		89A15C630EE4661A00B48DEB /* bytecodes-irregexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "bytecodes-irregexp.h"; sourceTree = "<group>"; };
-		89A15C660EE4665300B48DEB /* interpreter-irregexp.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "interpreter-irregexp.cc"; sourceTree = "<group>"; };
-		89A15C670EE4665300B48DEB /* interpreter-irregexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "interpreter-irregexp.h"; sourceTree = "<group>"; };
-		89A15C6D0EE466A900B48DEB /* platform-freebsd.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "platform-freebsd.cc"; sourceTree = "<group>"; };
-		89A15C700EE466D000B48DEB /* regexp-macro-assembler-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "regexp-macro-assembler-arm.cc"; path = "arm/regexp-macro-assembler-arm.cc"; sourceTree = "<group>"; };
-		89A15C710EE466D000B48DEB /* regexp-macro-assembler-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "regexp-macro-assembler-arm.h"; path = "arm/regexp-macro-assembler-arm.h"; sourceTree = "<group>"; };
-		89A15C720EE466D000B48DEB /* regexp-macro-assembler-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "regexp-macro-assembler-ia32.cc"; path = "ia32/regexp-macro-assembler-ia32.cc"; sourceTree = "<group>"; };
-		89A15C730EE466D000B48DEB /* regexp-macro-assembler-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "regexp-macro-assembler-ia32.h"; path = "ia32/regexp-macro-assembler-ia32.h"; sourceTree = "<group>"; };
-		89A15C740EE466D000B48DEB /* regexp-macro-assembler-irregexp-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "regexp-macro-assembler-irregexp-inl.h"; sourceTree = "<group>"; };
-		89A15C750EE466D000B48DEB /* regexp-macro-assembler-irregexp.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "regexp-macro-assembler-irregexp.cc"; sourceTree = "<group>"; };
-		89A15C760EE466D000B48DEB /* regexp-macro-assembler-irregexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "regexp-macro-assembler-irregexp.h"; sourceTree = "<group>"; };
-		89A15C770EE466D000B48DEB /* regexp-macro-assembler-tracer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "regexp-macro-assembler-tracer.cc"; sourceTree = "<group>"; };
-		89A15C780EE466D000B48DEB /* regexp-macro-assembler-tracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "regexp-macro-assembler-tracer.h"; sourceTree = "<group>"; };
-		89A15C790EE466D000B48DEB /* regexp-macro-assembler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "regexp-macro-assembler.cc"; sourceTree = "<group>"; };
-		89A15C7A0EE466D000B48DEB /* regexp-macro-assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "regexp-macro-assembler.h"; sourceTree = "<group>"; };
-		89A15C910EE46A1700B48DEB /* d8-readline.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-readline.cc"; path = "../src/d8-readline.cc"; sourceTree = "<group>"; };
-		89A15C920EE46A1700B48DEB /* d8.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = d8.cc; path = ../src/d8.cc; sourceTree = "<group>"; };
-		89A15C930EE46A1700B48DEB /* d8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = d8.h; path = ../src/d8.h; sourceTree = "<group>"; };
-		89A15C940EE46A1700B48DEB /* d8.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = d8.js; path = ../src/d8.js; sourceTree = "<group>"; };
-		89B12E8D0E7FF2A40080BA62 /* presubmit.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = presubmit.py; sourceTree = "<group>"; };
-		89B91B7B12D4EF95002FF4BC /* assembler-x64-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-x64-inl.h"; path = "x64/assembler-x64-inl.h"; sourceTree = "<group>"; };
-		89B91B7C12D4EF95002FF4BC /* assembler-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "assembler-x64.cc"; path = "x64/assembler-x64.cc"; sourceTree = "<group>"; };
-		89B91B7D12D4EF95002FF4BC /* assembler-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-x64.h"; path = "x64/assembler-x64.h"; sourceTree = "<group>"; };
-		89B91B7E12D4EF95002FF4BC /* builtins-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "builtins-x64.cc"; path = "x64/builtins-x64.cc"; sourceTree = "<group>"; };
-		89B91B7F12D4EF95002FF4BC /* code-stubs-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "code-stubs-x64.cc"; path = "x64/code-stubs-x64.cc"; sourceTree = "<group>"; };
-		89B91B8012D4EF95002FF4BC /* code-stubs-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "code-stubs-x64.h"; path = "x64/code-stubs-x64.h"; sourceTree = "<group>"; };
-		89B91B8212D4EF95002FF4BC /* codegen-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "codegen-x64.cc"; path = "x64/codegen-x64.cc"; sourceTree = "<group>"; };
-		89B91B8312D4EF95002FF4BC /* codegen-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "codegen-x64.h"; path = "x64/codegen-x64.h"; sourceTree = "<group>"; };
-		89B91B8412D4EF95002FF4BC /* cpu-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "cpu-x64.cc"; path = "x64/cpu-x64.cc"; sourceTree = "<group>"; };
-		89B91B8512D4EF95002FF4BC /* debug-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "debug-x64.cc"; path = "x64/debug-x64.cc"; sourceTree = "<group>"; };
-		89B91B8612D4EF95002FF4BC /* deoptimizer-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "deoptimizer-x64.cc"; path = "x64/deoptimizer-x64.cc"; sourceTree = "<group>"; };
-		89B91B8712D4EF95002FF4BC /* disasm-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "disasm-x64.cc"; path = "x64/disasm-x64.cc"; sourceTree = "<group>"; };
-		89B91B8812D4EF95002FF4BC /* frames-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "frames-x64.cc"; path = "x64/frames-x64.cc"; sourceTree = "<group>"; };
-		89B91B8912D4EF95002FF4BC /* frames-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "frames-x64.h"; path = "x64/frames-x64.h"; sourceTree = "<group>"; };
-		89B91B8A12D4EF95002FF4BC /* full-codegen-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "full-codegen-x64.cc"; path = "x64/full-codegen-x64.cc"; sourceTree = "<group>"; };
-		89B91B8B12D4EF95002FF4BC /* ic-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ic-x64.cc"; path = "x64/ic-x64.cc"; sourceTree = "<group>"; };
-		89B91B8D12D4EF95002FF4BC /* lithium-codegen-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-codegen-x64.h"; path = "x64/lithium-codegen-x64.h"; sourceTree = "<group>"; };
-		89B91B8E12D4EF95002FF4BC /* lithium-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-x64.h"; path = "x64/lithium-x64.h"; sourceTree = "<group>"; };
-		89B91B8F12D4EF95002FF4BC /* macro-assembler-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "macro-assembler-x64.cc"; path = "x64/macro-assembler-x64.cc"; sourceTree = "<group>"; };
-		89B91B9012D4EF95002FF4BC /* macro-assembler-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "macro-assembler-x64.h"; path = "x64/macro-assembler-x64.h"; sourceTree = "<group>"; };
-		89B91B9112D4EF95002FF4BC /* regexp-macro-assembler-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "regexp-macro-assembler-x64.cc"; path = "x64/regexp-macro-assembler-x64.cc"; sourceTree = "<group>"; };
-		89B91B9212D4EF95002FF4BC /* regexp-macro-assembler-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "regexp-macro-assembler-x64.h"; path = "x64/regexp-macro-assembler-x64.h"; sourceTree = "<group>"; };
-		89B91B9612D4EF95002FF4BC /* simulator-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "simulator-x64.cc"; path = "x64/simulator-x64.cc"; sourceTree = "<group>"; };
-		89B91B9712D4EF95002FF4BC /* simulator-x64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "simulator-x64.h"; path = "x64/simulator-x64.h"; sourceTree = "<group>"; };
-		89B91B9812D4EF95002FF4BC /* stub-cache-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "stub-cache-x64.cc"; path = "x64/stub-cache-x64.cc"; sourceTree = "<group>"; };
-		89B91BBE12D4F02A002FF4BC /* v8_shell-x64 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "v8_shell-x64"; sourceTree = BUILT_PRODUCTS_DIR; };
-		89B91BCE12D4F02A002FF4BC /* d8-x64 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "d8-x64"; sourceTree = BUILT_PRODUCTS_DIR; };
-		89D7DDD312E8DDCF001E2B82 /* lithium-gap-resolver-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-gap-resolver-ia32.cc"; path = "ia32/lithium-gap-resolver-ia32.cc"; sourceTree = "<group>"; };
-		89D7DDD412E8DDCF001E2B82 /* lithium-gap-resolver-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lithium-gap-resolver-ia32.h"; path = "ia32/lithium-gap-resolver-ia32.h"; sourceTree = "<group>"; };
-		89D7DDD612E8DE09001E2B82 /* gdb-jit.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gdb-jit.cc"; sourceTree = "<group>"; };
-		89D7DDD712E8DE09001E2B82 /* gdb-jit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gdb-jit.h"; sourceTree = "<group>"; };
-		89D7DDD812E8DE09001E2B82 /* inspector.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inspector.cc; sourceTree = "<group>"; };
-		89D7DDD912E8DE09001E2B82 /* inspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inspector.h; sourceTree = "<group>"; };
-		89F23C870E78D5B2006B2466 /* libv8-arm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libv8-arm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
-		89F23C950E78D5B6006B2466 /* v8_shell-arm */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "v8_shell-arm"; sourceTree = BUILT_PRODUCTS_DIR; };
-		89F3605A12DCDF6400ACF8A6 /* lithium-codegen-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-codegen-x64.cc"; path = "x64/lithium-codegen-x64.cc"; sourceTree = "<group>"; };
-		89FB0E360F8E531900B04B3C /* d8-posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-posix.cc"; path = "../src/d8-posix.cc"; sourceTree = "<group>"; };
-		89FB0E370F8E531900B04B3C /* d8-windows.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-windows.cc"; path = "../src/d8-windows.cc"; sourceTree = "<group>"; };
-		89FE7C0513532165008662BD /* date.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = date.js; sourceTree = "<group>"; };
-		89FE7C0613532165008662BD /* debug-debugger.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "debug-debugger.js"; sourceTree = "<group>"; };
-		89FE7C0713532165008662BD /* liveedit-debugger.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "liveedit-debugger.js"; sourceTree = "<group>"; };
-		89FE7C0813532165008662BD /* mirror-debugger.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "mirror-debugger.js"; sourceTree = "<group>"; };
-		89FE7C0913532165008662BD /* regexp.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = regexp.js; sourceTree = "<group>"; };
-		9C1F8E1D133906180068B362 /* small-pointer-list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "small-pointer-list.h"; sourceTree = "<group>"; };
-		9C76176D133FB7740057370B /* platform-tls-mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "platform-tls-mac.h"; sourceTree = "<group>"; };
-		9C8E8061133CF772004058A5 /* platform-tls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "platform-tls.h"; sourceTree = "<group>"; };
-		9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "heap-profiler.cc"; sourceTree = "<group>"; };
-		9F11D99F105AF0A300EBE5B2 /* heap-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "heap-profiler.h"; sourceTree = "<group>"; };
-		9F2B370E114FF62D007CDAF4 /* circular-queue-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "circular-queue-inl.h"; sourceTree = "<group>"; };
-		9F2B370F114FF62D007CDAF4 /* circular-queue.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "circular-queue.cc"; sourceTree = "<group>"; };
-		9F2B3710114FF62D007CDAF4 /* circular-queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "circular-queue.h"; sourceTree = "<group>"; };
-		9F2B37231152CEA0007CDAF4 /* cpu-profiler-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cpu-profiler-inl.h"; sourceTree = "<group>"; };
-		9F2B37241152CEA0007CDAF4 /* cpu-profiler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "cpu-profiler.cc"; sourceTree = "<group>"; };
-		9F2B37251152CEA0007CDAF4 /* cpu-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cpu-profiler.h"; sourceTree = "<group>"; };
-		9F4B7B870FCC877A00DC4117 /* log-utils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "log-utils.cc"; sourceTree = "<group>"; };
-		9F4B7B880FCC877A00DC4117 /* log-utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "log-utils.h"; sourceTree = "<group>"; };
-		9F73E3AE114E61A100F84A5A /* profile-generator-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "profile-generator-inl.h"; sourceTree = "<group>"; };
-		9F73E3AF114E61A100F84A5A /* profile-generator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "profile-generator.cc"; sourceTree = "<group>"; };
-		9F73E3B0114E61A100F84A5A /* profile-generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "profile-generator.h"; sourceTree = "<group>"; };
-		9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "func-name-inferrer.cc"; sourceTree = "<group>"; };
-		9F92FAA80F8F28AD0089F02C /* func-name-inferrer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "func-name-inferrer.h"; sourceTree = "<group>"; };
-		9FA36F62116BA26500C4CD55 /* v8-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-profiler.h"; sourceTree = "<group>"; };
-		9FA37332116DD9F000C4CD55 /* vm-state-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state-inl.h"; sourceTree = "<group>"; };
-		9FA37334116DD9F000C4CD55 /* vm-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state.h"; sourceTree = "<group>"; };
-		9FA38B9B1175B2D200C4CD55 /* cached-powers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cached-powers.h"; sourceTree = "<group>"; };
-		9FA38B9C1175B2D200C4CD55 /* data-flow.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "data-flow.cc"; sourceTree = "<group>"; };
-		9FA38B9D1175B2D200C4CD55 /* data-flow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "data-flow.h"; sourceTree = "<group>"; };
-		9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "diy-fp.cc"; sourceTree = "<group>"; };
-		9FA38B9F1175B2D200C4CD55 /* diy-fp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "diy-fp.h"; sourceTree = "<group>"; };
-		9FA38BA01175B2D200C4CD55 /* double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = double.h; sourceTree = "<group>"; };
-		9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fast-dtoa.cc"; sourceTree = "<group>"; };
-		9FA38BA21175B2D200C4CD55 /* fast-dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fast-dtoa.h"; sourceTree = "<group>"; };
-		9FA38BA51175B2D200C4CD55 /* full-codegen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "full-codegen.cc"; sourceTree = "<group>"; };
-		9FA38BA61175B2D200C4CD55 /* full-codegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "full-codegen.h"; sourceTree = "<group>"; };
-		9FA38BA91175B2D200C4CD55 /* liveedit.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = liveedit.cc; sourceTree = "<group>"; };
-		9FA38BAA1175B2D200C4CD55 /* liveedit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = liveedit.h; sourceTree = "<group>"; };
-		9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "splay-tree-inl.h"; sourceTree = "<group>"; };
-		9FA38BAD1175B2D200C4CD55 /* splay-tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "splay-tree.h"; sourceTree = "<group>"; };
-		9FA38BAE1175B2D200C4CD55 /* type-info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "type-info.cc"; sourceTree = "<group>"; };
-		9FA38BAF1175B2D200C4CD55 /* type-info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "type-info.h"; sourceTree = "<group>"; };
-		9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "full-codegen-ia32.cc"; path = "ia32/full-codegen-ia32.cc"; sourceTree = "<group>"; };
-		9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "full-codegen-arm.cc"; path = "arm/full-codegen-arm.cc"; sourceTree = "<group>"; };
-		9FF7A28211A642EA0051B8F2 /* unbound-queue-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unbound-queue-inl.h"; sourceTree = "<group>"; };
-		9FF7A28311A642EA0051B8F2 /* unbound-queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unbound-queue.h"; sourceTree = "<group>"; };
-		C2BD4BD5120165460046BF9F /* dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cc; sourceTree = "<group>"; };
-		C2BD4BD6120165460046BF9F /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; };
-		C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fixed-dtoa.cc"; sourceTree = "<group>"; };
-		C2BD4BDA120165A70046BF9F /* fixed-dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fixed-dtoa.h"; sourceTree = "<group>"; };
-		C2D1E9711212F27B00187A52 /* objects-visiting.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "objects-visiting.cc"; sourceTree = "<group>"; };
-		C2D1E9721212F27B00187A52 /* objects-visiting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "objects-visiting.h"; sourceTree = "<group>"; };
-		C68081AB1225120B001EAFE4 /* code-stubs-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "code-stubs-arm.cc"; path = "arm/code-stubs-arm.cc"; sourceTree = "<group>"; };
-		C68081AC1225120B001EAFE4 /* code-stubs-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "code-stubs-arm.h"; path = "arm/code-stubs-arm.h"; sourceTree = "<group>"; };
-		C68081B012251239001EAFE4 /* code-stubs-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "code-stubs-ia32.cc"; path = "ia32/code-stubs-ia32.cc"; sourceTree = "<group>"; };
-		C68081B412251257001EAFE4 /* code-stubs-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "code-stubs-ia32.h"; path = "ia32/code-stubs-ia32.h"; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		893988050F2A35FA007D5254 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				893988070F2A35FA007D5254 /* libv8.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		895692A612D4ED240072C313 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		8970F2EE0E719FB2006AE7B5 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		897C77D412B68E3D000767A8 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				897C77DD12B68E6E000767A8 /* libv8-arm.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		897F76780E71B4CC007ACF34 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				897F76850E71B6B1007ACF34 /* libv8.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89B91BB912D4F02A002FF4BC /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				89B91BFA12D4F1AA002FF4BC /* libv8-x64.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89B91BC912D4F02A002FF4BC /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				89B91BFB12D4F1BB002FF4BC /* libv8-x64.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89F23C830E78D5B2006B2466 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89F23C8F0E78D5B6006B2466 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				896FD03A0E78D717003DFB6A /* libv8-arm.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		8915B8660E719336009C4E19 = {
-			isa = PBXGroup;
-			children = (
-				897FF1C00E719CB600D62E90 /* Products */,
-				897FF0CF0E71996900D62E90 /* v8 */,
-			);
-			sourceTree = "<group>";
-		};
-		893E24E212B14BD20083370F /* C++ */ = {
-			isa = PBXGroup;
-			children = (
-				89B91C0C12D4F439002FF4BC /* arm */,
-				89B91C0312D4F275002FF4BC /* ia32 */,
-				89B91B7A12D4EF65002FF4BC /* x64 */,
-				897FF0F60E719B8F00D62E90 /* accessors.cc */,
-				897FF0F70E719B8F00D62E90 /* accessors.h */,
-				895D5B4C1334210400254083 /* allocation-inl.h */,
-				897FF0F80E719B8F00D62E90 /* allocation.cc */,
-				897FF0F90E719B8F00D62E90 /* allocation.h */,
-				897FF0FA0E719B8F00D62E90 /* api.cc */,
-				897FF0FB0E719B8F00D62E90 /* api.h */,
-				893986D40F29020C007D5254 /* apiutils.h */,
-				897FF0FC0E719B8F00D62E90 /* arguments.h */,
-				897FF1030E719B8F00D62E90 /* assembler.cc */,
-				897FF1040E719B8F00D62E90 /* assembler.h */,
-				893E248412B14B3D0083370F /* ast-inl.h */,
-				897FF1050E719B8F00D62E90 /* ast.cc */,
-				897FF1060E719B8F00D62E90 /* ast.h */,
-				893E248512B14B3D0083370F /* atomicops.h */,
-				893E24CF12B14B780083370F /* atomicops_internals_x86_macosx.h */,
-				893E248612B14B3D0083370F /* bignum-dtoa.cc */,
-				893E248712B14B3D0083370F /* bignum-dtoa.h */,
-				893E248812B14B3D0083370F /* bignum.cc */,
-				893E248912B14B3D0083370F /* bignum.h */,
-				897FF1070E719B8F00D62E90 /* bootstrapper.cc */,
-				897FF1080E719B8F00D62E90 /* bootstrapper.h */,
-				897FF10B0E719B8F00D62E90 /* builtins.cc */,
-				897FF10C0E719B8F00D62E90 /* builtins.h */,
-				89A15C630EE4661A00B48DEB /* bytecodes-irregexp.h */,
-				893E248A12B14B3D0083370F /* cached-powers.cc */,
-				9FA38B9B1175B2D200C4CD55 /* cached-powers.h */,
-				897FF10D0E719B8F00D62E90 /* char-predicates-inl.h */,
-				897FF10E0E719B8F00D62E90 /* char-predicates.h */,
-				897FF10F0E719B8F00D62E90 /* checks.cc */,
-				897FF1100E719B8F00D62E90 /* checks.h */,
-				9F2B370E114FF62D007CDAF4 /* circular-queue-inl.h */,
-				9F2B370F114FF62D007CDAF4 /* circular-queue.cc */,
-				9F2B3710114FF62D007CDAF4 /* circular-queue.h */,
-				897FF1110E719B8F00D62E90 /* code-stubs.cc */,
-				897FF1120E719B8F00D62E90 /* code-stubs.h */,
-				897FF1130E719B8F00D62E90 /* code.h */,
-				897FF1170E719B8F00D62E90 /* codegen.cc */,
-				897FF1180E719B8F00D62E90 /* codegen.h */,
-				89495E460E79FC23001F68C3 /* compilation-cache.cc */,
-				89495E470E79FC23001F68C3 /* compilation-cache.h */,
-				897FF1190E719B8F00D62E90 /* compiler.cc */,
-				897FF11A0E719B8F00D62E90 /* compiler.h */,
-				897FF11C0E719B8F00D62E90 /* contexts.cc */,
-				897FF11D0E719B8F00D62E90 /* contexts.h */,
-				897FF11E0E719B8F00D62E90 /* conversions-inl.h */,
-				897FF11F0E719B8F00D62E90 /* conversions.cc */,
-				897FF1200E719B8F00D62E90 /* conversions.h */,
-				897FF1210E719B8F00D62E90 /* counters.cc */,
-				897FF1220E719B8F00D62E90 /* counters.h */,
-				897FF1230E719B8F00D62E90 /* cpu-arm.cc */,
-				9F2B37231152CEA0007CDAF4 /* cpu-profiler-inl.h */,
-				9F2B37241152CEA0007CDAF4 /* cpu-profiler.cc */,
-				9F2B37251152CEA0007CDAF4 /* cpu-profiler.h */,
-				897FF1250E719B8F00D62E90 /* cpu.h */,
-				9FA38B9C1175B2D200C4CD55 /* data-flow.cc */,
-				9FA38B9D1175B2D200C4CD55 /* data-flow.h */,
-				893A722A0F7B4A3200303DD2 /* dateparser-inl.h */,
-				897FF1260E719B8F00D62E90 /* dateparser.cc */,
-				897FF1270E719B8F00D62E90 /* dateparser.h */,
-				8956B6CD0F5D86570033B5A2 /* debug-agent.cc */,
-				8956B6CE0F5D86570033B5A2 /* debug-agent.h */,
-				897FF1280E719B8F00D62E90 /* debug.cc */,
-				897FF1290E719B8F00D62E90 /* debug.h */,
-				893E248B12B14B3D0083370F /* deoptimizer.cc */,
-				893E248C12B14B3D0083370F /* deoptimizer.h */,
-				897FF12A0E719B8F00D62E90 /* disasm-arm.cc */,
-				897FF12C0E719B8F00D62E90 /* disasm.h */,
-				897FF12D0E719B8F00D62E90 /* disassembler.cc */,
-				897FF12E0E719B8F00D62E90 /* disassembler.h */,
-				9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */,
-				9FA38B9F1175B2D200C4CD55 /* diy-fp.h */,
-				9FA38BA01175B2D200C4CD55 /* double.h */,
-				C2BD4BD5120165460046BF9F /* dtoa.cc */,
-				C2BD4BD6120165460046BF9F /* dtoa.h */,
-				897FF1300E719B8F00D62E90 /* execution.cc */,
-				897FF1310E719B8F00D62E90 /* execution.h */,
-				893E24D812B14B9F0083370F /* externalize-string-extension.cc */,
-				893E24D912B14B9F0083370F /* externalize-string-extension.h */,
-				897FF1320E719B8F00D62E90 /* factory.cc */,
-				897FF1330E719B8F00D62E90 /* factory.h */,
-				9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */,
-				9FA38BA21175B2D200C4CD55 /* fast-dtoa.h */,
-				C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */,
-				C2BD4BDA120165A70046BF9F /* fixed-dtoa.h */,
-				89471C7F0EB23EE400B6874B /* flag-definitions.h */,
-				897FF1350E719B8F00D62E90 /* flags.cc */,
-				897FF1360E719B8F00D62E90 /* flags.h */,
-				8981F5FE1010500F00D1520E /* frame-element.cc */,
-				8981F5FF1010500F00D1520E /* frame-element.h */,
-				897FF1370E719B8F00D62E90 /* frames-arm.cc */,
-				897FF1380E719B8F00D62E90 /* frames-arm.h */,
-				897FF13B0E719B8F00D62E90 /* frames-inl.h */,
-				897FF13C0E719B8F00D62E90 /* frames.cc */,
-				897FF13D0E719B8F00D62E90 /* frames.h */,
-				9FA38BA51175B2D200C4CD55 /* full-codegen.cc */,
-				9FA38BA61175B2D200C4CD55 /* full-codegen.h */,
-				9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */,
-				9F92FAA80F8F28AD0089F02C /* func-name-inferrer.h */,
-				893E24DA12B14B9F0083370F /* gc-extension.cc */,
-				893E24DB12B14B9F0083370F /* gc-extension.h */,
-				89D7DDD612E8DE09001E2B82 /* gdb-jit.cc */,
-				89D7DDD712E8DE09001E2B82 /* gdb-jit.h */,
-				897FF13E0E719B8F00D62E90 /* global-handles.cc */,
-				897FF13F0E719B8F00D62E90 /* global-handles.h */,
-				897FF1400E719B8F00D62E90 /* globals.h */,
-				897FF1410E719B8F00D62E90 /* handles-inl.h */,
-				897FF1420E719B8F00D62E90 /* handles.cc */,
-				897FF1430E719B8F00D62E90 /* handles.h */,
-				897FF1440E719B8F00D62E90 /* hashmap.cc */,
-				897FF1450E719B8F00D62E90 /* hashmap.h */,
-				897FF1460E719B8F00D62E90 /* heap-inl.h */,
-				9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */,
-				9F11D99F105AF0A300EBE5B2 /* heap-profiler.h */,
-				897FF1470E719B8F00D62E90 /* heap.cc */,
-				897FF1480E719B8F00D62E90 /* heap.h */,
-				893E248D12B14B3D0083370F /* hydrogen-instructions.cc */,
-				893E248E12B14B3D0083370F /* hydrogen-instructions.h */,
-				893E248F12B14B3D0083370F /* hydrogen.cc */,
-				893E249012B14B3D0083370F /* hydrogen.h */,
-				897FF14B0E719B8F00D62E90 /* ic-inl.h */,
-				897FF14C0E719B8F00D62E90 /* ic.cc */,
-				897FF14D0E719B8F00D62E90 /* ic.h */,
-				89D7DDD812E8DE09001E2B82 /* inspector.cc */,
-				89D7DDD912E8DE09001E2B82 /* inspector.h */,
-				89A15C660EE4665300B48DEB /* interpreter-irregexp.cc */,
-				89A15C670EE4665300B48DEB /* interpreter-irregexp.h */,
-				895D5B521334212D00254083 /* isolate.cc */,
-				891C92FE133422EB00FF4757 /* isolate.h */,
-				897FF14E0E719B8F00D62E90 /* jsregexp.cc */,
-				897FF14F0E719B8F00D62E90 /* jsregexp.h */,
-				897FF1500E719B8F00D62E90 /* list-inl.h */,
-				897FF1510E719B8F00D62E90 /* list.h */,
-				891C92FD1334226000FF4757 /* lithium-allocator-inl.h */,
-				893E249312B14B3D0083370F /* lithium-allocator.cc */,
-				893E249412B14B3D0083370F /* lithium-allocator.h */,
-				894A59E712D777E80000766D /* lithium.cc */,
-				894A59E812D777E80000766D /* lithium.h */,
-				9FA38BA91175B2D200C4CD55 /* liveedit.cc */,
-				9FA38BAA1175B2D200C4CD55 /* liveedit.h */,
-				22A76C900FF259E600FDC694 /* log-inl.h */,
-				9F4B7B870FCC877A00DC4117 /* log-utils.cc */,
-				9F4B7B880FCC877A00DC4117 /* log-utils.h */,
-				897FF1520E719B8F00D62E90 /* log.cc */,
-				897FF1530E719B8F00D62E90 /* log.h */,
-				897FF1580E719B8F00D62E90 /* macro-assembler.h */,
-				897FF1590E719B8F00D62E90 /* mark-compact.cc */,
-				897FF15A0E719B8F00D62E90 /* mark-compact.h */,
-				897FF15B0E719B8F00D62E90 /* v8memory.h */,
-				897FF15C0E719B8F00D62E90 /* messages.cc */,
-				897FF15D0E719B8F00D62E90 /* messages.h */,
-				897FF15E0E719B8F00D62E90 /* mksnapshot.cc */,
-				897FF15F0E719B8F00D62E90 /* natives.h */,
-				897FF1600E719B8F00D62E90 /* objects-debug.cc */,
-				897FF1610E719B8F00D62E90 /* objects-inl.h */,
-				8946827412C26EB700C914BC /* objects-printer.cc */,
-				C2D1E9711212F27B00187A52 /* objects-visiting.cc */,
-				C2D1E9721212F27B00187A52 /* objects-visiting.h */,
-				897FF1620E719B8F00D62E90 /* objects.cc */,
-				897FF1630E719B8F00D62E90 /* objects.h */,
-				897FF1640E719B8F00D62E90 /* parser.cc */,
-				897FF1650E719B8F00D62E90 /* parser.h */,
-				89A15C6D0EE466A900B48DEB /* platform-freebsd.cc */,
-				897FF1660E719B8F00D62E90 /* platform-linux.cc */,
-				897FF1670E719B8F00D62E90 /* platform-macos.cc */,
-				897FF1680E719B8F00D62E90 /* platform-nullos.cc */,
-				893A72230F7B0FF200303DD2 /* platform-posix.cc */,
-				9C76176D133FB7740057370B /* platform-tls-mac.h */,
-				9C8E8061133CF772004058A5 /* platform-tls.h */,
-				897FF1690E719B8F00D62E90 /* platform-win32.cc */,
-				897FF16A0E719B8F00D62E90 /* platform.h */,
-				893E249512B14B3D0083370F /* preparse-data.cc */,
-				893E249612B14B3D0083370F /* preparse-data.h */,
-				893E249812B14B3D0083370F /* preparser.cc */,
-				893E249912B14B3D0083370F /* preparser.h */,
-				897FF16B0E719B8F00D62E90 /* prettyprinter.cc */,
-				897FF16C0E719B8F00D62E90 /* prettyprinter.h */,
-				9F73E3AE114E61A100F84A5A /* profile-generator-inl.h */,
-				9F73E3AF114E61A100F84A5A /* profile-generator.cc */,
-				9F73E3B0114E61A100F84A5A /* profile-generator.h */,
-				897FF16D0E719B8F00D62E90 /* property.cc */,
-				897FF16E0E719B8F00D62E90 /* property.h */,
-				89A15C740EE466D000B48DEB /* regexp-macro-assembler-irregexp-inl.h */,
-				89A15C750EE466D000B48DEB /* regexp-macro-assembler-irregexp.cc */,
-				89A15C760EE466D000B48DEB /* regexp-macro-assembler-irregexp.h */,
-				89A15C770EE466D000B48DEB /* regexp-macro-assembler-tracer.cc */,
-				89A15C780EE466D000B48DEB /* regexp-macro-assembler-tracer.h */,
-				89A15C790EE466D000B48DEB /* regexp-macro-assembler.cc */,
-				89A15C7A0EE466D000B48DEB /* regexp-macro-assembler.h */,
-				8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */,
-				8944AD0F0F1D4D3A0028D560 /* regexp-stack.h */,
-				897FF16F0E719B8F00D62E90 /* rewriter.cc */,
-				897FF1700E719B8F00D62E90 /* rewriter.h */,
-				893E249A12B14B3D0083370F /* runtime-profiler.cc */,
-				893E249B12B14B3D0083370F /* runtime-profiler.h */,
-				897FF1710E719B8F00D62E90 /* runtime.cc */,
-				897FF1720E719B8F00D62E90 /* runtime.h */,
-				893E249C12B14B3D0083370F /* safepoint-table.cc */,
-				893E249D12B14B3D0083370F /* safepoint-table.h */,
-				893E249E12B14B3D0083370F /* scanner-base.cc */,
-				893E249F12B14B3D0083370F /* scanner-base.h */,
-				897FF1730E719B8F00D62E90 /* scanner.cc */,
-				897FF1740E719B8F00D62E90 /* scanner.h */,
-				897FF1750E719B8F00D62E90 /* SConscript */,
-				897FF1760E719B8F00D62E90 /* scopeinfo.cc */,
-				897FF1770E719B8F00D62E90 /* scopeinfo.h */,
-				897FF1780E719B8F00D62E90 /* scopes.cc */,
-				897FF1790E719B8F00D62E90 /* scopes.h */,
-				897FF17A0E719B8F00D62E90 /* serialize.cc */,
-				897FF17B0E719B8F00D62E90 /* serialize.h */,
-				897FF17C0E719B8F00D62E90 /* shell.h */,
-				893E24A012B14B3D0083370F /* simulator.h */,
-				9C1F8E1D133906180068B362 /* small-pointer-list.h */,
-				897FF1810E719B8F00D62E90 /* smart-pointer.h */,
-				897FF1820E719B8F00D62E90 /* snapshot-common.cc */,
-				897FF1830E719B8F00D62E90 /* snapshot-empty.cc */,
-				897FF1840E719B8F00D62E90 /* snapshot.h */,
-				897FF1850E719B8F00D62E90 /* spaces-inl.h */,
-				897FF1860E719B8F00D62E90 /* spaces.cc */,
-				897FF1870E719B8F00D62E90 /* spaces.h */,
-				9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */,
-				9FA38BAD1175B2D200C4CD55 /* splay-tree.h */,
-				893E24A112B14B3D0083370F /* string-search.cc */,
-				893E24A212B14B3D0083370F /* string-search.h */,
-				897FF1880E719B8F00D62E90 /* string-stream.cc */,
-				897FF1890E719B8F00D62E90 /* string-stream.h */,
-				893E24A312B14B3D0083370F /* strtod.cc */,
-				893E24A412B14B3D0083370F /* strtod.h */,
-				897FF18C0E719B8F00D62E90 /* stub-cache.cc */,
-				897FF18D0E719B8F00D62E90 /* stub-cache.h */,
-				897FF18E0E719B8F00D62E90 /* token.cc */,
-				897FF18F0E719B8F00D62E90 /* token.h */,
-				9FA38BAE1175B2D200C4CD55 /* type-info.cc */,
-				9FA38BAF1175B2D200C4CD55 /* type-info.h */,
-				9FF7A28211A642EA0051B8F2 /* unbound-queue-inl.h */,
-				9FF7A28311A642EA0051B8F2 /* unbound-queue.h */,
-				897FF1920E719B8F00D62E90 /* unicode-inl.h */,
-				897FF1930E719B8F00D62E90 /* unicode.cc */,
-				897FF1940E719B8F00D62E90 /* unicode.h */,
-				897FF1970E719B8F00D62E90 /* utils.cc */,
-				897FF1980E719B8F00D62E90 /* utils.h */,
-				897FF1990E719B8F00D62E90 /* v8-counters.cc */,
-				897FF19A0E719B8F00D62E90 /* v8-counters.h */,
-				897FF19B0E719B8F00D62E90 /* v8.cc */,
-				897FF19C0E719B8F00D62E90 /* v8.h */,
-				893E24A512B14B3D0083370F /* v8checks.h */,
-				893E24A612B14B3D0083370F /* v8globals.h */,
-				897FF19D0E719B8F00D62E90 /* v8threads.cc */,
-				897FF19E0E719B8F00D62E90 /* v8threads.h */,
-				893E24A712B14B3D0083370F /* v8utils.h */,
-				897FF19F0E719B8F00D62E90 /* variables.cc */,
-				897FF1A00E719B8F00D62E90 /* variables.h */,
-				897FF32F0FAA0ED200136CF6 /* version.cc */,
-				897FF3300FAA0ED200136CF6 /* version.h */,
-				9FA37332116DD9F000C4CD55 /* vm-state-inl.h */,
-				9FA37334116DD9F000C4CD55 /* vm-state.h */,
-				897FF1A10E719B8F00D62E90 /* zone-inl.h */,
-				897FF1A20E719B8F00D62E90 /* zone.cc */,
-				897FF1A30E719B8F00D62E90 /* zone.h */,
-			);
-			name = "C++";
-			sourceTree = "<group>";
-		};
-		897FF0CF0E71996900D62E90 /* v8 */ = {
-			isa = PBXGroup;
-			children = (
-				897FF0D10E71999E00D62E90 /* include */,
-				897FF1B30E719BCE00D62E90 /* samples */,
-				897FF0D00E71999800D62E90 /* src */,
-				897FF1B40E719BE800D62E90 /* tools */,
-			);
-			name = v8;
-			path = ..;
-			sourceTree = "<group>";
-		};
-		897FF0D00E71999800D62E90 /* src */ = {
-			isa = PBXGroup;
-			children = (
-				893E24E212B14BD20083370F /* C++ */,
-				89A9C1630E71C8E300BE6CCA /* generated */,
-				897FF0D80E719ABA00D62E90 /* js */,
-			);
-			path = src;
-			sourceTree = "<group>";
-		};
-		897FF0D10E71999E00D62E90 /* include */ = {
-			isa = PBXGroup;
-			children = (
-				893E248112B14AD40083370F /* v8-preparser.h */,
-				893E248212B14AD40083370F /* v8-testing.h */,
-				893E248312B14AD40083370F /* v8stdint.h */,
-				897FF0D40E719A8500D62E90 /* v8-debug.h */,
-				9FA36F62116BA26500C4CD55 /* v8-profiler.h */,
-				897FF0D50E719A8500D62E90 /* v8.h */,
-			);
-			path = include;
-			sourceTree = "<group>";
-		};
-		897FF0D80E719ABA00D62E90 /* js */ = {
-			isa = PBXGroup;
-			children = (
-				89FE7C0513532165008662BD /* date.js */,
-				89FE7C0613532165008662BD /* debug-debugger.js */,
-				89FE7C0713532165008662BD /* liveedit-debugger.js */,
-				89FE7C0813532165008662BD /* mirror-debugger.js */,
-				89FE7C0913532165008662BD /* regexp.js */,
-				897FF1A60E719BC100D62E90 /* apinatives.js */,
-				897FF1A70E719BC100D62E90 /* array.js */,
-				897FF1AA0E719BC100D62E90 /* math.js */,
-				897FF1AB0E719BC100D62E90 /* messages.js */,
-				897FF1AE0E719BC100D62E90 /* runtime.js */,
-				897FF1AF0E719BC100D62E90 /* string.js */,
-				897FF1B00E719BC100D62E90 /* uri.js */,
-				897FF1B10E719BC100D62E90 /* v8natives.js */,
-			);
-			name = js;
-			sourceTree = "<group>";
-		};
-		897FF1B30E719BCE00D62E90 /* samples */ = {
-			isa = PBXGroup;
-			children = (
-				893988150F2A3686007D5254 /* d8-debug.cc */,
-				893A72320F7B4AD700303DD2 /* d8-debug.h */,
-				89FB0E360F8E531900B04B3C /* d8-posix.cc */,
-				89A15C910EE46A1700B48DEB /* d8-readline.cc */,
-				89FB0E370F8E531900B04B3C /* d8-windows.cc */,
-				89A15C920EE46A1700B48DEB /* d8.cc */,
-				89A15C930EE46A1700B48DEB /* d8.h */,
-				89A15C940EE46A1700B48DEB /* d8.js */,
-				897FF1B50E719C0900D62E90 /* shell.cc */,
-			);
-			path = samples;
-			sourceTree = "<group>";
-		};
-		897FF1B40E719BE800D62E90 /* tools */ = {
-			isa = PBXGroup;
-			children = (
-				897FF1B60E719C2300D62E90 /* js2c.py */,
-				897FF1B70E719C2E00D62E90 /* macros.py */,
-				89B12E8D0E7FF2A40080BA62 /* presubmit.py */,
-			);
-			path = tools;
-			sourceTree = "<group>";
-		};
-		897FF1C00E719CB600D62E90 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				897F767A0E71B4CC007ACF34 /* v8_shell */,
-				8939880B0F2A35FA007D5254 /* d8 */,
-				89F23C950E78D5B6006B2466 /* v8_shell-arm */,
-				89F23C870E78D5B2006B2466 /* libv8-arm.a */,
-				8970F2F00E719FB2006AE7B5 /* libv8.a */,
-				897C77D912B68E3D000767A8 /* d8-arm */,
-				895692AA12D4ED240072C313 /* libv8-x64.a */,
-				89B91BBE12D4F02A002FF4BC /* v8_shell-x64 */,
-				89B91BCE12D4F02A002FF4BC /* d8-x64 */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		89A9C1630E71C8E300BE6CCA /* generated */ = {
-			isa = PBXGroup;
-			children = (
-				58DA027D136ECC87007399A4 /* experimental-libraries.cc */,
-				893988320F2A3B8B007D5254 /* d8-js.cc */,
-				8900116B0E71CA2300F91F35 /* libraries.cc */,
-			);
-			path = generated;
-			sourceTree = CONFIGURATION_TEMP_DIR;
-		};
-		89B91B7A12D4EF65002FF4BC /* x64 */ = {
-			isa = PBXGroup;
-			children = (
-				89B91B7B12D4EF95002FF4BC /* assembler-x64-inl.h */,
-				89B91B7C12D4EF95002FF4BC /* assembler-x64.cc */,
-				89B91B7D12D4EF95002FF4BC /* assembler-x64.h */,
-				89B91B7E12D4EF95002FF4BC /* builtins-x64.cc */,
-				89B91B7F12D4EF95002FF4BC /* code-stubs-x64.cc */,
-				89B91B8012D4EF95002FF4BC /* code-stubs-x64.h */,
-				89B91B8212D4EF95002FF4BC /* codegen-x64.cc */,
-				89B91B8312D4EF95002FF4BC /* codegen-x64.h */,
-				89B91B8412D4EF95002FF4BC /* cpu-x64.cc */,
-				89B91B8512D4EF95002FF4BC /* debug-x64.cc */,
-				89B91B8612D4EF95002FF4BC /* deoptimizer-x64.cc */,
-				89B91B8712D4EF95002FF4BC /* disasm-x64.cc */,
-				89B91B8812D4EF95002FF4BC /* frames-x64.cc */,
-				89B91B8912D4EF95002FF4BC /* frames-x64.h */,
-				89B91B8A12D4EF95002FF4BC /* full-codegen-x64.cc */,
-				89B91B8B12D4EF95002FF4BC /* ic-x64.cc */,
-				89F3605A12DCDF6400ACF8A6 /* lithium-codegen-x64.cc */,
-				89B91B8D12D4EF95002FF4BC /* lithium-codegen-x64.h */,
-				8924315A12F8539900906AB2 /* lithium-gap-resolver-x64.cc */,
-				8924315B12F8539900906AB2 /* lithium-gap-resolver-x64.h */,
-				8938A2A212D63B630080CDDE /* lithium-x64.cc */,
-				89B91B8E12D4EF95002FF4BC /* lithium-x64.h */,
-				89B91B8F12D4EF95002FF4BC /* macro-assembler-x64.cc */,
-				89B91B9012D4EF95002FF4BC /* macro-assembler-x64.h */,
-				89B91B9112D4EF95002FF4BC /* regexp-macro-assembler-x64.cc */,
-				89B91B9212D4EF95002FF4BC /* regexp-macro-assembler-x64.h */,
-				89B91B9612D4EF95002FF4BC /* simulator-x64.cc */,
-				89B91B9712D4EF95002FF4BC /* simulator-x64.h */,
-				89B91B9812D4EF95002FF4BC /* stub-cache-x64.cc */,
-			);
-			name = x64;
-			sourceTree = "<group>";
-		};
-		89B91C0312D4F275002FF4BC /* ia32 */ = {
-			isa = PBXGroup;
-			children = (
-				89D7DDD312E8DDCF001E2B82 /* lithium-gap-resolver-ia32.cc */,
-				89D7DDD412E8DDCF001E2B82 /* lithium-gap-resolver-ia32.h */,
-				897FF1000E719B8F00D62E90 /* assembler-ia32-inl.h */,
-				897FF1010E719B8F00D62E90 /* assembler-ia32.cc */,
-				897FF1020E719B8F00D62E90 /* assembler-ia32.h */,
-				897FF10A0E719B8F00D62E90 /* builtins-ia32.cc */,
-				C68081B012251239001EAFE4 /* code-stubs-ia32.cc */,
-				C68081B412251257001EAFE4 /* code-stubs-ia32.h */,
-				897FF1150E719B8F00D62E90 /* codegen-ia32.cc */,
-				8964482B0E9C00F700E7C516 /* codegen-ia32.h */,
-				897FF1240E719B8F00D62E90 /* cpu-ia32.cc */,
-				898BD20D0EF6CC850068B00A /* debug-ia32.cc */,
-				893E24D012B14B8A0083370F /* deoptimizer-ia32.cc */,
-				897FF12B0E719B8F00D62E90 /* disasm-ia32.cc */,
-				897FF1390E719B8F00D62E90 /* frames-ia32.cc */,
-				897FF13A0E719B8F00D62E90 /* frames-ia32.h */,
-				9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */,
-				897FF14A0E719B8F00D62E90 /* ic-ia32.cc */,
-				893E24D112B14B8A0083370F /* lithium-codegen-ia32.cc */,
-				893E24D212B14B8A0083370F /* lithium-codegen-ia32.h */,
-				893E24D312B14B8A0083370F /* lithium-ia32.cc */,
-				893E24D412B14B8A0083370F /* lithium-ia32.h */,
-				897FF1560E719B8F00D62E90 /* macro-assembler-ia32.cc */,
-				897FF1570E719B8F00D62E90 /* macro-assembler-ia32.h */,
-				89A15C720EE466D000B48DEB /* regexp-macro-assembler-ia32.cc */,
-				89A15C730EE466D000B48DEB /* regexp-macro-assembler-ia32.h */,
-				897FF17F0E719B8F00D62E90 /* simulator-ia32.cc */,
-				897FF1800E719B8F00D62E90 /* simulator-ia32.h */,
-				897FF18B0E719B8F00D62E90 /* stub-cache-ia32.cc */,
-			);
-			name = ia32;
-			sourceTree = "<group>";
-		};
-		89B91C0C12D4F439002FF4BC /* arm */ = {
-			isa = PBXGroup;
-			children = (
-				897FF0FD0E719B8F00D62E90 /* assembler-arm-inl.h */,
-				897FF0FE0E719B8F00D62E90 /* assembler-arm.cc */,
-				897FF0FF0E719B8F00D62E90 /* assembler-arm.h */,
-				897FF1090E719B8F00D62E90 /* builtins-arm.cc */,
-				C68081AB1225120B001EAFE4 /* code-stubs-arm.cc */,
-				C68081AC1225120B001EAFE4 /* code-stubs-arm.h */,
-				897FF1140E719B8F00D62E90 /* codegen-arm.cc */,
-				896448BC0E9D530500E7C516 /* codegen-arm.h */,
-				895FA748107FFE73006F39D4 /* constants-arm.cc */,
-				897FF11B0E719B8F00D62E90 /* constants-arm.h */,
-				898BD20C0EF6CC850068B00A /* debug-arm.cc */,
-				893E24C612B14B510083370F /* deoptimizer-arm.cc */,
-				9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */,
-				897FF1490E719B8F00D62E90 /* ic-arm.cc */,
-				893E24C712B14B510083370F /* lithium-arm.cc */,
-				893E24C812B14B510083370F /* lithium-arm.h */,
-				893E24C912B14B520083370F /* lithium-codegen-arm.cc */,
-				893E24CA12B14B520083370F /* lithium-codegen-arm.h */,
-				896FA1E3130F93D300042054 /* lithium-gap-resolver-arm.cc */,
-				896FA1E4130F93D300042054 /* lithium-gap-resolver-arm.h */,
-				897FF1540E719B8F00D62E90 /* macro-assembler-arm.cc */,
-				897FF1550E719B8F00D62E90 /* macro-assembler-arm.h */,
-				89A15C700EE466D000B48DEB /* regexp-macro-assembler-arm.cc */,
-				89A15C710EE466D000B48DEB /* regexp-macro-assembler-arm.h */,
-				897FF17D0E719B8F00D62E90 /* simulator-arm.cc */,
-				897FF17E0E719B8F00D62E90 /* simulator-arm.h */,
-				897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */,
-			);
-			name = arm;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
-		893987FE0F2A35FA007D5254 /* d8_shell */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 893988080F2A35FA007D5254 /* Build configuration list for PBXNativeTarget "d8_shell" */;
-			buildPhases = (
-				893988220F2A376C007D5254 /* ShellScript */,
-				893988030F2A35FA007D5254 /* Sources */,
-				893988050F2A35FA007D5254 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				893988010F2A35FA007D5254 /* PBXTargetDependency */,
-			);
-			name = d8_shell;
-			productName = v8_shell;
-			productReference = 8939880B0F2A35FA007D5254 /* d8 */;
-			productType = "com.apple.product-type.tool";
-		};
-		8956922712D4ED240072C313 /* v8-x64 */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 895692A712D4ED240072C313 /* Build configuration list for PBXNativeTarget "v8-x64" */;
-			buildPhases = (
-				8956922812D4ED240072C313 /* ShellScript */,
-				8956922912D4ED240072C313 /* Sources */,
-				895692A612D4ED240072C313 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = "v8-x64";
-			productName = v8;
-			productReference = 895692AA12D4ED240072C313 /* libv8-x64.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-		8970F2EF0E719FB2006AE7B5 /* v8 */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 8970F2F70E719FC1006AE7B5 /* Build configuration list for PBXNativeTarget "v8" */;
-			buildPhases = (
-				89EA6FB50E71AA1F00F59E1B /* ShellScript */,
-				8970F2ED0E719FB2006AE7B5 /* Sources */,
-				8970F2EE0E719FB2006AE7B5 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = v8;
-			productName = v8;
-			productReference = 8970F2F00E719FB2006AE7B5 /* libv8.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-		897C77CB12B68E3D000767A8 /* d8_shell-arm */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 897C77D612B68E3D000767A8 /* Build configuration list for PBXNativeTarget "d8_shell-arm" */;
-			buildPhases = (
-				897C77CE12B68E3D000767A8 /* ShellScript */,
-				897C77CF12B68E3D000767A8 /* Sources */,
-				897C77D412B68E3D000767A8 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				897C77DC12B68E5D000767A8 /* PBXTargetDependency */,
-			);
-			name = "d8_shell-arm";
-			productName = v8_shell;
-			productReference = 897C77D912B68E3D000767A8 /* d8-arm */;
-			productType = "com.apple.product-type.tool";
-		};
-		897F76790E71B4CC007ACF34 /* v8_shell */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 897F767E0E71B4EA007ACF34 /* Build configuration list for PBXNativeTarget "v8_shell" */;
-			buildPhases = (
-				897F76770E71B4CC007ACF34 /* Sources */,
-				897F76780E71B4CC007ACF34 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				897F76830E71B6AC007ACF34 /* PBXTargetDependency */,
-			);
-			name = v8_shell;
-			productName = v8_shell;
-			productReference = 897F767A0E71B4CC007ACF34 /* v8_shell */;
-			productType = "com.apple.product-type.tool";
-		};
-		89B91BB412D4F02A002FF4BC /* v8_shell-x64 */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 89B91BBB12D4F02A002FF4BC /* Build configuration list for PBXNativeTarget "v8_shell-x64" */;
-			buildPhases = (
-				89B91BB712D4F02A002FF4BC /* Sources */,
-				89B91BB912D4F02A002FF4BC /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				89B91BD112D4F036002FF4BC /* PBXTargetDependency */,
-			);
-			name = "v8_shell-x64";
-			productName = "v8_shell-arm";
-			productReference = 89B91BBE12D4F02A002FF4BC /* v8_shell-x64 */;
-			productType = "com.apple.product-type.tool";
-		};
-		89B91BC012D4F02A002FF4BC /* d8_shell-x64 */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 89B91BCB12D4F02A002FF4BC /* Build configuration list for PBXNativeTarget "d8_shell-x64" */;
-			buildPhases = (
-				89B91BC312D4F02A002FF4BC /* ShellScript */,
-				89B91BC412D4F02A002FF4BC /* Sources */,
-				89B91BC912D4F02A002FF4BC /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				89B91BFD12D4F1BF002FF4BC /* PBXTargetDependency */,
-			);
-			name = "d8_shell-x64";
-			productName = v8_shell;
-			productReference = 89B91BCE12D4F02A002FF4BC /* d8-x64 */;
-			productType = "com.apple.product-type.tool";
-		};
-		89F23C3C0E78D5B2006B2466 /* v8-arm */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 89F23C840E78D5B2006B2466 /* Build configuration list for PBXNativeTarget "v8-arm" */;
-			buildPhases = (
-				89F23C3D0E78D5B2006B2466 /* ShellScript */,
-				89F23C3E0E78D5B2006B2466 /* Sources */,
-				89F23C830E78D5B2006B2466 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = "v8-arm";
-			productName = "v8-arm";
-			productReference = 89F23C870E78D5B2006B2466 /* libv8-arm.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-		89F23C880E78D5B6006B2466 /* v8_shell-arm */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 89F23C920E78D5B6006B2466 /* Build configuration list for PBXNativeTarget "v8_shell-arm" */;
-			buildPhases = (
-				89F23C8D0E78D5B6006B2466 /* Sources */,
-				89F23C8F0E78D5B6006B2466 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				896FD03C0E78D71F003DFB6A /* PBXTargetDependency */,
-			);
-			name = "v8_shell-arm";
-			productName = "v8_shell-arm";
-			productReference = 89F23C950E78D5B6006B2466 /* v8_shell-arm */;
-			productType = "com.apple.product-type.tool";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		8915B8680E719336009C4E19 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 8915B86B0E719336009C4E19 /* Build configuration list for PBXProject "v8" */;
-			compatibilityVersion = "Xcode 3.1";
-			developmentRegion = English;
-			hasScannedForEncodings = 0;
-			knownRegions = (
-				English,
-				Japanese,
-				French,
-				German,
-			);
-			mainGroup = 8915B8660E719336009C4E19;
-			productRefGroup = 897FF1C00E719CB600D62E90 /* Products */;
-			projectDirPath = "";
-			projectRoot = ..;
-			targets = (
-				7BF891930E73098D000BAF8A /* All */,
-				8970F2EF0E719FB2006AE7B5 /* v8 */,
-				897F76790E71B4CC007ACF34 /* v8_shell */,
-				893987FE0F2A35FA007D5254 /* d8_shell */,
-				89F23C3C0E78D5B2006B2466 /* v8-arm */,
-				89F23C880E78D5B6006B2466 /* v8_shell-arm */,
-				897C77CB12B68E3D000767A8 /* d8_shell-arm */,
-				8956922712D4ED240072C313 /* v8-x64 */,
-				89B91BB412D4F02A002FF4BC /* v8_shell-x64 */,
-				89B91BC012D4F02A002FF4BC /* d8_shell-x64 */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXShellScriptBuildPhase section */
-		893988220F2A376C007D5254 /* ShellScript */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"d8.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nD8_CC=\"${V8_GENERATED_SOURCES_DIR}/d8-js.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${D8_CC}.new\" \\\n  \"D8\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${D8_CC}.new\" \"${D8_CC}\" >& /dev/null ; then\n  mv \"${D8_CC}.new\" \"${D8_CC}\"\nelse\n  rm \"${D8_CC}.new\"\nfi";
-		};
-		8956922812D4ED240072C313 /* ShellScript */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-debugger.js\"\\\n\" liveedit-debugger.js\"\\\n\" mirror-debugger.js\"\\\n\" date.js\"\\\n\" json.js\"\\\n\" regexp.js\"\\\n\" macros.py\"\n\nEXPERIMENTAL_LIBRARY_FILES=\"proxy.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nfor i in ${EXPERIMENTAL_JS_FILES} ; do\n  NATIVE_EXPERIMENTAL_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nEXPERIMENTAL_LIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/experimental-libraries.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"CORE\" \\\n  ${NATIVE_JS_FILES}\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \\\n  \"EXPERIMENTAL\" \\\n  ${NATIVE_EXPERIMENTAL_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \"${EXPERIMENTAL_LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \"${EXPERIMENTAL_LIBRARIES_CC}\"\nelse\n  rm \"${EXPERIMENTAL_LIBRARIES_CC}.new\"\nfi";
-		};
-		897C77CE12B68E3D000767A8 /* ShellScript */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"d8.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nD8_CC=\"${V8_GENERATED_SOURCES_DIR}/d8-js.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${D8_CC}.new\" \\\n  \"D8\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${D8_CC}.new\" \"${D8_CC}\" >& /dev/null ; then\n  mv \"${D8_CC}.new\" \"${D8_CC}\"\nelse\n  rm \"${D8_CC}.new\"\nfi";
-		};
-		89B91BC312D4F02A002FF4BC /* ShellScript */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"d8.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nD8_CC=\"${V8_GENERATED_SOURCES_DIR}/d8-js.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${D8_CC}.new\" \\\n  \"D8\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${D8_CC}.new\" \"${D8_CC}\" >& /dev/null ; then\n  mv \"${D8_CC}.new\" \"${D8_CC}\"\nelse\n  rm \"${D8_CC}.new\"\nfi";
-		};
-		89EA6FB50E71AA1F00F59E1B /* ShellScript */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-debugger.js\"\\\n\" liveedit-debugger.js\"\\\n\" mirror-debugger.js\"\\\n\" date.js\"\\\n\" json.js\"\\\n\" regexp.js\"\\\n\" macros.py\"\n\nEXPERIMENTAL_LIBRARY_FILES=\"proxy.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nfor i in ${EXPERIMENTAL_JS_FILES} ; do\n  NATIVE_EXPERIMENTAL_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nEXPERIMENTAL_LIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/experimental-libraries.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"CORE\" \\\n  ${NATIVE_JS_FILES}\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \\\n  \"EXPERIMENTAL\" \\\n  ${NATIVE_EXPERIMENTAL_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \"${EXPERIMENTAL_LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \"${EXPERIMENTAL_LIBRARIES_CC}\"\nelse\n  rm \"${EXPERIMENTAL_LIBRARIES_CC}.new\"\nfi";
-		};
-		89F23C3D0E78D5B2006B2466 /* ShellScript */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-debugger.js\"\\\n\" liveedit-debugger.js\"\\\n\" mirror-debugger.js\"\\\n\" date.js\"\\\n\" json.js\"\\\n\" regexp.js\"\\\n\" macros.py\"\n\nEXPERIMENTAL_LIBRARY_FILES=\"proxy.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nfor i in ${EXPERIMENTAL_JS_FILES} ; do\n  NATIVE_EXPERIMENTAL_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nEXPERIMENTAL_LIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/experimental-libraries.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"CORE\" \\\n  ${NATIVE_JS_FILES}\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \\\n  \"EXPERIMENTAL\" \\\n  ${NATIVE_EXPERIMENTAL_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \"${EXPERIMENTAL_LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${EXPERIMENTAL_LIBRARIES_CC}.new\" \"${EXPERIMENTAL_LIBRARIES_CC}\"\nelse\n  rm \"${EXPERIMENTAL_LIBRARIES_CC}.new\"\nfi";
-		};
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
-		893988030F2A35FA007D5254 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				893988160F2A3688007D5254 /* d8-debug.cc in Sources */,
-				893988330F2A3B8F007D5254 /* d8-js.cc in Sources */,
-				89FB0E3A0F8E533F00B04B3C /* d8-posix.cc in Sources */,
-				8939880D0F2A362A007D5254 /* d8.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		8956922912D4ED240072C313 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				8956922A12D4ED240072C313 /* objects-visiting.cc in Sources */,
-				8956922B12D4ED240072C313 /* accessors.cc in Sources */,
-				8956922C12D4ED240072C313 /* allocation.cc in Sources */,
-				8956922D12D4ED240072C313 /* api.cc in Sources */,
-				8956922F12D4ED240072C313 /* assembler.cc in Sources */,
-				8956923012D4ED240072C313 /* ast.cc in Sources */,
-				8956923112D4ED240072C313 /* bootstrapper.cc in Sources */,
-				8956923312D4ED240072C313 /* builtins.cc in Sources */,
-				8956923412D4ED240072C313 /* checks.cc in Sources */,
-				8956923512D4ED240072C313 /* circular-queue.cc in Sources */,
-				8956923612D4ED240072C313 /* code-stubs.cc in Sources */,
-				8956923812D4ED240072C313 /* codegen.cc in Sources */,
-				8956923912D4ED240072C313 /* compilation-cache.cc in Sources */,
-				8956923A12D4ED240072C313 /* compiler.cc in Sources */,
-				8956923B12D4ED240072C313 /* contexts.cc in Sources */,
-				8956923C12D4ED240072C313 /* conversions.cc in Sources */,
-				8956923D12D4ED240072C313 /* fixed-dtoa.cc in Sources */,
-				8956923E12D4ED240072C313 /* counters.cc in Sources */,
-				8956924012D4ED240072C313 /* cpu-profiler.cc in Sources */,
-				8956924112D4ED240072C313 /* data-flow.cc in Sources */,
-				8956924212D4ED240072C313 /* dateparser.cc in Sources */,
-				8956924312D4ED240072C313 /* debug-agent.cc in Sources */,
-				8956924512D4ED240072C313 /* dtoa.cc in Sources */,
-				8956924612D4ED240072C313 /* debug.cc in Sources */,
-				8956924812D4ED240072C313 /* disassembler.cc in Sources */,
-				8956924912D4ED240072C313 /* diy-fp.cc in Sources */,
-				8956924A12D4ED240072C313 /* execution.cc in Sources */,
-				8956924B12D4ED240072C313 /* factory.cc in Sources */,
-				8956924C12D4ED240072C313 /* fast-dtoa.cc in Sources */,
-				8956924D12D4ED240072C313 /* flags.cc in Sources */,
-				8956924E12D4ED240072C313 /* frame-element.cc in Sources */,
-				8956925012D4ED240072C313 /* frames.cc in Sources */,
-				8956925212D4ED240072C313 /* full-codegen.cc in Sources */,
-				8956925312D4ED240072C313 /* func-name-inferrer.cc in Sources */,
-				8956925412D4ED240072C313 /* global-handles.cc in Sources */,
-				8956925512D4ED240072C313 /* handles.cc in Sources */,
-				8956925612D4ED240072C313 /* hashmap.cc in Sources */,
-				8956925712D4ED240072C313 /* heap-profiler.cc in Sources */,
-				8956925812D4ED240072C313 /* heap.cc in Sources */,
-				8956925912D4ED240072C313 /* ic-ia32.cc in Sources */,
-				8956925A12D4ED240072C313 /* ic.cc in Sources */,
-				8956925B12D4ED240072C313 /* interpreter-irregexp.cc in Sources */,
-				8956925C12D4ED240072C313 /* jsregexp.cc in Sources */,
-				8956926012D4ED240072C313 /* libraries.cc in Sources */,
-				8956926112D4ED240072C313 /* liveedit.cc in Sources */,
-				8956926212D4ED240072C313 /* log-utils.cc in Sources */,
-				8956926312D4ED240072C313 /* log.cc in Sources */,
-				8956926512D4ED240072C313 /* mark-compact.cc in Sources */,
-				8956926612D4ED240072C313 /* messages.cc in Sources */,
-				8956926712D4ED240072C313 /* objects-debug.cc in Sources */,
-				8956926812D4ED240072C313 /* objects.cc in Sources */,
-				8956926A12D4ED240072C313 /* parser.cc in Sources */,
-				8956926B12D4ED240072C313 /* platform-macos.cc in Sources */,
-				8956926C12D4ED240072C313 /* platform-posix.cc in Sources */,
-				8956926D12D4ED240072C313 /* prettyprinter.cc in Sources */,
-				8956926E12D4ED240072C313 /* profile-generator.cc in Sources */,
-				8956926F12D4ED240072C313 /* property.cc in Sources */,
-				8956927112D4ED240072C313 /* regexp-macro-assembler-irregexp.cc in Sources */,
-				8956927212D4ED240072C313 /* regexp-macro-assembler-tracer.cc in Sources */,
-				8956927312D4ED240072C313 /* regexp-macro-assembler.cc in Sources */,
-				8956927412D4ED240072C313 /* regexp-stack.cc in Sources */,
-				8956927712D4ED240072C313 /* rewriter.cc in Sources */,
-				8956927812D4ED240072C313 /* runtime.cc in Sources */,
-				8956927912D4ED240072C313 /* scanner.cc in Sources */,
-				8956927A12D4ED240072C313 /* scopeinfo.cc in Sources */,
-				8956927B12D4ED240072C313 /* scopes.cc in Sources */,
-				8956927C12D4ED240072C313 /* serialize.cc in Sources */,
-				8956927D12D4ED240072C313 /* snapshot-common.cc in Sources */,
-				8956927E12D4ED240072C313 /* snapshot-empty.cc in Sources */,
-				8956927F12D4ED240072C313 /* spaces.cc in Sources */,
-				8956928012D4ED240072C313 /* string-stream.cc in Sources */,
-				8956928012D4ED240072C313 /* string-stream.cc in Sources */,
-				8956928212D4ED240072C313 /* stub-cache.cc in Sources */,
-				8956928312D4ED240072C313 /* token.cc in Sources */,
-				8956928512D4ED240072C313 /* type-info.cc in Sources */,
-				8956928612D4ED240072C313 /* unicode.cc in Sources */,
-				8956928712D4ED240072C313 /* utils.cc in Sources */,
-				8956928812D4ED240072C313 /* v8-counters.cc in Sources */,
-				8956928912D4ED240072C313 /* v8.cc in Sources */,
-				8956928A12D4ED240072C313 /* v8threads.cc in Sources */,
-				8956928B12D4ED240072C313 /* variables.cc in Sources */,
-				8956928C12D4ED240072C313 /* version.cc in Sources */,
-				8956929012D4ED240072C313 /* zone.cc in Sources */,
-				8956929212D4ED240072C313 /* bignum-dtoa.cc in Sources */,
-				8956929312D4ED240072C313 /* bignum.cc in Sources */,
-				8956929412D4ED240072C313 /* cached-powers.cc in Sources */,
-				8956929512D4ED240072C313 /* deoptimizer.cc in Sources */,
-				8956929612D4ED240072C313 /* hydrogen-instructions.cc in Sources */,
-				8956929712D4ED240072C313 /* hydrogen.cc in Sources */,
-				8956929812D4ED240072C313 /* lithium-allocator.cc in Sources */,
-				8956929912D4ED240072C313 /* preparse-data.cc in Sources */,
-				8956929A12D4ED240072C313 /* preparser.cc in Sources */,
-				8956929B12D4ED240072C313 /* runtime-profiler.cc in Sources */,
-				8956929C12D4ED240072C313 /* safepoint-table.cc in Sources */,
-				8956929D12D4ED240072C313 /* scanner-base.cc in Sources */,
-				8956929E12D4ED240072C313 /* string-search.cc in Sources */,
-				8956929F12D4ED240072C313 /* strtod.cc in Sources */,
-				895692A312D4ED240072C313 /* externalize-string-extension.cc in Sources */,
-				895692A412D4ED240072C313 /* gc-extension.cc in Sources */,
-				895692A512D4ED240072C313 /* objects-printer.cc in Sources */,
-				89B91B9B12D4EF95002FF4BC /* assembler-x64.cc in Sources */,
-				89B91B9C12D4EF95002FF4BC /* builtins-x64.cc in Sources */,
-				89B91B9D12D4EF95002FF4BC /* code-stubs-x64.cc in Sources */,
-				89B91B9E12D4EF95002FF4BC /* codegen-x64.cc in Sources */,
-				89B91B9F12D4EF95002FF4BC /* cpu-x64.cc in Sources */,
-				89B91BA012D4EF95002FF4BC /* debug-x64.cc in Sources */,
-				89B91BA112D4EF95002FF4BC /* deoptimizer-x64.cc in Sources */,
-				89B91BA212D4EF95002FF4BC /* disasm-x64.cc in Sources */,
-				89B91BA312D4EF95002FF4BC /* frames-x64.cc in Sources */,
-				89B91BA412D4EF95002FF4BC /* full-codegen-x64.cc in Sources */,
-				89B91BA512D4EF95002FF4BC /* ic-x64.cc in Sources */,
-				89B91BA712D4EF95002FF4BC /* macro-assembler-x64.cc in Sources */,
-				89B91BA812D4EF95002FF4BC /* regexp-macro-assembler-x64.cc in Sources */,
-				89B91BAA12D4EF95002FF4BC /* simulator-x64.cc in Sources */,
-				89B91BAB12D4EF95002FF4BC /* stub-cache-x64.cc in Sources */,
-				8938A2A312D63B630080CDDE /* lithium-x64.cc in Sources */,
-				894A59E912D777E80000766D /* lithium.cc in Sources */,
-				89F3605B12DCDF6400ACF8A6 /* lithium-codegen-x64.cc in Sources */,
-				89D7DDDE12E8DE09001E2B82 /* gdb-jit.cc in Sources */,
-				89D7DDDF12E8DE09001E2B82 /* inspector.cc in Sources */,
-				8924315C12F8539900906AB2 /* lithium-gap-resolver-x64.cc in Sources */,
-				895D5B551334212D00254083 /* isolate.cc in Sources */,
-				58DA0280136ECC87007399A4 /* experimental-libraries.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		8970F2ED0E719FB2006AE7B5 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				C2D1E9731212F2BC00187A52 /* objects-visiting.cc in Sources */,
-				89A88DEC0E71A5FF0043BA31 /* accessors.cc in Sources */,
-				89A88DED0E71A6000043BA31 /* allocation.cc in Sources */,
-				89A88DEE0E71A6010043BA31 /* api.cc in Sources */,
-				89A88DEF0E71A60A0043BA31 /* assembler-ia32.cc in Sources */,
-				89A88DF00E71A60A0043BA31 /* assembler.cc in Sources */,
-				89A88DF10E71A60B0043BA31 /* ast.cc in Sources */,
-				89A88DF20E71A60C0043BA31 /* bootstrapper.cc in Sources */,
-				89A88DF40E71A6160043BA31 /* builtins-ia32.cc in Sources */,
-				89A88DF50E71A6170043BA31 /* builtins.cc in Sources */,
-				89A88DF60E71A61C0043BA31 /* checks.cc in Sources */,
-				9F2B3712114FF62D007CDAF4 /* circular-queue.cc in Sources */,
-				893CCE640E71D83700357A03 /* code-stubs.cc in Sources */,
-				89A88DF70E71A6240043BA31 /* codegen-ia32.cc in Sources */,
-				89A88DF80E71A6260043BA31 /* codegen.cc in Sources */,
-				89495E480E79FC23001F68C3 /* compilation-cache.cc in Sources */,
-				89A88DF90E71A6430043BA31 /* compiler.cc in Sources */,
-				89A88DFA0E71A6440043BA31 /* contexts.cc in Sources */,
-				89A88DFB0E71A6440043BA31 /* conversions.cc in Sources */,
-				C2BD4BDB120165A70046BF9F /* fixed-dtoa.cc in Sources */,
-				89A88DFC0E71A6460043BA31 /* counters.cc in Sources */,
-				89A88DFD0E71A6470043BA31 /* cpu-ia32.cc in Sources */,
-				9F2B37271152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
-				9FA38BBA1175B2D200C4CD55 /* data-flow.cc in Sources */,
-				89A88DFE0E71A6480043BA31 /* dateparser.cc in Sources */,
-				8956B6CF0F5D86730033B5A2 /* debug-agent.cc in Sources */,
-				898BD20E0EF6CC930068B00A /* debug-ia32.cc in Sources */,
-				C2BD4BD7120165460046BF9F /* dtoa.cc in Sources */,
-				89A88DFF0E71A6530043BA31 /* debug.cc in Sources */,
-				89A88E000E71A6540043BA31 /* disasm-ia32.cc in Sources */,
-				89A88E010E71A6550043BA31 /* disassembler.cc in Sources */,
-				9FA38BBB1175B2D200C4CD55 /* diy-fp.cc in Sources */,
-				89A88E030E71A65B0043BA31 /* execution.cc in Sources */,
-				89A88E040E71A65D0043BA31 /* factory.cc in Sources */,
-				9FA38BBC1175B2D200C4CD55 /* fast-dtoa.cc in Sources */,
-				89A88E050E71A65D0043BA31 /* flags.cc in Sources */,
-				8981F6001010501900D1520E /* frame-element.cc in Sources */,
-				89A88E060E71A6600043BA31 /* frames-ia32.cc in Sources */,
-				89A88E070E71A6610043BA31 /* frames.cc in Sources */,
-				9FA38BC51175B2E500C4CD55 /* full-codegen-ia32.cc in Sources */,
-				9FA38BBE1175B2D200C4CD55 /* full-codegen.cc in Sources */,
-				9F92FAA90F8F28AD0089F02C /* func-name-inferrer.cc in Sources */,
-				89A88E080E71A6620043BA31 /* global-handles.cc in Sources */,
-				89A88E090E71A6640043BA31 /* handles.cc in Sources */,
-				89A88E0A0E71A6650043BA31 /* hashmap.cc in Sources */,
-				9F11D9A0105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
-				89A88E0B0E71A66C0043BA31 /* heap.cc in Sources */,
-				89A88E0C0E71A66D0043BA31 /* ic-ia32.cc in Sources */,
-				89A88E0D0E71A66E0043BA31 /* ic.cc in Sources */,
-				89A15C850EE4678B00B48DEB /* interpreter-irregexp.cc in Sources */,
-				89A88E0E0E71A66F0043BA31 /* jsregexp.cc in Sources */,
-				8900116C0E71CA2300F91F35 /* libraries.cc in Sources */,
-				9FA38BBF1175B2D200C4CD55 /* liveedit.cc in Sources */,
-				9F4B7B890FCC877A00DC4117 /* log-utils.cc in Sources */,
-				89A88E0F0E71A6740043BA31 /* log.cc in Sources */,
-				89A88E100E71A6770043BA31 /* macro-assembler-ia32.cc in Sources */,
-				89A88E110E71A6780043BA31 /* mark-compact.cc in Sources */,
-				89A88E120E71A67A0043BA31 /* messages.cc in Sources */,
-				89A88E130E71A6860043BA31 /* objects-debug.cc in Sources */,
-				89A88E140E71A6870043BA31 /* objects.cc in Sources */,
-				89A88E150E71A68C0043BA31 /* parser.cc in Sources */,
-				89A88E160E71A68E0043BA31 /* platform-macos.cc in Sources */,
-				893A72240F7B101400303DD2 /* platform-posix.cc in Sources */,
-				89A88E170E71A6950043BA31 /* prettyprinter.cc in Sources */,
-				9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */,
-				89A88E180E71A6960043BA31 /* property.cc in Sources */,
-				89A15C7B0EE466EB00B48DEB /* regexp-macro-assembler-ia32.cc in Sources */,
-				89A15C830EE4675E00B48DEB /* regexp-macro-assembler-irregexp.cc in Sources */,
-				89A15C8A0EE467D100B48DEB /* regexp-macro-assembler-tracer.cc in Sources */,
-				89A15C810EE4674900B48DEB /* regexp-macro-assembler.cc in Sources */,
-				8944AD100F1D4D500028D560 /* regexp-stack.cc in Sources */,
-				89A88E190E71A6970043BA31 /* rewriter.cc in Sources */,
-				89A88E1A0E71A69B0043BA31 /* runtime.cc in Sources */,
-				89A88E1B0E71A69D0043BA31 /* scanner.cc in Sources */,
-				89A88E1C0E71A69E0043BA31 /* scopeinfo.cc in Sources */,
-				89A88E1D0E71A6A00043BA31 /* scopes.cc in Sources */,
-				89A88E1E0E71A6A30043BA31 /* serialize.cc in Sources */,
-				89A88E1F0E71A6B40043BA31 /* snapshot-common.cc in Sources */,
-				89A88E200E71A6B60043BA31 /* snapshot-empty.cc in Sources */,
-				89A88E210E71A6B70043BA31 /* spaces.cc in Sources */,
-				89A88E220E71A6BC0043BA31 /* string-stream.cc in Sources */,
-				89A88E220E71A6BC0043BA31 /* string-stream.cc in Sources */,
-				89A88E230E71A6BE0043BA31 /* stub-cache-ia32.cc in Sources */,
-				89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */,
-				89A88E250E71A6C20043BA31 /* token.cc in Sources */,
-				9FA38BC01175B2D200C4CD55 /* type-info.cc in Sources */,
-				89A88E270E71A6CB0043BA31 /* unicode.cc in Sources */,
-				89A88E290E71A6CE0043BA31 /* utils.cc in Sources */,
-				89A88E2A0E71A6D00043BA31 /* v8-counters.cc in Sources */,
-				89A88E2B0E71A6D10043BA31 /* v8.cc in Sources */,
-				89A88E2C0E71A6D20043BA31 /* v8threads.cc in Sources */,
-				89A88E2D0E71A6D50043BA31 /* variables.cc in Sources */,
-				89B933AF0FAA0F9600201304 /* version.cc in Sources */,
-				89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */,
-				C68081B112251239001EAFE4 /* code-stubs-ia32.cc in Sources */,
-				893E24B712B14B3D0083370F /* bignum-dtoa.cc in Sources */,
-				893E24B812B14B3D0083370F /* bignum.cc in Sources */,
-				893E24B912B14B3D0083370F /* cached-powers.cc in Sources */,
-				893E24BA12B14B3D0083370F /* deoptimizer.cc in Sources */,
-				893E24BB12B14B3D0083370F /* hydrogen-instructions.cc in Sources */,
-				893E24BC12B14B3D0083370F /* hydrogen.cc in Sources */,
-				893E24BD12B14B3D0083370F /* lithium-allocator.cc in Sources */,
-				893E24BE12B14B3D0083370F /* preparse-data.cc in Sources */,
-				893E24C012B14B3D0083370F /* preparser.cc in Sources */,
-				893E24C112B14B3D0083370F /* runtime-profiler.cc in Sources */,
-				893E24C212B14B3D0083370F /* safepoint-table.cc in Sources */,
-				893E24C312B14B3D0083370F /* scanner-base.cc in Sources */,
-				893E24C412B14B3D0083370F /* string-search.cc in Sources */,
-				893E24C512B14B3D0083370F /* strtod.cc in Sources */,
-				893E24D512B14B8A0083370F /* deoptimizer-ia32.cc in Sources */,
-				893E24D612B14B8A0083370F /* lithium-codegen-ia32.cc in Sources */,
-				893E24D712B14B8A0083370F /* lithium-ia32.cc in Sources */,
-				893E24DC12B14B9F0083370F /* externalize-string-extension.cc in Sources */,
-				893E24DD12B14B9F0083370F /* gc-extension.cc in Sources */,
-				8946827512C26EB700C914BC /* objects-printer.cc in Sources */,
-				894A59EB12D777E80000766D /* lithium.cc in Sources */,
-				89D7DDD512E8DDCF001E2B82 /* lithium-gap-resolver-ia32.cc in Sources */,
-				89D7DDDA12E8DE09001E2B82 /* gdb-jit.cc in Sources */,
-				89D7DDDB12E8DE09001E2B82 /* inspector.cc in Sources */,
-				895D5B531334212D00254083 /* isolate.cc in Sources */,
-				58DA027E136ECC87007399A4 /* experimental-libraries.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		897C77CF12B68E3D000767A8 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				897C77D012B68E3D000767A8 /* d8-debug.cc in Sources */,
-				897C77D112B68E3D000767A8 /* d8-js.cc in Sources */,
-				897C77D212B68E3D000767A8 /* d8-posix.cc in Sources */,
-				897C77D312B68E3D000767A8 /* d8.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		897F76770E71B4CC007ACF34 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				897F767F0E71B690007ACF34 /* shell.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89B91BB712D4F02A002FF4BC /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				89B91BB812D4F02A002FF4BC /* shell.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89B91BC412D4F02A002FF4BC /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				89B91BC512D4F02A002FF4BC /* d8-debug.cc in Sources */,
-				89B91BC612D4F02A002FF4BC /* d8-js.cc in Sources */,
-				89B91BC712D4F02A002FF4BC /* d8-posix.cc in Sources */,
-				89B91BC812D4F02A002FF4BC /* d8.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89F23C3E0E78D5B2006B2466 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				C2D1E9741212F2CF00187A52 /* objects-visiting.cc in Sources */,
-				89F23C3F0E78D5B2006B2466 /* accessors.cc in Sources */,
-				89F23C400E78D5B2006B2466 /* allocation.cc in Sources */,
-				89F23C410E78D5B2006B2466 /* api.cc in Sources */,
-				89F23C970E78D5E3006B2466 /* assembler-arm.cc in Sources */,
-				89F23C430E78D5B2006B2466 /* assembler.cc in Sources */,
-				89F23C440E78D5B2006B2466 /* ast.cc in Sources */,
-				89F23C450E78D5B2006B2466 /* bootstrapper.cc in Sources */,
-				89F23C980E78D5E7006B2466 /* builtins-arm.cc in Sources */,
-				89F23C470E78D5B2006B2466 /* builtins.cc in Sources */,
-				89F23C480E78D5B2006B2466 /* checks.cc in Sources */,
-				9F2B3711114FF62D007CDAF4 /* circular-queue.cc in Sources */,
-				89F23C490E78D5B2006B2466 /* code-stubs.cc in Sources */,
-				89F23C990E78D5E9006B2466 /* codegen-arm.cc in Sources */,
-				89F23C4B0E78D5B2006B2466 /* codegen.cc in Sources */,
-				89495E490E79FC23001F68C3 /* compilation-cache.cc in Sources */,
-				89F23C4C0E78D5B2006B2466 /* compiler.cc in Sources */,
-				895FA753107FFED3006F39D4 /* constants-arm.cc in Sources */,
-				89F23C4D0E78D5B2006B2466 /* contexts.cc in Sources */,
-				89F23C4E0E78D5B2006B2466 /* conversions.cc in Sources */,
-				89F23C4F0E78D5B2006B2466 /* counters.cc in Sources */,
-				89F23C9A0E78D5EC006B2466 /* cpu-arm.cc in Sources */,
-				9F2B37261152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
-				C2BD4BE4120166180046BF9F /* fixed-dtoa.cc in Sources */,
-				C2BD4BE51201661F0046BF9F /* dtoa.cc in Sources */,
-				9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */,
-				89F23C510E78D5B2006B2466 /* dateparser.cc in Sources */,
-				894599A30F5D8729008DA8FB /* debug-agent.cc in Sources */,
-				898BD20F0EF6CC9A0068B00A /* debug-arm.cc in Sources */,
-				89F23C520E78D5B2006B2466 /* debug.cc in Sources */,
-				89F23C9B0E78D5EE006B2466 /* disasm-arm.cc in Sources */,
-				89F23C540E78D5B2006B2466 /* disassembler.cc in Sources */,
-				9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */,
-				89F23C560E78D5B2006B2466 /* execution.cc in Sources */,
-				89F23C570E78D5B2006B2466 /* factory.cc in Sources */,
-				9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */,
-				89F23C580E78D5B2006B2466 /* flags.cc in Sources */,
-				8981F6011010502800D1520E /* frame-element.cc in Sources */,
-				89F23C9C0E78D5F1006B2466 /* frames-arm.cc in Sources */,
-				89F23C5A0E78D5B2006B2466 /* frames.cc in Sources */,
-				9FA38BCF1175B30400C4CD55 /* full-codegen-arm.cc in Sources */,
-				9FA38BB71175B2D200C4CD55 /* full-codegen.cc in Sources */,
-				9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */,
-				89F23C5B0E78D5B2006B2466 /* global-handles.cc in Sources */,
-				89F23C5C0E78D5B2006B2466 /* handles.cc in Sources */,
-				89F23C5D0E78D5B2006B2466 /* hashmap.cc in Sources */,
-				9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
-				89F23C5E0E78D5B2006B2466 /* heap.cc in Sources */,
-				89F23C9D0E78D5FB006B2466 /* ic-arm.cc in Sources */,
-				89F23C600E78D5B2006B2466 /* ic.cc in Sources */,
-				890A13FE0EE9C47F00E49346 /* interpreter-irregexp.cc in Sources */,
-				89F23C610E78D5B2006B2466 /* jsregexp.cc in Sources */,
-				89F23C620E78D5B2006B2466 /* libraries.cc in Sources */,
-				9FA38BB81175B2D200C4CD55 /* liveedit.cc in Sources */,
-				9F4B7B8A0FCC877A00DC4117 /* log-utils.cc in Sources */,
-				89F23C630E78D5B2006B2466 /* log.cc in Sources */,
-				89F23C9E0E78D5FD006B2466 /* macro-assembler-arm.cc in Sources */,
-				89F23C650E78D5B2006B2466 /* mark-compact.cc in Sources */,
-				89F23C660E78D5B2006B2466 /* messages.cc in Sources */,
-				89F23C670E78D5B2006B2466 /* objects-debug.cc in Sources */,
-				89F23C680E78D5B2006B2466 /* objects.cc in Sources */,
-				89F23C690E78D5B2006B2466 /* parser.cc in Sources */,
-				89F23C6A0E78D5B2006B2466 /* platform-macos.cc in Sources */,
-				893A72250F7B101B00303DD2 /* platform-posix.cc in Sources */,
-				89F23C6B0E78D5B2006B2466 /* prettyprinter.cc in Sources */,
-				9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */,
-				89F23C6C0E78D5B2006B2466 /* property.cc in Sources */,
-				890A14010EE9C4B000E49346 /* regexp-macro-assembler-arm.cc in Sources */,
-				890A14020EE9C4B400E49346 /* regexp-macro-assembler-irregexp.cc in Sources */,
-				890A14030EE9C4B500E49346 /* regexp-macro-assembler-tracer.cc in Sources */,
-				890A14040EE9C4B700E49346 /* regexp-macro-assembler.cc in Sources */,
-				8944AD110F1D4D570028D560 /* regexp-stack.cc in Sources */,
-				89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */,
-				89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */,
-				89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */,
-				89F23C700E78D5B2006B2466 /* scopeinfo.cc in Sources */,
-				89F23C710E78D5B2006B2466 /* scopes.cc in Sources */,
-				89F23C720E78D5B2006B2466 /* serialize.cc in Sources */,
-				89F23C9F0E78D604006B2466 /* simulator-arm.cc in Sources */,
-				89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */,
-				89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */,
-				89F23C750E78D5B2006B2466 /* spaces.cc in Sources */,
-				89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */,
-				89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */,
-				89F23CA00E78D609006B2466 /* stub-cache-arm.cc in Sources */,
-				89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */,
-				89F23C790E78D5B2006B2466 /* token.cc in Sources */,
-				9FA38BB91175B2D200C4CD55 /* type-info.cc in Sources */,
-				89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */,
-				89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */,
-				89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */,
-				89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */,
-				89F23C800E78D5B2006B2466 /* v8threads.cc in Sources */,
-				89F23C810E78D5B2006B2466 /* variables.cc in Sources */,
-				89B933B00FAA0F9D00201304 /* version.cc in Sources */,
-				89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
-				C68081AD1225120B001EAFE4 /* code-stubs-arm.cc in Sources */,
-				893E24A812B14B3D0083370F /* bignum-dtoa.cc in Sources */,
-				893E24A912B14B3D0083370F /* bignum.cc in Sources */,
-				893E24AA12B14B3D0083370F /* cached-powers.cc in Sources */,
-				893E24AB12B14B3D0083370F /* deoptimizer.cc in Sources */,
-				893E24AC12B14B3D0083370F /* hydrogen-instructions.cc in Sources */,
-				893E24AD12B14B3D0083370F /* hydrogen.cc in Sources */,
-				893E24AE12B14B3D0083370F /* lithium-allocator.cc in Sources */,
-				893E24AF12B14B3D0083370F /* preparse-data.cc in Sources */,
-				893E24B112B14B3D0083370F /* preparser.cc in Sources */,
-				893E24B212B14B3D0083370F /* runtime-profiler.cc in Sources */,
-				893E24B312B14B3D0083370F /* safepoint-table.cc in Sources */,
-				893E24B412B14B3D0083370F /* scanner-base.cc in Sources */,
-				893E24B512B14B3D0083370F /* string-search.cc in Sources */,
-				893E24B612B14B3D0083370F /* strtod.cc in Sources */,
-				893E24CC12B14B520083370F /* deoptimizer-arm.cc in Sources */,
-				893E24CD12B14B520083370F /* lithium-arm.cc in Sources */,
-				893E24CE12B14B520083370F /* lithium-codegen-arm.cc in Sources */,
-				893E24DE12B14B9F0083370F /* externalize-string-extension.cc in Sources */,
-				893E24DF12B14B9F0083370F /* gc-extension.cc in Sources */,
-				8946827612C26EB700C914BC /* objects-printer.cc in Sources */,
-				894A59EA12D777E80000766D /* lithium.cc in Sources */,
-				89D7DDDC12E8DE09001E2B82 /* gdb-jit.cc in Sources */,
-				89D7DDDD12E8DE09001E2B82 /* inspector.cc in Sources */,
-				896FA1E5130F93D300042054 /* lithium-gap-resolver-arm.cc in Sources */,
-				895D5B541334212D00254083 /* isolate.cc in Sources */,
-				58DA027F136ECC87007399A4 /* experimental-libraries.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		89F23C8D0E78D5B6006B2466 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				89F23C8E0E78D5B6006B2466 /* shell.cc in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
-		7BF891970E73099F000BAF8A /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 8970F2EF0E719FB2006AE7B5 /* v8 */;
-			targetProxy = 7BF891960E73099F000BAF8A /* PBXContainerItemProxy */;
-		};
-		7BF891990E73099F000BAF8A /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 897F76790E71B4CC007ACF34 /* v8_shell */;
-			targetProxy = 7BF891980E73099F000BAF8A /* PBXContainerItemProxy */;
-		};
-		8938A29512D63A680080CDDE /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 89B91BC012D4F02A002FF4BC /* d8_shell-x64 */;
-			targetProxy = 8938A29412D63A680080CDDE /* PBXContainerItemProxy */;
-		};
-		8938A29712D63A680080CDDE /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 89B91BB412D4F02A002FF4BC /* v8_shell-x64 */;
-			targetProxy = 8938A29612D63A680080CDDE /* PBXContainerItemProxy */;
-		};
-		8938A29912D63A680080CDDE /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 8956922712D4ED240072C313 /* v8-x64 */;
-			targetProxy = 8938A29812D63A680080CDDE /* PBXContainerItemProxy */;
-		};
-		893988010F2A35FA007D5254 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 8970F2EF0E719FB2006AE7B5 /* v8 */;
-			targetProxy = 893988020F2A35FA007D5254 /* PBXContainerItemProxy */;
-		};
-		893988100F2A3647007D5254 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 893987FE0F2A35FA007D5254 /* d8_shell */;
-			targetProxy = 8939880F0F2A3647007D5254 /* PBXContainerItemProxy */;
-		};
-		896FD03C0E78D71F003DFB6A /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 89F23C3C0E78D5B2006B2466 /* v8-arm */;
-			targetProxy = 896FD03B0E78D71F003DFB6A /* PBXContainerItemProxy */;
-		};
-		896FD03E0E78D731003DFB6A /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 89F23C3C0E78D5B2006B2466 /* v8-arm */;
-			targetProxy = 896FD03D0E78D731003DFB6A /* PBXContainerItemProxy */;
-		};
-		896FD0400E78D735003DFB6A /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 89F23C880E78D5B6006B2466 /* v8_shell-arm */;
-			targetProxy = 896FD03F0E78D735003DFB6A /* PBXContainerItemProxy */;
-		};
-		897C77DC12B68E5D000767A8 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 89F23C3C0E78D5B2006B2466 /* v8-arm */;
-			targetProxy = 897C77DB12B68E5D000767A8 /* PBXContainerItemProxy */;
-		};
-		897F76830E71B6AC007ACF34 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 8970F2EF0E719FB2006AE7B5 /* v8 */;
-			targetProxy = 897F76820E71B6AC007ACF34 /* PBXContainerItemProxy */;
-		};
-		89B91BD112D4F036002FF4BC /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 8956922712D4ED240072C313 /* v8-x64 */;
-			targetProxy = 89B91BD012D4F036002FF4BC /* PBXContainerItemProxy */;
-		};
-		89B91BFD12D4F1BF002FF4BC /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 8956922712D4ED240072C313 /* v8-x64 */;
-			targetProxy = 89B91BFC12D4F1BF002FF4BC /* PBXContainerItemProxy */;
-		};
-		89EED40D12B69A0A0075BE1C /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 897C77CB12B68E3D000767A8 /* d8_shell-arm */;
-			targetProxy = 89EED40C12B69A0A0075BE1C /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
-		7BF891940E73098D000BAF8A /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				PRODUCT_NAME = All;
-			};
-			name = Debug;
-		};
-		7BF891950E73098D000BAF8A /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				PRODUCT_NAME = All;
-			};
-			name = Release;
-		};
-		8915B8690E719336009C4E19 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_C_LANGUAGE_STANDARD = ansi;
-				GCC_DYNAMIC_NO_PIC = YES;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PRECOMPILE_PREFIX_HEADER = YES;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					DEBUG,
-					ENABLE_LOGGING_AND_PROFILING,
-					V8_ENABLE_CHECKS,
-					OBJECT_PRINT,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
-				GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
-				OTHER_CFLAGS = (
-					"$(OTHER_CFLAGS)",
-					"-fstack-protector",
-					"-fstack-protector-all",
-				);
-				PREBINDING = NO;
-				SYMROOT = ../xcodebuild;
-				USE_HEADERMAP = NO;
-				WARNING_CFLAGS = (
-					"$(WARNING_CFLAGS)",
-					"-Wall",
-					"-Wendif-labels",
-				);
-			};
-			name = Debug;
-		};
-		8915B86A0E719336009C4E19 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				DEAD_CODE_STRIPPING = YES;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				DEPLOYMENT_POSTPROCESSING = YES;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_C_LANGUAGE_STANDARD = ansi;
-				GCC_DYNAMIC_NO_PIC = YES;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
-				GCC_OPTIMIZATION_LEVEL = 2;
-				GCC_PRECOMPILE_PREFIX_HEADER = YES;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					NDEBUG,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
-				GCC_TREAT_WARNINGS_AS_ERRORS = NO;
-				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
-				PREBINDING = NO;
-				STRIP_STYLE = all;
-				SYMROOT = ../xcodebuild;
-				USE_HEADERMAP = NO;
-				WARNING_CFLAGS = (
-					"$(WARNING_CFLAGS)",
-					"-Wall",
-					"-Wendif-labels",
-				);
-			};
-			name = Release;
-		};
-		893988090F2A35FA007D5254 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_IA32,
-					DEBUG,
-					V8_ENABLE_CHECKS,
-					OBJECT_PRINT,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = d8;
-			};
-			name = Debug;
-		};
-		8939880A0F2A35FA007D5254 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_IA32,
-					NDEBUG,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = d8;
-			};
-			name = Release;
-		};
-		895692A812D4ED240072C313 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
-				DEPLOYMENT_POSTPROCESSING = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					ENABLE_DISASSEMBLER,
-					V8_TARGET_ARCH_X64,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8-x64";
-				STRIP_STYLE = debugging;
-			};
-			name = Debug;
-		};
-		895692A912D4ED240072C313 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
-				DEPLOYMENT_POSTPROCESSING = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_X64,
-					NDEBUG,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8-x64";
-				STRIP_STYLE = debugging;
-			};
-			name = Release;
-		};
-		8970F2F10E719FB2006AE7B5 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				DEPLOYMENT_POSTPROCESSING = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					ENABLE_DISASSEMBLER,
-					V8_TARGET_ARCH_IA32,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = v8;
-				STRIP_STYLE = debugging;
-			};
-			name = Debug;
-		};
-		8970F2F20E719FB2006AE7B5 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				DEPLOYMENT_POSTPROCESSING = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_IA32,
-					NDEBUG,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = v8;
-				STRIP_STYLE = debugging;
-			};
-			name = Release;
-		};
-		897C77D712B68E3D000767A8 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_IA32,
-					DEBUG,
-					V8_ENABLE_CHECKS,
-					OBJECT_PRINT,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "d8-arm";
-			};
-			name = Debug;
-		};
-		897C77D812B68E3D000767A8 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_IA32,
-					NDEBUG,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "d8-arm";
-			};
-			name = Release;
-		};
-		897F767C0E71B4CC007ACF34 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_IA32,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = v8_shell;
-			};
-			name = Debug;
-		};
-		897F767D0E71B4CC007ACF34 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_IA32,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = v8_shell;
-			};
-			name = Release;
-		};
-		89B91BBC12D4F02A002FF4BC /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_X64,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8_shell-x64";
-			};
-			name = Debug;
-		};
-		89B91BBD12D4F02A002FF4BC /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_X64,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8_shell-x64";
-			};
-			name = Release;
-		};
-		89B91BCC12D4F02A002FF4BC /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_X64,
-					DEBUG,
-					V8_ENABLE_CHECKS,
-					OBJECT_PRINT,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "d8-x64";
-			};
-			name = Debug;
-		};
-		89B91BCD12D4F02A002FF4BC /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_X64,
-					NDEBUG,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "d8-x64";
-			};
-			name = Release;
-		};
-		89F23C850E78D5B2006B2466 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				DEPLOYMENT_POSTPROCESSING = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_ARM,
-					ENABLE_DISASSEMBLER,
-					ENABLE_VMSTATE_TRACKING,
-					ENABLE_LOGGING_AND_PROFILING,
-					ENABLE_DEBUGGER_SUPPORT,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8-arm";
-				STRIP_STYLE = debugging;
-			};
-			name = Debug;
-		};
-		89F23C860E78D5B2006B2466 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				DEPLOYMENT_POSTPROCESSING = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_ARM,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8-arm";
-				STRIP_STYLE = debugging;
-			};
-			name = Release;
-		};
-		89F23C930E78D5B6006B2466 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_ARM,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8_shell-arm";
-			};
-			name = Debug;
-		};
-		89F23C940E78D5B6006B2466 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"$(GCC_PREPROCESSOR_DEFINITIONS)",
-					V8_TARGET_ARCH_ARM,
-				);
-				HEADER_SEARCH_PATHS = ../src;
-				PRODUCT_NAME = "v8_shell-arm";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		7BF8919F0E7309BE000BAF8A /* Build configuration list for PBXAggregateTarget "All" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				7BF891940E73098D000BAF8A /* Debug */,
-				7BF891950E73098D000BAF8A /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		8915B86B0E719336009C4E19 /* Build configuration list for PBXProject "v8" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				8915B8690E719336009C4E19 /* Debug */,
-				8915B86A0E719336009C4E19 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		893988080F2A35FA007D5254 /* Build configuration list for PBXNativeTarget "d8_shell" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				893988090F2A35FA007D5254 /* Debug */,
-				8939880A0F2A35FA007D5254 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		895692A712D4ED240072C313 /* Build configuration list for PBXNativeTarget "v8-x64" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				895692A812D4ED240072C313 /* Debug */,
-				895692A912D4ED240072C313 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		8970F2F70E719FC1006AE7B5 /* Build configuration list for PBXNativeTarget "v8" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				8970F2F10E719FB2006AE7B5 /* Debug */,
-				8970F2F20E719FB2006AE7B5 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		897C77D612B68E3D000767A8 /* Build configuration list for PBXNativeTarget "d8_shell-arm" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				897C77D712B68E3D000767A8 /* Debug */,
-				897C77D812B68E3D000767A8 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		897F767E0E71B4EA007ACF34 /* Build configuration list for PBXNativeTarget "v8_shell" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				897F767C0E71B4CC007ACF34 /* Debug */,
-				897F767D0E71B4CC007ACF34 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		89B91BBB12D4F02A002FF4BC /* Build configuration list for PBXNativeTarget "v8_shell-x64" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				89B91BBC12D4F02A002FF4BC /* Debug */,
-				89B91BBD12D4F02A002FF4BC /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		89B91BCB12D4F02A002FF4BC /* Build configuration list for PBXNativeTarget "d8_shell-x64" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				89B91BCC12D4F02A002FF4BC /* Debug */,
-				89B91BCD12D4F02A002FF4BC /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		89F23C840E78D5B2006B2466 /* Build configuration list for PBXNativeTarget "v8-arm" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				89F23C850E78D5B2006B2466 /* Debug */,
-				89F23C860E78D5B2006B2466 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		89F23C920E78D5B6006B2466 /* Build configuration list for PBXNativeTarget "v8_shell-arm" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				89F23C930E78D5B6006B2466 /* Debug */,
-				89F23C940E78D5B6006B2466 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 8915B8680E719336009C4E19 /* Project object */;
-}