Version 3.22.9

Ensure only whitelisted stubs have sse2 versions in the snapshot. (fix for chromium 304565)

Implement ArrayBuffer.isView.

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@17127 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index db3f14e..4cddf03 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2013-10-10: Version 3.22.9
+
+        Ensure only whitelisted stubs have sse2 versions in the snapshot.
+        (fix for chromium 304565)
+
+        Implement ArrayBuffer.isView.
+
+        Performance and stability improvements on all platforms.
+
+
 2013-10-04: Version 3.22.8
 
         Performance and stability improvements on all platforms.
diff --git a/Makefile b/Makefile
index 6f1de5c..0eb1722 100644
--- a/Makefile
+++ b/Makefile
@@ -222,8 +222,8 @@
 
 # List of files that trigger Makefile regeneration:
 GYPFILES = build/all.gyp build/features.gypi build/standalone.gypi \
-	   build/toolchain.gypi preparser/preparser.gyp samples/samples.gyp \
-	   src/d8.gyp test/cctest/cctest.gyp tools/gyp/v8.gyp
+           build/toolchain.gypi samples/samples.gyp src/d8.gyp \
+           test/cctest/cctest.gyp tools/gyp/v8.gyp
 
 # If vtunejit=on, the v8vtune.gyp will be appended.
 ifeq ($(vtunejit), on)
diff --git a/build/all.gyp b/build/all.gyp
index 4b2fe52..ad71fb0 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -8,7 +8,6 @@
       'target_name': 'All',
       'type': 'none',
       'dependencies': [
-        '../preparser/preparser.gyp:*',
         '../samples/samples.gyp:*',
         '../src/d8.gyp:d8',
         '../test/cctest/cctest.gyp:*',
diff --git a/include/v8-preparser.h b/include/v8-preparser.h
deleted file mode 100644
index 1da7718..0000000
--- a/include/v8-preparser.h
+++ /dev/null
@@ -1,84 +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.
-
-#ifndef PREPARSER_H
-#define PREPARSER_H
-
-#include "v8.h"
-#include "v8stdint.h"
-
-namespace v8 {
-
-// The result of preparsing is either a stack overflow error, or an opaque
-// blob of data that can be passed back into the parser.
-class V8_EXPORT PreParserData {
- public:
-  PreParserData(size_t size, const uint8_t* data)
-      : data_(data), size_(size) { }
-
-  // Create a PreParserData value where stack_overflow reports true.
-  static PreParserData StackOverflow() { return PreParserData(0, NULL); }
-
-  // Whether the pre-parser stopped due to a stack overflow.
-  // If this is the case, size() and data() should not be used.
-  bool stack_overflow() { return size_ == 0u; }
-
-  // The size of the data in bytes.
-  size_t size() const { return size_; }
-
-  // Pointer to the data.
-  const uint8_t* data() const { return data_; }
-
- private:
-  const uint8_t* const data_;
-  const size_t size_;
-};
-
-
-// Interface for a stream of Unicode characters.
-class V8_EXPORT UnicodeInputStream {  // NOLINT - V8_EXPORT is not a class name.
- public:
-  virtual ~UnicodeInputStream();
-
-  // Returns the next Unicode code-point in the input, or a negative value when
-  // there is no more input in the stream.
-  virtual int32_t Next() = 0;
-};
-
-
-// Preparse a JavaScript program. The source code is provided as a
-// UnicodeInputStream. The max_stack_size limits the amount of stack
-// space that the preparser is allowed to use. If the preparser uses
-// more stack space than the limit provided, the result's stack_overflow()
-// method will return true. Otherwise the result contains preparser
-// data that can be used by the V8 parser to speed up parsing.
-PreParserData V8_EXPORT Preparse(UnicodeInputStream* input,
-                                size_t max_stack_size);
-
-}  // namespace v8.
-
-#endif  // PREPARSER_H
diff --git a/preparser/preparser-process.cc b/preparser/preparser-process.cc
deleted file mode 100644
index b816744..0000000
--- a/preparser/preparser-process.cc
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../include/v8.h"
-#include "../include/v8stdint.h"
-#include "../include/v8-preparser.h"
-
-#include "../src/preparse-data-format.h"
-
-namespace i = v8::internal;
-
-// This file is only used for testing the preparser.
-// The first argument must be the path of a JavaScript source file, or
-// the flags "-e" and the next argument is then the source of a JavaScript
-// program.
-// Optionally this can be followed by the word "throws" (case sensitive),
-// which signals that the parsing is expected to throw - the default is
-// to expect the parsing to not throw.
-// The command line can further be followed by a message text (the
-// *type* of the exception to throw), and even more optionally, the
-// start and end position reported with the exception.
-//
-// This source file is preparsed and tested against the expectations, and if
-// successful, the resulting preparser data is written to stdout.
-// Diagnostic output is output on stderr.
-// The source file must contain only ASCII characters (UTF-8 isn't supported).
-// The file is read into memory, so it should have a reasonable size.
-
-
-// Adapts an ASCII string to the UnicodeInputStream interface.
-class AsciiInputStream : public v8::UnicodeInputStream {
- public:
-  AsciiInputStream(const uint8_t* buffer, size_t length)
-      : buffer_(buffer),
-        end_offset_(static_cast<int>(length)),
-        offset_(0) { }
-
-  virtual ~AsciiInputStream() { }
-
-  virtual void PushBack(int32_t ch) {
-    offset_--;
-#ifdef DEBUG
-    if (offset_ < 0 ||
-        (ch != ((offset_ >= end_offset_) ? -1 : buffer_[offset_]))) {
-      fprintf(stderr, "Invalid pushback: '%c' at offset %d.", ch, offset_);
-      exit(1);
-    }
-#endif
-  }
-
-  virtual int32_t Next() {
-    if (offset_ >= end_offset_) {
-      offset_++;  // Increment anyway to allow symmetric pushbacks.
-      return -1;
-    }
-    uint8_t next_char = buffer_[offset_];
-#ifdef DEBUG
-    if (next_char > 0x7fu) {
-      fprintf(stderr, "Non-ASCII character in input: '%c'.", next_char);
-      exit(1);
-    }
-#endif
-    offset_++;
-    return static_cast<int32_t>(next_char);
-  }
-
- private:
-  const uint8_t* buffer_;
-  const int end_offset_;
-  int offset_;
-};
-
-
-bool ReadBuffer(FILE* source, void* buffer, size_t length) {
-  size_t actually_read = fread(buffer, 1, length, source);
-  return (actually_read == length);
-}
-
-
-bool WriteBuffer(FILE* dest, const void* buffer, size_t length) {
-  size_t actually_written = fwrite(buffer, 1, length, dest);
-  return (actually_written == length);
-}
-
-
-class PreparseDataInterpreter {
- public:
-  PreparseDataInterpreter(const uint8_t* data, int length)
-      : data_(data), length_(length), message_(NULL) { }
-
-  ~PreparseDataInterpreter() {
-    if (message_ != NULL) delete[] message_;
-  }
-
-  bool valid() {
-    int header_length =
-      i::PreparseDataConstants::kHeaderSize * sizeof(int);  // NOLINT
-    return length_ >= header_length;
-  }
-
-  bool throws() {
-    return valid() &&
-        word(i::PreparseDataConstants::kHasErrorOffset) != 0;
-  }
-
-  const char* message() {
-    if (message_ != NULL) return message_;
-    if (!throws()) return NULL;
-    int text_pos = i::PreparseDataConstants::kHeaderSize +
-                   i::PreparseDataConstants::kMessageTextPos;
-    int length = word(text_pos);
-    char* buffer = new char[length + 1];
-    for (int i = 1; i <= length; i++) {
-      int character = word(text_pos + i);
-      buffer[i - 1] = character;
-    }
-    buffer[length] = '\0';
-    message_ = buffer;
-    return buffer;
-  }
-
-  int beg_pos() {
-    if (!throws()) return -1;
-    return word(i::PreparseDataConstants::kHeaderSize +
-                i::PreparseDataConstants::kMessageStartPos);
-  }
-
-  int end_pos() {
-    if (!throws()) return -1;
-    return word(i::PreparseDataConstants::kHeaderSize +
-                i::PreparseDataConstants::kMessageEndPos);
-  }
-
- private:
-  int word(int offset) {
-    const int* word_data = reinterpret_cast<const int*>(data_);
-    if (word_data + offset < reinterpret_cast<const int*>(data_ + length_)) {
-      return word_data[offset];
-    }
-    return -1;
-  }
-
-  const uint8_t* const data_;
-  const int length_;
-  const char* message_;
-};
-
-
-template <typename T>
-class ScopedPointer {
- public:
-  explicit ScopedPointer() : pointer_(NULL) {}
-  explicit ScopedPointer(T* pointer) : pointer_(pointer) {}
-  ~ScopedPointer() { if (pointer_ != NULL) delete[] pointer_; }
-  T& operator[](int index) { return pointer_[index]; }
-  T* operator*() { return pointer_ ;}
-  T* operator=(T* new_value) {
-    if (pointer_ != NULL) delete[] pointer_;
-    pointer_ = new_value;
-    return new_value;
-  }
- private:
-  T* pointer_;
-};
-
-
-
-void fail(v8::PreParserData* data, const char* message, ...) {
-  va_list args;
-  va_start(args, message);
-  vfprintf(stderr, message, args);
-  va_end(args);
-  fflush(stderr);
-  if (data != NULL) {
-    // Print preparser data to stdout.
-    uint32_t size = static_cast<uint32_t>(data->size());
-    fprintf(stderr, "LOG: data size: %u\n", size);
-    if (!WriteBuffer(stdout, data->data(), size)) {
-      perror("ERROR: Writing data");
-      fflush(stderr);
-    }
-  }
-  exit(EXIT_FAILURE);
-}
-
-
-bool IsFlag(const char* arg) {
-  // Anything starting with '-' is considered a flag.
-  // It's summarily ignored for now.
-  return arg[0] == '-';
-}
-
-
-struct ExceptionExpectation {
-  ExceptionExpectation()
-      : throws(false), type(NULL), beg_pos(-1), end_pos(-1) { }
-  bool throws;
-  const char* type;
-  int beg_pos;
-  int end_pos;
-};
-
-
-void CheckException(v8::PreParserData* data,
-                    ExceptionExpectation* expects) {
-  PreparseDataInterpreter reader(data->data(), static_cast<int>(data->size()));
-  if (expects->throws) {
-    if (!reader.throws()) {
-      if (expects->type == NULL) {
-        fail(data, "Didn't throw as expected\n");
-      } else {
-        fail(data, "Didn't throw \"%s\" as expected\n", expects->type);
-      }
-    }
-    if (expects->type != NULL) {
-      const char* actual_message = reader.message();
-      if (strcmp(expects->type, actual_message)) {
-        fail(data, "Wrong error message. Expected <%s>, found <%s> at %d..%d\n",
-             expects->type, actual_message, reader.beg_pos(), reader.end_pos());
-      }
-    }
-    if (expects->beg_pos >= 0) {
-      if (expects->beg_pos != reader.beg_pos()) {
-        fail(data, "Wrong error start position: Expected %i, found %i\n",
-             expects->beg_pos, reader.beg_pos());
-      }
-    }
-    if (expects->end_pos >= 0) {
-      if (expects->end_pos != reader.end_pos()) {
-        fail(data, "Wrong error end position: Expected %i, found %i\n",
-             expects->end_pos, reader.end_pos());
-      }
-    }
-  } else if (reader.throws()) {
-    const char* message = reader.message();
-    fail(data, "Throws unexpectedly with message: %s at location %d-%d\n",
-         message, reader.beg_pos(), reader.end_pos());
-  }
-}
-
-
-ExceptionExpectation ParseExpectation(int argc, const char* argv[]) {
-  // Parse ["throws" [<exn-type> [<start> [<end>]]]].
-  ExceptionExpectation expects;
-  int arg_index = 0;
-  while (argc > arg_index && strncmp("throws", argv[arg_index], 7)) {
-    arg_index++;
-  }
-  if (argc > arg_index) {
-    expects.throws = true;
-    arg_index++;
-    if (argc > arg_index && !IsFlag(argv[arg_index])) {
-      expects.type = argv[arg_index];
-      arg_index++;
-      if (argc > arg_index && !IsFlag(argv[arg_index])) {
-        expects.beg_pos = atoi(argv[arg_index]);  // NOLINT
-        arg_index++;
-        if (argc > arg_index && !IsFlag(argv[arg_index])) {
-          expects.end_pos = atoi(argv[arg_index]);  // NOLINT
-        }
-      }
-    }
-  }
-  return expects;
-}
-
-
-int main(int argc, const char* argv[]) {
-  // Parse command line.
-  // Format:  preparser (<scriptfile> | -e "<source>")
-  //                    ["throws" [<exn-type> [<start> [<end>]]]]
-  // Any flags (except an initial -e) are ignored.
-  // Flags must not separate "throws" and its arguments.
-
-  // Check for mandatory filename argument.
-  int arg_index = 1;
-  if (argc <= arg_index) {
-    fail(NULL, "ERROR: No filename on command line.\n");
-  }
-  const uint8_t* source = NULL;
-  const char* filename = argv[arg_index];
-  if (!strcmp(filename, "-e")) {
-    arg_index++;
-    if (argc <= arg_index) {
-      fail(NULL, "ERROR: No source after -e on command line.\n");
-    }
-    source = reinterpret_cast<const uint8_t*>(argv[arg_index]);
-  }
-  // Check remainder of command line for exception expectations.
-  arg_index++;
-  ExceptionExpectation expects =
-      ParseExpectation(argc - arg_index, argv + arg_index);
-
-  v8::V8::Initialize();
-
-  ScopedPointer<uint8_t> buffer;
-  size_t length;
-
-  if (source == NULL) {
-    // Open JS file.
-    FILE* input = fopen(filename, "rb");
-    if (input == NULL) {
-      perror("ERROR: Error opening file");
-      fflush(stderr);
-      return EXIT_FAILURE;
-    }
-    // Find length of JS file.
-    if (fseek(input, 0, SEEK_END) != 0) {
-      perror("ERROR: Error during seek");
-      fflush(stderr);
-      return EXIT_FAILURE;
-    }
-    length = static_cast<size_t>(ftell(input));
-    rewind(input);
-    // Read JS file into memory buffer.
-    buffer = new uint8_t[length];
-    if (!ReadBuffer(input, *buffer, length)) {
-      perror("ERROR: Reading file");
-      fflush(stderr);
-      return EXIT_FAILURE;
-    }
-    fclose(input);
-    source = *buffer;
-  } else {
-    length = strlen(reinterpret_cast<const char*>(source));
-  }
-
-  // Preparse input file.
-  AsciiInputStream input_buffer(source, length);
-  size_t kMaxStackSize = 64 * 1024 * sizeof(void*);  // NOLINT
-  v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize);
-
-  // Fail if stack overflow.
-  if (data.stack_overflow()) {
-    fail(&data, "ERROR: Stack overflow\n");
-  }
-
-  // Check that the expected exception is thrown, if an exception is
-  // expected.
-  CheckException(&data, &expects);
-
-  return EXIT_SUCCESS;
-}
diff --git a/preparser/preparser.gyp b/preparser/preparser.gyp
deleted file mode 100644
index 23cbfff..0000000
--- a/preparser/preparser.gyp
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2011 the V8 project authors. All rights reserved.
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-#       copyright notice, this list of conditions and the following
-#       disclaimer in the documentation and/or other materials provided
-#       with the distribution.
-#     * Neither the name of Google Inc. nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-{
-  'variables': {
-    'v8_code': 1,
-  },
-  'includes': ['../build/toolchain.gypi', '../build/features.gypi'],
-  'targets': [
-    {
-      'target_name': 'preparser',
-      'type': 'executable',
-      'conditions': [
-        # preparser can't link against a shared library, so link against
-        # the underlying static targets.
-        ['v8_use_snapshot=="true"', {
-          'dependencies': ['../tools/gyp/v8.gyp:v8_snapshot'],
-        }, {
-          'dependencies': [
-            '../tools/gyp/v8.gyp:v8_nosnapshot.<(v8_target_arch)',
-          ],
-        }],
-      ],
-      'include_dirs+': [
-        '../src',
-      ],
-      'sources': [
-        'preparser-process.cc',
-        '../include/v8-preparser.h',
-        '../src/preparser-api.cc',
-      ],
-    },
-  ],
-}
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index bd8b061..05b25ae 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -50,6 +50,7 @@
 #endif
 unsigned CpuFeatures::supported_ = 0;
 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
+unsigned CpuFeatures::cross_compile_ = 0;
 unsigned CpuFeatures::cache_line_size_ = 64;
 
 
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 47dda2a..8caa64d 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -64,23 +64,41 @@
   // Check whether a feature is supported by the target CPU.
   static bool IsSupported(CpuFeature f) {
     ASSERT(initialized_);
-    return (supported_ & (1u << f)) != 0;
+    return Check(f, supported_);
   }
 
   static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
     ASSERT(initialized_);
-    return (found_by_runtime_probing_only_ &
-            (static_cast<uint64_t>(1) << f)) != 0;
+    return Check(f, found_by_runtime_probing_only_);
   }
 
   static bool IsSafeForSnapshot(CpuFeature f) {
-    return (IsSupported(f) &&
+    return Check(f, cross_compile_) ||
+           (IsSupported(f) &&
             (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
   }
 
   static unsigned cache_line_size() { return cache_line_size_; }
 
+  static bool VerifyCrossCompiling() {
+    return cross_compile_ == 0;
+  }
+
+  static bool VerifyCrossCompiling(CpuFeature f) {
+    unsigned mask = flag2set(f);
+    return cross_compile_ == 0 ||
+           (cross_compile_ & mask) == mask;
+  }
+
  private:
+  static bool Check(CpuFeature f, unsigned set) {
+    return (set & flag2set(f)) != 0;
+  }
+
+  static unsigned flag2set(CpuFeature f) {
+    return 1u << f;
+  }
+
 #ifdef DEBUG
   static bool initialized_;
 #endif
@@ -88,6 +106,8 @@
   static unsigned found_by_runtime_probing_only_;
   static unsigned cache_line_size_;
 
+  static unsigned cross_compile_;
+
   friend class ExternalReference;
   friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index b83ee21..ff14172 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1082,12 +1082,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) {
-  LOperand* object = UseRegisterAtStart(instr->object());
-  return DefineAsRegister(new(zone()) LInstanceSize(object));
-}
-
-
 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
   LOperand* receiver = UseRegisterAtStart(instr->receiver());
   LOperand* function = UseRegisterAtStart(instr->function());
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 5a095b5..0894652 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -105,7 +105,6 @@
   V(InnerAllocatedObject)                       \
   V(InstanceOf)                                 \
   V(InstanceOfKnownGlobal)                      \
-  V(InstanceSize)                               \
   V(InstructionGap)                             \
   V(Integer32ToDouble)                          \
   V(Integer32ToSmi)                             \
@@ -1148,19 +1147,6 @@
 };
 
 
-class LInstanceSize V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LInstanceSize(LOperand* object) {
-    inputs_[0] = object;
-  }
-
-  LOperand* object() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceSize, "instance-size")
-  DECLARE_HYDROGEN_ACCESSOR(InstanceSize)
-};
-
-
 class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
  public:
   LBoundsCheck(LOperand* index, LOperand* length) {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index af7f6af..71c1f86 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2847,14 +2847,6 @@
 }
 
 
-void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
-  Register object = ToRegister(instr->object());
-  Register result = ToRegister(instr->result());
-  __ ldr(result, FieldMemOperand(object, HeapObject::kMapOffset));
-  __ ldrb(result, FieldMemOperand(result, Map::kInstanceSizeOffset));
-}
-
-
 void LCodeGen::DoCmpT(LCmpT* instr) {
   ASSERT(ToRegister(instr->context()).is(cp));
   Token::Value op = instr->op();
diff --git a/src/arraybuffer.js b/src/arraybuffer.js
index 4a4f570..c5c98db 100644
--- a/src/arraybuffer.js
+++ b/src/arraybuffer.js
@@ -81,6 +81,10 @@
   return result;
 }
 
+function ArrayBufferIsView(obj) {
+  return %ArrayBufferIsView(obj);
+}
+
 function SetUpArrayBuffer() {
   %CheckIsBootstrapping();
 
@@ -93,6 +97,10 @@
 
   InstallGetter($ArrayBuffer.prototype, "byteLength", ArrayBufferGetByteLength);
 
+  InstallFunctions($ArrayBuffer, DONT_ENUM, $Array(
+      "isView", ArrayBufferIsView
+  ));
+
   InstallFunctions($ArrayBuffer.prototype, DONT_ENUM, $Array(
       "slice", ArrayBufferSlice
   ));
diff --git a/src/assembler.cc b/src/assembler.cc
index 6581aa1..cd2bedd 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -210,19 +210,14 @@
 // Implementation of PlatformFeatureScope
 
 PlatformFeatureScope::PlatformFeatureScope(CpuFeature f)
-    : old_supported_(CpuFeatures::supported_),
-      old_found_by_runtime_probing_only_(
-          CpuFeatures::found_by_runtime_probing_only_) {
+    : old_cross_compile_(CpuFeatures::cross_compile_) {
   uint64_t mask = static_cast<uint64_t>(1) << f;
-  CpuFeatures::supported_ |= mask;
-  CpuFeatures::found_by_runtime_probing_only_ &= ~mask;
+  CpuFeatures::cross_compile_ |= mask;
 }
 
 
 PlatformFeatureScope::~PlatformFeatureScope() {
-  CpuFeatures::supported_ = old_supported_;
-  CpuFeatures::found_by_runtime_probing_only_ =
-      old_found_by_runtime_probing_only_;
+  CpuFeatures::cross_compile_ = old_cross_compile_;
 }
 
 
diff --git a/src/assembler.h b/src/assembler.h
index 1220074..3bba98b 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -142,8 +142,7 @@
   ~PlatformFeatureScope();
 
  private:
-  uint64_t old_supported_;
-  uint64_t old_found_by_runtime_probing_only_;
+  uint64_t old_cross_compile_;
 };
 
 
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 456ecc0..dcf9e5b 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -434,7 +434,6 @@
 
 template <>
 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
-  Zone* zone = this->zone();
   HValue* undefined = graph()->GetConstantUndefined();
 
   HInstruction* boilerplate = Add<HLoadKeyed>(GetParameter(0),
@@ -448,8 +447,10 @@
   checker.And();
 
   int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize;
-  HValue* boilerplate_size =
-      AddInstruction(new(zone) HInstanceSize(boilerplate));
+  HValue* boilerplate_map = Add<HLoadNamedField>(
+      boilerplate, HObjectAccess::ForMap());
+  HValue* boilerplate_size = Add<HLoadNamedField>(
+      boilerplate_map, HObjectAccess::ForMapInstanceSize());
   HValue* size_in_words = Add<HConstant>(size >> kPointerSizeLog2);
   checker.If<HCompareNumericAndBranch>(boilerplate_size,
                                        size_in_words, Token::EQ);
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 75b8807..0911d9a 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -129,6 +129,11 @@
 }
 
 
+void CodeStub::VerifyPlatformFeatures(Isolate* isolate) {
+  ASSERT(CpuFeatures::VerifyCrossCompiling());
+}
+
+
 Handle<Code> CodeStub::GetCode(Isolate* isolate) {
   Factory* factory = isolate->factory();
   Heap* heap = isolate->heap();
@@ -141,6 +146,10 @@
     return Handle<Code>(code);
   }
 
+#ifdef DEBUG
+  VerifyPlatformFeatures(isolate);
+#endif
+
   {
     HandleScope scope(isolate);
 
@@ -297,8 +306,6 @@
   // expensive at runtime. When solved we should be able to add most binops to
   // the snapshot instead of hand-picking them.
   // Generated list of commonly used stubs
-  Generate(Token::ADD, GENERIC, STRING, STRING, NO_OVERWRITE, isolate);
-  Generate(Token::ADD, GENERIC, STRING, STRING, OVERWRITE_RIGHT, isolate);
   Generate(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE, isolate);
   Generate(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
   Generate(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
@@ -326,12 +333,6 @@
   Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
   Generate(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
   Generate(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
-  Generate(Token::ADD, STRING, GENERIC, STRING, NO_OVERWRITE, isolate);
-  Generate(Token::ADD, STRING, GENERIC, STRING, OVERWRITE_LEFT, isolate);
-  Generate(Token::ADD, STRING, GENERIC, STRING, OVERWRITE_RIGHT, isolate);
-  Generate(Token::ADD, STRING, STRING, STRING, NO_OVERWRITE, isolate);
-  Generate(Token::ADD, STRING, STRING, STRING, OVERWRITE_LEFT, isolate);
-  Generate(Token::ADD, STRING, STRING, STRING, OVERWRITE_RIGHT, isolate);
   Generate(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE, isolate);
   Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
   Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 9b25319..d2101ae 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -209,6 +209,7 @@
   // Generates the assembler code for the stub.
   virtual Handle<Code> GenerateCode(Isolate* isolate) = 0;
 
+  virtual void VerifyPlatformFeatures(Isolate* isolate);
 
   // Returns whether the code generated for this stub needs to be allocated as
   // a fixed (non-moveable) code object.
@@ -1043,6 +1044,10 @@
     return MONOMORPHIC;
   }
 
+  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
+    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
+  }
+
   virtual Code::ExtraICState GetExtraICState() {
     bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI &&
                      CpuFeatures::IsSafeForSnapshot(SSE2);
@@ -1348,6 +1353,11 @@
   virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE;
   static void GenerateAheadOfTime(Isolate* isolate);
 
+ protected:
+  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
+    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
+  };
+
  private:
   void GenerateCore(MacroAssembler* masm,
                     Label* throw_normal_exception,
@@ -1766,6 +1776,11 @@
 
   virtual bool SometimesSetsUpAFrame() { return false; }
 
+ protected:
+  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
+    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
+  }
+
  private:
   static const int kBitsPerRegisterNumber = 6;
   STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
diff --git a/src/d8.cc b/src/d8.cc
index 6eb7248..96407a8 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -1231,6 +1231,7 @@
 
 
 void SourceGroup::Execute(Isolate* isolate) {
+  bool exception_was_thrown = false;
   for (int i = begin_offset_; i < end_offset_; ++i) {
     const char* arg = argv_[i];
     if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
@@ -1239,7 +1240,8 @@
       Handle<String> file_name = String::New("unnamed");
       Handle<String> source = String::New(argv_[i + 1]);
       if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
-        Shell::Exit(1);
+        exception_was_thrown = true;
+        break;
       }
       ++i;
     } else if (arg[0] == '-') {
@@ -1254,10 +1256,14 @@
         Shell::Exit(1);
       }
       if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
-        Shell::Exit(1);
+        exception_was_thrown = true;
+        break;
       }
     }
   }
+  if (exception_was_thrown != Shell::options.expected_to_throw) {
+    Shell::Exit(1);
+  }
 }
 
 
@@ -1413,6 +1419,9 @@
       options.dump_heap_constants = true;
       argv[i] = NULL;
 #endif
+    } else if (strcmp(argv[i], "--throws") == 0) {
+      options.expected_to_throw = true;
+      argv[i] = NULL;
     }
 #ifdef V8_SHARED
     else if (strcmp(argv[i], "--dump-counters") == 0) {
diff --git a/src/d8.h b/src/d8.h
index 1ae1bcf..42013e8 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -232,6 +232,7 @@
      interactive_shell(false),
      test_shell(false),
      dump_heap_constants(false),
+     expected_to_throw(false),
      num_isolates(1),
      isolate_sources(NULL) { }
 
@@ -256,6 +257,7 @@
   bool interactive_shell;
   bool test_shell;
   bool dump_heap_constants;
+  bool expected_to_throw;
   int num_isolates;
   SourceGroup* isolate_sources;
 };
diff --git a/src/hydrogen-canonicalize.cc b/src/hydrogen-canonicalize.cc
index 4d96415..d3f72e9 100644
--- a/src/hydrogen-canonicalize.cc
+++ b/src/hydrogen-canonicalize.cc
@@ -26,6 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "hydrogen-canonicalize.h"
+#include "hydrogen-redundant-phi.h"
 
 namespace v8 {
 namespace internal {
@@ -57,8 +58,15 @@
       }
     }
   }
+
   // Perform actual Canonicalization pass.
+  HRedundantPhiEliminationPhase redundant_phi_eliminator(graph());
   for (int i = 0; i < blocks->length(); ++i) {
+    // Eliminate redundant phis in the block first; changes to their inputs
+    // might have made them redundant, and eliminating them creates more
+    // opportunities for constant folding and strength reduction.
+    redundant_phi_eliminator.ProcessBlock(blocks->at(i));
+    // Now canonicalize each instruction.
     for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) {
       HInstruction* instr = it.Current();
       HValue* value = instr->Canonicalize();
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index ec99f9b..733347b 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -126,7 +126,6 @@
   V(InnerAllocatedObject)                      \
   V(InstanceOf)                                \
   V(InstanceOfKnownGlobal)                     \
-  V(InstanceSize)                              \
   V(InvokeFunction)                            \
   V(IsConstructCallAndBranch)                  \
   V(IsObjectAndBranch)                         \
@@ -4473,26 +4472,6 @@
 };
 
 
-// TODO(mstarzinger): This instruction should be modeled as a load of the map
-// field followed by a load of the instance size field once HLoadNamedField is
-// flexible enough to accommodate byte-field loads.
-class HInstanceSize V8_FINAL : public HTemplateInstruction<1> {
- public:
-  explicit HInstanceSize(HValue* object) {
-    SetOperandAt(0, object);
-    set_representation(Representation::Integer32());
-  }
-
-  HValue* object() { return OperandAt(0); }
-
-  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
-    return Representation::Tagged();
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceSize)
-};
-
-
 class HPower V8_FINAL : public HTemplateInstruction<2> {
  public:
   static HInstruction* New(Zone* zone,
@@ -5828,6 +5807,12 @@
     return HObjectAccess(kMaps, JSObject::kMapOffset);
   }
 
+  static HObjectAccess ForMapInstanceSize() {
+    return HObjectAccess(kInobject,
+                         Map::kInstanceSizeOffset,
+                         Representation::Byte());
+  }
+
   static HObjectAccess ForPropertyCellValue() {
     return HObjectAccess(kInobject, PropertyCell::kValueOffset);
   }
diff --git a/src/hydrogen-redundant-phi.cc b/src/hydrogen-redundant-phi.cc
index 9c38200..1263833 100644
--- a/src/hydrogen-redundant-phi.cc
+++ b/src/hydrogen-redundant-phi.cc
@@ -31,37 +31,18 @@
 namespace internal {
 
 void HRedundantPhiEliminationPhase::Run() {
-  // We do a simple fixed point iteration without any work list, because
-  // machine-generated JavaScript can lead to a very dense Hydrogen graph with
-  // an enormous work list and will consequently result in OOM. Experiments
-  // showed that this simple algorithm is good enough, and even e.g. tracking
-  // the set or range of blocks to consider is not a real improvement.
-  bool need_another_iteration;
+  // Gather all phis from all blocks first.
   const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
-  ZoneList<HPhi*> redundant_phis(blocks->length(), zone());
-  do {
-    need_another_iteration = false;
-    for (int i = 0; i < blocks->length(); ++i) {
-      HBasicBlock* block = blocks->at(i);
-      for (int j = 0; j < block->phis()->length(); j++) {
-        HPhi* phi = block->phis()->at(j);
-        HValue* replacement = phi->GetRedundantReplacement();
-        if (replacement != NULL) {
-          // Remember phi to avoid concurrent modification of the block's phis.
-          redundant_phis.Add(phi, zone());
-          for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
-            HValue* value = it.value();
-            value->SetOperandAt(it.index(), replacement);
-            need_another_iteration |= value->IsPhi();
-          }
-        }
-      }
-      for (int i = 0; i < redundant_phis.length(); i++) {
-        block->RemovePhi(redundant_phis[i]);
-      }
-      redundant_phis.Clear();
+  ZoneList<HPhi*> all_phis(blocks->length(), zone());
+  for (int i = 0; i < blocks->length(); ++i) {
+    HBasicBlock* block = blocks->at(i);
+    for (int j = 0; j < block->phis()->length(); j++) {
+      all_phis.Add(block->phis()->at(j), zone());
     }
-  } while (need_another_iteration);
+  }
+
+  // Iteratively reduce all phis in the list.
+  ProcessPhis(&all_phis);
 
 #if DEBUG
   // Make sure that we *really* removed all redundant phis.
@@ -73,4 +54,35 @@
 #endif
 }
 
+
+void HRedundantPhiEliminationPhase::ProcessBlock(HBasicBlock* block) {
+  ProcessPhis(block->phis());
+}
+
+
+void HRedundantPhiEliminationPhase::ProcessPhis(const ZoneList<HPhi*>* phis) {
+  bool updated;
+  do {
+    // Iterately replace all redundant phis in the given list.
+    updated = false;
+    for (int i = 0; i < phis->length(); i++) {
+      HPhi* phi = phis->at(i);
+      if (phi->CheckFlag(HValue::kIsDead)) continue;  // Already replaced.
+
+      HValue* replacement = phi->GetRedundantReplacement();
+      if (replacement != NULL) {
+        phi->SetFlag(HValue::kIsDead);
+        for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
+          HValue* value = it.value();
+          value->SetOperandAt(it.index(), replacement);
+          // Iterate again if used in another non-dead phi.
+          updated |= value->IsPhi() && !value->CheckFlag(HValue::kIsDead);
+        }
+        phi->block()->RemovePhi(phi);
+      }
+    }
+  } while (updated);
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/hydrogen-redundant-phi.h b/src/hydrogen-redundant-phi.h
index 6291fa5..960ae69 100644
--- a/src/hydrogen-redundant-phi.h
+++ b/src/hydrogen-redundant-phi.h
@@ -42,8 +42,11 @@
       : HPhase("H_Redundant phi elimination", graph) { }
 
   void Run();
+  void ProcessBlock(HBasicBlock* block);
 
  private:
+  void ProcessPhis(const ZoneList<HPhi*>* phis);
+
   DISALLOW_COPY_AND_ASSIGN(HRedundantPhiEliminationPhase);
 };
 
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index c2e8431..a4412d0 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -53,6 +53,7 @@
 #endif
 uint64_t CpuFeatures::supported_ = 0;
 uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
+uint64_t CpuFeatures::cross_compile_ = 0;
 
 
 ExternalReference ExternalReference::cpu_features() {
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 7c3999b..07851f8 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -535,31 +535,52 @@
   // Check whether a feature is supported by the target CPU.
   static bool IsSupported(CpuFeature f) {
     ASSERT(initialized_);
+    if (Check(f, cross_compile_)) return true;
     if (f == SSE2 && !FLAG_enable_sse2) return false;
     if (f == SSE3 && !FLAG_enable_sse3) return false;
     if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
     if (f == CMOV && !FLAG_enable_cmov) return false;
-    return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
+    return Check(f, supported_);
   }
 
   static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
     ASSERT(initialized_);
-    return (found_by_runtime_probing_only_ &
-            (static_cast<uint64_t>(1) << f)) != 0;
+    return Check(f, found_by_runtime_probing_only_);
   }
 
   static bool IsSafeForSnapshot(CpuFeature f) {
-    return (IsSupported(f) &&
+    return Check(f, cross_compile_) ||
+           (IsSupported(f) &&
             (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
   }
 
+  static bool VerifyCrossCompiling() {
+    return cross_compile_ == 0;
+  }
+
+  static bool VerifyCrossCompiling(CpuFeature f) {
+    uint64_t mask = flag2set(f);
+    return cross_compile_ == 0 ||
+           (cross_compile_ & mask) == mask;
+  }
+
  private:
+  static bool Check(CpuFeature f, uint64_t set) {
+    return (set & flag2set(f)) != 0;
+  }
+
+  static uint64_t flag2set(CpuFeature f) {
+    return static_cast<uint64_t>(1) << f;
+  }
+
 #ifdef DEBUG
   static bool initialized_;
 #endif
   static uint64_t supported_;
   static uint64_t found_by_runtime_probing_only_;
 
+  static uint64_t cross_compile_;
+
   friend class ExternalReference;
   friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index d73fdfb..504a8b1 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3003,14 +3003,6 @@
 }
 
 
-void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
-  Register object = ToRegister(instr->object());
-  Register result = ToRegister(instr->result());
-  __ mov(result, FieldOperand(object, HeapObject::kMapOffset));
-  __ movzx_b(result, FieldOperand(result, Map::kInstanceSizeOffset));
-}
-
-
 void LCodeGen::DoCmpT(LCmpT* instr) {
   Token::Value op = instr->op();
 
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index a4d2e18..ba225ef 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1150,12 +1150,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) {
-  LOperand* object = UseRegisterAtStart(instr->object());
-  return DefineAsRegister(new(zone()) LInstanceSize(object));
-}
-
-
 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
   LOperand* receiver = UseRegister(instr->receiver());
   LOperand* function = UseRegisterAtStart(instr->function());
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index b4f4d5d..f3f9efa 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -107,7 +107,6 @@
   V(InnerAllocatedObject)                       \
   V(InstanceOf)                                 \
   V(InstanceOfKnownGlobal)                      \
-  V(InstanceSize)                               \
   V(InstructionGap)                             \
   V(Integer32ToDouble)                          \
   V(Integer32ToSmi)                             \
@@ -1131,19 +1130,6 @@
 };
 
 
-class LInstanceSize V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LInstanceSize(LOperand* object) {
-    inputs_[0] = object;
-  }
-
-  LOperand* object() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceSize, "instance-size")
-  DECLARE_HYDROGEN_ACCESSOR(InstanceSize)
-};
-
-
 class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
  public:
   LBoundsCheck(LOperand* index, LOperand* length) {
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index 345b642..0972a82 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -48,6 +48,7 @@
 #endif
 unsigned CpuFeatures::supported_ = 0;
 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
+unsigned CpuFeatures::cross_compile_ = 0;
 
 
 ExternalReference ExternalReference::cpu_features() {
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index 3a0ea40..2468c3c 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -411,27 +411,47 @@
   // Check whether a feature is supported by the target CPU.
   static bool IsSupported(CpuFeature f) {
     ASSERT(initialized_);
-    return (supported_ & (1u << f)) != 0;
+    return Check(f, supported_);
   }
 
   static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
     ASSERT(initialized_);
-    return (found_by_runtime_probing_only_ &
-            (static_cast<uint64_t>(1) << f)) != 0;
+    return Check(f, found_by_runtime_probing_only_);
   }
 
   static bool IsSafeForSnapshot(CpuFeature f) {
-    return (IsSupported(f) &&
+    return Check(f, cross_compile_) ||
+           (IsSupported(f) &&
             (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
   }
 
+  static bool VerifyCrossCompiling() {
+    return cross_compile_ == 0;
+  }
+
+  static bool VerifyCrossCompiling(CpuFeature f) {
+    unsigned mask = flag2set(f);
+    return cross_compile_ == 0 ||
+           (cross_compile_ & mask) == mask;
+  }
+
  private:
+  static bool Check(CpuFeature f, unsigned set) {
+    return (set & flag2set(f)) != 0;
+  }
+
+  static unsigned flag2set(CpuFeature f) {
+    return 1u << f;
+  }
+
 #ifdef DEBUG
   static bool initialized_;
 #endif
   static unsigned supported_;
   static unsigned found_by_runtime_probing_only_;
 
+  static unsigned cross_compile_;
+
   friend class ExternalReference;
   friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 192bed5..f598894 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -2694,14 +2694,6 @@
 }
 
 
-void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
-  Register object = ToRegister(instr->object());
-  Register result = ToRegister(instr->result());
-  __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset));
-  __ lbu(result, FieldMemOperand(result, Map::kInstanceSizeOffset));
-}
-
-
 void LCodeGen::DoCmpT(LCmpT* instr) {
   ASSERT(ToRegister(instr->context()).is(cp));
   Token::Value op = instr->op();
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index f853eec..363c827 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -1082,12 +1082,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) {
-  LOperand* object = UseRegisterAtStart(instr->object());
-  return DefineAsRegister(new(zone()) LInstanceSize(object));
-}
-
-
 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
   LOperand* receiver = UseRegisterAtStart(instr->receiver());
   LOperand* function = UseRegisterAtStart(instr->function());
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 4af16ee..68f1de9 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -105,7 +105,6 @@
   V(InnerAllocatedObject)                       \
   V(InstanceOf)                                 \
   V(InstanceOfKnownGlobal)                      \
-  V(InstanceSize)                               \
   V(InstructionGap)                             \
   V(Integer32ToDouble)                          \
   V(Integer32ToSmi)                             \
@@ -1143,19 +1142,6 @@
 };
 
 
-class LInstanceSize V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LInstanceSize(LOperand* object) {
-    inputs_[0] = object;
-  }
-
-  LOperand* object() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceSize, "instance-size")
-  DECLARE_HYDROGEN_ACCESSOR(InstanceSize)
-};
-
-
 class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
  public:
   LBoundsCheck(LOperand* index, LOperand* length) {
diff --git a/src/preparser-api.cc b/src/preparser-api.cc
deleted file mode 100644
index 462dfe2..0000000
--- a/src/preparser-api.cc
+++ /dev/null
@@ -1,196 +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.
-
-#ifdef _MSC_VER
-#define V8_WIN32_LEAN_AND_MEAN
-#include "win32-headers.h"
-#endif
-
-#include "../include/v8-preparser.h"
-
-#include "globals.h"
-#include "checks.h"
-#include "allocation.h"
-#include "utils.h"
-#include "list.h"
-#include "hashmap.h"
-#include "preparse-data-format.h"
-#include "preparse-data.h"
-#include "preparser.h"
-
-namespace v8 {
-namespace internal {
-
-// UTF16Buffer based on a v8::UnicodeInputStream.
-class InputStreamUtf16Buffer : public Utf16CharacterStream {
- public:
-  /* The InputStreamUtf16Buffer maintains an internal buffer
-   * that is filled in chunks from the Utf16CharacterStream.
-   * It also maintains unlimited pushback capability, but optimized
-   * for small pushbacks.
-   * The pushback_buffer_ pointer points to the limit of pushbacks
-   * in the current buffer. There is room for a few pushback'ed chars before
-   * the buffer containing the most recently read chunk. If this is overflowed,
-   * an external buffer is allocated/reused to hold further pushbacks, and
-   * pushback_buffer_ and buffer_cursor_/buffer_end_ now points to the
-   * new buffer. When this buffer is read to the end again, the cursor is
-   * switched back to the internal buffer
-   */
-  explicit InputStreamUtf16Buffer(v8::UnicodeInputStream* stream)
-      : Utf16CharacterStream(),
-        stream_(stream),
-        pushback_buffer_(buffer_),
-        pushback_buffer_end_cache_(NULL),
-        pushback_buffer_backing_(NULL),
-        pushback_buffer_backing_size_(0) {
-    buffer_cursor_ = buffer_end_ = buffer_ + kPushBackSize;
-  }
-
-  virtual ~InputStreamUtf16Buffer() {
-    if (pushback_buffer_backing_ != NULL) {
-      DeleteArray(pushback_buffer_backing_);
-    }
-  }
-
-  virtual void PushBack(uc32 ch) {
-    ASSERT(pos_ > 0);
-    if (ch == kEndOfInput) {
-      pos_--;
-      return;
-    }
-    if (buffer_cursor_ <= pushback_buffer_) {
-      // No more room in the current buffer to do pushbacks.
-      if (pushback_buffer_end_cache_ == NULL) {
-        // We have overflowed the pushback space at the beginning of buffer_.
-        // Switch to using a separate allocated pushback buffer.
-        if (pushback_buffer_backing_ == NULL) {
-          // Allocate a buffer the first time we need it.
-          pushback_buffer_backing_ = NewArray<uc16>(kPushBackSize);
-          pushback_buffer_backing_size_ = kPushBackSize;
-        }
-        pushback_buffer_ = pushback_buffer_backing_;
-        pushback_buffer_end_cache_ = buffer_end_;
-        buffer_end_ = pushback_buffer_backing_ + pushback_buffer_backing_size_;
-        buffer_cursor_ = buffer_end_ - 1;
-      } else {
-        // Hit the bottom of the allocated pushback buffer.
-        // Double the buffer and continue.
-        uc16* new_buffer = NewArray<uc16>(pushback_buffer_backing_size_ * 2);
-        OS::MemCopy(new_buffer + pushback_buffer_backing_size_,
-                    pushback_buffer_backing_,
-                    pushback_buffer_backing_size_);
-        DeleteArray(pushback_buffer_backing_);
-        buffer_cursor_ = new_buffer + pushback_buffer_backing_size_;
-        pushback_buffer_backing_ = pushback_buffer_ = new_buffer;
-        buffer_end_ = pushback_buffer_backing_ + pushback_buffer_backing_size_;
-      }
-    }
-    pushback_buffer_[buffer_cursor_ - pushback_buffer_- 1] =
-        static_cast<uc16>(ch);
-    pos_--;
-  }
-
- protected:
-  virtual bool ReadBlock() {
-    if (pushback_buffer_end_cache_ != NULL) {
-      buffer_cursor_ = buffer_;
-      buffer_end_ = pushback_buffer_end_cache_;
-      pushback_buffer_end_cache_ = NULL;
-      return buffer_end_ > buffer_cursor_;
-    }
-    // Copy the top of the buffer into the pushback area.
-    int32_t value;
-    uc16* buffer_start = buffer_ + kPushBackSize;
-    buffer_cursor_ = buffer_end_ = buffer_start;
-    while ((value = stream_->Next()) >= 0) {
-      if (value >
-          static_cast<int32_t>(unibrow::Utf16::kMaxNonSurrogateCharCode)) {
-        buffer_start[buffer_end_++ - buffer_start] =
-            unibrow::Utf16::LeadSurrogate(value);
-        buffer_start[buffer_end_++ - buffer_start] =
-            unibrow::Utf16::TrailSurrogate(value);
-      } else {
-        // buffer_end_ is a const pointer, but buffer_ is writable.
-        buffer_start[buffer_end_++ - buffer_start] = static_cast<uc16>(value);
-      }
-      // Stop one before the end of the buffer in case we get a surrogate pair.
-      if (buffer_end_ <= buffer_ + 1 + kPushBackSize + kBufferSize) break;
-    }
-    return buffer_end_ > buffer_start;
-  }
-
-  virtual unsigned SlowSeekForward(unsigned pos) {
-    // Seeking in the input is not used by preparsing.
-    // It's only used by the real parser based on preparser data.
-    UNIMPLEMENTED();
-    return 0;
-  }
-
- private:
-  static const unsigned kBufferSize = 512;
-  static const unsigned kPushBackSize = 16;
-  v8::UnicodeInputStream* const stream_;
-  // Buffer holding first kPushBackSize characters of pushback buffer,
-  // then kBufferSize chars of read-ahead.
-  // The pushback buffer is only used if pushing back characters past
-  // the start of a block.
-  uc16 buffer_[kPushBackSize + kBufferSize];
-  // Limit of pushbacks before new allocation is necessary.
-  uc16* pushback_buffer_;
-  // Only if that pushback buffer at the start of buffer_ isn't sufficient
-  // is the following used.
-  const uc16* pushback_buffer_end_cache_;
-  uc16* pushback_buffer_backing_;
-  unsigned pushback_buffer_backing_size_;
-};
-
-}  // namespace internal.
-
-
-UnicodeInputStream::~UnicodeInputStream() { }
-
-
-PreParserData Preparse(UnicodeInputStream* input, size_t max_stack) {
-  internal::InputStreamUtf16Buffer buffer(input);
-  uintptr_t stack_limit = reinterpret_cast<uintptr_t>(&buffer) - max_stack;
-  internal::UnicodeCache unicode_cache;
-  internal::Scanner scanner(&unicode_cache);
-  scanner.Initialize(&buffer);
-  internal::CompleteParserRecorder recorder;
-  preparser::PreParser preparser(&scanner, &recorder, stack_limit);
-  preparser.set_allow_lazy(true);
-  preparser::PreParser::PreParseResult result = preparser.PreParseProgram();
-  if (result == preparser::PreParser::kPreParseStackOverflow) {
-    return PreParserData::StackOverflow();
-  }
-  internal::Vector<unsigned> pre_data = recorder.ExtractData();
-  size_t size = pre_data.length() * sizeof(pre_data[0]);
-  unsigned char* data = reinterpret_cast<unsigned char*>(pre_data.start());
-  return PreParserData(size, data);
-}
-
-}  // namespace v8.
diff --git a/src/runtime.cc b/src/runtime.cc
index af3c39e..26dc36d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -801,6 +801,16 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferIsView) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, object, 0);
+  return object->IsJSArrayBufferView()
+    ? isolate->heap()->true_value()
+    : isolate->heap()->false_value();
+}
+
+
 enum TypedArrayId {
   // arrayIds below should be synchromized with typedarray.js natives.
   ARRAY_ID_UINT8 = 1,
@@ -12610,11 +12620,8 @@
     return isolate->Throw(isolate->heap()->illegal_argument_string());
   }
 
-  if (frame_id != StackFrame::NO_ID &&
-      step_action != StepIn &&
-      step_action != StepNext &&
-      step_action != StepOut &&
-      step_action != StepMin) {
+  if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
+      step_action != StepMin && step_action != StepOut) {
     return isolate->ThrowIllegalOperation();
   }
 
diff --git a/src/runtime.h b/src/runtime.h
index 1b68863..5566226 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -362,6 +362,7 @@
   F(ArrayBufferInitialize, 2, 1)\
   F(ArrayBufferGetByteLength, 1, 1)\
   F(ArrayBufferSliceImpl, 3, 1) \
+  F(ArrayBufferIsView, 1, 1) \
   \
   F(TypedArrayInitialize, 5, 1) \
   F(TypedArrayInitializeFromArrayLike, 4, 1) \
diff --git a/src/v8preparserdll-main.cc b/src/v8preparserdll-main.cc
deleted file mode 100644
index c0344d3..0000000
--- a/src/v8preparserdll-main.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <windows.h>
-
-#include "../include/v8-preparser.h"
-
-extern "C" {
-BOOL WINAPI DllMain(HANDLE hinstDLL,
-                    DWORD dwReason,
-                    LPVOID lpvReserved) {
-  // Do nothing.
-  return TRUE;
-}
-}
diff --git a/src/version.cc b/src/version.cc
index 9f7a3db..575f559 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     22
-#define BUILD_NUMBER      8
+#define BUILD_NUMBER      9
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index b6a28fc..aedfa07 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -44,7 +44,7 @@
 #endif
 uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures;
 uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
-
+uint64_t CpuFeatures::cross_compile_ = 0;
 
 ExternalReference ExternalReference::cpu_features() {
   ASSERT(CpuFeatures::initialized_);
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index f4cc4a3..fd1e1e7 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -471,26 +471,45 @@
 
   // Check whether a feature is supported by the target CPU.
   static bool IsSupported(CpuFeature f) {
+    if (Check(f, cross_compile_)) return true;
     ASSERT(initialized_);
     if (f == SSE3 && !FLAG_enable_sse3) return false;
     if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
     if (f == CMOV && !FLAG_enable_cmov) return false;
     if (f == SAHF && !FLAG_enable_sahf) return false;
-    return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
+    return Check(f, supported_);
   }
 
   static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
     ASSERT(initialized_);
-    return (found_by_runtime_probing_only_ &
-            (static_cast<uint64_t>(1) << f)) != 0;
+    return Check(f, found_by_runtime_probing_only_);
   }
 
   static bool IsSafeForSnapshot(CpuFeature f) {
-    return (IsSupported(f) &&
+    return Check(f, cross_compile_) ||
+           (IsSupported(f) &&
             (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
   }
 
+  static bool VerifyCrossCompiling() {
+    return cross_compile_ == 0;
+  }
+
+  static bool VerifyCrossCompiling(CpuFeature f) {
+    uint64_t mask = flag2set(f);
+    return cross_compile_ == 0 ||
+           (cross_compile_ & mask) == mask;
+  }
+
  private:
+  static bool Check(CpuFeature f, uint64_t set) {
+    return (set & flag2set(f)) != 0;
+  }
+
+  static uint64_t flag2set(CpuFeature f) {
+    return static_cast<uint64_t>(1) << f;
+  }
+
   // Safe defaults include CMOV for X64. It is always available, if
   // anyone checks, but they shouldn't need to check.
   // The required user mode extensions in X64 are (from AMD64 ABI Table A.1):
@@ -503,6 +522,8 @@
   static uint64_t supported_;
   static uint64_t found_by_runtime_probing_only_;
 
+  static uint64_t cross_compile_;
+
   friend class ExternalReference;
   friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 495ca74..35fdcbb 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -2539,14 +2539,6 @@
 }
 
 
-void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
-  Register object = ToRegister(instr->object());
-  Register result = ToRegister(instr->result());
-  __ movq(result, FieldOperand(object, HeapObject::kMapOffset));
-  __ movzxbq(result, FieldOperand(result, Map::kInstanceSizeOffset));
-}
-
-
 void LCodeGen::DoCmpT(LCmpT* instr) {
   Token::Value op = instr->op();
 
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 9b9ac04..d5d6436 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1077,12 +1077,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) {
-  LOperand* object = UseRegisterAtStart(instr->object());
-  return DefineAsRegister(new(zone()) LInstanceSize(object));
-}
-
-
 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
   LOperand* receiver = UseRegister(instr->receiver());
   LOperand* function = UseRegisterAtStart(instr->function());
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 36e9bdf..0de9ea5 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -105,7 +105,6 @@
   V(InnerAllocatedObject)                       \
   V(InstanceOf)                                 \
   V(InstanceOfKnownGlobal)                      \
-  V(InstanceSize)                               \
   V(InstructionGap)                             \
   V(Integer32ToDouble)                          \
   V(Integer32ToSmi)                             \
@@ -1078,19 +1077,6 @@
 };
 
 
-class LInstanceSize V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LInstanceSize(LOperand* object) {
-    inputs_[0] = object;
-  }
-
-  LOperand* object() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(InstanceSize, "instance-size")
-  DECLARE_HYDROGEN_ACCESSOR(InstanceSize)
-};
-
-
 class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
  public:
   LBoundsCheck(LOperand* index, LOperand* length) {
diff --git a/test/mjsunit/debug-step-4-in-frame.js b/test/mjsunit/debug-step-4-in-frame.js
index 483883a..65ac490 100644
--- a/test/mjsunit/debug-step-4-in-frame.js
+++ b/test/mjsunit/debug-step-4-in-frame.js
@@ -29,17 +29,12 @@
 // Get the Debug object exposed from the debug context global object.
 Debug = debug.Debug
 
-// Tests how debugger can step into/over not necessarily in the top frame.
+// Tests how debugger can step over not necessarily in the top frame.
 
 // Simple 3 functions, that protocol their execution state in global
 // variable state.
 var state;
 
-function e() {
-  for (state[3] = 0; state[3] < 5; state[3]++) {
-    void ("" + e + state[3]);
-  }
-}
 function f() {
   var a = 1978;
   for (state[2] = 0; state[2] < 5; state[2]++) {
@@ -48,20 +43,18 @@
 }
 function g() {
   for (state[1] = 0; state[1] < 5; state[1]++) {
-    f() + e();
+    f();
   }
 }
 function h() {
-  state = [-1, -1, -1, -1];
+  state = [-1, -1, -1];
   for (state[0] = 0; state[0] < 5; state[0]++) {
     g();
   }
 }
 
-function TestCase(frame_index, step_count, expected_final_state, action) {
-  action = action || Debug.StepAction.StepNext;
-  print("Test case, parameters " + frame_index + "/" + step_count +
-      ", action " + action);
+function TestCase(frame_index, step_count, expected_final_state) {
+  print("Test case, parameters " + frame_index + "/" + step_count);
 
   var listener_exception = null;
   var state_snapshot;
@@ -79,7 +72,8 @@
           if (frame_index !== undefined) {
             context_frame = exec_state.frame(frame_index);
           }
-          exec_state.prepareStep(action, step_count, context_frame);
+          exec_state.prepareStep(Debug.StepAction.StepNext,
+              step_count, context_frame);
           listener_state = 1;
         } else if (listener_state == 1) {
           state_snapshot = String(state);
@@ -109,61 +103,30 @@
   assertEquals(expected_final_state, state_snapshot);
 }
 
-function TestCase2(frame_index, step_count, expected_final_state) {
-  return TestCase(frame_index, step_count, expected_final_state,
-      Debug.StepAction.StepIn);
-}
 
 // Warm-up -- make sure all is compiled and ready for breakpoint.
 h();
 
 
-// Stepping over on the default (top) frame.
-TestCase(undefined, 0, "0,0,-1,-1");
-TestCase(undefined, 1, "0,0,-1,-1");
-TestCase(undefined, 2, "0,0,0,-1");
-TestCase(undefined, 5, "0,0,1,-1");
-TestCase(undefined, 8, "0,0,3,-1");
+// Stepping in the default (top) frame.
+TestCase(undefined, 0, "0,0,-1");
+TestCase(undefined, 1, "0,0,-1");
+TestCase(undefined, 2, "0,0,0");
+TestCase(undefined, 5, "0,0,1");
+TestCase(undefined, 8, "0,0,3");
 
-// Stepping over on the frame #0 (should be exactly the same as above).
-TestCase(0, 0, "0,0,-1,-1");
-TestCase(0, 1, "0,0,-1,-1");
-TestCase(0, 2, "0,0,0,-1");
-TestCase(0, 5, "0,0,1,-1");
-TestCase(0, 8, "0,0,3,-1");
+// Stepping in the frame #0 (should be exactly the same as above).
+TestCase(0, 0, "0,0,-1");
+TestCase(0, 1, "0,0,-1");
+TestCase(0, 2, "0,0,0");
+TestCase(0, 5, "0,0,1");
+TestCase(0, 8, "0,0,3");
 
-// Stepping over on the frame #1.
-TestCase(1, 0, "0,0,5,5");
-TestCase(1, 3, "0,1,5,5");
-TestCase(1, 8, "0,4,5,5");
+// Stepping in the frame #1.
+TestCase(1, 0, "0,0,5");
+TestCase(1, 3, "0,1,5");
+TestCase(1, 8, "0,4,5");
 
-// Stepping over on the frame #2.
-TestCase(2, 3, "1,5,5,5");
-TestCase(2, 8, "4,5,5,5");
-
-// Stepping into on the default (top) frame.
-TestCase2(undefined, 0, "0,0,-1,-1");
-TestCase2(undefined, 1, "0,0,-1,-1");
-TestCase2(undefined, 2, "0,0,0,-1");
-TestCase2(undefined, 5, "0,0,1,-1");
-TestCase2(undefined, 8, "0,0,3,-1");
-
-// Stepping into on the frame #0 (should be exactly the same as above).
-TestCase2(0, 0, "0,0,-1,-1");
-TestCase2(0, 1, "0,0,-1,-1");
-TestCase2(0, 2, "0,0,0,-1");
-TestCase2(0, 5, "0,0,1,-1");
-TestCase2(0, 8, "0,0,3,-1");
-
-// Stepping into on the frame #1.
-TestCase2(1, 0, "0,0,5,-1");
-TestCase2(1, 3, "0,0,5,0");
-TestCase2(1, 8, "0,0,5,2");
-TestCase2(1, 9, "0,0,5,3");
-
-// Stepping into on the frame #2.
-TestCase2(2, 0, "0,5,5,5");
-TestCase2(2, 3, "1,5,5,5");
-TestCase2(2, 4, "1,0,5,5");
-TestCase2(2, 8, "1,0,0,5");
-TestCase2(2, 9, "1,0,1,5");
+// Stepping in the frame #2.
+TestCase(2, 3, "1,5,5");
+TestCase(2, 8, "4,5,5");
diff --git a/test/mjsunit/harmony/typedarrays.js b/test/mjsunit/harmony/typedarrays.js
index c6d130f..e20fbad 100644
--- a/test/mjsunit/harmony/typedarrays.js
+++ b/test/mjsunit/harmony/typedarrays.js
@@ -123,6 +123,7 @@
   var ab = new ArrayBuffer(256*elementSize);
 
   var a0 = new constr(30);
+  assertTrue(ArrayBuffer.isView(a0));
   assertSame(elementSize, a0.BYTES_PER_ELEMENT);
   assertSame(30, a0.length);
   assertSame(30*elementSize, a0.byteLength);
@@ -476,6 +477,7 @@
   var ab = new ArrayBuffer(256);
 
   var d1 = new DataView(ab, 1, 255);
+  assertTrue(ArrayBuffer.isView(d1));
   assertSame(ab, d1.buffer);
   assertSame(1, d1.byteOffset);
   assertSame(255, d1.byteLength);
diff --git a/test/preparser/preparser.status b/test/preparser/preparser.status
index e66251b..37512bd 100644
--- a/test/preparser/preparser.status
+++ b/test/preparser/preparser.status
@@ -27,6 +27,15 @@
 
 [
 [ALWAYS, {
+  # TODO(mstarzinger): Uhm, this is kind of embarrassing, but our parser
+  # does not catch some syntax errors with duplicate properties in object
+  # literals that our preparser actually caught. I will fix this glitch in a
+  # follow-up change.
+  'duplicate-property/*': [SKIP],
+
+  # TODO(mstarzinger): This script parses but throws a TypeError when run.
+  'non-alphanum': [FAIL],
+
   # We don't parse RegExps at scanning time, so we can't fail on octal
   # escapes (we need to parse to distinguish octal escapes from valid
   # back-references).
diff --git a/test/preparser/strict-identifiers.pyt b/test/preparser/strict-identifiers.pyt
index f979088..446980f 100644
--- a/test/preparser/strict-identifiers.pyt
+++ b/test/preparser/strict-identifiers.pyt
@@ -147,25 +147,25 @@
 """)
 
 break_normal = Template("break-normal-$id", """
-  for (;;) {
+  $id: for (;false;) {
     break $id;
   }
 """)
 
 break_strict = StrictTemplate("break-strict-$id", """
-  for (;;) {
+  $id: for (;false;) {
     break $id;
   }
 """)
 
 continue_normal = Template("continue-normal-$id", """
-  for (;;) {
+  $id: for (;false;) {
     continue $id;
   }
 """)
 
 continue_strict = StrictTemplate("continue-strict-$id", """
-  for (;;) {
+  $id: for (;false;) {
     continue $id;
   }
 """)
diff --git a/test/preparser/testcfg.py b/test/preparser/testcfg.py
index 566fd5c..3e999f9 100644
--- a/test/preparser/testcfg.py
+++ b/test/preparser/testcfg.py
@@ -39,7 +39,7 @@
     super(PreparserTestSuite, self).__init__(name, root)
 
   def shell(self):
-    return "preparser"
+    return "d8"
 
   def _GetExpectations(self):
     expects_file = os.path.join(self.root, "preparser.expectation")
@@ -64,7 +64,7 @@
       testname = os.path.join(filename, name)
       flags = ["-e", source]
       if expectation:
-        flags += ["throws", expectation]
+        flags += ["--throws"]
       test = testcase.TestCase(self, testname, flags=flags)
       result.append(test)
     def Template(name, source):
@@ -89,7 +89,7 @@
       throws = expectations.get(f, None)
       flags = [f + ".js"]
       if throws:
-        flags += ["throws", throws]
+        flags += ["--throws"]
       test = testcase.TestCase(self, f, flags=flags)
       result.append(test)
 
diff --git a/tools/android-sync.sh b/tools/android-sync.sh
index f172754..460e92d 100755
--- a/tools/android-sync.sh
+++ b/tools/android-sync.sh
@@ -88,7 +88,6 @@
 echo -n "sync to $ANDROID_V8/$OUTDIR/$ARCH_MODE"
 sync_file "$OUTDIR/$ARCH_MODE/cctest"
 sync_file "$OUTDIR/$ARCH_MODE/d8"
-sync_file "$OUTDIR/$ARCH_MODE/preparser"
 echo ""
 echo -n "sync to $ANDROID_V8/tools"
 sync_file tools/consarray.js
diff --git a/tools/presubmit.py b/tools/presubmit.py
index 12475b3..780dab9 100755
--- a/tools/presubmit.py
+++ b/tools/presubmit.py
@@ -226,7 +226,7 @@
               or (name in CppLintProcessor.IGNORE_LINT))
 
   def GetPathsToSearch(self):
-    return ['src', 'preparser', 'include', 'samples', join('test', 'cctest')]
+    return ['src', 'include', 'samples', join('test', 'cctest')]
 
   def GetCpplintScript(self, prio_path):
     for path in [prio_path] + os.environ["PATH"].split(os.pathsep):