Version 3.19.10

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@14980 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 25d11b1..bdfc73f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-06: Version 3.19.10
+
+        Performance and stability improvements on all platforms.
+
+
 2013-06-05: Version 3.19.9
 
         Implemented Load IC support for loading properties from primitive
diff --git a/include/v8.h b/include/v8.h
index 28a63f0..7a38c1e 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1524,11 +1524,19 @@
   V8_DEPRECATED(V8_INLINE(bool MayContainNonAscii()) const) { return true; }
 
   /**
-   * Returns whether this string contains only one byte data.
+   * Returns whether this string is known to contain only one byte data.
+   * Does not read the string.
+   * False negatives are possible.
    */
   bool IsOneByte() const;
 
   /**
+   * Returns whether this string contain only one byte data.
+   * Will read the entire string in some cases.
+   */
+  bool ContainsOnlyOneByte() const;
+
+  /**
    * Write the contents of the string to an external buffer.
    * If no arguments are given, expects the buffer to be large
    * enough to hold the entire string and NULL terminator. Copies
@@ -2811,7 +2819,10 @@
 template<typename T>
 class ReturnValue {
  public:
-  V8_INLINE(explicit ReturnValue(internal::Object** slot));
+  template <class S> V8_INLINE(ReturnValue(const ReturnValue<S>& that))
+      : value_(that.value_) {
+    TYPE_CHECK(T, S);
+  }
   // Handle setters
   template <typename S> V8_INLINE(void Set(const Persistent<S>& handle));
   template <typename S> V8_INLINE(void Set(const Handle<S> handle));
@@ -2825,7 +2836,12 @@
   V8_INLINE(void SetUndefined());
   // Convenience getter for Isolate
   V8_INLINE(Isolate* GetIsolate());
+
  private:
+  template<class F> friend class ReturnValue;
+  template<class F> friend class FunctionCallbackInfo;
+  template<class F> friend class PropertyCallbackInfo;
+  V8_INLINE(explicit ReturnValue(internal::Object** slot));
   internal::Object** value_;
 };
 
diff --git a/src/api.cc b/src/api.cc
index b2dc2e1..4cdd77e 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -4304,6 +4304,85 @@
 }
 
 
+class ContainsOnlyOneByteHelper {
+ public:
+  ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
+  bool Check(i::String* string) {
+    i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
+    if (cons_string == NULL) return is_one_byte_;
+    return CheckCons(cons_string);
+  }
+  void VisitOneByteString(const uint8_t* chars, int length) {
+    // Nothing to do.
+  }
+  // TODO(dcarney): do word aligned read.
+  void VisitTwoByteString(const uint16_t* chars, int length) {
+    // Check whole string without breaking.
+    uint16_t total = 0;
+    for (int i = 0; i < length; i++) {
+      total |= chars[i] >> 8;
+    }
+    if (total != 0) is_one_byte_ = false;
+  }
+
+ private:
+  bool CheckCons(i::ConsString* cons_string) {
+    while (true) {
+      // Check left side if flat.
+      i::String* left = cons_string->first();
+      i::ConsString* left_as_cons =
+          i::String::VisitFlat(this, left, 0);
+      if (!is_one_byte_) return false;
+      // Check right side if flat.
+      i::String* right = cons_string->second();
+      i::ConsString* right_as_cons =
+          i::String::VisitFlat(this, right, 0);
+      if (!is_one_byte_) return false;
+      // Standard recurse/iterate trick.
+      if (left_as_cons != NULL && right_as_cons != NULL) {
+        if (left->length() < right->length()) {
+          CheckCons(left_as_cons);
+          cons_string = right_as_cons;
+        } else {
+          CheckCons(right_as_cons);
+          cons_string = left_as_cons;
+        }
+        // Check fast return.
+        if (!is_one_byte_) return false;
+        continue;
+      }
+      // Descend left in place.
+      if (left_as_cons != NULL) {
+        cons_string = left_as_cons;
+        continue;
+      }
+      // Descend right in place.
+      if (right_as_cons != NULL) {
+        cons_string = right_as_cons;
+        continue;
+      }
+      // Terminate.
+      break;
+    }
+    return is_one_byte_;
+  }
+  bool is_one_byte_;
+  DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
+};
+
+
+bool String::ContainsOnlyOneByte() const {
+  i::Handle<i::String> str = Utils::OpenHandle(this);
+  if (IsDeadCheck(str->GetIsolate(),
+                  "v8::String::ContainsOnlyOneByte()")) {
+    return false;
+  }
+  if (str->HasOnlyOneByteChars()) return true;
+  ContainsOnlyOneByteHelper helper;
+  return helper.Check(*str);
+}
+
+
 class Utf8LengthHelper : public i::AllStatic {
  public:
   enum State {
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 2fd7170..3fbe0c5 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -30,7 +30,6 @@
 #if defined(V8_TARGET_ARCH_ARM)
 
 #include "bootstrapper.h"
-#include "builtins-decls.h"
 #include "code-stubs.h"
 #include "regexp-macro-assembler.h"
 #include "stub-cache.h"
@@ -146,7 +145,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(ArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
 }
 
 
@@ -168,7 +167,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
 }
 
 
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index 4241502..4d415ef 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -235,54 +235,6 @@
 }
 
 
-void RegExpMacroAssemblerARM::CheckCharacters(Vector<const uc16> str,
-                                              int cp_offset,
-                                              Label* on_failure,
-                                              bool check_end_of_string) {
-  if (on_failure == NULL) {
-    // Instead of inlining a backtrack for each test, (re)use the global
-    // backtrack target.
-    on_failure = &backtrack_label_;
-  }
-
-  if (check_end_of_string) {
-    // Is last character of required match inside string.
-    CheckPosition(cp_offset + str.length() - 1, on_failure);
-  }
-
-  __ add(r0, end_of_input_address(), Operand(current_input_offset()));
-  if (cp_offset != 0) {
-    int byte_offset = cp_offset * char_size();
-    __ add(r0, r0, Operand(byte_offset));
-  }
-
-  // r0 : Address of characters to match against str.
-  int stored_high_byte = 0;
-  for (int i = 0; i < str.length(); i++) {
-    if (mode_ == ASCII) {
-      __ ldrb(r1, MemOperand(r0, char_size(), PostIndex));
-      ASSERT(str[i] <= String::kMaxOneByteCharCode);
-      __ cmp(r1, Operand(str[i]));
-    } else {
-      __ ldrh(r1, MemOperand(r0, char_size(), PostIndex));
-      uc16 match_char = str[i];
-      int match_high_byte = (match_char >> 8);
-      if (match_high_byte == 0) {
-        __ cmp(r1, Operand(str[i]));
-      } else {
-        if (match_high_byte != stored_high_byte) {
-          __ mov(r2, Operand(match_high_byte));
-          stored_high_byte = match_high_byte;
-        }
-        __ add(r3, r2, Operand(match_char & 0xff));
-        __ cmp(r1, r3);
-      }
-    }
-    BranchOrBacktrack(ne, on_failure);
-  }
-}
-
-
 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) {
   __ ldr(r0, MemOperand(backtrack_stackpointer(), 0));
   __ cmp(current_input_offset(), r0);
@@ -556,7 +508,7 @@
   case 'd':
     // Match ASCII digits ('0'..'9')
     __ sub(r0, current_character(), Operand('0'));
-    __ cmp(current_character(), Operand('9' - '0'));
+    __ cmp(r0, Operand('9' - '0'));
     BranchOrBacktrack(hi, on_no_match);
     return true;
   case 'D':
diff --git a/src/arm/regexp-macro-assembler-arm.h b/src/arm/regexp-macro-assembler-arm.h
index 921d8f5..1825752 100644
--- a/src/arm/regexp-macro-assembler-arm.h
+++ b/src/arm/regexp-macro-assembler-arm.h
@@ -53,10 +53,6 @@
                                       Label* on_equal);
   virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
   virtual void CheckCharacterLT(uc16 limit, Label* on_less);
-  virtual void CheckCharacters(Vector<const uc16> str,
-                               int cp_offset,
-                               Label* on_failure,
-                               bool check_end_of_string);
   // A "greedy loop" is a loop that is both greedy and with a simple
   // body. It has a particularly simple implementation.
   virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
diff --git a/src/ast.cc b/src/ast.cc
index 8c0351c..b4c0430 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -792,12 +792,12 @@
 
 
 bool RegExpAssertion::IsAnchoredAtStart() {
-  return type() == RegExpAssertion::START_OF_INPUT;
+  return assertion_type() == RegExpAssertion::START_OF_INPUT;
 }
 
 
 bool RegExpAssertion::IsAnchoredAtEnd() {
-  return type() == RegExpAssertion::END_OF_INPUT;
+  return assertion_type() == RegExpAssertion::END_OF_INPUT;
 }
 
 
@@ -929,7 +929,7 @@
 
 
 void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
-  switch (that->type()) {
+  switch (that->assertion_type()) {
     case RegExpAssertion::START_OF_INPUT:
       stream()->Add("@^i");
       break;
diff --git a/src/ast.h b/src/ast.h
index 41c910a..2ffa473b 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -39,7 +39,8 @@
 #include "small-pointer-list.h"
 #include "smart-pointers.h"
 #include "token.h"
-#include "type-info.h"
+#include "type-info.h"  // TODO(rossberg): this should eventually be removed
+#include "types.h"
 #include "utils.h"
 #include "variables.h"
 #include "interface.h"
@@ -163,9 +164,9 @@
 typedef ZoneList<Handle<Object> > ZoneObjectList;
 
 
-#define DECLARE_NODE_TYPE(type)                                         \
-  virtual void Accept(AstVisitor* v);                                   \
-  virtual AstNode::Type node_type() const { return AstNode::k##type; }  \
+#define DECLARE_NODE_TYPE(type)                                             \
+  virtual void Accept(AstVisitor* v);                                       \
+  virtual AstNode::NodeType node_type() const { return AstNode::k##type; }  \
   template<class> friend class AstNodeFactory;
 
 
@@ -197,7 +198,7 @@
 class AstNode: public ZoneObject {
  public:
 #define DECLARE_TYPE_ENUM(type) k##type,
-  enum Type {
+  enum NodeType {
     AST_NODE_LIST(DECLARE_TYPE_ENUM)
     kInvalid = -1
   };
@@ -212,7 +213,7 @@
   virtual ~AstNode() { }
 
   virtual void Accept(AstVisitor* v) = 0;
-  virtual Type node_type() const = 0;
+  virtual NodeType node_type() const = 0;
 
   // Type testing & conversion functions overridden by concrete subclasses.
 #define DECLARE_NODE_FUNCTIONS(type)                  \
@@ -354,6 +355,9 @@
   // True iff the expression is the undefined literal.
   bool IsUndefinedLiteral();
 
+  // Expression type
+  Handle<Type> type() { return type_; }
+
   // Type feedback information for assignments and properties.
   virtual bool IsMonomorphic() {
     UNREACHABLE();
@@ -383,10 +387,12 @@
 
  protected:
   explicit Expression(Isolate* isolate)
-      : id_(GetNextId(isolate)),
+      : type_(Type::Any(), isolate),
+        id_(GetNextId(isolate)),
         test_id_(GetNextId(isolate)) {}
 
  private:
+  Handle<Type> type_;
   byte to_boolean_types_;
 
   const BailoutId id_;
@@ -396,7 +402,7 @@
 
 class BreakableStatement: public Statement {
  public:
-  enum Type {
+  enum BreakableType {
     TARGET_FOR_ANONYMOUS,
     TARGET_FOR_NAMED_ONLY
   };
@@ -412,15 +418,18 @@
   Label* break_target() { return &break_target_; }
 
   // Testers.
-  bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
+  bool is_target_for_anonymous() const {
+    return breakable_type_ == TARGET_FOR_ANONYMOUS;
+  }
 
   BailoutId EntryId() const { return entry_id_; }
   BailoutId ExitId() const { return exit_id_; }
 
  protected:
-  BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
+  BreakableStatement(
+      Isolate* isolate, ZoneStringList* labels, BreakableType breakable_type)
       : labels_(labels),
-        type_(type),
+        breakable_type_(breakable_type),
         entry_id_(GetNextId(isolate)),
         exit_id_(GetNextId(isolate)) {
     ASSERT(labels == NULL || labels->length() > 0);
@@ -429,7 +438,7 @@
 
  private:
   ZoneStringList* labels_;
-  Type type_;
+  BreakableType breakable_type_;
   Label break_target_;
   const BailoutId entry_id_;
   const BailoutId exit_id_;
@@ -1123,7 +1132,7 @@
 
   // Virtual behaviour. TargetCollectors are never part of the AST.
   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
-  virtual Type node_type() const { return kInvalid; }
+  virtual NodeType node_type() const { return kInvalid; }
   virtual TargetCollector* AsTargetCollector() { return this; }
 
   ZoneList<Label*>* targets() { return &targets_; }
@@ -2117,7 +2126,7 @@
 
 class FunctionLiteral: public Expression {
  public:
-  enum Type {
+  enum FunctionType {
     ANONYMOUS_EXPRESSION,
     NAMED_EXPRESSION,
     DECLARATION
@@ -2216,7 +2225,7 @@
                   int expected_property_count,
                   int handler_count,
                   int parameter_count,
-                  Type type,
+                  FunctionType function_type,
                   ParameterFlag has_duplicate_parameters,
                   IsFunctionFlag is_function,
                   IsParenthesizedFlag is_parenthesized,
@@ -2232,8 +2241,8 @@
         parameter_count_(parameter_count),
         function_token_position_(RelocInfo::kNoPosition) {
     bitfield_ =
-        IsExpression::encode(type != DECLARATION) |
-        IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
+        IsExpression::encode(function_type != DECLARATION) |
+        IsAnonymous::encode(function_type == ANONYMOUS_EXPRESSION) |
         Pretenure::encode(false) |
         HasDuplicateParameters::encode(has_duplicate_parameters) |
         IsFunction::encode(is_function) |
@@ -2379,7 +2388,7 @@
 
 class RegExpAssertion: public RegExpTree {
  public:
-  enum Type {
+  enum AssertionType {
     START_OF_LINE,
     START_OF_INPUT,
     END_OF_LINE,
@@ -2387,7 +2396,7 @@
     BOUNDARY,
     NON_BOUNDARY
   };
-  explicit RegExpAssertion(Type type) : type_(type) { }
+  explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { }
   virtual void* Accept(RegExpVisitor* visitor, void* data);
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success);
@@ -2397,9 +2406,9 @@
   virtual bool IsAnchoredAtEnd();
   virtual int min_match() { return 0; }
   virtual int max_match() { return 0; }
-  Type type() { return type_; }
+  AssertionType assertion_type() { return assertion_type_; }
  private:
-  Type type_;
+  AssertionType assertion_type_;
 };
 
 
@@ -2512,13 +2521,13 @@
 
 class RegExpQuantifier: public RegExpTree {
  public:
-  enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
-  RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
+  enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE };
+  RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body)
       : body_(body),
         min_(min),
         max_(max),
         min_match_(min * body->min_match()),
-        type_(type) {
+        quantifier_type_(type) {
     if (max > 0 && body->max_match() > kInfinity / max) {
       max_match_ = kInfinity;
     } else {
@@ -2542,9 +2551,9 @@
   virtual int max_match() { return max_match_; }
   int min() { return min_; }
   int max() { return max_; }
-  bool is_possessive() { return type_ == POSSESSIVE; }
-  bool is_non_greedy() { return type_ == NON_GREEDY; }
-  bool is_greedy() { return type_ == GREEDY; }
+  bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
+  bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; }
+  bool is_greedy() { return quantifier_type_ == GREEDY; }
   RegExpTree* body() { return body_; }
 
  private:
@@ -2553,7 +2562,7 @@
   int max_;
   int min_match_;
   int max_match_;
-  Type type_;
+  QuantifierType quantifier_type_;
 };
 
 
@@ -3086,14 +3095,14 @@
       int handler_count,
       int parameter_count,
       FunctionLiteral::ParameterFlag has_duplicate_parameters,
-      FunctionLiteral::Type type,
+      FunctionLiteral::FunctionType function_type,
       FunctionLiteral::IsFunctionFlag is_function,
       FunctionLiteral::IsParenthesizedFlag is_parenthesized,
       FunctionLiteral::IsGeneratorFlag is_generator) {
     FunctionLiteral* lit = new(zone_) FunctionLiteral(
         isolate_, name, scope, body,
         materialized_literal_count, expected_property_count, handler_count,
-        parameter_count, type, has_duplicate_parameters, is_function,
+        parameter_count, function_type, has_duplicate_parameters, is_function,
         is_parenthesized, is_generator);
     // Top-level literal doesn't count for the AST's properties.
     if (is_function == FunctionLiteral::kIsFunction) {
diff --git a/src/builtins-decls.h b/src/builtins-decls.h
deleted file mode 100644
index 8c038dc..0000000
--- a/src/builtins-decls.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef V8_BUILTINS_DECLS_H_
-#define V8_BUILTINS_DECLS_H_
-
-#include "arguments.h"
-
-namespace v8 {
-namespace internal {
-
-// TODO(mvstanton): move these to runtime.h/.cc
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, InternalArrayConstructor_StubFailure);
-
-} }  // namespace v8::internal
-
-#endif  // V8_BUILTINS_DECLS_H_
diff --git a/src/builtins.cc b/src/builtins.cc
index b42fd5a..d97a477 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -194,93 +194,6 @@
 }
 
 
-static MaybeObject* ArrayConstructorStubFailureCommon(
-    Isolate* isolate,
-    Handle<JSFunction> constructor,
-    Handle<Object> type_info,
-    Arguments* caller_args) {
-  bool holey = false;
-  if (caller_args->length() == 1 && (*caller_args)[0]->IsSmi()) {
-    int value = Smi::cast((*caller_args)[0])->value();
-    holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray);
-  }
-
-  JSArray* array;
-  MaybeObject* maybe_array;
-  if (!type_info.is_null() &&
-      *type_info != isolate->heap()->undefined_value() &&
-      JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi()) {
-    JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
-    Smi* smi = Smi::cast(cell->value());
-    ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
-    if (holey && !IsFastHoleyElementsKind(to_kind)) {
-      to_kind = GetHoleyElementsKind(to_kind);
-      // Update the allocation site info to reflect the advice alteration.
-      cell->set_value(Smi::FromInt(to_kind));
-    }
-
-    maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite(
-        *constructor, type_info);
-    if (!maybe_array->To(&array)) return maybe_array;
-  } else {
-    maybe_array = isolate->heap()->AllocateJSObject(*constructor);
-    if (!maybe_array->To(&array)) return maybe_array;
-    // We might need to transition to holey
-    ElementsKind kind = constructor->initial_map()->elements_kind();
-    if (holey && !IsFastHoleyElementsKind(kind)) {
-      kind = GetHoleyElementsKind(kind);
-      maybe_array = array->TransitionElementsKind(kind);
-      if (maybe_array->IsFailure()) return maybe_array;
-    }
-  }
-
-  maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0,
-      DONT_INITIALIZE_ARRAY_ELEMENTS);
-  if (maybe_array->IsFailure()) return maybe_array;
-  maybe_array = ArrayConstructInitializeElements(array, caller_args);
-  if (maybe_array->IsFailure()) return maybe_array;
-  return array;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure) {
-  // If we get 2 arguments then they are the stub parameters (constructor, type
-  // info).  If we get 3, then the first one is a pointer to the arguments
-  // passed by the caller.
-  Arguments empty_args(0, NULL);
-  bool no_caller_args = args.length() == 2;
-  ASSERT(no_caller_args || args.length() == 3);
-  int parameters_start = no_caller_args ? 0 : 1;
-  Arguments* caller_args = no_caller_args
-      ? &empty_args
-      : reinterpret_cast<Arguments*>(args[0]);
-  Handle<JSFunction> constructor = args.at<JSFunction>(parameters_start);
-  Handle<Object> type_info = args.at<Object>(parameters_start + 1);
-
-  return ArrayConstructorStubFailureCommon(isolate,
-                                           constructor,
-                                           type_info,
-                                           caller_args);
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, InternalArrayConstructor_StubFailure) {
-  Arguments empty_args(0, NULL);
-  bool no_caller_args = args.length() == 1;
-  ASSERT(no_caller_args || args.length() == 2);
-  int parameters_start = no_caller_args ? 0 : 1;
-  Arguments* caller_args = no_caller_args
-      ? &empty_args
-      : reinterpret_cast<Arguments*>(args[0]);
-  Handle<JSFunction> constructor = args.at<JSFunction>(parameters_start);
-
-  return ArrayConstructorStubFailureCommon(isolate,
-                                           constructor,
-                                           Handle<Object>::null(),
-                                           caller_args);
-}
-
-
 static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
                                            Isolate* isolate,
                                            JSFunction* constructor) {
diff --git a/src/factory.cc b/src/factory.cc
index ab42b19..f963334 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -676,9 +676,9 @@
 }
 
 
-Handle<Object> Factory::NewTypeError(const char* type,
+Handle<Object> Factory::NewTypeError(const char* message,
                                      Vector< Handle<Object> > args) {
-  return NewError("MakeTypeError", type, args);
+  return NewError("MakeTypeError", message, args);
 }
 
 
@@ -687,9 +687,9 @@
 }
 
 
-Handle<Object> Factory::NewRangeError(const char* type,
+Handle<Object> Factory::NewRangeError(const char* message,
                                       Vector< Handle<Object> > args) {
-  return NewError("MakeRangeError", type, args);
+  return NewError("MakeRangeError", message, args);
 }
 
 
@@ -698,8 +698,9 @@
 }
 
 
-Handle<Object> Factory::NewSyntaxError(const char* type, Handle<JSArray> args) {
-  return NewError("MakeSyntaxError", type, args);
+Handle<Object> Factory::NewSyntaxError(const char* message,
+                                       Handle<JSArray> args) {
+  return NewError("MakeSyntaxError", message, args);
 }
 
 
@@ -708,9 +709,9 @@
 }
 
 
-Handle<Object> Factory::NewReferenceError(const char* type,
+Handle<Object> Factory::NewReferenceError(const char* message,
                                           Vector< Handle<Object> > args) {
-  return NewError("MakeReferenceError", type, args);
+  return NewError("MakeReferenceError", message, args);
 }
 
 
@@ -720,7 +721,7 @@
 
 
 Handle<Object> Factory::NewError(const char* maker,
-                                 const char* type,
+                                 const char* message,
                                  Vector< Handle<Object> > args) {
   // Instantiate a closeable HandleScope for EscapeFrom.
   v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate()));
@@ -729,24 +730,24 @@
     array->set(i, *args[i]);
   }
   Handle<JSArray> object = NewJSArrayWithElements(array);
-  Handle<Object> result = NewError(maker, type, object);
+  Handle<Object> result = NewError(maker, message, object);
   return result.EscapeFrom(&scope);
 }
 
 
-Handle<Object> Factory::NewEvalError(const char* type,
+Handle<Object> Factory::NewEvalError(const char* message,
                                      Vector< Handle<Object> > args) {
-  return NewError("MakeEvalError", type, args);
+  return NewError("MakeEvalError", message, args);
 }
 
 
-Handle<Object> Factory::NewError(const char* type,
+Handle<Object> Factory::NewError(const char* message,
                                  Vector< Handle<Object> > args) {
-  return NewError("MakeError", type, args);
+  return NewError("MakeError", message, args);
 }
 
 
-Handle<String> Factory::EmergencyNewError(const char* type,
+Handle<String> Factory::EmergencyNewError(const char* message,
                                           Handle<JSArray> args) {
   const int kBufferSize = 1000;
   char buffer[kBufferSize];
@@ -754,8 +755,8 @@
   char* p = &buffer[0];
 
   Vector<char> v(buffer, kBufferSize);
-  OS::StrNCpy(v, type, space);
-  space -= Min(space, strlen(type));
+  OS::StrNCpy(v, message, space);
+  space -= Min(space, strlen(message));
   p = &buffer[kBufferSize] - space;
 
   for (unsigned i = 0; i < ARRAY_SIZE(args); i++) {
@@ -784,7 +785,7 @@
 
 
 Handle<Object> Factory::NewError(const char* maker,
-                                 const char* type,
+                                 const char* message,
                                  Handle<JSArray> args) {
   Handle<String> make_str = InternalizeUtf8String(maker);
   Handle<Object> fun_obj(
@@ -793,11 +794,11 @@
   // If the builtins haven't been properly configured yet this error
   // constructor may not have been defined.  Bail out.
   if (!fun_obj->IsJSFunction()) {
-    return EmergencyNewError(type, args);
+    return EmergencyNewError(message, args);
   }
   Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
-  Handle<Object> type_obj = InternalizeUtf8String(type);
-  Handle<Object> argv[] = { type_obj, args };
+  Handle<Object> message_obj = InternalizeUtf8String(message);
+  Handle<Object> argv[] = { message_obj, args };
 
   // Invoke the JavaScript factory method. If an exception is thrown while
   // running the factory method, use the exception as the result.
diff --git a/src/factory.h b/src/factory.h
index 233b3b0..66304a9 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -369,33 +369,33 @@
 
   // Interface for creating error objects.
 
-  Handle<Object> NewError(const char* maker, const char* type,
+  Handle<Object> NewError(const char* maker, const char* message,
                           Handle<JSArray> args);
-  Handle<String> EmergencyNewError(const char* type, Handle<JSArray> args);
-  Handle<Object> NewError(const char* maker, const char* type,
+  Handle<String> EmergencyNewError(const char* message, Handle<JSArray> args);
+  Handle<Object> NewError(const char* maker, const char* message,
                           Vector< Handle<Object> > args);
-  Handle<Object> NewError(const char* type,
+  Handle<Object> NewError(const char* message,
                           Vector< Handle<Object> > args);
   Handle<Object> NewError(Handle<String> message);
   Handle<Object> NewError(const char* constructor,
                           Handle<String> message);
 
-  Handle<Object> NewTypeError(const char* type,
+  Handle<Object> NewTypeError(const char* message,
                               Vector< Handle<Object> > args);
   Handle<Object> NewTypeError(Handle<String> message);
 
-  Handle<Object> NewRangeError(const char* type,
+  Handle<Object> NewRangeError(const char* message,
                                Vector< Handle<Object> > args);
   Handle<Object> NewRangeError(Handle<String> message);
 
-  Handle<Object> NewSyntaxError(const char* type, Handle<JSArray> args);
+  Handle<Object> NewSyntaxError(const char* message, Handle<JSArray> args);
   Handle<Object> NewSyntaxError(Handle<String> message);
 
-  Handle<Object> NewReferenceError(const char* type,
+  Handle<Object> NewReferenceError(const char* message,
                                    Vector< Handle<Object> > args);
   Handle<Object> NewReferenceError(Handle<String> message);
 
-  Handle<Object> NewEvalError(const char* type,
+  Handle<Object> NewEvalError(const char* message,
                               Vector< Handle<Object> > args);
 
 
diff --git a/src/handles-inl.h b/src/handles-inl.h
index 9d38f38..4f4490b 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -57,7 +57,8 @@
   if (location_ == other.location_) return true;
   if (location_ == NULL || other.location_ == NULL) return false;
   // Dereferencing deferred handles to check object equality is safe.
-  SLOW_ASSERT(IsDereferenceAllowed(true) && other.IsDereferenceAllowed(true));
+  SLOW_ASSERT(IsDereferenceAllowed(NO_DEFERRED_CHECK) &&
+              other.IsDereferenceAllowed(NO_DEFERRED_CHECK));
   return *location_ == *other.location_;
 }
 
@@ -65,20 +66,21 @@
 template <typename T>
 inline T* Handle<T>::operator*() const {
   ASSERT(location_ != NULL && !(*location_)->IsFailure());
-  SLOW_ASSERT(IsDereferenceAllowed(false));
+  SLOW_ASSERT(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
   return *BitCast<T**>(location_);
 }
 
 template <typename T>
 inline T** Handle<T>::location() const {
   ASSERT(location_ == NULL || !(*location_)->IsFailure());
-  SLOW_ASSERT(location_ == NULL || IsDereferenceAllowed(false));
+  SLOW_ASSERT(location_ == NULL ||
+              IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
   return location_;
 }
 
 #ifdef DEBUG
 template <typename T>
-bool Handle<T>::IsDereferenceAllowed(bool explicitly_allow_deferred) const {
+bool Handle<T>::IsDereferenceAllowed(DereferenceCheckMode mode) const {
   ASSERT(location_ != NULL);
   Object* object = *BitCast<T**>(location_);
   if (object->IsSmi()) return true;
@@ -91,7 +93,7 @@
     return true;
   }
   if (!AllowHandleDereference::IsAllowed()) return false;
-  if (!explicitly_allow_deferred &&
+  if (mode == INCLUDE_DEFERRED_CHECK &&
       !AllowDeferredHandleDereference::IsAllowed()) {
     // Accessing maps and internalized strings is safe.
     if (heap_object->IsMap()) return true;
diff --git a/src/handles.h b/src/handles.h
index 573298a..0cd4f5b 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -61,7 +61,7 @@
     location_ = reinterpret_cast<T**>(handle.location_);
   }
 
-  INLINE(T* operator ->() const) { return operator*(); }
+  INLINE(T* operator->() const) { return operator*(); }
 
   // Check if this handle refers to the exact same object as the other handle.
   INLINE(bool is_identical_to(const Handle<T> other) const);
@@ -85,7 +85,9 @@
   inline Handle<T> EscapeFrom(v8::HandleScope* scope);
 
 #ifdef DEBUG
-  bool IsDereferenceAllowed(bool explicitly_allow_deferred) const;
+  enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK };
+
+  bool IsDereferenceAllowed(DereferenceCheckMode mode) const;
 #endif  // DEBUG
 
  private:
diff --git a/src/heap.cc b/src/heap.cc
index 5e88aca..6a89efd 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -151,6 +151,7 @@
       last_idle_notification_gc_count_(0),
       last_idle_notification_gc_count_init_(false),
       mark_sweeps_since_idle_round_started_(0),
+      ms_count_at_last_idle_notification_(0),
       gc_count_at_last_idle_gc_(0),
       scavenges_since_last_idle_round_(kIdleScavengeThreshold),
       gcs_since_last_deopt_(0),
@@ -5707,7 +5708,6 @@
       uncommit = true;
     }
     CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
-    mark_sweeps_since_idle_round_started_++;
     gc_count_at_last_idle_gc_ = gc_count_;
     if (uncommit) {
       new_space_.Shrink();
@@ -5783,9 +5783,18 @@
     }
   }
 
+  int new_mark_sweeps = ms_count_ - ms_count_at_last_idle_notification_;
+  mark_sweeps_since_idle_round_started_ += new_mark_sweeps;
+  ms_count_at_last_idle_notification_ = ms_count_;
+
   int remaining_mark_sweeps = kMaxMarkSweepsInIdleRound -
                               mark_sweeps_since_idle_round_started_;
 
+  if (remaining_mark_sweeps <= 0) {
+    FinishIdleRound();
+    return true;
+  }
+
   if (incremental_marking()->IsStopped()) {
     // If there are no more than two GCs left in this idle round and we are
     // allowed to do a full GC, then make those GCs full in order to compact
@@ -5795,7 +5804,6 @@
     if (remaining_mark_sweeps <= 2 && hint >= kMinHintForFullGC) {
       CollectAllGarbage(kReduceMemoryFootprintMask,
                         "idle notification: finalize idle round");
-      mark_sweeps_since_idle_round_started_++;
     } else {
       incremental_marking()->Start();
     }
@@ -5803,12 +5811,6 @@
   if (!incremental_marking()->IsStopped()) {
     AdvanceIdleIncrementalMarking(step_size);
   }
-
-  if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
-    FinishIdleRound();
-    return true;
-  }
-
   return false;
 }
 
diff --git a/src/heap.h b/src/heap.h
index 394a02a..6d04454 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -2261,6 +2261,7 @@
 
   void StartIdleRound() {
     mark_sweeps_since_idle_round_started_ = 0;
+    ms_count_at_last_idle_notification_ = ms_count_;
   }
 
   void FinishIdleRound() {
@@ -2337,6 +2338,7 @@
   bool last_idle_notification_gc_count_init_;
 
   int mark_sweeps_since_idle_round_started_;
+  int ms_count_at_last_idle_notification_;
   unsigned int gc_count_at_last_idle_gc_;
   int scavenges_since_last_idle_round_;
 
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 5fae5f7..d3f1a9e 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -2498,8 +2498,10 @@
   Representation observed_left = observed_input_representation(0);
   Representation observed_right = observed_input_representation(1);
 
-  Representation rep = Representation::Smi();
-  if (observed_left.IsInteger32() && observed_right.IsInteger32()) {
+  Representation rep = Representation::None();
+  rep = rep.generalize(observed_left);
+  rep = rep.generalize(observed_right);
+  if (rep.IsNone() || rep.IsSmiOrInteger32()) {
     if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
     if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
   } else {
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 5da6d52..d1cfb8e 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -898,13 +898,11 @@
 HValue* HGraphBuilder::LoopBuilder::BeginBody(
     HValue* initial,
     HValue* terminating,
-    Token::Value token,
-    Representation input_representation) {
+    Token::Value token) {
   HEnvironment* env = builder_->environment();
   phi_ = new(zone()) HPhi(env->values()->length(), zone());
   header_block_->AddPhi(phi_);
   phi_->AddInput(initial);
-  phi_->AssumeRepresentation(Representation::Integer32());
   env->Push(initial);
   builder_->current_block()->GotoNoSimulate(header_block_);
 
@@ -918,9 +916,6 @@
   builder_->set_current_block(header_block_);
   HCompareIDAndBranch* compare =
       new(zone()) HCompareIDAndBranch(phi_, terminating, token);
-  compare->set_observed_input_representation(input_representation,
-                                             input_representation);
-  compare->AssumeRepresentation(input_representation);
   compare->SetSuccessorAt(0, body_block_);
   compare->SetSuccessorAt(1, exit_block_);
   builder_->current_block()->Finish(compare);
@@ -934,7 +929,6 @@
       increment_ = HSub::New(zone(), context_, phi_, one);
     }
     increment_->ClearFlag(HValue::kCanOverflow);
-    increment_->AssumeRepresentation(Representation::Integer32());
     builder_->AddInstruction(increment_);
     return increment_;
   } else {
@@ -954,7 +948,6 @@
       increment_ = HSub::New(zone(), context_, phi_, one);
     }
     increment_->ClearFlag(HValue::kCanOverflow);
-    increment_->AssumeRepresentation(Representation::Integer32());
     builder_->AddInstruction(increment_);
   }
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index db607d5..5cb99a1 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1217,8 +1217,7 @@
     HValue* BeginBody(
         HValue* initial,
         HValue* terminating,
-        Token::Value token,
-        Representation input_representation = Representation::Integer32());
+        Token::Value token);
     void EndBody();
 
    private:
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 8cb4725..ad1c65d 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -30,7 +30,6 @@
 #if defined(V8_TARGET_ARCH_IA32)
 
 #include "bootstrapper.h"
-#include "builtins-decls.h"
 #include "code-stubs.h"
 #include "isolate.h"
 #include "jsregexp.h"
@@ -138,7 +137,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(ArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
 }
 
 
@@ -160,7 +159,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
 }
 
 
@@ -7766,14 +7765,16 @@
 
 void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
   // Ecx is the only volatile register we must save.
+  const int kNumSavedRegisters = 1;
   __ push(ecx);
 
   // Calculate and push the original stack pointer.
-  __ lea(eax, Operand(esp, kPointerSize));
+  __ lea(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize));
   __ push(eax);
 
-  // Calculate and push the function address.
-  __ mov(eax, Operand(eax, 0));
+  // Retrieve our return address and use it to calculate the calling
+  // function's address.
+  __ mov(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize));
   __ sub(eax, Immediate(Assembler::kCallInstructionLength));
   __ push(eax);
 
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index d635fe1..397ebde 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -209,86 +209,6 @@
 }
 
 
-void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str,
-                                               int cp_offset,
-                                               Label* on_failure,
-                                               bool check_end_of_string) {
-#ifdef DEBUG
-  // If input is ASCII, don't even bother calling here if the string to
-  // match contains a non-ASCII character.
-  if (mode_ == ASCII) {
-    ASSERT(String::IsOneByte(str.start(), str.length()));
-  }
-#endif
-  int byte_length = str.length() * char_size();
-  int byte_offset = cp_offset * char_size();
-  if (check_end_of_string) {
-    // Check that there are at least str.length() characters left in the input.
-    __ cmp(edi, Immediate(-(byte_offset + byte_length)));
-    BranchOrBacktrack(greater, on_failure);
-  }
-
-  if (on_failure == NULL) {
-    // Instead of inlining a backtrack, (re)use the global backtrack target.
-    on_failure = &backtrack_label_;
-  }
-
-  // Do one character test first to minimize loading for the case that
-  // we don't match at all (loading more than one character introduces that
-  // chance of reading unaligned and reading across cache boundaries).
-  // If the first character matches, expect a larger chance of matching the
-  // string, and start loading more characters at a time.
-  if (mode_ == ASCII) {
-    __ cmpb(Operand(esi, edi, times_1, byte_offset),
-            static_cast<int8_t>(str[0]));
-  } else {
-    // Don't use 16-bit immediate. The size changing prefix throws off
-    // pre-decoding.
-    __ movzx_w(eax,
-               Operand(esi, edi, times_1, byte_offset));
-    __ cmp(eax, static_cast<int32_t>(str[0]));
-  }
-  BranchOrBacktrack(not_equal, on_failure);
-
-  __ lea(ebx, Operand(esi, edi, times_1, 0));
-  for (int i = 1, n = str.length(); i < n;) {
-    if (mode_ == ASCII) {
-      if (i <= n - 4) {
-        int combined_chars =
-            (static_cast<uint32_t>(str[i + 0]) << 0) |
-            (static_cast<uint32_t>(str[i + 1]) << 8) |
-            (static_cast<uint32_t>(str[i + 2]) << 16) |
-            (static_cast<uint32_t>(str[i + 3]) << 24);
-        __ cmp(Operand(ebx, byte_offset + i), Immediate(combined_chars));
-        i += 4;
-      } else {
-        __ cmpb(Operand(ebx, byte_offset + i),
-                static_cast<int8_t>(str[i]));
-        i += 1;
-      }
-    } else {
-      ASSERT(mode_ == UC16);
-      if (i <= n - 2) {
-        __ cmp(Operand(ebx, byte_offset + i * sizeof(uc16)),
-               Immediate(*reinterpret_cast<const int*>(&str[i])));
-        i += 2;
-      } else {
-        // Avoid a 16-bit immediate operation. It uses the length-changing
-        // 0x66 prefix which causes pre-decoder misprediction and pipeline
-        // stalls. See
-        // "Intel(R) 64 and IA-32 Architectures Optimization Reference Manual"
-        // (248966.pdf) section 3.4.2.3 "Length-Changing Prefixes (LCP)"
-        __ movzx_w(eax,
-                   Operand(ebx, byte_offset + i * sizeof(uc16)));
-        __ cmp(eax, static_cast<int32_t>(str[i]));
-        i += 1;
-      }
-    }
-    BranchOrBacktrack(not_equal, on_failure);
-  }
-}
-
-
 void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) {
   Label fallthrough;
   __ cmp(edi, Operand(backtrack_stackpointer(), 0));
diff --git a/src/ia32/regexp-macro-assembler-ia32.h b/src/ia32/regexp-macro-assembler-ia32.h
index 6040d80..3933336 100644
--- a/src/ia32/regexp-macro-assembler-ia32.h
+++ b/src/ia32/regexp-macro-assembler-ia32.h
@@ -52,10 +52,6 @@
                                       Label* on_equal);
   virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
   virtual void CheckCharacterLT(uc16 limit, Label* on_less);
-  virtual void CheckCharacters(Vector<const uc16> str,
-                               int cp_offset,
-                               Label* on_failure,
-                               bool check_end_of_string);
   // A "greedy loop" is a loop that is both greedy and with a simple
   // body. It has a particularly simple implementation.
   virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index f32ab13..7838c04 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -950,10 +950,10 @@
 
 
 int TextElement::length() {
-  if (type == ATOM) {
+  if (text_type == ATOM) {
     return data.u_atom->length();
   } else {
-    ASSERT(type == CHAR_CLASS);
+    ASSERT(text_type == CHAR_CLASS);
     return 1;
   }
 }
@@ -1165,7 +1165,7 @@
 
 
 bool Trace::DeferredAction::Mentions(int that) {
-  if (type() == ActionNode::CLEAR_CAPTURES) {
+  if (action_type() == ActionNode::CLEAR_CAPTURES) {
     Interval range = static_cast<DeferredClearCaptures*>(this)->range();
     return range.Contains(that);
   } else {
@@ -1191,7 +1191,7 @@
        action != NULL;
        action = action->next()) {
     if (action->Mentions(reg)) {
-      if (action->type() == ActionNode::STORE_POSITION) {
+      if (action->action_type() == ActionNode::STORE_POSITION) {
         *cp_offset = static_cast<DeferredCapture*>(action)->cp_offset();
         return true;
       } else {
@@ -1209,7 +1209,7 @@
   for (DeferredAction* action = actions_;
        action != NULL;
        action = action->next()) {
-    if (action->type() == ActionNode::CLEAR_CAPTURES) {
+    if (action->action_type() == ActionNode::CLEAR_CAPTURES) {
       Interval range = static_cast<DeferredClearCaptures*>(action)->range();
       for (int i = range.from(); i <= range.to(); i++)
         affected_registers->Set(i, zone);
@@ -1273,7 +1273,7 @@
          action != NULL;
          action = action->next()) {
       if (action->Mentions(reg)) {
-        switch (action->type()) {
+        switch (action->action_type()) {
           case ActionNode::SET_REGISTER: {
             Trace::DeferredSetRegister* psr =
                 static_cast<Trace::DeferredSetRegister*>(action);
@@ -2304,7 +2304,7 @@
                             int budget,
                             bool not_at_start) {
   if (budget <= 0) return 0;
-  if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0;  // Rewinds input!
+  if (action_type_ == POSITIVE_SUBMATCH_SUCCESS) return 0;  // Rewinds input!
   return on_success()->EatsAtLeast(still_to_find,
                                    budget - 1,
                                    not_at_start);
@@ -2315,9 +2315,9 @@
                               int budget,
                               BoyerMooreLookahead* bm,
                               bool not_at_start) {
-  if (type_ == BEGIN_SUBMATCH) {
+  if (action_type_ == BEGIN_SUBMATCH) {
     bm->SetRest(offset);
-  } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) {
+  } else if (action_type_ != POSITIVE_SUBMATCH_SUCCESS) {
     on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
   }
   SaveBMInfo(bm, not_at_start, offset);
@@ -2333,7 +2333,7 @@
   // implies false.  So lets just return the max answer (still_to_find) since
   // that won't prevent us from preloading a lot of characters for the other
   // branches in the node graph.
-  if (type() == AT_START && not_at_start) return still_to_find;
+  if (assertion_type() == AT_START && not_at_start) return still_to_find;
   return on_success()->EatsAtLeast(still_to_find,
                                    budget - 1,
                                    not_at_start);
@@ -2345,7 +2345,7 @@
                                  BoyerMooreLookahead* bm,
                                  bool not_at_start) {
   // Match the behaviour of EatsAtLeast on this node.
-  if (type() == AT_START && not_at_start) return;
+  if (assertion_type() == AT_START && not_at_start) return;
   on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
   SaveBMInfo(bm, not_at_start, offset);
 }
@@ -2562,7 +2562,7 @@
   }
   for (int k = 0; k < elms_->length(); k++) {
     TextElement elm = elms_->at(k);
-    if (elm.type == TextElement::ATOM) {
+    if (elm.text_type == TextElement::ATOM) {
       Vector<const uc16> quarks = elm.data.u_atom->data();
       for (int i = 0; i < characters && i < quarks.length(); i++) {
         QuickCheckDetails::Position* pos =
@@ -2815,7 +2815,7 @@
   int element_count = elms_->length();
   for (int i = 0; i < element_count; i++) {
     TextElement elm = elms_->at(i);
-    if (elm.type == TextElement::ATOM) {
+    if (elm.text_type == TextElement::ATOM) {
       Vector<const uc16> quarks = elm.data.u_atom->data();
       for (int j = 0; j < quarks.length(); j++) {
         uint16_t c = quarks[j];
@@ -2831,7 +2831,7 @@
         copy[j] = converted;
       }
     } else {
-      ASSERT(elm.type == TextElement::CHAR_CLASS);
+      ASSERT(elm.text_type == TextElement::CHAR_CLASS);
       RegExpCharacterClass* cc = elm.data.u_char_class;
       ZoneList<CharacterRange>* ranges = cc->ranges(zone());
       if (!CharacterRange::IsCanonical(ranges)) {
@@ -3086,7 +3086,7 @@
     if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
     if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE;
   }
-  bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY);
+  bool at_boundary = (assertion_type_ == AssertionNode::AT_BOUNDARY);
   if (next_is_word_character == Trace::UNKNOWN) {
     Label before_non_word;
     Label before_word;
@@ -3149,7 +3149,7 @@
                                          RegExpCompiler* compiler,
                                          int filled_in,
                                          bool not_at_start) {
-  if (type_ == AT_START && not_at_start) {
+  if (assertion_type_ == AT_START && not_at_start) {
     details->set_cannot_match();
     return;
   }
@@ -3162,7 +3162,7 @@
 
 void AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) {
   RegExpMacroAssembler* assembler = compiler->macro_assembler();
-  switch (type_) {
+  switch (assertion_type_) {
     case AT_END: {
       Label ok;
       assembler->CheckPosition(trace->cp_offset(), &ok);
@@ -3255,7 +3255,7 @@
   for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) {
     TextElement elm = elms_->at(i);
     int cp_offset = trace->cp_offset() + elm.cp_offset;
-    if (elm.type == TextElement::ATOM) {
+    if (elm.text_type == TextElement::ATOM) {
       Vector<const uc16> quarks = elm.data.u_atom->data();
       for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) {
         if (first_element_checked && i == 0 && j == 0) continue;
@@ -3293,7 +3293,7 @@
         }
       }
     } else {
-      ASSERT_EQ(elm.type, TextElement::CHAR_CLASS);
+      ASSERT_EQ(elm.text_type, TextElement::CHAR_CLASS);
       if (pass == CHARACTER_CLASS_MATCH) {
         if (first_element_checked && i == 0) continue;
         if (DeterminedAlready(quick_check, elm.cp_offset)) continue;
@@ -3316,7 +3316,7 @@
 int TextNode::Length() {
   TextElement elm = elms_->last();
   ASSERT(elm.cp_offset >= 0);
-  if (elm.type == TextElement::ATOM) {
+  if (elm.text_type == TextElement::ATOM) {
     return elm.cp_offset + elm.data.u_atom->data().length();
   } else {
     return elm.cp_offset + 1;
@@ -3422,7 +3422,7 @@
   int element_count = elms_->length();
   for (int i = 0; i < element_count; i++) {
     TextElement elm = elms_->at(i);
-    if (elm.type == TextElement::CHAR_CLASS) {
+    if (elm.text_type == TextElement::CHAR_CLASS) {
       RegExpCharacterClass* cc = elm.data.u_char_class;
       // None of the standard character classes is different in the case
       // independent case and it slows us down if we don't know that.
@@ -3439,7 +3439,7 @@
 
 int TextNode::GreedyLoopTextLength() {
   TextElement elm = elms_->at(elms_->length() - 1);
-  if (elm.type == TextElement::CHAR_CLASS) {
+  if (elm.text_type == TextElement::CHAR_CLASS) {
     return elm.cp_offset + 1;
   } else {
     return elm.cp_offset + elm.data.u_atom->data().length();
@@ -3451,7 +3451,7 @@
     RegExpCompiler* compiler) {
   if (elms_->length() != 1) return NULL;
   TextElement elm = elms_->at(0);
-  if (elm.type != TextElement::CHAR_CLASS) return NULL;
+  if (elm.text_type != TextElement::CHAR_CLASS) return NULL;
   RegExpCharacterClass* node = elm.data.u_char_class;
   ZoneList<CharacterRange>* ranges = node->ranges(zone());
   if (!CharacterRange::IsCanonical(ranges)) {
@@ -4196,7 +4196,7 @@
 
   RecursionCheck rc(compiler);
 
-  switch (type_) {
+  switch (action_type_) {
     case STORE_POSITION: {
       Trace::DeferredCapture
           new_capture(data_.u_position_register.reg,
@@ -4526,7 +4526,7 @@
   for (int i = 0; i < that->elements()->length(); i++) {
     if (i > 0) stream()->Add(" ");
     TextElement elm = that->elements()->at(i);
-    switch (elm.type) {
+    switch (elm.text_type) {
       case TextElement::ATOM: {
         stream()->Add("'%w'", elm.data.u_atom->data());
         break;
@@ -4573,7 +4573,7 @@
 
 void DotPrinter::VisitAssertion(AssertionNode* that) {
   stream()->Add("  n%p [", that);
-  switch (that->type()) {
+  switch (that->assertion_type()) {
     case AssertionNode::AT_END:
       stream()->Add("label=\"$\", shape=septagon");
       break;
@@ -4600,7 +4600,7 @@
 
 void DotPrinter::VisitAction(ActionNode* that) {
   stream()->Add("  n%p [", that);
-  switch (that->type_) {
+  switch (that->action_type_) {
     case ActionNode::SET_REGISTER:
       stream()->Add("label=\"$%i:=%i\", shape=octagon",
                     that->data_.u_store_register.reg,
@@ -5013,7 +5013,7 @@
   NodeInfo info;
   Zone* zone = compiler->zone();
 
-  switch (type()) {
+  switch (assertion_type()) {
     case START_OF_LINE:
       return AssertionNode::AfterNewline(on_success);
     case START_OF_INPUT:
@@ -5715,7 +5715,7 @@
   for (int i = 0; i < element_count; i++) {
     TextElement& elm = elements()->at(i);
     elm.cp_offset = cp_offset;
-    if (elm.type == TextElement::ATOM) {
+    if (elm.text_type == TextElement::ATOM) {
       cp_offset += elm.data.u_atom->data().length();
     } else {
       cp_offset++;
@@ -5835,7 +5835,7 @@
       return;
     }
     TextElement text = elements()->at(i);
-    if (text.type == TextElement::ATOM) {
+    if (text.text_type == TextElement::ATOM) {
       RegExpAtom* atom = text.data.u_atom;
       for (int j = 0; j < atom->length(); j++, offset++) {
         if (offset >= bm->length()) {
@@ -5858,7 +5858,7 @@
         }
       }
     } else {
-      ASSERT(text.type == TextElement::CHAR_CLASS);
+      ASSERT(text.text_type == TextElement::CHAR_CLASS);
       RegExpCharacterClass* char_class = text.data.u_char_class;
       ZoneList<CharacterRange>* ranges = char_class->ranges(zone());
       if (char_class->is_negated()) {
@@ -5971,7 +5971,7 @@
 
 void DispatchTableConstructor::VisitText(TextNode* that) {
   TextElement elm = that->elements()->at(0);
-  switch (elm.type) {
+  switch (elm.text_type) {
     case TextElement::ATOM: {
       uc16 c = elm.data.u_atom->data()[0];
       AddRange(CharacterRange(c, c));
diff --git a/src/jsregexp.h b/src/jsregexp.h
index 625f192..181a1b2 100644
--- a/src/jsregexp.h
+++ b/src/jsregexp.h
@@ -429,13 +429,13 @@
 
 class TextElement {
  public:
-  enum Type {UNINITIALIZED, ATOM, CHAR_CLASS};
-  TextElement() : type(UNINITIALIZED) { }
-  explicit TextElement(Type t) : type(t), cp_offset(-1) { }
+  enum TextType {UNINITIALIZED, ATOM, CHAR_CLASS};
+  TextElement() : text_type(UNINITIALIZED) { }
+  explicit TextElement(TextType t) : text_type(t), cp_offset(-1) { }
   static TextElement Atom(RegExpAtom* atom);
   static TextElement CharClass(RegExpCharacterClass* char_class);
   int length();
-  Type type;
+  TextType text_type;
   union {
     RegExpAtom* u_atom;
     RegExpCharacterClass* u_char_class;
@@ -739,7 +739,7 @@
 
 class ActionNode: public SeqRegExpNode {
  public:
-  enum Type {
+  enum ActionType {
     SET_REGISTER,
     INCREMENT_REGISTER,
     STORE_POSITION,
@@ -780,7 +780,7 @@
                             int budget,
                             BoyerMooreLookahead* bm,
                             bool not_at_start);
-  Type type() { return type_; }
+  ActionType action_type() { return action_type_; }
   // TODO(erikcorry): We should allow some action nodes in greedy loops.
   virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
 
@@ -813,10 +813,10 @@
       int range_to;
     } u_clear_captures;
   } data_;
-  ActionNode(Type type, RegExpNode* on_success)
+  ActionNode(ActionType action_type, RegExpNode* on_success)
       : SeqRegExpNode(on_success),
-        type_(type) { }
-  Type type_;
+        action_type_(action_type) { }
+  ActionType action_type_;
   friend class DotPrinter;
 };
 
@@ -876,7 +876,7 @@
 
 class AssertionNode: public SeqRegExpNode {
  public:
-  enum AssertionNodeType {
+  enum AssertionType {
     AT_END,
     AT_START,
     AT_BOUNDARY,
@@ -909,8 +909,7 @@
                             int budget,
                             BoyerMooreLookahead* bm,
                             bool not_at_start);
-  AssertionNodeType type() { return type_; }
-  void set_type(AssertionNodeType type) { type_ = type; }
+  AssertionType assertion_type() { return assertion_type_; }
 
  private:
   void EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace);
@@ -918,9 +917,9 @@
   void BacktrackIfPrevious(RegExpCompiler* compiler,
                            Trace* trace,
                            IfPrevious backtrack_if_previous);
-  AssertionNode(AssertionNodeType t, RegExpNode* on_success)
-      : SeqRegExpNode(on_success), type_(t) { }
-  AssertionNodeType type_;
+  AssertionNode(AssertionType t, RegExpNode* on_success)
+      : SeqRegExpNode(on_success), assertion_type_(t) { }
+  AssertionType assertion_type_;
 };
 
 
@@ -1337,14 +1336,14 @@
 
   class DeferredAction {
    public:
-    DeferredAction(ActionNode::Type type, int reg)
-        : type_(type), reg_(reg), next_(NULL) { }
+    DeferredAction(ActionNode::ActionType action_type, int reg)
+        : action_type_(action_type), reg_(reg), next_(NULL) { }
     DeferredAction* next() { return next_; }
     bool Mentions(int reg);
     int reg() { return reg_; }
-    ActionNode::Type type() { return type_; }
+    ActionNode::ActionType action_type() { return action_type_; }
    private:
-    ActionNode::Type type_;
+    ActionNode::ActionType action_type_;
     int reg_;
     DeferredAction* next_;
     friend class Trace;
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index b738648..1a00bc0 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -30,7 +30,6 @@
 #if defined(V8_TARGET_ARCH_MIPS)
 
 #include "bootstrapper.h"
-#include "builtins-decls.h"
 #include "code-stubs.h"
 #include "codegen.h"
 #include "regexp-macro-assembler.h"
@@ -147,7 +146,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(ArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
 }
 
 
@@ -169,7 +168,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-  FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
 }
 
 
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index 3e255b7..977f050 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -235,55 +235,6 @@
 }
 
 
-void RegExpMacroAssemblerMIPS::CheckCharacters(Vector<const uc16> str,
-                                               int cp_offset,
-                                               Label* on_failure,
-                                               bool check_end_of_string) {
-  if (on_failure == NULL) {
-    // Instead of inlining a backtrack for each test, (re)use the global
-    // backtrack target.
-    on_failure = &backtrack_label_;
-  }
-
-  if (check_end_of_string) {
-    // Is last character of required match inside string.
-    CheckPosition(cp_offset + str.length() - 1, on_failure);
-  }
-
-  __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
-  if (cp_offset != 0) {
-    int byte_offset = cp_offset * char_size();
-    __ Addu(a0, a0, Operand(byte_offset));
-  }
-
-  // a0 : Address of characters to match against str.
-  int stored_high_byte = 0;
-  for (int i = 0; i < str.length(); i++) {
-    if (mode_ == ASCII) {
-      __ lbu(a1, MemOperand(a0, 0));
-      __ addiu(a0, a0, char_size());
-      ASSERT(str[i] <= String::kMaxOneByteCharCode);
-      BranchOrBacktrack(on_failure, ne, a1, Operand(str[i]));
-    } else {
-      __ lhu(a1, MemOperand(a0, 0));
-      __ addiu(a0, a0, char_size());
-      uc16 match_char = str[i];
-      int match_high_byte = (match_char >> 8);
-      if (match_high_byte == 0) {
-        BranchOrBacktrack(on_failure, ne, a1, Operand(str[i]));
-      } else {
-        if (match_high_byte != stored_high_byte) {
-          __ li(a2, Operand(match_high_byte));
-          stored_high_byte = match_high_byte;
-        }
-        __ Addu(a3, a2, Operand(match_char & 0xff));
-        BranchOrBacktrack(on_failure, ne, a1, Operand(a3));
-      }
-    }
-  }
-}
-
-
 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
   Label backtrack_non_equal;
   __ lw(a0, MemOperand(backtrack_stackpointer(), 0));
diff --git a/src/mips/regexp-macro-assembler-mips.h b/src/mips/regexp-macro-assembler-mips.h
index 3ad64f9..86ae4d4 100644
--- a/src/mips/regexp-macro-assembler-mips.h
+++ b/src/mips/regexp-macro-assembler-mips.h
@@ -55,10 +55,6 @@
                                       Label* on_equal);
   virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
   virtual void CheckCharacterLT(uc16 limit, Label* on_less);
-  virtual void CheckCharacters(Vector<const uc16> str,
-                               int cp_offset,
-                               Label* on_failure,
-                               bool check_end_of_string);
   // A "greedy loop" is a loop that is both greedy and with a simple
   // body. It has a particularly simple implementation.
   virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 549c9ff..8eab562 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -540,6 +540,8 @@
     case JS_FUNCTION_TYPE: return "JS_FUNCTION";
     case CODE_TYPE: return "CODE";
     case JS_ARRAY_TYPE: return "JS_ARRAY";
+    case JS_ARRAY_BUFFER_TYPE: return "JS_ARRAY_BUFFER";
+    case JS_TYPED_ARRAY_TYPE: return "JS_TYPED_ARRAY";
     case JS_PROXY_TYPE: return "JS_PROXY";
     case JS_WEAK_MAP_TYPE: return "JS_WEAK_MAP";
     case JS_REGEXP_TYPE: return "JS_REGEXP";
@@ -822,7 +824,7 @@
   byte_offset()->ShortPrint(out);
   PrintF(out, "\n - byte_length = ");
   byte_length()->ShortPrint(out);
-  PrintF(out, " - length = ");
+  PrintF(out, "\n - length = ");
   length()->ShortPrint(out);
   PrintF("\n");
   PrintElements(out);
diff --git a/src/objects.cc b/src/objects.cc
index ca1c650..24c60ec 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1205,6 +1205,11 @@
   if (FLAG_enable_slow_asserts) {
     // Assert that the resource and the string are equivalent.
     ASSERT(static_cast<size_t>(this->length()) == resource->length());
+    if (this->IsTwoByteRepresentation()) {
+      ScopedVector<uint16_t> smart_chars(this->length());
+      String::WriteToFlat(this, smart_chars.start(), 0, this->length());
+      ASSERT(String::IsOneByte(smart_chars.start(), this->length()));
+    }
     ScopedVector<char> smart_chars(this->length());
     String::WriteToFlat(this, smart_chars.start(), 0, this->length());
     ASSERT(memcmp(smart_chars.start(),
diff --git a/src/objects.h b/src/objects.h
index a16ebbf..b7b32f8 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -3677,7 +3677,7 @@
   static inline ScopeInfo* cast(Object* object);
 
   // Return the type of this scope.
-  ScopeType Type();
+  ScopeType scope_type();
 
   // Does this scope call eval?
   bool CallsEval();
@@ -3860,7 +3860,7 @@
   };
 
   // Properties of scopes.
-  class TypeField:             public BitField<ScopeType,            0, 3> {};
+  class ScopeTypeField:        public BitField<ScopeType,            0, 3> {};
   class CallsEvalField:        public BitField<bool,                 3, 1> {};
   class LanguageModeField:     public BitField<LanguageMode,         4, 2> {};
   class FunctionVariableField: public BitField<FunctionVariableInfo, 6, 2> {};
diff --git a/src/parser.cc b/src/parser.cc
index f032d97..4aaa9a1 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -202,9 +202,8 @@
 }
 
 
-void RegExpBuilder::AddQuantifierToAtom(int min,
-                                        int max,
-                                        RegExpQuantifier::Type type) {
+void RegExpBuilder::AddQuantifierToAtom(
+    int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
   if (pending_empty_) {
     pending_empty_ = false;
     return;
@@ -244,7 +243,8 @@
     UNREACHABLE();
     return;
   }
-  terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom), zone());
+  terms_.Add(
+      new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
   LAST(ADD_TERM);
 }
 
@@ -410,8 +410,8 @@
 }
 
 
-Scope* Parser::NewScope(Scope* parent, ScopeType type) {
-  Scope* result = new(zone()) Scope(parent, type, zone());
+Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
+  Scope* result = new(zone()) Scope(parent, scope_type, zone());
   result->Initialize();
   return result;
 }
@@ -758,7 +758,7 @@
            info()->is_extended_mode());
     ASSERT(info()->language_mode() == shared_info->language_mode());
     scope->SetLanguageMode(shared_info->language_mode());
-    FunctionLiteral::Type type = shared_info->is_expression()
+    FunctionLiteral::FunctionType function_type = shared_info->is_expression()
         ? (shared_info->is_anonymous()
               ? FunctionLiteral::ANONYMOUS_EXPRESSION
               : FunctionLiteral::NAMED_EXPRESSION)
@@ -768,7 +768,7 @@
                                   false,  // Strict mode name already checked.
                                   shared_info->is_generator(),
                                   RelocInfo::kNoPosition,
-                                  type,
+                                  function_type,
                                   &ok);
     // Make sure the results agree.
     ASSERT(ok == (result != NULL));
@@ -799,20 +799,20 @@
 }
 
 
-void Parser::ReportMessage(const char* type, Vector<const char*> args) {
+void Parser::ReportMessage(const char* message, Vector<const char*> args) {
   Scanner::Location source_location = scanner().location();
-  ReportMessageAt(source_location, type, args);
+  ReportMessageAt(source_location, message, args);
 }
 
 
-void Parser::ReportMessage(const char* type, Vector<Handle<String> > args) {
+void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) {
   Scanner::Location source_location = scanner().location();
-  ReportMessageAt(source_location, type, args);
+  ReportMessageAt(source_location, message, args);
 }
 
 
 void Parser::ReportMessageAt(Scanner::Location source_location,
-                             const char* type,
+                             const char* message,
                              Vector<const char*> args) {
   MessageLocation location(script_,
                            source_location.beg_pos,
@@ -824,13 +824,13 @@
     elements->set(i, *arg_string);
   }
   Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
-  Handle<Object> result = factory->NewSyntaxError(type, array);
+  Handle<Object> result = factory->NewSyntaxError(message, array);
   isolate()->Throw(*result, &location);
 }
 
 
 void Parser::ReportMessageAt(Scanner::Location source_location,
-                             const char* type,
+                             const char* message,
                              Vector<Handle<String> > args) {
   MessageLocation location(script_,
                            source_location.beg_pos,
@@ -841,7 +841,7 @@
     elements->set(i, *args[i]);
   }
   Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
-  Handle<Object> result = factory->NewSyntaxError(type, array);
+  Handle<Object> result = factory->NewSyntaxError(message, array);
   isolate()->Throw(*result, &location);
 }
 
@@ -1538,12 +1538,12 @@
         *ok = false;
         return;
       }
-      Handle<String> type_string =
+      Handle<String> message_string =
           isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"),
                                                   TENURED);
       Expression* expression =
           NewThrowTypeError(isolate()->factory()->redeclaration_string(),
-                            type_string, name);
+                            message_string, name);
       declaration_scope->SetIllegalRedeclaration(expression);
     }
   }
@@ -2345,8 +2345,9 @@
   Scope* declaration_scope = top_scope_->DeclarationScope();
   if (declaration_scope->is_global_scope() ||
       declaration_scope->is_eval_scope()) {
-    Handle<String> type = isolate()->factory()->illegal_return_string();
-    Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
+    Handle<String> message = isolate()->factory()->illegal_return_string();
+    Expression* throw_error =
+        NewThrowSyntaxError(message, Handle<Object>::null());
     return factory()->NewExpressionStatement(throw_error);
   }
   return result;
@@ -2737,9 +2738,9 @@
         // error here but for compatibility with JSC we choose to report
         // the error at runtime.
         if (expression == NULL || !expression->IsValidLeftHandSide()) {
-          Handle<String> type =
+          Handle<String> message =
               isolate()->factory()->invalid_lhs_in_for_in_string();
-          expression = NewThrowReferenceError(type);
+          expression = NewThrowReferenceError(message);
         }
         ForInStatement* loop = factory()->NewForInStatement(labels);
         Target target(&this->target_stack_, loop);
@@ -2856,9 +2857,9 @@
   // runtime.
   // TODO(ES5): Should change parsing for spec conformance.
   if (expression == NULL || !expression->IsValidLeftHandSide()) {
-    Handle<String> type =
+    Handle<String> message =
         isolate()->factory()->invalid_lhs_in_assignment_string();
-    expression = NewThrowReferenceError(type);
+    expression = NewThrowReferenceError(message);
   }
 
   if (!top_scope_->is_classic_mode()) {
@@ -3126,9 +3127,9 @@
     // error here but for compatibility with JSC we choose to report the
     // error at runtime.
     if (expression == NULL || !expression->IsValidLeftHandSide()) {
-      Handle<String> type =
+      Handle<String> message =
           isolate()->factory()->invalid_lhs_in_prefix_op_string();
-      expression = NewThrowReferenceError(type);
+      expression = NewThrowReferenceError(message);
     }
 
     if (!top_scope_->is_classic_mode()) {
@@ -3161,9 +3162,9 @@
     // error here but for compatibility with JSC we choose to report the
     // error at runtime.
     if (expression == NULL || !expression->IsValidLeftHandSide()) {
-      Handle<String> type =
+      Handle<String> message =
           isolate()->factory()->invalid_lhs_in_postfix_op_string();
-      expression = NewThrowReferenceError(type);
+      expression = NewThrowReferenceError(message);
     }
 
     if (!top_scope_->is_classic_mode()) {
@@ -3322,14 +3323,14 @@
       name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
                                                  CHECK_OK);
     }
-    FunctionLiteral::Type type = name.is_null()
+    FunctionLiteral::FunctionType function_type = name.is_null()
         ? FunctionLiteral::ANONYMOUS_EXPRESSION
         : FunctionLiteral::NAMED_EXPRESSION;
     result = ParseFunctionLiteral(name,
                                   is_strict_reserved_name,
                                   is_generator,
                                   function_token_position,
-                                  type,
+                                  function_type,
                                   CHECK_OK);
   } else {
     result = ParsePrimaryExpression(CHECK_OK);
@@ -3658,24 +3659,25 @@
   if (object_literal != NULL) {
     ASSERT(object_literal->is_simple());
     if (object_literal->fast_elements()) {
-      result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
+      result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
     } else {
-      result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
+      result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
     }
     result->set(kElementsSlot, *object_literal->constant_properties());
   } else {
     ArrayLiteral* array_literal = expression->AsArrayLiteral();
     ASSERT(array_literal != NULL && array_literal->is_simple());
-    result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
+    result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
     result->set(kElementsSlot, *array_literal->constant_elements());
   }
   return result;
 }
 
 
-CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) {
-  Smi* type_value = Smi::cast(value->get(kTypeSlot));
-  return static_cast<Type>(type_value->value());
+CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
+    Handle<FixedArray> value) {
+  Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
+  return static_cast<LiteralType>(literal_type->value());
 }
 
 
@@ -4163,12 +4165,13 @@
 };
 
 
-FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
-                                              bool name_is_strict_reserved,
-                                              bool is_generator,
-                                              int function_token_position,
-                                              FunctionLiteral::Type type,
-                                              bool* ok) {
+FunctionLiteral* Parser::ParseFunctionLiteral(
+    Handle<String> function_name,
+    bool name_is_strict_reserved,
+    bool is_generator,
+    int function_token_position,
+    FunctionLiteral::FunctionType function_type,
+    bool* ok) {
   // Function ::
   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
 
@@ -4186,7 +4189,8 @@
   // Function declarations are function scoped in normal mode, so they are
   // hoisted. In harmony block scoping mode they are block scoped, so they
   // are not hoisted.
-  Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode())
+  Scope* scope =
+      (function_type == FunctionLiteral::DECLARATION && !is_extended_mode())
       ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
       : NewScope(top_scope_, FUNCTION_SCOPE);
   ZoneList<Statement*>* body = NULL;
@@ -4272,7 +4276,7 @@
     // instead of Variables and Proxis as is the case now.
     Variable* fvar = NULL;
     Token::Value fvar_init_op = Token::INIT_CONST;
-    if (type == FunctionLiteral::NAMED_EXPRESSION) {
+    if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
       if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY;
       VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST;
       fvar = new(zone()) Variable(top_scope_,
@@ -4476,7 +4480,7 @@
                                     handler_count,
                                     num_parameters,
                                     duplicate_parameters,
-                                    type,
+                                    function_type,
                                     FunctionLiteral::kIsFunction,
                                     parenthesized,
                                     generator);
@@ -4822,22 +4826,22 @@
 }
 
 
-Expression* Parser::NewThrowReferenceError(Handle<String> type) {
+Expression* Parser::NewThrowReferenceError(Handle<String> message) {
   return NewThrowError(isolate()->factory()->MakeReferenceError_string(),
-                       type, HandleVector<Object>(NULL, 0));
+                       message, HandleVector<Object>(NULL, 0));
 }
 
 
-Expression* Parser::NewThrowSyntaxError(Handle<String> type,
+Expression* Parser::NewThrowSyntaxError(Handle<String> message,
                                         Handle<Object> first) {
   int argc = first.is_null() ? 0 : 1;
   Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
   return NewThrowError(
-      isolate()->factory()->MakeSyntaxError_string(), type, arguments);
+      isolate()->factory()->MakeSyntaxError_string(), message, arguments);
 }
 
 
-Expression* Parser::NewThrowTypeError(Handle<String> type,
+Expression* Parser::NewThrowTypeError(Handle<String> message,
                                       Handle<Object> first,
                                       Handle<Object> second) {
   ASSERT(!first.is_null() && !second.is_null());
@@ -4845,12 +4849,12 @@
   Vector< Handle<Object> > arguments =
       HandleVector<Object>(elements, ARRAY_SIZE(elements));
   return NewThrowError(
-      isolate()->factory()->MakeTypeError_string(), type, arguments);
+      isolate()->factory()->MakeTypeError_string(), message, arguments);
 }
 
 
 Expression* Parser::NewThrowError(Handle<String> constructor,
-                                  Handle<String> type,
+                                  Handle<String> message,
                                   Vector< Handle<Object> > arguments) {
   int argc = arguments.length();
   Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
@@ -4865,7 +4869,7 @@
       elements, FAST_ELEMENTS, TENURED);
 
   ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone());
-  args->Add(factory()->NewLiteral(type), zone());
+  args->Add(factory()->NewLiteral(message), zone());
   args->Add(factory()->NewLiteral(array), zone());
   CallRuntime* call_constructor =
       factory()->NewCallRuntime(constructor, NULL, args);
@@ -5006,20 +5010,21 @@
       int end_capture_index = captures_started();
 
       int capture_index = stored_state->capture_index();
-      SubexpressionType type = stored_state->group_type();
+      SubexpressionType group_type = stored_state->group_type();
 
       // Restore previous state.
       stored_state = stored_state->previous_state();
       builder = stored_state->builder();
 
       // Build result of subexpression.
-      if (type == CAPTURE) {
+      if (group_type == CAPTURE) {
         RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
         captures_->at(capture_index - 1) = capture;
         body = capture;
-      } else if (type != GROUPING) {
-        ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
-        bool is_positive = (type == POSITIVE_LOOKAHEAD);
+      } else if (group_type != GROUPING) {
+        ASSERT(group_type == POSITIVE_LOOKAHEAD ||
+               group_type == NEGATIVE_LOOKAHEAD);
+        bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
         body = new(zone()) RegExpLookahead(body,
                                    is_positive,
                                    end_capture_index - capture_index,
@@ -5053,10 +5058,10 @@
     }
     case '$': {
       Advance();
-      RegExpAssertion::Type type =
+      RegExpAssertion::AssertionType assertion_type =
           multiline_ ? RegExpAssertion::END_OF_LINE :
                        RegExpAssertion::END_OF_INPUT;
-      builder->AddAssertion(new(zone()) RegExpAssertion(type));
+      builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
       continue;
     }
     case '.': {
@@ -5070,18 +5075,18 @@
       break;
     }
     case '(': {
-      SubexpressionType type = CAPTURE;
+      SubexpressionType subexpr_type = CAPTURE;
       Advance();
       if (current() == '?') {
         switch (Next()) {
           case ':':
-            type = GROUPING;
+            subexpr_type = GROUPING;
             break;
           case '=':
-            type = POSITIVE_LOOKAHEAD;
+            subexpr_type = POSITIVE_LOOKAHEAD;
             break;
           case '!':
-            type = NEGATIVE_LOOKAHEAD;
+            subexpr_type = NEGATIVE_LOOKAHEAD;
             break;
           default:
             ReportError(CStrVector("Invalid group") CHECK_FAILED);
@@ -5098,7 +5103,7 @@
         captures_->Add(NULL, zone());
       }
       // Store current state and begin new disjunction parsing.
-      stored_state = new(zone()) RegExpParserState(stored_state, type,
+      stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
                                                    captures_started(), zone());
       builder = stored_state->builder();
       continue;
@@ -5286,16 +5291,16 @@
     default:
       continue;
     }
-    RegExpQuantifier::Type type = RegExpQuantifier::GREEDY;
+    RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
     if (current() == '?') {
-      type = RegExpQuantifier::NON_GREEDY;
+      quantifier_type = RegExpQuantifier::NON_GREEDY;
       Advance();
     } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
       // FLAG_regexp_possessive_quantifier is a debug-only flag.
-      type = RegExpQuantifier::POSSESSIVE;
+      quantifier_type = RegExpQuantifier::POSSESSIVE;
       Advance();
     }
-    builder->AddQuantifierToAtom(min, max, type);
+    builder->AddQuantifierToAtom(min, max, quantifier_type);
   }
 }
 
diff --git a/src/parser.h b/src/parser.h
index ed9ee10..eea617f 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -269,7 +269,8 @@
   void AddAtom(RegExpTree* tree);
   void AddAssertion(RegExpTree* tree);
   void NewAlternative();  // '|'
-  void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type);
+  void AddQuantifierToAtom(
+      int min, int max, RegExpQuantifier::QuantifierType type);
   RegExpTree* ToRegExp();
 
  private:
@@ -690,7 +691,7 @@
                                         bool name_is_reserved,
                                         bool is_generator,
                                         int function_token_position,
-                                        FunctionLiteral::Type type,
+                                        FunctionLiteral::FunctionType type,
                                         bool* ok);
 
 
@@ -867,7 +868,7 @@
 // can be fully handled at compile time.
 class CompileTimeValue: public AllStatic {
  public:
-  enum Type {
+  enum LiteralType {
     OBJECT_LITERAL_FAST_ELEMENTS,
     OBJECT_LITERAL_SLOW_ELEMENTS,
     ARRAY_LITERAL
@@ -881,13 +882,13 @@
   static Handle<FixedArray> GetValue(Expression* expression);
 
   // Get the type of a compile time value returned by GetValue().
-  static Type GetType(Handle<FixedArray> value);
+  static LiteralType GetLiteralType(Handle<FixedArray> value);
 
   // Get the elements array of a compile time value returned by GetValue().
   static Handle<FixedArray> GetElements(Handle<FixedArray> value);
 
  private:
-  static const int kTypeSlot = 0;
+  static const int kLiteralTypeSlot = 0;
   static const int kElementsSlot = 1;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
diff --git a/src/regexp-macro-assembler-irregexp.cc b/src/regexp-macro-assembler-irregexp.cc
index e678d60..c69011f 100644
--- a/src/regexp-macro-assembler-irregexp.cc
+++ b/src/regexp-macro-assembler-irregexp.cc
@@ -410,28 +410,6 @@
 }
 
 
-void RegExpMacroAssemblerIrregexp::CheckCharacters(
-  Vector<const uc16> str,
-  int cp_offset,
-  Label* on_failure,
-  bool check_end_of_string) {
-  ASSERT(cp_offset >= kMinCPOffset);
-  ASSERT(cp_offset + str.length() - 1 <= kMaxCPOffset);
-  // It is vital that this loop is backwards due to the unchecked character
-  // load below.
-  for (int i = str.length() - 1; i >= 0; i--) {
-    if (check_end_of_string && i == str.length() - 1) {
-      Emit(BC_LOAD_CURRENT_CHAR, cp_offset + i);
-      EmitOrLink(on_failure);
-    } else {
-      Emit(BC_LOAD_CURRENT_CHAR_UNCHECKED, cp_offset + i);
-    }
-    Emit(BC_CHECK_NOT_CHAR, str[i]);
-    EmitOrLink(on_failure);
-  }
-}
-
-
 void RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index,
                                                 int comparand,
                                                 Label* on_less_than) {
diff --git a/src/regexp-macro-assembler-irregexp.h b/src/regexp-macro-assembler-irregexp.h
index 4bc2980..3569d8b 100644
--- a/src/regexp-macro-assembler-irregexp.h
+++ b/src/regexp-macro-assembler-irregexp.h
@@ -103,10 +103,6 @@
   virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
   virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
                                                Label* on_no_match);
-  virtual void CheckCharacters(Vector<const uc16> str,
-                               int cp_offset,
-                               Label* on_failure,
-                               bool check_end_of_string);
   virtual void IfRegisterLT(int register_index, int comparand, Label* if_lt);
   virtual void IfRegisterGE(int register_index, int comparand, Label* if_ge);
   virtual void IfRegisterEqPos(int register_index, Label* if_eq);
diff --git a/src/regexp-macro-assembler-tracer.cc b/src/regexp-macro-assembler-tracer.cc
index f878e8c..1ce1fa4 100644
--- a/src/regexp-macro-assembler-tracer.cc
+++ b/src/regexp-macro-assembler-tracer.cc
@@ -383,21 +383,6 @@
 }
 
 
-void RegExpMacroAssemblerTracer::CheckCharacters(Vector<const uc16> str,
-                                                 int cp_offset,
-                                                 Label* on_failure,
-                                                 bool check_end_of_string) {
-  PrintF(" %s(str=\"",
-         check_end_of_string ? "CheckCharacters" : "CheckCharactersUnchecked");
-  for (int i = 0; i < str.length(); i++) {
-    PrintF("0x%04x", str[i]);
-  }
-  PrintF("\", cp_offset=%d, label[%08x])\n",
-         cp_offset, LabelToInt(on_failure));
-  assembler_->CheckCharacters(str, cp_offset, on_failure, check_end_of_string);
-}
-
-
 bool RegExpMacroAssemblerTracer::CheckSpecialCharacterClass(
     uc16 type,
     Label* on_no_match) {
diff --git a/src/regexp-macro-assembler-tracer.h b/src/regexp-macro-assembler-tracer.h
index ac262df..852fb80 100644
--- a/src/regexp-macro-assembler-tracer.h
+++ b/src/regexp-macro-assembler-tracer.h
@@ -49,11 +49,6 @@
                                       Label* on_equal);
   virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
   virtual void CheckCharacterLT(uc16 limit, Label* on_less);
-  virtual void CheckCharacters(
-      Vector<const uc16> str,
-      int cp_offset,
-      Label* on_failure,
-      bool check_end_of_string);
   virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
   virtual void CheckNotAtStart(Label* on_not_at_start);
   virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
diff --git a/src/regexp-macro-assembler.h b/src/regexp-macro-assembler.h
index 211ab6b..1ff8bd9 100644
--- a/src/regexp-macro-assembler.h
+++ b/src/regexp-macro-assembler.h
@@ -87,17 +87,6 @@
                                       Label* on_equal) = 0;
   virtual void CheckCharacterGT(uc16 limit, Label* on_greater) = 0;
   virtual void CheckCharacterLT(uc16 limit, Label* on_less) = 0;
-  // Check the current character for a match with a literal string.  If we
-  // fail to match then goto the on_failure label.  If check_eos is set then
-  // the end of input always fails.  If check_eos is clear then it is the
-  // caller's responsibility to ensure that the end of string is not hit.
-  // If the label is NULL then we should pop a backtrack address off
-  // the stack and go to that.
-  virtual void CheckCharacters(
-      Vector<const uc16> str,
-      int cp_offset,
-      Label* on_failure,
-      bool check_eos) = 0;
   virtual void CheckGreedyLoop(Label* on_tos_equals_current_position) = 0;
   virtual void CheckNotAtStart(Label* on_not_at_start) = 0;
   virtual void CheckNotBackReference(int start_reg, Label* on_no_match) = 0;
diff --git a/src/runtime.cc b/src/runtime.cc
index f8147a2..0516c9c 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -425,7 +425,7 @@
     Handle<FixedArray> array) {
   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
   const bool kHasNoFunctionLiteral = false;
-  switch (CompileTimeValue::GetType(array)) {
+  switch (CompileTimeValue::GetLiteralType(array)) {
     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
       return CreateObjectLiteralBoilerplate(isolate,
                                             literals,
@@ -11234,7 +11234,9 @@
           context_ = Handle<Context>(context_->previous(), isolate_);
         }
       }
-      if (scope_info->Type() != EVAL_SCOPE) nested_scope_chain_.Add(scope_info);
+      if (scope_info->scope_type() != EVAL_SCOPE) {
+        nested_scope_chain_.Add(scope_info);
+      }
     } else {
       // Reparse the code and analyze the scopes.
       Handle<Script> script(Script::cast(shared_info->script()));
@@ -11242,13 +11244,13 @@
 
       // Check whether we are in global, eval or function code.
       Handle<ScopeInfo> scope_info(shared_info->scope_info());
-      if (scope_info->Type() != FUNCTION_SCOPE) {
+      if (scope_info->scope_type() != FUNCTION_SCOPE) {
         // Global or eval code.
         CompilationInfoWithZone info(script);
-        if (scope_info->Type() == GLOBAL_SCOPE) {
+        if (scope_info->scope_type() == GLOBAL_SCOPE) {
           info.MarkAsGlobal();
         } else {
-          ASSERT(scope_info->Type() == EVAL_SCOPE);
+          ASSERT(scope_info->scope_type() == EVAL_SCOPE);
           info.MarkAsEval();
           info.SetContext(Handle<Context>(function_->context()));
         }
@@ -11314,7 +11316,7 @@
     ASSERT(!failed_);
     if (!nested_scope_chain_.is_empty()) {
       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
-      switch (scope_info->Type()) {
+      switch (scope_info->scope_type()) {
         case FUNCTION_SCOPE:
           ASSERT(context_->IsFunctionContext() ||
                  !scope_info->HasContext());
@@ -12022,7 +12024,7 @@
     Handle<Context> current = context_chain.RemoveLast();
     ASSERT(!(scope_info->HasContext() & current.is_null()));
 
-    if (scope_info->Type() == CATCH_SCOPE) {
+    if (scope_info->scope_type() == CATCH_SCOPE) {
       ASSERT(current->IsCatchContext());
       Handle<String> name(String::cast(current->extension()));
       Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX),
@@ -12032,7 +12034,7 @@
                                               context,
                                               name,
                                               thrown_object);
-    } else if (scope_info->Type() == BLOCK_SCOPE) {
+    } else if (scope_info->scope_type() == BLOCK_SCOPE) {
       // Materialize the contents of the block scope into a JSObject.
       ASSERT(current->IsBlockContext());
       Handle<JSObject> block_scope_object =
@@ -12047,7 +12049,7 @@
       new_context->set_previous(*context);
       context = new_context;
     } else {
-      ASSERT(scope_info->Type() == WITH_SCOPE);
+      ASSERT(scope_info->scope_type() == WITH_SCOPE);
       ASSERT(current->IsWithContext());
       Handle<JSObject> extension(JSObject::cast(current->extension()));
       context =
@@ -13441,6 +13443,107 @@
 }
 
 
+static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
+                                           Handle<JSFunction> constructor,
+                                           Handle<Object> type_info,
+                                           Arguments* caller_args) {
+  bool holey = false;
+  bool can_use_type_feedback = true;
+  if (caller_args->length() == 1) {
+    Object* argument_one = (*caller_args)[0];
+    if (argument_one->IsSmi()) {
+      int value = Smi::cast(argument_one)->value();
+      if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
+        // the array is a dictionary in this case.
+        can_use_type_feedback = false;
+      } else if (value != 0) {
+        holey = true;
+      }
+    } else {
+      // Non-smi length argument produces a dictionary
+      can_use_type_feedback = false;
+    }
+  }
+
+  JSArray* array;
+  MaybeObject* maybe_array;
+  if (!type_info.is_null() &&
+      *type_info != isolate->heap()->undefined_value() &&
+      JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() &&
+      can_use_type_feedback) {
+    JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
+    Smi* smi = Smi::cast(cell->value());
+    ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
+    if (holey && !IsFastHoleyElementsKind(to_kind)) {
+      to_kind = GetHoleyElementsKind(to_kind);
+      // Update the allocation site info to reflect the advice alteration.
+      cell->set_value(Smi::FromInt(to_kind));
+    }
+
+    maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite(
+        *constructor, type_info);
+    if (!maybe_array->To(&array)) return maybe_array;
+  } else {
+    maybe_array = isolate->heap()->AllocateJSObject(*constructor);
+    if (!maybe_array->To(&array)) return maybe_array;
+    // We might need to transition to holey
+    ElementsKind kind = constructor->initial_map()->elements_kind();
+    if (holey && !IsFastHoleyElementsKind(kind)) {
+      kind = GetHoleyElementsKind(kind);
+      maybe_array = array->TransitionElementsKind(kind);
+      if (maybe_array->IsFailure()) return maybe_array;
+    }
+  }
+
+  maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0,
+      DONT_INITIALIZE_ARRAY_ELEMENTS);
+  if (maybe_array->IsFailure()) return maybe_array;
+  maybe_array = ArrayConstructInitializeElements(array, caller_args);
+  if (maybe_array->IsFailure()) return maybe_array;
+  return array;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
+  HandleScope scope(isolate);
+  // If we get 2 arguments then they are the stub parameters (constructor, type
+  // info).  If we get 3, then the first one is a pointer to the arguments
+  // passed by the caller.
+  Arguments empty_args(0, NULL);
+  bool no_caller_args = args.length() == 2;
+  ASSERT(no_caller_args || args.length() == 3);
+  int parameters_start = no_caller_args ? 0 : 1;
+  Arguments* caller_args = no_caller_args
+      ? &empty_args
+      : reinterpret_cast<Arguments*>(args[0]);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
+  CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
+
+  return ArrayConstructorCommon(isolate,
+                                constructor,
+                                type_info,
+                                caller_args);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) {
+  HandleScope scope(isolate);
+  Arguments empty_args(0, NULL);
+  bool no_caller_args = args.length() == 1;
+  ASSERT(no_caller_args || args.length() == 2);
+  int parameters_start = no_caller_args ? 0 : 1;
+  Arguments* caller_args = no_caller_args
+      ? &empty_args
+      : reinterpret_cast<Arguments*>(args[0]);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
+
+  return ArrayConstructorCommon(isolate,
+                                constructor,
+                                Handle<Object>::null(),
+                                caller_args);
+}
+
+
 // ----------------------------------------------------------------------------
 // Implementation of Runtime
 
diff --git a/src/runtime.h b/src/runtime.h
index 73177ea..c28972c 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -287,6 +287,8 @@
   F(GetArrayKeys, 2, 1) \
   F(MoveArrayContents, 2, 1) \
   F(EstimateNumberOfElements, 1, 1) \
+  F(ArrayConstructor, -1, 1) \
+  F(InternalArrayConstructor, -1, 1) \
   \
   /* Getters and Setters */ \
   F(LookupAccessor, 3, 1) \
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index b9dea22..c9df1fb 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -78,7 +78,7 @@
   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
 
   // Encode the flags.
-  int flags = TypeField::encode(scope->type()) |
+  int flags = ScopeTypeField::encode(scope->scope_type()) |
       CallsEvalField::encode(scope->calls_eval()) |
       LanguageModeField::encode(scope->language_mode()) |
       FunctionVariableField::encode(function_name_info) |
@@ -155,9 +155,9 @@
 }
 
 
-ScopeType ScopeInfo::Type() {
+ScopeType ScopeInfo::scope_type() {
   ASSERT(length() > 0);
-  return TypeField::decode(Flags());
+  return ScopeTypeField::decode(Flags());
 }
 
 
@@ -193,9 +193,9 @@
         FunctionVariableField::decode(Flags()) == CONTEXT;
     bool has_context = context_locals > 0 ||
         function_name_context_slot ||
-        Type() == WITH_SCOPE ||
-        (Type() == FUNCTION_SCOPE && CallsEval()) ||
-        Type() == MODULE_SCOPE;
+        scope_type() == WITH_SCOPE ||
+        (scope_type() == FUNCTION_SCOPE && CallsEval()) ||
+        scope_type() == MODULE_SCOPE;
     if (has_context) {
       return Context::MIN_CONTEXT_SLOTS + context_locals +
           (function_name_context_slot ? 1 : 0);
diff --git a/src/scopes.cc b/src/scopes.cc
index 208dc76..6ae7cc0 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -104,7 +104,7 @@
 // ----------------------------------------------------------------------------
 // Implementation of Scope
 
-Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone)
+Scope::Scope(Scope* outer_scope, ScopeType scope_type, Zone* zone)
     : isolate_(zone->isolate()),
       inner_scopes_(4, zone),
       variables_(zone),
@@ -114,19 +114,19 @@
       unresolved_(16, zone),
       decls_(4, zone),
       interface_(FLAG_harmony_modules &&
-                 (type == MODULE_SCOPE || type == GLOBAL_SCOPE)
+                 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE)
                      ? Interface::NewModule(zone) : NULL),
       already_resolved_(false),
       zone_(zone) {
-  SetDefaults(type, outer_scope, Handle<ScopeInfo>::null());
+  SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null());
   // The outermost scope must be a global scope.
-  ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL);
+  ASSERT(scope_type == GLOBAL_SCOPE || outer_scope != NULL);
   ASSERT(!HasIllegalRedeclaration());
 }
 
 
 Scope::Scope(Scope* inner_scope,
-             ScopeType type,
+             ScopeType scope_type,
              Handle<ScopeInfo> scope_info,
              Zone* zone)
     : isolate_(Isolate::Current()),
@@ -140,7 +140,7 @@
       interface_(NULL),
       already_resolved_(true),
       zone_(zone) {
-  SetDefaults(type, NULL, scope_info);
+  SetDefaults(scope_type, NULL, scope_info);
   if (!scope_info.is_null()) {
     num_heap_slots_ = scope_info_->ContextLength();
   }
@@ -177,11 +177,11 @@
 }
 
 
-void Scope::SetDefaults(ScopeType type,
+void Scope::SetDefaults(ScopeType scope_type,
                         Scope* outer_scope,
                         Handle<ScopeInfo> scope_info) {
   outer_scope_ = outer_scope;
-  type_ = type;
+  scope_type_ = scope_type;
   scope_name_ = isolate_->factory()->empty_string();
   dynamics_ = NULL;
   receiver_ = NULL;
@@ -780,8 +780,8 @@
 
 
 #ifdef DEBUG
-static const char* Header(ScopeType type) {
-  switch (type) {
+static const char* Header(ScopeType scope_type) {
+  switch (scope_type) {
     case EVAL_SCOPE: return "eval";
     case FUNCTION_SCOPE: return "function";
     case MODULE_SCOPE: return "module";
@@ -855,7 +855,7 @@
   int n1 = n0 + 2;  // indentation
 
   // Print header.
-  Indent(n0, Header(type_));
+  Indent(n0, Header(scope_type_));
   if (scope_name_->length() > 0) {
     PrintF(" ");
     PrintName(scope_name_);
diff --git a/src/scopes.h b/src/scopes.h
index 66384a1..06aaa90 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -97,7 +97,7 @@
   // ---------------------------------------------------------------------------
   // Construction
 
-  Scope(Scope* outer_scope, ScopeType type, Zone* zone);
+  Scope(Scope* outer_scope, ScopeType scope_type, Zone* zone);
 
   // Compute top scope and allocate variables. For lazy compilation the top
   // scope only contains the single lazily compiled function, so this
@@ -282,13 +282,13 @@
   // Predicates.
 
   // Specific scope types.
-  bool is_eval_scope() const { return type_ == EVAL_SCOPE; }
-  bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
-  bool is_module_scope() const { return type_ == MODULE_SCOPE; }
-  bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
-  bool is_catch_scope() const { return type_ == CATCH_SCOPE; }
-  bool is_block_scope() const { return type_ == BLOCK_SCOPE; }
-  bool is_with_scope() const { return type_ == WITH_SCOPE; }
+  bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
+  bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
+  bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
+  bool is_global_scope() const { return scope_type_ == GLOBAL_SCOPE; }
+  bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
+  bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; }
+  bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
   bool is_declaration_scope() const {
     return is_eval_scope() || is_function_scope() ||
         is_module_scope() || is_global_scope();
@@ -321,7 +321,7 @@
   // Accessors.
 
   // The type of this scope.
-  ScopeType type() const { return type_; }
+  ScopeType scope_type() const { return scope_type_; }
 
   // The language mode of this scope.
   LanguageMode language_mode() const { return language_mode_; }
@@ -449,7 +449,7 @@
   ZoneList<Scope*> inner_scopes_;  // the immediately enclosed inner scopes
 
   // The scope type.
-  ScopeType type_;
+  ScopeType scope_type_;
 
   // Debugging support.
   Handle<String> scope_name_;
diff --git a/src/typedarray.js b/src/typedarray.js
index 4fade00..04c487f 100644
--- a/src/typedarray.js
+++ b/src/typedarray.js
@@ -94,7 +94,7 @@
       } else if (!IS_UNDEFINED(arg1)){
         ConstructByArrayLike(this, arg1);
       } else {
-        throw MakeTypeError("parameterless_typed_array_constr", name);
+        throw MakeTypeError("parameterless_typed_array_constr", [name]);
       }
     } else {
       return new constructor(arg1, arg2, arg3);
diff --git a/src/types.cc b/src/types.cc
new file mode 100644
index 0000000..2a96055
--- /dev/null
+++ b/src/types.cc
@@ -0,0 +1,281 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "types.h"
+
+namespace v8 {
+namespace internal {
+
+// Get the smallest bitset subsuming this type.
+int Type::LubBitset() {
+  if (this->is_bitset()) {
+    return this->as_bitset();
+  } else if (this->is_union()) {
+    Handle<Unioned> unioned = this->as_union();
+    int bitset = kNone;
+    for (int i = 0; i < unioned->length(); ++i) {
+      bitset |= union_get(unioned, i)->LubBitset();
+    }
+    return bitset;
+  } else {
+    Map* map =
+        this->is_class() ? *this->as_class() : this->as_constant()->map();
+    switch (map->instance_type()) {
+      case STRING_TYPE:
+      case ASCII_STRING_TYPE:
+      case CONS_STRING_TYPE:
+      case CONS_ASCII_STRING_TYPE:
+      case SLICED_STRING_TYPE:
+      case EXTERNAL_STRING_TYPE:
+      case EXTERNAL_ASCII_STRING_TYPE:
+      case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
+      case SHORT_EXTERNAL_STRING_TYPE:
+      case SHORT_EXTERNAL_ASCII_STRING_TYPE:
+      case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
+      case INTERNALIZED_STRING_TYPE:
+      case ASCII_INTERNALIZED_STRING_TYPE:
+      case CONS_INTERNALIZED_STRING_TYPE:
+      case CONS_ASCII_INTERNALIZED_STRING_TYPE:
+      case EXTERNAL_INTERNALIZED_STRING_TYPE:
+      case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
+      case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
+      case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
+      case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
+      case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
+        return kString;
+      case SYMBOL_TYPE:
+        return kSymbol;
+      case ODDBALL_TYPE:
+        return kOddball;
+      case HEAP_NUMBER_TYPE:
+        return kDouble;
+      case JS_VALUE_TYPE:
+      case JS_DATE_TYPE:
+      case JS_OBJECT_TYPE:
+      case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
+      case JS_GENERATOR_OBJECT_TYPE:
+      case JS_MODULE_TYPE:
+      case JS_GLOBAL_OBJECT_TYPE:
+      case JS_BUILTINS_OBJECT_TYPE:
+      case JS_GLOBAL_PROXY_TYPE:
+      case JS_ARRAY_BUFFER_TYPE:
+      case JS_TYPED_ARRAY_TYPE:
+      case JS_WEAK_MAP_TYPE:
+      case JS_REGEXP_TYPE:
+        return kOtherObject;
+      case JS_ARRAY_TYPE:
+        return kArray;
+      case JS_FUNCTION_TYPE:
+        return kFunction;
+      case JS_PROXY_TYPE:
+      case JS_FUNCTION_PROXY_TYPE:
+        return kProxy;
+      default:
+        UNREACHABLE();
+        return kNone;
+    }
+  }
+}
+
+
+// Get the largest bitset subsumed by this type.
+int Type::GlbBitset() {
+  if (this->is_bitset()) {
+    return this->as_bitset();
+  } else if (this->is_union()) {
+    // All but the first are non-bitsets and thus would yield kNone anyway.
+    return union_get(this->as_union(), 0)->GlbBitset();
+  } else {
+    return kNone;
+  }
+}
+
+
+// Check this <= that.
+bool Type::Is(Handle<Type> that) {
+  // Fast path for bitsets.
+  if (that->is_bitset()) {
+    return (this->LubBitset() | that->as_bitset()) == that->as_bitset();
+  }
+
+  if (that->is_class()) {
+    return this->is_class() && *this->as_class() == *that->as_class();
+  }
+  if (that->is_constant()) {
+    return this->is_constant() && *this->as_constant() == *that->as_constant();
+  }
+
+  // (T1 \/ ... \/ Tn) <= T  <=>  (T1 <= T) /\ ... /\ (Tn <= T)
+  if (this->is_union()) {
+    Handle<Unioned> unioned = this->as_union();
+    for (int i = 0; i < unioned->length(); ++i) {
+      Handle<Type> this_i = union_get(unioned, i);
+      if (!this_i->Is(that)) return false;
+    }
+    return true;
+  }
+
+  // T <= (T1 \/ ... \/ Tn)  <=>  (T <= T1) \/ ... \/ (T <= Tn)
+  // (iff T is not a union)
+  if (that->is_union()) {
+    Handle<Unioned> unioned = that->as_union();
+    for (int i = 0; i < unioned->length(); ++i) {
+      Handle<Type> that_i = union_get(unioned, i);
+      if (this->Is(that_i)) return true;
+      if (this->is_bitset()) break;  // Fast fail, no other field is a bitset.
+    }
+    return false;
+  }
+
+  return false;
+}
+
+
+// Check this overlaps that.
+bool Type::Maybe(Handle<Type> that) {
+  // Fast path for bitsets.
+  if (this->is_bitset()) {
+    return (this->as_bitset() & that->LubBitset()) != 0;
+  }
+  if (that->is_bitset()) {
+    return (this->LubBitset() & that->as_bitset()) != 0;
+  }
+
+  if (this->is_class()) {
+    return that->is_class() && *this->as_class() == *that->as_class();
+  }
+  if (this->is_constant()) {
+    return that->is_constant() && *this->as_constant() == *that->as_constant();
+  }
+
+  // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
+  if (this->is_union()) {
+    Handle<Unioned> unioned = this->as_union();
+    for (int i = 0; i < unioned->length(); ++i) {
+      Handle<Type> this_i = union_get(unioned, i);
+      if (this_i->Maybe(that)) return true;
+    }
+    return false;
+  }
+
+  // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
+  if (that->is_union()) {
+    Handle<Unioned> unioned = that->as_union();
+    for (int i = 0; i < unioned->length(); ++i) {
+      Handle<Type> that_i = union_get(unioned, i);
+      if (this->Maybe(that_i)) return true;
+    }
+    return false;
+  }
+
+  return false;
+}
+
+
+bool Type::InUnion(Handle<Unioned> unioned, int current_size) {
+  ASSERT(!this->is_union());
+  for (int i = 0; i < current_size; ++i) {
+    Handle<Type> type = union_get(unioned, i);
+    if (type->is_bitset() ? this->Is(type) : this == *type) return true;
+  }
+  return false;
+}
+
+// Get non-bitsets from this which are not subsumed by that, store at unioned,
+// starting at index. Returns updated index.
+int Type::ExtendUnion(Handle<Unioned> result, int current_size) {
+  int old_size = current_size;
+  if (this->is_class() || this->is_constant()) {
+    if (!this->InUnion(result, old_size)) result->set(current_size++, this);
+  } else if (this->is_union()) {
+    Handle<Unioned> unioned = this->as_union();
+    for (int i = 0; i < unioned->length(); ++i) {
+      Handle<Type> type = union_get(unioned, i);
+      ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0))));
+      if (type->is_bitset()) continue;
+      if (!type->InUnion(result, old_size)) result->set(current_size++, *type);
+    }
+  }
+  return current_size;
+}
+
+
+// Union is O(1) on simple bit unions, but O(n*m) on structured unions.
+// TODO(rossberg): Should we use object sets somehow? Is it worth it?
+Type* Type::Union(Handle<Type> type1, Handle<Type> type2) {
+  // Fast case: bit sets.
+  if (type1->is_bitset() && type2->is_bitset()) {
+    return from_bitset(type1->as_bitset() | type2->as_bitset());
+  }
+
+  // Semi-fast case: Unioned objects are neither involved nor produced.
+  if (!(type1->is_union() || type2->is_union())) {
+    if (type1->Is(type2)) return *type2;
+    if (type2->Is(type1)) return *type1;
+  }
+
+  // Slow case: may need to produce a Unioned object.
+  Isolate* isolate = NULL;
+  int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0;
+  if (!type1->is_bitset()) {
+    isolate = HeapObject::cast(*type1)->GetIsolate();
+    size += (type1->is_union() ? type1->as_union()->length() : 1);
+  }
+  if (!type2->is_bitset()) {
+    isolate = HeapObject::cast(*type2)->GetIsolate();
+    size += (type2->is_union() ? type2->as_union()->length() : 1);
+  }
+  ASSERT(isolate != NULL);
+  ASSERT(size >= 2);
+  Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
+  size = 0;
+
+  int bitset = type1->GlbBitset() | type2->GlbBitset();
+  if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
+  size = type1->ExtendUnion(unioned, size);
+  size = type2->ExtendUnion(unioned, size);
+
+  if (size == 1) {
+    return *union_get(unioned, 0);
+  } else if (size == unioned->length()) {
+    return from_handle(unioned);
+  }
+
+  // There was an overlap. Copy to smaller union.
+  Handle<Unioned> result = isolate->factory()->NewFixedArray(size);
+  for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
+  return from_handle(result);
+}
+
+
+Type* Type::Optional(Handle<Type> type) {
+  return type->is_bitset()
+      ? from_bitset(type->as_bitset() | kUndefined)
+      : Union(type, Undefined()->handle_via_isolate_of(*type));
+}
+
+} }  // namespace v8::internal
diff --git a/src/types.h b/src/types.h
new file mode 100644
index 0000000..018969f
--- /dev/null
+++ b/src/types.h
@@ -0,0 +1,200 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_TYPES_H_
+#define V8_TYPES_H_
+
+#include "v8.h"
+
+#include "objects.h"
+
+namespace v8 {
+namespace internal {
+
+
+// A simple type system for compiler-internal use. It is based entirely on
+// union types, and all subtyping hence amounts to set inclusion. Besides the
+// obvious primitive types and some predefined unions, the type language also
+// can express class types (a.k.a. specific maps) and singleton types (i.e.,
+// concrete constants).
+//
+// The following equations and inequations hold:
+//
+//   None <= T
+//   T <= Any
+//
+//   Oddball = Boolean \/ Null \/ Undefined
+//   Number = Smi \/ Double
+//   Name = String \/ Symbol
+//   UniqueName = InternalizedString \/ Symbol
+//   InternalizedString < String
+//
+//   Receiver = Object \/ Proxy
+//   Array < Object
+//   Function < Object
+//
+//   Class(map) < T   iff instance_type(map) < T
+//   Constant(x) < T  iff instance_type(map(x)) < T
+//
+// Note that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
+// change! (Its instance type cannot, however.)
+// TODO(rossberg): the latter is not currently true for proxies, because of fix,
+// but will hold once we implement direct proxies.
+//
+// There are two main functions for testing types:
+//
+//   T1->Is(T2)     -- tests whether T1 is included in T2 (i.e., T1 <= T2)
+//   T1->Maybe(T2)  -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
+//
+// Typically, the latter should be used to check whether a specific case needs
+// handling (e.g., via T->Maybe(Number)).
+//
+// There is no functionality to discover whether a type is a leaf in the
+// lattice. That is intentional. It should always be possible to refine the
+// lattice (e.g., splitting up number types further) without invalidating any
+// existing assumptions or tests.
+//
+// Internally, all 'primitive' types, and their unions, are represented as
+// bitsets via smis. Class and Constant are heap pointers to the respective
+// argument. Only unions containing Class'es or Constant's require allocation.
+//
+// The type representation is heap-allocated, so cannot (currently) be used in
+// a parallel compilation context.
+
+class Type : public Object {
+ public:
+  static Type* None() { return from_bitset(kNone); }
+  static Type* Any() { return from_bitset(kAny); }
+
+  static Type* Oddball() { return from_bitset(kOddball); }
+  static Type* Boolean() { return from_bitset(kBoolean); }
+  static Type* Null() { return from_bitset(kNull); }
+  static Type* Undefined() { return from_bitset(kUndefined); }
+
+  static Type* Number() { return from_bitset(kNumber); }
+  static Type* Smi() { return from_bitset(kSmi); }
+  static Type* Double() { return from_bitset(kDouble); }
+
+  static Type* Name() { return from_bitset(kName); }
+  static Type* UniqueName() { return from_bitset(kUniqueName); }
+  static Type* String() { return from_bitset(kString); }
+  static Type* InternalizedString() { return from_bitset(kInternalizedString); }
+  static Type* Symbol() { return from_bitset(kSymbol); }
+
+  static Type* Receiver() { return from_bitset(kReceiver); }
+  static Type* Object() { return from_bitset(kObject); }
+  static Type* Array() { return from_bitset(kArray); }
+  static Type* Function() { return from_bitset(kFunction); }
+  static Type* Proxy() { return from_bitset(kProxy); }
+
+  static Type* Class(Handle<Map> map) { return from_handle(map); }
+  static Type* Constant(Handle<HeapObject> value) {
+    ASSERT(!value->IsMap() && !value->IsFixedArray());
+    return from_handle(value);
+  }
+
+  static Type* Union(Handle<Type> type1, Handle<Type> type2);
+  static Type* Optional(Handle<Type> type);  // type \/ Undefined
+
+  bool Is(Handle<Type> that);
+  bool Maybe(Handle<Type> that);
+
+  // TODO(rossberg): method to iterate unions?
+
+ private:
+  // A union is a fixed array containing types. Invariants:
+  // - its length is at least 2
+  // - at most one field is a bitset, and it must go into index 0
+  // - no field is a union
+  typedef FixedArray Unioned;
+
+  enum {
+    kNull = 1 << 0,
+    kUndefined = 1 << 1,
+    kBoolean = 1 << 2,
+    kSmi = 1 << 3,
+    kDouble = 1 << 4,
+    kSymbol = 1 << 5,
+    kInternalizedString = 1 << 6,
+    kOtherString = 1 << 7,
+    kArray = 1 << 8,
+    kFunction = 1 << 9,
+    kOtherObject = 1 << 10,
+    kProxy = 1 << 11,
+
+    kOddball = kBoolean | kNull | kUndefined,
+    kNumber = kSmi | kDouble,
+    kString = kInternalizedString | kOtherString,
+    kUniqueName = kSymbol | kInternalizedString,
+    kName = kSymbol | kString,
+    kObject = kArray | kFunction | kOtherObject,
+    kReceiver = kObject | kProxy,
+    kAny = kOddball | kNumber | kName | kReceiver,
+    kNone = 0
+  };
+
+  bool is_bitset() { return this->IsSmi(); }
+  bool is_class() { return this->IsMap(); }
+  bool is_constant() { return !(is_bitset() || is_class() || is_union()); }
+  bool is_union() { return this->IsFixedArray(); }
+
+  int as_bitset() { return Smi::cast(this)->value(); }
+  Handle<Map> as_class() { return Handle<Map>::cast(handle()); }
+  Handle<HeapObject> as_constant() {
+    ASSERT(is_constant());
+    return Handle<HeapObject>::cast(handle());
+  }
+  Handle<Unioned> as_union() { return Handle<Unioned>::cast(handle()); }
+
+  Handle<Type> handle() { return handle_via_isolate_of(this); }
+  Handle<Type> handle_via_isolate_of(Type* type) {
+    ASSERT(type->IsHeapObject());
+    return v8::internal::handle(this, HeapObject::cast(type)->GetIsolate());
+  }
+
+  static Type* from_bitset(int bitset) {
+    return static_cast<Type*>(Object::cast(Smi::FromInt(bitset)));
+  }
+  static Type* from_handle(Handle<HeapObject> handle) {
+    return static_cast<Type*>(Object::cast(*handle));
+  }
+
+  static Handle<Type> union_get(Handle<Unioned> unioned, int i) {
+    Type* type = static_cast<Type*>(unioned->get(i));
+    ASSERT(!type->is_union());
+    return type->handle_via_isolate_of(from_handle(unioned));
+  }
+
+  int LubBitset();  // least upper bound that's a bitset
+  int GlbBitset();  // greatest lower bound that's a bitset
+  bool InUnion(Handle<Unioned> unioned, int current_size);
+  int ExtendUnion(Handle<Unioned> unioned, int current_size);
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_TYPES_H_
diff --git a/src/typing.cc b/src/typing.cc
index c2d418f..3e4144e 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -27,7 +27,6 @@
 
 #include "typing.h"
 
-#include "v8.h"
 #include "parser.h"  // for CompileTimeValue; TODO(rossberg): should move
 #include "scopes.h"
 
diff --git a/src/version.cc b/src/version.cc
index 82ed285..bfb413f 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     19
-#define BUILD_NUMBER      9
-#define PATCH_LEVEL       2
+#define BUILD_NUMBER      10
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index f5d38f3..bc2e59a 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -30,7 +30,6 @@
 #if defined(V8_TARGET_ARCH_X64)
 
 #include "bootstrapper.h"
-#include "builtins-decls.h"
 #include "code-stubs.h"
 #include "regexp-macro-assembler.h"
 #include "stub-cache.h"
@@ -133,7 +132,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(ArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
 }
 
 
@@ -155,7 +154,7 @@
   descriptor->register_params_ = registers;
   descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
   descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
+      Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
 }
 
 
@@ -6756,17 +6755,17 @@
 
   // Calculate the original stack pointer and store it in the second arg.
 #ifdef _WIN64
-  __ lea(rdx, Operand(rsp, kNumSavedRegisters * kPointerSize));
+  __ lea(rdx, Operand(rsp, (kNumSavedRegisters + 1) * kPointerSize));
 #else
-  __ lea(rsi, Operand(rsp, kNumSavedRegisters * kPointerSize));
+  __ lea(rsi, Operand(rsp, (kNumSavedRegisters + 1) * kPointerSize));
 #endif
 
   // Calculate the function address to the first arg.
 #ifdef _WIN64
-  __ movq(rcx, Operand(rdx, 0));
+  __ movq(rcx, Operand(rsp, kNumSavedRegisters * kPointerSize));
   __ subq(rcx, Immediate(Assembler::kShortCallInstructionLength));
 #else
-  __ movq(rdi, Operand(rsi, 0));
+  __ movq(rdi, Operand(rsp, kNumSavedRegisters * kPointerSize));
   __ subq(rdi, Immediate(Assembler::kShortCallInstructionLength));
 #endif
 
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 012dcc8..4a4a84e 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -226,101 +226,6 @@
 }
 
 
-void RegExpMacroAssemblerX64::CheckCharacters(Vector<const uc16> str,
-                                              int cp_offset,
-                                              Label* on_failure,
-                                              bool check_end_of_string) {
-#ifdef DEBUG
-  // If input is ASCII, don't even bother calling here if the string to
-  // match contains a non-ASCII character.
-  if (mode_ == ASCII) {
-    ASSERT(String::IsOneByte(str.start(), str.length()));
-  }
-#endif
-  int byte_length = str.length() * char_size();
-  int byte_offset = cp_offset * char_size();
-  if (check_end_of_string) {
-    // Check that there are at least str.length() characters left in the input.
-    __ cmpl(rdi, Immediate(-(byte_offset + byte_length)));
-    BranchOrBacktrack(greater, on_failure);
-  }
-
-  if (on_failure == NULL) {
-    // Instead of inlining a backtrack, (re)use the global backtrack target.
-    on_failure = &backtrack_label_;
-  }
-
-  // Do one character test first to minimize loading for the case that
-  // we don't match at all (loading more than one character introduces that
-  // chance of reading unaligned and reading across cache boundaries).
-  // If the first character matches, expect a larger chance of matching the
-  // string, and start loading more characters at a time.
-  if (mode_ == ASCII) {
-    __ cmpb(Operand(rsi, rdi, times_1, byte_offset),
-            Immediate(static_cast<int8_t>(str[0])));
-  } else {
-    // Don't use 16-bit immediate. The size changing prefix throws off
-    // pre-decoding.
-    __ movzxwl(rax,
-               Operand(rsi, rdi, times_1, byte_offset));
-    __ cmpl(rax, Immediate(static_cast<int32_t>(str[0])));
-  }
-  BranchOrBacktrack(not_equal, on_failure);
-
-  __ lea(rbx, Operand(rsi, rdi, times_1, 0));
-  for (int i = 1, n = str.length(); i < n; ) {
-    if (mode_ == ASCII) {
-      if (i + 8 <= n) {
-        uint64_t combined_chars =
-            (static_cast<uint64_t>(str[i + 0]) << 0) ||
-            (static_cast<uint64_t>(str[i + 1]) << 8) ||
-            (static_cast<uint64_t>(str[i + 2]) << 16) ||
-            (static_cast<uint64_t>(str[i + 3]) << 24) ||
-            (static_cast<uint64_t>(str[i + 4]) << 32) ||
-            (static_cast<uint64_t>(str[i + 5]) << 40) ||
-            (static_cast<uint64_t>(str[i + 6]) << 48) ||
-            (static_cast<uint64_t>(str[i + 7]) << 56);
-        __ movq(rax, combined_chars, RelocInfo::NONE64);
-        __ cmpq(rax, Operand(rbx, byte_offset + i));
-        i += 8;
-      } else if (i + 4 <= n) {
-        uint32_t combined_chars =
-            (static_cast<uint32_t>(str[i + 0]) << 0) ||
-            (static_cast<uint32_t>(str[i + 1]) << 8) ||
-            (static_cast<uint32_t>(str[i + 2]) << 16) ||
-            (static_cast<uint32_t>(str[i + 3]) << 24);
-        __ cmpl(Operand(rbx, byte_offset + i), Immediate(combined_chars));
-        i += 4;
-      } else {
-        __ cmpb(Operand(rbx, byte_offset + i),
-                Immediate(static_cast<int8_t>(str[i])));
-        i++;
-      }
-    } else {
-      ASSERT(mode_ == UC16);
-      if (i + 4 <= n) {
-        uint64_t combined_chars = *reinterpret_cast<const uint64_t*>(&str[i]);
-        __ movq(rax, combined_chars, RelocInfo::NONE64);
-        __ cmpq(rax,
-                Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)));
-        i += 4;
-      } else if (i + 2 <= n) {
-        uint32_t combined_chars = *reinterpret_cast<const uint32_t*>(&str[i]);
-        __ cmpl(Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)),
-                Immediate(combined_chars));
-        i += 2;
-      } else {
-        __ movzxwl(rax,
-                   Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)));
-        __ cmpl(rax, Immediate(str[i]));
-        i++;
-      }
-    }
-    BranchOrBacktrack(not_equal, on_failure);
-  }
-}
-
-
 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
   Label fallthrough;
   __ cmpl(rdi, Operand(backtrack_stackpointer(), 0));
diff --git a/src/x64/regexp-macro-assembler-x64.h b/src/x64/regexp-macro-assembler-x64.h
index 296c866..b230ea4 100644
--- a/src/x64/regexp-macro-assembler-x64.h
+++ b/src/x64/regexp-macro-assembler-x64.h
@@ -55,10 +55,6 @@
                                       Label* on_equal);
   virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
   virtual void CheckCharacterLT(uc16 limit, Label* on_less);
-  virtual void CheckCharacters(Vector<const uc16> str,
-                               int cp_offset,
-                               Label* on_failure,
-                               bool check_end_of_string);
   // A "greedy loop" is a loop that is both greedy and with a simple
   // body. It has a particularly simple implementation.
   virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index 0a91ed5..75e4158 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -99,6 +99,7 @@
         'test-strtod.cc',
         'test-thread-termination.cc',
         'test-threads.cc',
+        'test-types.cc',
         'test-unbound-queue.cc',
         'test-utils.cc',
         'test-version.cc',
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
old mode 100644
new mode 100755
index cb3a38e..d514b1e
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -2007,88 +2007,90 @@
 
 v8::Handle<v8::Object> bottom;
 
-static v8::Handle<Value> CheckThisIndexedPropertyHandler(
+static void CheckThisIndexedPropertyHandler(
     uint32_t index,
-    const AccessorInfo& info) {
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CheckReturnValue(info);
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<Value>();
 }
 
-static v8::Handle<Value> CheckThisNamedPropertyHandler(
+static void CheckThisNamedPropertyHandler(
     Local<String> name,
-    const AccessorInfo& info) {
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CheckReturnValue(info);
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<Value>();
 }
 
-
-v8::Handle<Value> CheckThisIndexedPropertySetter(uint32_t index,
-                                                 Local<Value> value,
-                                                 const AccessorInfo& info) {
-  ApiTestFuzzer::Fuzz();
-  CHECK(info.This()->Equals(bottom));
-  return v8::Handle<Value>();
-}
-
-
-v8::Handle<Value> CheckThisNamedPropertySetter(Local<String> property,
-                                               Local<Value> value,
-                                               const AccessorInfo& info) {
-  ApiTestFuzzer::Fuzz();
-  CHECK(info.This()->Equals(bottom));
-  return v8::Handle<Value>();
-}
-
-v8::Handle<v8::Integer> CheckThisIndexedPropertyQuery(
+void CheckThisIndexedPropertySetter(
     uint32_t index,
-    const AccessorInfo& info) {
+    Local<Value> value,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CheckReturnValue(info);
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Integer>();
 }
 
 
-v8::Handle<v8::Integer> CheckThisNamedPropertyQuery(Local<String> property,
-                                                    const AccessorInfo& info) {
-  ApiTestFuzzer::Fuzz();
-  CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Integer>();
-}
-
-
-v8::Handle<v8::Boolean> CheckThisIndexedPropertyDeleter(
-    uint32_t index,
-    const AccessorInfo& info) {
-  ApiTestFuzzer::Fuzz();
-  CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Boolean>();
-}
-
-
-v8::Handle<v8::Boolean> CheckThisNamedPropertyDeleter(
+void CheckThisNamedPropertySetter(
     Local<String> property,
-    const AccessorInfo& info) {
+    Local<Value> value,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CheckReturnValue(info);
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Boolean>();
+}
+
+void CheckThisIndexedPropertyQuery(
+    uint32_t index,
+    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+  CheckReturnValue(info);
+  ApiTestFuzzer::Fuzz();
+  CHECK(info.This()->Equals(bottom));
 }
 
 
-v8::Handle<v8::Array> CheckThisIndexedPropertyEnumerator(
-    const AccessorInfo& info) {
+void CheckThisNamedPropertyQuery(
+    Local<String> property,
+    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+  CheckReturnValue(info);
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Array>();
 }
 
 
-v8::Handle<v8::Array> CheckThisNamedPropertyEnumerator(
-    const AccessorInfo& info) {
+void CheckThisIndexedPropertyDeleter(
+    uint32_t index,
+    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+  CheckReturnValue(info);
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
-  return v8::Handle<v8::Array>();
+}
+
+
+void CheckThisNamedPropertyDeleter(
+    Local<String> property,
+    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+  CheckReturnValue(info);
+  ApiTestFuzzer::Fuzz();
+  CHECK(info.This()->Equals(bottom));
+}
+
+
+void CheckThisIndexedPropertyEnumerator(
+    const v8::PropertyCallbackInfo<v8::Array>& info) {
+  CheckReturnValue(info);
+  ApiTestFuzzer::Fuzz();
+  CHECK(info.This()->Equals(bottom));
+}
+
+
+void CheckThisNamedPropertyEnumerator(
+    const v8::PropertyCallbackInfo<v8::Array>& info) {
+  CheckReturnValue(info);
+  ApiTestFuzzer::Fuzz();
+  CHECK(info.This()->Equals(bottom));
 }
 
 
@@ -12085,9 +12087,10 @@
 
 
 static i::Handle<i::JSFunction>* foo_ptr = NULL;
-static int foo_count = 0;
+static int foo_entry_count = 0;
 static i::Handle<i::JSFunction>* bar_ptr = NULL;
-static int bar_count = 0;
+static int bar_entry_count = 0;
+static int bar_caller_count = 0;
 
 
 static void entry_hook(uintptr_t function,
@@ -12097,14 +12100,21 @@
   CHECK(code != NULL);
 
   if (bar_ptr != NULL && code == (*bar_ptr)->code())
-    ++bar_count;
+    ++bar_entry_count;
 
   if (foo_ptr != NULL && code == (*foo_ptr)->code())
-    ++foo_count;
+    ++foo_entry_count;
 
-  // TODO(siggi): Verify return_addr_location.
-  //     This can be done by capturing JitCodeEvents, but requires an ordered
-  //     collection.
+  // Let's check whether bar is the caller.
+  if (bar_ptr != NULL) {
+    const v8::internal::byte* caller =
+        *reinterpret_cast<v8::internal::byte**>(return_addr_location);
+
+    if ((*bar_ptr)->code()->instruction_start() <= caller &&
+        (*bar_ptr)->code()->instruction_end() > caller) {
+      ++bar_caller_count;
+    }
+  }
 }
 
 
@@ -12175,17 +12185,20 @@
   CHECK(v8::V8::SetFunctionEntryHook(NULL));
 
   // Reset the entry count to zero and set the entry hook.
-  bar_count = 0;
-  foo_count = 0;
+  bar_entry_count = 0;
+  bar_caller_count = 0;
+  foo_entry_count = 0;
   CHECK(v8::V8::SetFunctionEntryHook(entry_hook));
   RunLoopInNewEnv();
 
-  CHECK_EQ(2, bar_count);
-  CHECK_EQ(200, foo_count);
+  CHECK_EQ(2, bar_entry_count);
+  CHECK_EQ(200, bar_caller_count);
+  CHECK_EQ(200, foo_entry_count);
 
   // Clear the entry hook and count.
-  bar_count = 0;
-  foo_count = 0;
+  bar_entry_count = 0;
+  bar_caller_count = 0;
+  foo_entry_count = 0;
   v8::V8::SetFunctionEntryHook(NULL);
 
   // Clear the compilation cache to make sure we don't reuse the
@@ -12194,8 +12207,9 @@
 
   // Verify that entry hooking is now disabled.
   RunLoopInNewEnv();
-  CHECK_EQ(0u, bar_count);
-  CHECK_EQ(0u, foo_count);
+  CHECK_EQ(0u, bar_entry_count);
+  CHECK_EQ(0u, bar_caller_count);
+  CHECK_EQ(0u, foo_entry_count);
 }
 
 
@@ -16867,6 +16881,51 @@
 }
 
 
+TEST(ContainsOnlyOneByte) {
+  v8::V8::Initialize();
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::HandleScope scope(isolate);
+  // Make a buffer long enough that it won't automatically be converted.
+  const int length = 200;
+  i::SmartArrayPointer<uint16_t> string_contents(new uint16_t[length]);
+  // Set to contain only one byte.
+  for (int i = 0; i < length-1; i++) {
+    string_contents[i] = 0x41;
+  }
+  string_contents[length-1] = 0;
+  // Simple case.
+  Handle<String> string;
+  string = String::NewExternal(new TestResource(*string_contents));
+  CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
+  // Counter example.
+  string = String::NewFromTwoByte(isolate, *string_contents);
+  CHECK(string->IsOneByte() && string->ContainsOnlyOneByte());
+  // Test left right and balanced cons strings.
+  Handle<String> base = String::NewFromUtf8(isolate, "a");
+  Handle<String> left = base;
+  Handle<String> right = base;
+  for (int i = 0; i < 1000; i++) {
+    left = String::Concat(base, left);
+    right = String::Concat(right, base);
+  }
+  Handle<String> balanced = String::Concat(left, base);
+  balanced = String::Concat(balanced, right);
+  Handle<String> cons_strings[] = {left, balanced, right};
+  Handle<String> two_byte =
+      String::NewExternal(new TestResource(*string_contents));
+  for (size_t i = 0; i < ARRAY_SIZE(cons_strings); i++) {
+    // Base assumptions.
+    string = cons_strings[i];
+    CHECK(string->IsOneByte() && string->ContainsOnlyOneByte());
+    // Test left and right concatentation.
+    string = String::Concat(two_byte, cons_strings[i]);
+    CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
+    string = String::Concat(cons_strings[i], two_byte);
+    CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
+  }
+}
+
+
 // Failed access check callback that performs a GC on each invocation.
 void FailedAccessCheckCallbackGC(Local<v8::Object> target,
                                  v8::AccessType type,
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 901c116..a4a525d 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -653,12 +653,14 @@
   explicit FooAccessorsData(int min_duration_ms)
       : min_duration_ms_(min_duration_ms),
         getter_duration_(0),
-        setter_duration_(0) {}
+        setter_duration_(0),
+        getter_iterations_(0),
+        setter_iterations_(0) {}
 
   static v8::Handle<v8::Value> Getter(v8::Local<v8::String> name,
                                       const v8::AccessorInfo& info) {
     FooAccessorsData* data = fromInfo(info);
-    data->getter_duration_ = data->Wait();
+    data->getter_duration_ = data->Wait(&data->getter_iterations_);
     return v8::Int32::New(2013);
   }
 
@@ -666,20 +668,21 @@
                      v8::Local<v8::Value> value,
                      const v8::AccessorInfo& info) {
     FooAccessorsData* data = fromInfo(info);
-    data->setter_duration_ = data->Wait();
+    data->setter_duration_ = data->Wait(&data->setter_iterations_);
   }
 
   void PrintAccessorTime() {
-    i::OS::Print("getter: %f ms; setter: %f ms\n", getter_duration_,
-        setter_duration_);
+    i::OS::Print("getter: %f ms (%d); setter: %f ms (%d)\n", getter_duration_,
+        getter_iterations_, setter_duration_, setter_iterations_);
   }
 
  private:
-  double Wait() {
+  double Wait(int* iterations) {
     double start = i::OS::TimeCurrentMillis();
     double duration = 0;
     while (duration < min_duration_ms_) {
       duration = i::OS::TimeCurrentMillis() - start;
+      ++*iterations;
     }
     return duration;
   }
@@ -692,6 +695,8 @@
   int min_duration_ms_;
   double getter_duration_;
   double setter_duration_;
+  int getter_iterations_;
+  int setter_iterations_;
 };
 
 
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index b580f4b..6367c74 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -1036,7 +1036,7 @@
     CHECK_EQ(scope->inner_scopes()->length(), 1);
 
     i::Scope* inner_scope = scope->inner_scopes()->at(0);
-    CHECK_EQ(inner_scope->type(), source_data[i].scope_type);
+    CHECK_EQ(inner_scope->scope_type(), source_data[i].scope_type);
     CHECK_EQ(inner_scope->start_position(), kPrefixLen);
     // The end position of a token is one position after the last
     // character belonging to that token.
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 6bcf5f5..ac62b75 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -784,15 +784,22 @@
   ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4,
                              Isolate::Current()->runtime_zone());
 
-  uc16 foo_chars[3] = {'f', 'o', 'o'};
-  Vector<const uc16> foo(foo_chars, 3);
-
-  Label fail;
-  m.CheckCharacters(foo, 0, &fail, true);
+  Label fail, backtrack;
+  m.PushBacktrack(&fail);
+  m.CheckNotAtStart(NULL);
+  m.LoadCurrentCharacter(2, NULL);
+  m.CheckNotCharacter('o', NULL);
+  m.LoadCurrentCharacter(1, NULL, false);
+  m.CheckNotCharacter('o', NULL);
+  m.LoadCurrentCharacter(0, NULL, false);
+  m.CheckNotCharacter('f', NULL);
   m.WriteCurrentPositionToRegister(0, 0);
+  m.WriteCurrentPositionToRegister(1, 3);
   m.AdvanceCurrentPosition(3);
-  m.WriteCurrentPositionToRegister(1, 0);
+  m.PushBacktrack(&backtrack);
   m.Succeed();
+  m.Bind(&backtrack);
+  m.Backtrack();
   m.Bind(&fail);
   m.Fail();
 
@@ -842,15 +849,22 @@
   ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4,
                              Isolate::Current()->runtime_zone());
 
-  uc16 foo_chars[3] = {'f', 'o', 'o'};
-  Vector<const uc16> foo(foo_chars, 3);
-
-  Label fail;
-  m.CheckCharacters(foo, 0, &fail, true);
+  Label fail, backtrack;
+  m.PushBacktrack(&fail);
+  m.CheckNotAtStart(NULL);
+  m.LoadCurrentCharacter(2, NULL);
+  m.CheckNotCharacter('o', NULL);
+  m.LoadCurrentCharacter(1, NULL, false);
+  m.CheckNotCharacter('o', NULL);
+  m.LoadCurrentCharacter(0, NULL, false);
+  m.CheckNotCharacter('f', NULL);
   m.WriteCurrentPositionToRegister(0, 0);
+  m.WriteCurrentPositionToRegister(1, 3);
   m.AdvanceCurrentPosition(3);
-  m.WriteCurrentPositionToRegister(1, 0);
+  m.PushBacktrack(&backtrack);
   m.Succeed();
+  m.Bind(&backtrack);
+  m.Backtrack();
   m.Bind(&fail);
   m.Fail();
 
@@ -1349,36 +1363,33 @@
   RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024),
                                  Isolate::Current()->runtime_zone());
   // ^f(o)o.
-  Label fail, fail2, start;
-  uc16 foo_chars[3];
-  foo_chars[0] = 'f';
-  foo_chars[1] = 'o';
-  foo_chars[2] = 'o';
-  Vector<const uc16> foo(foo_chars, 3);
+  Label start, fail, backtrack;
+
   m.SetRegister(4, 42);
   m.PushRegister(4, RegExpMacroAssembler::kNoStackLimitCheck);
   m.AdvanceRegister(4, 42);
   m.GoTo(&start);
   m.Fail();
   m.Bind(&start);
-  m.PushBacktrack(&fail2);
-  m.CheckCharacters(foo, 0, &fail, true);
+  m.PushBacktrack(&fail);
+  m.CheckNotAtStart(NULL);
+  m.LoadCurrentCharacter(0, NULL);
+  m.CheckNotCharacter('f', NULL);
+  m.LoadCurrentCharacter(1, NULL);
+  m.CheckNotCharacter('o', NULL);
+  m.LoadCurrentCharacter(2, NULL);
+  m.CheckNotCharacter('o', NULL);
   m.WriteCurrentPositionToRegister(0, 0);
-  m.PushCurrentPosition();
+  m.WriteCurrentPositionToRegister(1, 3);
+  m.WriteCurrentPositionToRegister(2, 1);
+  m.WriteCurrentPositionToRegister(3, 2);
   m.AdvanceCurrentPosition(3);
-  m.WriteCurrentPositionToRegister(1, 0);
-  m.PopCurrentPosition();
-  m.AdvanceCurrentPosition(1);
-  m.WriteCurrentPositionToRegister(2, 0);
-  m.AdvanceCurrentPosition(1);
-  m.WriteCurrentPositionToRegister(3, 0);
+  m.PushBacktrack(&backtrack);
   m.Succeed();
-
-  m.Bind(&fail);
+  m.Bind(&backtrack);
+  m.ClearRegisters(2, 3);
   m.Backtrack();
-  m.Succeed();
-
-  m.Bind(&fail2);
+  m.Bind(&fail);
   m.PopRegister(0);
   m.Fail();
 
diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc
new file mode 100644
index 0000000..d5852e0
--- /dev/null
+++ b/test/cctest/test-types.cc
@@ -0,0 +1,521 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "cctest.h"
+#include "types.h"
+
+using namespace v8::internal;
+
+// Testing auxiliaries (breaking the Type abstraction).
+static bool IsBitset(Type* type) { return type->IsSmi(); }
+static bool IsClass(Type* type) { return type->IsMap(); }
+static bool IsUnion(Type* type) { return type->IsFixedArray(); }
+static bool IsConstant(Type* type) {
+  return !(IsBitset(type) || IsClass(type) || IsUnion(type));
+}
+
+static int AsBitset(Type* type) { return Smi::cast(type)->value(); }
+static Map* AsClass(Type* type) { return Map::cast(type); }
+static HeapObject* AsConstant(Type* type) { return HeapObject::cast(type); }
+static FixedArray* AsUnion(Type* type) { return FixedArray::cast(type); }
+
+class HandlifiedTypes {
+ public:
+  explicit HandlifiedTypes(Isolate* isolate) :
+      None(Type::None(), isolate),
+      Any(Type::Any(), isolate),
+      Oddball(Type::Oddball(), isolate),
+      Boolean(Type::Boolean(), isolate),
+      Null(Type::Null(), isolate),
+      Undefined(Type::Undefined(), isolate),
+      Number(Type::Number(), isolate),
+      Smi(Type::Smi(), isolate),
+      Double(Type::Double(), isolate),
+      Name(Type::Name(), isolate),
+      UniqueName(Type::UniqueName(), isolate),
+      String(Type::String(), isolate),
+      InternalizedString(Type::InternalizedString(), isolate),
+      Symbol(Type::Symbol(), isolate),
+      Receiver(Type::Receiver(), isolate),
+      Object(Type::Object(), isolate),
+      Array(Type::Array(), isolate),
+      Function(Type::Function(), isolate),
+      Proxy(Type::Proxy(), isolate),
+      object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
+      array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
+      isolate_(isolate) {
+    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
+    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
+    array = isolate->factory()->NewJSArray(20);
+    ObjectClass = handle(Type::Class(object_map), isolate);
+    ArrayClass = handle(Type::Class(array_map), isolate);
+    ObjectConstant1 = handle(Type::Constant(object1), isolate);
+    ObjectConstant2 = handle(Type::Constant(object2), isolate);
+    ArrayConstant = handle(Type::Constant(array), isolate);
+  }
+
+  Handle<Type> None;
+  Handle<Type> Any;
+  Handle<Type> Oddball;
+  Handle<Type> Boolean;
+  Handle<Type> Null;
+  Handle<Type> Undefined;
+  Handle<Type> Number;
+  Handle<Type> Smi;
+  Handle<Type> Double;
+  Handle<Type> Name;
+  Handle<Type> UniqueName;
+  Handle<Type> String;
+  Handle<Type> InternalizedString;
+  Handle<Type> Symbol;
+  Handle<Type> Receiver;
+  Handle<Type> Object;
+  Handle<Type> Array;
+  Handle<Type> Function;
+  Handle<Type> Proxy;
+
+  Handle<Type> ObjectClass;
+  Handle<Type> ArrayClass;
+  Handle<Type> ObjectConstant1;
+  Handle<Type> ObjectConstant2;
+  Handle<Type> ArrayConstant;
+
+  Handle<Map> object_map;
+  Handle<Map> array_map;
+
+  Handle<JSObject> object1;
+  Handle<JSObject> object2;
+  Handle<JSArray> array;
+
+  Handle<Type> Union(Handle<Type> type1, Handle<Type> type2) {
+    return handle(Type::Union(type1, type2), isolate_);
+  }
+
+ private:
+  Isolate* isolate_;
+};
+
+
+TEST(Bitset) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  HandleScope scope(isolate);
+  HandlifiedTypes T(isolate);
+
+  CHECK(IsBitset(*T.None));
+  CHECK(IsBitset(*T.Any));
+  CHECK(IsBitset(*T.String));
+  CHECK(IsBitset(*T.Object));
+
+  CHECK(IsBitset(Type::Union(T.String, T.Number)));
+  CHECK(IsBitset(Type::Union(T.String, T.Receiver)));
+  CHECK(IsBitset(Type::Optional(T.Object)));
+
+  CHECK_EQ(0, AsBitset(*T.None));
+  CHECK_EQ(AsBitset(*T.Number) | AsBitset(*T.String),
+           AsBitset(Type::Union(T.String, T.Number)));
+  CHECK_EQ(AsBitset(*T.Receiver),
+           AsBitset(Type::Union(T.Receiver, T.Object)));
+  CHECK_EQ(AsBitset(*T.String) | AsBitset(*T.Undefined),
+           AsBitset(Type::Optional(T.String)));
+}
+
+
+TEST(Class) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  HandleScope scope(isolate);
+  HandlifiedTypes T(isolate);
+
+  CHECK(IsClass(*T.ObjectClass));
+  CHECK(IsClass(*T.ArrayClass));
+
+  CHECK(*T.object_map == AsClass(*T.ObjectClass));
+  CHECK(*T.array_map == AsClass(*T.ArrayClass));
+}
+
+
+TEST(Constant) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  HandleScope scope(isolate);
+  HandlifiedTypes T(isolate);
+
+  CHECK(IsConstant(*T.ObjectConstant1));
+  CHECK(IsConstant(*T.ObjectConstant2));
+  CHECK(IsConstant(*T.ArrayConstant));
+
+  CHECK(*T.object1 == AsConstant(*T.ObjectConstant1));
+  CHECK(*T.object2 == AsConstant(*T.ObjectConstant2));
+  CHECK(*T.object1 != AsConstant(*T.ObjectConstant2));
+  CHECK(*T.array == AsConstant(*T.ArrayConstant));
+}
+
+
+static void CheckSub(Handle<Type> type1, Handle<Type> type2) {
+  CHECK(type1->Is(type2));
+  CHECK(!type2->Is(type1));
+  if (IsBitset(*type1) && IsBitset(*type2)) {
+    CHECK_NE(AsBitset(*type1), AsBitset(*type2));
+  }
+}
+
+static void CheckUnordered(Handle<Type> type1, Handle<Type> type2) {
+  CHECK(!type1->Is(type2));
+  CHECK(!type2->Is(type1));
+  if (IsBitset(*type1) && IsBitset(*type2)) {
+    CHECK_NE(AsBitset(*type1), AsBitset(*type2));
+  }
+}
+
+TEST(Is) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  HandleScope scope(isolate);
+  HandlifiedTypes T(isolate);
+
+  // Reflexivity
+  CHECK(T.None->Is(T.None));
+  CHECK(T.Any->Is(T.Any));
+  CHECK(T.Object->Is(T.Object));
+
+  CHECK(T.ObjectClass->Is(T.ObjectClass));
+  CHECK(T.ObjectConstant1->Is(T.ObjectConstant1));
+
+  // Symmetry and Transitivity
+  CheckSub(T.None, T.Number);
+  CheckSub(T.None, T.Any);
+
+  CheckSub(T.Oddball, T.Any);
+  CheckSub(T.Boolean, T.Oddball);
+  CheckSub(T.Null, T.Oddball);
+  CheckSub(T.Undefined, T.Oddball);
+  CheckUnordered(T.Boolean, T.Null);
+  CheckUnordered(T.Undefined, T.Null);
+  CheckUnordered(T.Boolean, T.Undefined);
+
+  CheckSub(T.Number, T.Any);
+  CheckSub(T.Smi, T.Number);
+  CheckSub(T.Double, T.Number);
+  CheckUnordered(T.Smi, T.Double);
+
+  CheckSub(T.Name, T.Any);
+  CheckSub(T.UniqueName, T.Any);
+  CheckSub(T.UniqueName, T.Name);
+  CheckSub(T.String, T.Name);
+  CheckSub(T.InternalizedString, T.String);
+  CheckSub(T.InternalizedString, T.UniqueName);
+  CheckSub(T.InternalizedString, T.Name);
+  CheckSub(T.Symbol, T.UniqueName);
+  CheckSub(T.Symbol, T.Name);
+  CheckUnordered(T.String, T.UniqueName);
+  CheckUnordered(T.String, T.Symbol);
+  CheckUnordered(T.InternalizedString, T.Symbol);
+
+  CheckSub(T.Receiver, T.Any);
+  CheckSub(T.Object, T.Any);
+  CheckSub(T.Object, T.Receiver);
+  CheckSub(T.Array, T.Object);
+  CheckSub(T.Function, T.Object);
+  CheckSub(T.Proxy, T.Receiver);
+  CheckUnordered(T.Object, T.Proxy);
+  CheckUnordered(T.Array, T.Function);
+
+  // Structured subtyping
+  CheckSub(T.ObjectClass, T.Object);
+  CheckSub(T.ArrayClass, T.Object);
+  CheckUnordered(T.ObjectClass, T.ArrayClass);
+
+  CheckSub(T.ObjectConstant1, T.Object);
+  CheckSub(T.ObjectConstant2, T.Object);
+  CheckSub(T.ArrayConstant, T.Object);
+  CheckSub(T.ArrayConstant, T.Array);
+  CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
+  CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
+
+  CheckUnordered(T.ObjectConstant1, T.ObjectClass);
+  CheckUnordered(T.ObjectConstant2, T.ObjectClass);
+  CheckUnordered(T.ObjectConstant1, T.ArrayClass);
+  CheckUnordered(T.ObjectConstant2, T.ArrayClass);
+  CheckUnordered(T.ArrayConstant, T.ObjectClass);
+}
+
+
+static void CheckOverlap(Handle<Type> type1, Handle<Type> type2) {
+  CHECK(type1->Maybe(type2));
+  CHECK(type2->Maybe(type1));
+  if (IsBitset(*type1) && IsBitset(*type2)) {
+    CHECK_NE(0, AsBitset(*type1) & AsBitset(*type2));
+  }
+}
+
+static void CheckDisjoint(Handle<Type> type1, Handle<Type> type2) {
+  CHECK(!type1->Is(type2));
+  CHECK(!type2->Is(type1));
+  CHECK(!type1->Maybe(type2));
+  CHECK(!type2->Maybe(type1));
+  if (IsBitset(*type1) && IsBitset(*type2)) {
+    CHECK_EQ(0, AsBitset(*type1) & AsBitset(*type2));
+  }
+}
+
+TEST(Maybe) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  HandleScope scope(isolate);
+  HandlifiedTypes T(isolate);
+
+  CheckOverlap(T.Any, T.Any);
+  CheckOverlap(T.Object, T.Object);
+
+  CheckOverlap(T.Oddball, T.Any);
+  CheckOverlap(T.Boolean, T.Oddball);
+  CheckOverlap(T.Null, T.Oddball);
+  CheckOverlap(T.Undefined, T.Oddball);
+  CheckDisjoint(T.Boolean, T.Null);
+  CheckDisjoint(T.Undefined, T.Null);
+  CheckDisjoint(T.Boolean, T.Undefined);
+
+  CheckOverlap(T.Number, T.Any);
+  CheckOverlap(T.Smi, T.Number);
+  CheckOverlap(T.Double, T.Number);
+  CheckDisjoint(T.Smi, T.Double);
+
+  CheckOverlap(T.Name, T.Any);
+  CheckOverlap(T.UniqueName, T.Any);
+  CheckOverlap(T.UniqueName, T.Name);
+  CheckOverlap(T.String, T.Name);
+  CheckOverlap(T.InternalizedString, T.String);
+  CheckOverlap(T.InternalizedString, T.UniqueName);
+  CheckOverlap(T.InternalizedString, T.Name);
+  CheckOverlap(T.Symbol, T.UniqueName);
+  CheckOverlap(T.Symbol, T.Name);
+  CheckOverlap(T.String, T.UniqueName);
+  CheckDisjoint(T.String, T.Symbol);
+  CheckDisjoint(T.InternalizedString, T.Symbol);
+
+  CheckOverlap(T.Receiver, T.Any);
+  CheckOverlap(T.Object, T.Any);
+  CheckOverlap(T.Object, T.Receiver);
+  CheckOverlap(T.Array, T.Object);
+  CheckOverlap(T.Function, T.Object);
+  CheckOverlap(T.Proxy, T.Receiver);
+  CheckDisjoint(T.Object, T.Proxy);
+  CheckDisjoint(T.Array, T.Function);
+
+  CheckOverlap(T.ObjectClass, T.Object);
+  CheckOverlap(T.ArrayClass, T.Object);
+  CheckOverlap(T.ObjectClass, T.ObjectClass);
+  CheckOverlap(T.ArrayClass, T.ArrayClass);
+  CheckDisjoint(T.ObjectClass, T.ArrayClass);
+
+  CheckOverlap(T.ObjectConstant1, T.Object);
+  CheckOverlap(T.ObjectConstant2, T.Object);
+  CheckOverlap(T.ArrayConstant, T.Object);
+  CheckOverlap(T.ArrayConstant, T.Array);
+  CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
+  CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
+  CheckDisjoint(T.ObjectConstant1, T.ArrayConstant);
+
+  CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
+  CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
+  CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
+  CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
+  CheckDisjoint(T.ArrayConstant, T.ObjectClass);
+}
+
+
+static void CheckEqual(Handle<Type> type1, Handle<Type> type2) {
+  CHECK_EQ(IsBitset(*type1), IsBitset(*type2));
+  CHECK_EQ(IsClass(*type1), IsClass(*type2));
+  CHECK_EQ(IsConstant(*type1), IsConstant(*type2));
+  CHECK_EQ(IsUnion(*type1), IsUnion(*type2));
+  if (IsBitset(*type1)) {
+    CHECK_EQ(AsBitset(*type1), AsBitset(*type2));
+  } else if (IsClass(*type1)) {
+    CHECK_EQ(AsClass(*type1), AsClass(*type2));
+  } else if (IsConstant(*type1)) {
+    CHECK_EQ(AsConstant(*type1), AsConstant(*type2));
+  } else if (IsUnion(*type1)) {
+    CHECK_EQ(AsUnion(*type1)->length(), AsUnion(*type2)->length());
+  }
+  CHECK(type1->Is(type2));
+  CHECK(type2->Is(type1));
+}
+
+TEST(Union) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  HandleScope scope(isolate);
+  HandlifiedTypes T(isolate);
+
+  // Bitset-bitset
+  CHECK(IsBitset(Type::Union(T.Object, T.Number)));
+  CHECK(IsBitset(Type::Union(T.Object, T.Object)));
+  CHECK(IsBitset(Type::Union(T.Any, T.None)));
+
+  CheckEqual(T.Union(T.None, T.Number), T.Number);
+  CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver);
+  CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number));
+  CheckSub(T.Union(T.Number, T.String), T.Any);
+
+  // Class-class
+  CHECK(IsClass(Type::Union(T.ObjectClass, T.ObjectClass)));
+  CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass)));
+
+  CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass);
+  CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass));
+  CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
+  CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
+  CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
+  CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
+  CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
+
+  // Constant-constant
+  CHECK(IsConstant(Type::Union(T.ObjectConstant1, T.ObjectConstant1)));
+  CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectConstant2)));
+
+  CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
+  CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2));
+  CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2));
+  CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
+  CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
+  CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
+  CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
+  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number);
+  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass);
+
+  // Bitset-class
+  CHECK(IsBitset(Type::Union(T.ObjectClass, T.Object)));
+  CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number)));
+
+  CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
+  CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
+  CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
+  CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
+  CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
+  CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
+  CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
+
+  // Bitset-constant
+  CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object)));
+  CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number)));
+
+  CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object);
+  CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any);
+  CheckSub(T.Union(T.ObjectConstant1, T.Smi), T.Union(T.Object, T.Number));
+  CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
+  CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
+  CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
+  CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
+
+  // Class-constant
+  CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass)));
+  CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2)));
+
+  CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
+  CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass));
+  CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass));
+  CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
+  CheckSub(
+      T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
+  CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant);
+  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
+  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
+
+  // Bitset-union
+  CHECK(IsBitset(
+      Type::Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
+  CHECK(IsUnion(
+      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
+
+  CheckEqual(
+      T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
+      T.Object);
+  CheckEqual(
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
+      T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
+  CheckSub(
+      T.Double,
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
+  CheckSub(
+      T.ObjectConstant1,
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
+  CheckSub(
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+      T.Any);
+  CheckSub(
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+      T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
+
+  // Class-union
+  CHECK(IsUnion(
+      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
+  CHECK(IsUnion(
+      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
+
+  CheckEqual(
+      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
+      T.Union(T.ObjectClass, T.ObjectConstant1));
+  CheckSub(
+      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
+      T.Object);
+  CheckEqual(
+      T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
+      T.Union(T.ArrayClass, T.ObjectConstant2));
+
+  // Constant-union
+  CHECK(IsUnion(Type::Union(
+      T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
+  CHECK(IsUnion(Type::Union(
+      T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)));
+  CHECK(IsUnion(Type::Union(
+      T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1)));
+
+  CheckEqual(
+      T.Union(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
+      T.Union(T.ObjectConstant2, T.ObjectConstant1));
+  CheckEqual(
+      T.Union(T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
+      T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
+
+  // Union-union
+  CHECK(IsBitset(
+      Type::Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array))));
+
+  CheckEqual(
+      T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1),
+              T.Union(T.ObjectConstant1, T.ObjectConstant2)),
+      T.Union(T.ObjectConstant2, T.ObjectConstant1));
+  CheckEqual(
+      T.Union(T.Union(T.ObjectConstant2, T.ArrayConstant),
+              T.Union(T.ObjectConstant1, T.ArrayConstant)),
+      T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant));
+  CheckEqual(
+      T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
+      T.Union(T.Number, T.Array));
+}
diff --git a/test/mjsunit/allocation-site-info.js b/test/mjsunit/allocation-site-info.js
index 4560531..f533d61 100644
--- a/test/mjsunit/allocation-site-info.js
+++ b/test/mjsunit/allocation-site-info.js
@@ -281,6 +281,23 @@
     obj = newarraycase_list_smiobj(2);
     assertKind(elements_kind.fast, obj);
 
+    function newarraycase_onearg(len, value) {
+      var a = new Array(len);
+      a[0] = value;
+      return a;
+    }
+
+    obj = newarraycase_onearg(5, 3.5);
+    assertKind(elements_kind.fast_double, obj);
+    obj = newarraycase_onearg(10, 5);
+    assertKind(elements_kind.fast_double, obj);
+    obj = newarraycase_onearg(0, 5);
+    assertKind(elements_kind.fast_double, obj);
+    // Now pass a length that forces the dictionary path.
+    obj = newarraycase_onearg(100000, 5);
+    assertKind(elements_kind.dictionary, obj);
+    assertTrue(obj.length == 100000);
+
     // Verify that cross context calls work
     var realmA = Realm.current();
     var realmB = Realm.create();
diff --git a/test/mjsunit/fuzz-natives-part2.js b/test/mjsunit/fuzz-natives-part2.js
index 50ca5c2..d5358af 100644
--- a/test/mjsunit/fuzz-natives-part2.js
+++ b/test/mjsunit/fuzz-natives-part2.js
@@ -162,6 +162,8 @@
   "ResolvePossiblyDirectEval": true,
   "Log": true,
   "DeclareGlobals": true,
+  "ArrayConstructor": true,
+  "InternalArrayConstructor": true,
 
   "PromoteScheduledException": true,
   "DeleteHandleScopeExtensions": true,
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 9b90cba..ed37e72 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -456,6 +456,8 @@
         '../../src/transitions.h',
         '../../src/type-info.cc',
         '../../src/type-info.h',
+        '../../src/types.cc',
+        '../../src/types.h',
         '../../src/typing.cc',
         '../../src/typing.h',
         '../../src/unbound-queue-inl.h',