Rollback trunk to 3.21.16.2

R=danno@chromium.org
BUG=

Review URL: https://codereview.chromium.org/24205004

git-svn-id: http://v8.googlecode.com/svn/trunk@16796 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/build/standalone.gypi b/build/standalone.gypi
index f183331..5c017d5 100644
--- a/build/standalone.gypi
+++ b/build/standalone.gypi
@@ -77,9 +77,6 @@
     # as errors.
     'v8_code%': 0,
 
-    # Relative path to icu.gyp from this file.
-    'icu_gyp_path': '../third_party/icu/icu.gyp',
-
     'conditions': [
       ['(v8_target_arch=="arm" and host_arch!="arm") or \
         (v8_target_arch=="mipsel" and host_arch!="mipsel") or \
diff --git a/include/v8.h b/include/v8.h
index 79f4478..de27338 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -819,7 +819,7 @@
  * value.
  */
 template<class T>
-struct V8_EXPORT Maybe {
+struct Maybe {
   Maybe() : has_value(false) {}
   explicit Maybe(T t) : has_value(true), value(t) {}
   Maybe(bool has, T t) : has_value(has), value(t) {}
@@ -2364,7 +2364,7 @@
   V8_INLINE Isolate* GetIsolate() const;
   V8_INLINE ReturnValue<T> GetReturnValue() const;
   // This shouldn't be public, but the arm compiler needs it.
-  static const int kArgsLength = 7;
+  static const int kArgsLength = 6;
 
  protected:
   friend class internal::FunctionCallbackArguments;
@@ -2375,7 +2375,6 @@
   static const int kDataIndex = -3;
   static const int kCalleeIndex = -4;
   static const int kHolderIndex = -5;
-  static const int kContextSaveIndex = -6;
 
   V8_INLINE FunctionCallbackInfo(internal::Object** implicit_args,
                    internal::Object** values,
@@ -3871,6 +3870,8 @@
 typedef void (*GCPrologueCallback)(GCType type, GCCallbackFlags flags);
 typedef void (*GCEpilogueCallback)(GCType type, GCCallbackFlags flags);
 
+typedef void (*GCCallback)();
+
 
 /**
  * Collection of V8 heap information.
@@ -4054,51 +4055,6 @@
   void SetReference(const Persistent<Object>& parent,
                     const Persistent<Value>& child);
 
-  typedef void (*GCPrologueCallback)(Isolate* isolate,
-                                     GCType type,
-                                     GCCallbackFlags flags);
-  typedef void (*GCEpilogueCallback)(Isolate* isolate,
-                                     GCType type,
-                                     GCCallbackFlags flags);
-
-  /**
-   * Enables the host application to receive a notification before a
-   * garbage collection.  Allocations are not allowed in the
-   * callback function, you therefore cannot manipulate objects (set
-   * or delete properties for example) since it is possible such
-   * operations will result in the allocation of objects. It is possible
-   * to specify the GCType filter for your callback. But it is not possible to
-   * register the same callback function two times with different
-   * GCType filters.
-   */
-  void AddGCPrologueCallback(
-      GCPrologueCallback callback, GCType gc_type_filter = kGCTypeAll);
-
-  /**
-   * This function removes callback which was installed by
-   * AddGCPrologueCallback function.
-   */
-  void RemoveGCPrologueCallback(GCPrologueCallback callback);
-
-  /**
-   * Enables the host application to receive a notification after a
-   * garbage collection.  Allocations are not allowed in the
-   * callback function, you therefore cannot manipulate objects (set
-   * or delete properties for example) since it is possible such
-   * operations will result in the allocation of objects. It is possible
-   * to specify the GCType filter for your callback. But it is not possible to
-   * register the same callback function two times with different
-   * GCType filters.
-   */
-  void AddGCEpilogueCallback(
-      GCEpilogueCallback callback, GCType gc_type_filter = kGCTypeAll);
-
-  /**
-   * This function removes callback which was installed by
-   * AddGCEpilogueCallback function.
-   */
-  void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
-
  private:
   Isolate();
   Isolate(const Isolate&);
@@ -4456,6 +4412,16 @@
   static void RemoveGCPrologueCallback(GCPrologueCallback callback);
 
   /**
+   * The function is deprecated. Please use AddGCPrologueCallback instead.
+   * Enables the host application to receive a notification before a
+   * garbage collection.  Allocations are not allowed in the
+   * callback function, you therefore cannot manipulate objects (set
+   * or delete properties for example) since it is possible such
+   * operations will result in the allocation of objects.
+   */
+  V8_DEPRECATED(static void SetGlobalGCPrologueCallback(GCCallback));
+
+  /**
    * Enables the host application to receive a notification after a
    * garbage collection.  Allocations are not allowed in the
    * callback function, you therefore cannot manipulate objects (set
@@ -4475,6 +4441,16 @@
   static void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
 
   /**
+   * The function is deprecated. Please use AddGCEpilogueCallback instead.
+   * Enables the host application to receive a notification after a
+   * major garbage collection.  Allocations are not allowed in the
+   * callback function, you therefore cannot manipulate objects (set
+   * or delete properties for example) since it is possible such
+   * operations will result in the allocation of objects.
+   */
+  V8_DEPRECATED(static void SetGlobalGCEpilogueCallback(GCCallback));
+
+  /**
    * Enables the host application to provide a mechanism to be notified
    * and perform custom logging when V8 Allocates Executable Memory.
    */
diff --git a/samples/samples.gyp b/samples/samples.gyp
index c93deca..be7b9ea 100644
--- a/samples/samples.gyp
+++ b/samples/samples.gyp
@@ -42,13 +42,13 @@
     'conditions': [
       ['v8_enable_i18n_support==1', {
         'dependencies': [
-          '<(icu_gyp_path):icui18n',
-          '<(icu_gyp_path):icuuc',
+          '<(DEPTH)/third_party/icu/icu.gyp:icui18n',
+          '<(DEPTH)/third_party/icu/icu.gyp:icuuc',
         ],
       }],
       ['OS=="win" and v8_enable_i18n_support==1', {
         'dependencies': [
-          '<(icu_gyp_path):icudata',
+          '<(DEPTH)/third_party/icu/icu.gyp:icudata',
         ],
       }],
     ],
diff --git a/src/api.cc b/src/api.cc
index 0a38fa9..71a8f4a 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -624,8 +624,7 @@
     uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
     isolate->stack_guard()->SetStackLimit(limit);
   }
-  if (constraints->is_memory_constrained().has_value &&
-      !i::FLAG_force_memory_constrained.has_value) {
+  if (constraints->is_memory_constrained().has_value) {
     isolate->set_is_memory_constrained(
         constraints->is_memory_constrained().value);
   }
@@ -2057,7 +2056,7 @@
     i::HandleScope scope(isolate_);
     i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
     i::Handle<i::String> name = isolate_->factory()->stack_string();
-    if (!i::JSReceiver::HasProperty(obj, name)) return v8::Local<Value>();
+    if (!obj->HasProperty(*name)) return v8::Local<Value>();
     i::Handle<i::Object> value = i::GetProperty(isolate_, obj, name);
     if (value.is_null()) return v8::Local<Value>();
     return v8::Utils::ToLocal(scope.CloseAndEscape(value));
@@ -3626,7 +3625,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
-  return i::JSReceiver::HasElement(self, index);
+  return self->HasElement(index);
 }
 
 
@@ -3680,8 +3679,8 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
              return false);
-  return i::JSReceiver::HasLocalProperty(
-      Utils::OpenHandle(this), Utils::OpenHandle(*key));
+  return Utils::OpenHandle(this)->HasLocalProperty(
+      *Utils::OpenHandle(*key));
 }
 
 
@@ -3814,7 +3813,7 @@
   ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   EXCEPTION_PREAMBLE(isolate);
-  i::Handle<i::JSObject> result = i::JSObject::Copy(self);
+  i::Handle<i::JSObject> result = i::Copy(self);
   has_pending_exception = result.is_null();
   EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
   return Utils::ToLocal(result);
@@ -6213,7 +6212,7 @@
   i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
   EXCEPTION_PREAMBLE(isolate);
   ENTER_V8(isolate);
-  i::Handle<i::JSObject> result = i::JSObject::Copy(paragon_handle);
+  i::Handle<i::JSObject> result = i::Copy(paragon_handle);
   has_pending_exception = result.is_null();
   EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
   return Utils::ToLocal(result);
@@ -6686,65 +6685,45 @@
 }
 
 
-void Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
-                                    GCType gc_type) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  isolate->heap()->AddGCPrologueCallback(callback, gc_type);
+void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCPrologueCallback()")) return;
+  isolate->heap()->SetGlobalGCPrologueCallback(callback);
 }
 
 
-void Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  isolate->heap()->RemoveGCPrologueCallback(callback);
-}
-
-
-void Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
-                                    GCType gc_type) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
-}
-
-
-void Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  isolate->heap()->RemoveGCEpilogueCallback(callback);
+void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::V8::SetGlobalGCEpilogueCallback()")) return;
+  isolate->heap()->SetGlobalGCEpilogueCallback(callback);
 }
 
 
 void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::AddGCPrologueCallback()")) return;
-  isolate->heap()->AddGCPrologueCallback(
-      reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
-      gc_type,
-      false);
+  isolate->heap()->AddGCPrologueCallback(callback, gc_type);
 }
 
 
 void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::RemoveGCPrologueCallback()")) return;
-  isolate->heap()->RemoveGCPrologueCallback(
-      reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
+  isolate->heap()->RemoveGCPrologueCallback(callback);
 }
 
 
 void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::AddGCEpilogueCallback()")) return;
-  isolate->heap()->AddGCEpilogueCallback(
-      reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
-      gc_type,
-      false);
+  isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
 }
 
 
 void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::RemoveGCEpilogueCallback()")) return;
-  isolate->heap()->RemoveGCEpilogueCallback(
-      reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
+  isolate->heap()->RemoveGCEpilogueCallback(callback);
 }
 
 
diff --git a/src/apinatives.js b/src/apinatives.js
index 6431901..5fb36c0 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -71,6 +71,7 @@
    (serialNumber in cache) && (cache[serialNumber] != kUninitialized);
   if (!isFunctionCached) {
     try {
+      cache[serialNumber] = null;
       var fun = %CreateApiFunction(data);
       if (name) %FunctionSetName(fun, name);
       var flags = %GetTemplateField(data, kApiFlagOffset);
diff --git a/src/arguments.h b/src/arguments.h
index f291816..c1db98b 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -237,7 +237,6 @@
   typedef FunctionCallbackInfo<Value> T;
   typedef CustomArguments<T> Super;
   static const int kArgsLength = T::kArgsLength;
-  static const int kHolderIndex = T::kHolderIndex;
 
   FunctionCallbackArguments(internal::Isolate* isolate,
       internal::Object* data,
@@ -254,7 +253,6 @@
     values[T::kDataIndex] = data;
     values[T::kCalleeIndex] = callee;
     values[T::kHolderIndex] = holder;
-    values[T::kContextSaveIndex] = isolate->heap()->the_hole_value();
     values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
     // Here the hole is set as default value.
     // It cannot escape into js as it's remove in Call below.
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 1399021..866b1c9 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -89,7 +89,6 @@
   static unsigned cache_line_size_;
 
   friend class ExternalReference;
-  friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
 };
 
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index b7a343f..f60e1f8 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -807,13 +807,12 @@
   // The following registers must be saved and restored when calling through to
   // the runtime:
   //   r0 - contains return address (beginning of patch sequence)
-  //   r1 - isolate
+  //   r1 - function object
   FrameScope scope(masm, StackFrame::MANUAL);
   __ stm(db_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit());
-  __ PrepareCallCFunction(1, 0, r2);
-  __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ PrepareCallCFunction(1, 0, r1);
   __ CallCFunction(
-      ExternalReference::get_make_code_young_function(masm->isolate()), 2);
+      ExternalReference::get_make_code_young_function(masm->isolate()), 1);
   __ ldm(ia_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit());
   __ mov(pc, r0);
 }
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 7ec7df9..cd1809f 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -2765,10 +2765,9 @@
 
   if (do_gc) {
     // Passing r0.
-    __ PrepareCallCFunction(2, 0, r1);
-    __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
+    __ PrepareCallCFunction(1, 0, r1);
     __ CallCFunction(ExternalReference::perform_gc_function(isolate),
-        2, 0);
+        1, 0);
   }
 
   ExternalReference scope_depth =
@@ -2842,7 +2841,7 @@
   // sp: stack pointer
   // fp: frame pointer
   //  Callee-saved register r4 still holds argc.
-  __ LeaveExitFrame(save_doubles_, r4, true);
+  __ LeaveExitFrame(save_doubles_, r4);
   __ mov(pc, lr);
 
   // check if we should retry or throw exception
@@ -3376,7 +3375,8 @@
     receiver = r0;
   }
 
-  StubCompiler::GenerateLoadStringLength(masm, receiver, r3, r4, &miss);
+  StubCompiler::GenerateLoadStringLength(masm, receiver, r3, r4, &miss,
+                                         support_wrapper_);
 
   __ bind(&miss);
   StubCompiler::TailCallBuiltin(
@@ -4071,7 +4071,7 @@
   DirectCEntryStub stub;
   stub.GenerateCall(masm, r7);
 
-  __ LeaveExitFrame(false, no_reg, true);
+  __ LeaveExitFrame(false, no_reg);
 
   // r0: result
   // subject: subject string (callee saved)
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 732d9f3..1bcf3e3 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -870,8 +870,7 @@
 }
 
 
-void Code::PatchPlatformCodeAge(Isolate* isolate,
-                                byte* sequence,
+void Code::PatchPlatformCodeAge(byte* sequence,
                                 Code::Age age,
                                 MarkingParity parity) {
   uint32_t young_length;
@@ -880,7 +879,7 @@
     CopyBytes(sequence, young_sequence, young_length);
     CPU::FlushICache(sequence, young_length);
   } else {
-    Code* stub = GetCodeAgeStub(isolate, age, parity);
+    Code* stub = GetCodeAgeStub(age, parity);
     CodePatcher patcher(sequence, young_length / Assembler::kInstrSize);
     patcher.masm()->add(r0, pc, Operand(-8));
     patcher.masm()->ldr(pc, MemOperand(pc, -4));
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 96a323e..59a8818 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -710,44 +710,51 @@
 
 LInstruction* LChunkBuilder::DoShift(Token::Value op,
                                      HBitwiseBinaryOperation* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
-    ASSERT(instr->left()->representation().Equals(instr->representation()));
-    ASSERT(instr->right()->representation().Equals(instr->representation()));
-    LOperand* left = UseRegisterAtStart(instr->left());
+  if (instr->representation().IsTagged()) {
+    ASSERT(instr->left()->representation().IsTagged());
+    ASSERT(instr->right()->representation().IsTagged());
 
-    HValue* right_value = instr->right();
-    LOperand* right = NULL;
-    int constant_value = 0;
-    bool does_deopt = false;
-    if (right_value->IsConstant()) {
-      HConstant* constant = HConstant::cast(right_value);
-      right = chunk_->DefineConstantOperand(constant);
-      constant_value = constant->Integer32Value() & 0x1f;
-      // Left shifts can deoptimize if we shift by > 0 and the result cannot be
-      // truncated to smi.
-      if (instr->representation().IsSmi() && constant_value > 0) {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
-      }
-    } else {
-      right = UseRegisterAtStart(right_value);
-    }
-
-    // Shift operations can only deoptimize if we do a logical shift
-    // by 0 and the result cannot be truncated to int32.
-    if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
-    }
-
-    LInstruction* result =
-        DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt));
-    return does_deopt ? AssignEnvironment(result) : result;
-  } else {
-    return DoArithmeticT(op, instr);
+    LOperand* left = UseFixed(instr->left(), r1);
+    LOperand* right = UseFixed(instr->right(), r0);
+    LArithmeticT* result = new(zone()) LArithmeticT(op, left, right);
+    return MarkAsCall(DefineFixed(result, r0), instr);
   }
+
+  ASSERT(instr->representation().IsSmiOrInteger32());
+  ASSERT(instr->left()->representation().Equals(instr->representation()));
+  ASSERT(instr->right()->representation().Equals(instr->representation()));
+  LOperand* left = UseRegisterAtStart(instr->left());
+
+  HValue* right_value = instr->right();
+  LOperand* right = NULL;
+  int constant_value = 0;
+  bool does_deopt = false;
+  if (right_value->IsConstant()) {
+    HConstant* constant = HConstant::cast(right_value);
+    right = chunk_->DefineConstantOperand(constant);
+    constant_value = constant->Integer32Value() & 0x1f;
+    // Left shifts can deoptimize if we shift by > 0 and the result cannot be
+    // truncated to smi.
+    if (instr->representation().IsSmi() && constant_value > 0) {
+      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
+    }
+  } else {
+    right = UseRegisterAtStart(right_value);
+  }
+
+  // Shift operations can only deoptimize if we do a logical shift
+  // by 0 and the result cannot be truncated to int32.
+  if (op == Token::SHR && constant_value == 0) {
+    if (FLAG_opt_safe_uint32_operations) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    } else {
+      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
+    }
+  }
+
+  LInstruction* result =
+      DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt));
+  return does_deopt ? AssignEnvironment(result) : result;
 }
 
 
@@ -756,25 +763,21 @@
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->left()->representation().IsDouble());
   ASSERT(instr->right()->representation().IsDouble());
-  if (op == Token::MOD) {
-    LOperand* left = UseFixedDouble(instr->left(), d1);
-    LOperand* right = UseFixedDouble(instr->right(), d2);
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    // We call a C function for double modulo. It can't trigger a GC. We need
-    // to use fixed result register for the call.
-    // TODO(fschneider): Allow any register as input registers.
-    return MarkAsCall(DefineFixedDouble(result, d1), instr);
-  } else {
-    LOperand* left = UseRegisterAtStart(instr->left());
-    LOperand* right = UseRegisterAtStart(instr->right());
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    return DefineAsRegister(result);
-  }
+  ASSERT(op != Token::MOD);
+  LOperand* left = UseRegisterAtStart(instr->left());
+  LOperand* right = UseRegisterAtStart(instr->right());
+  LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
+  return DefineAsRegister(result);
 }
 
 
 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
-                                           HBinaryOperation* instr) {
+                                           HArithmeticBinaryOperation* instr) {
+  ASSERT(op == Token::ADD ||
+         op == Token::DIV ||
+         op == Token::MOD ||
+         op == Token::MUL ||
+         op == Token::SUB);
   HValue* left = instr->left();
   HValue* right = instr->right();
   ASSERT(left->representation().IsTagged());
@@ -1344,34 +1347,41 @@
   if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
-    ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
 
     LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
     LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
     return DefineAsRegister(new(zone()) LBitI(left, right));
   } else {
-    return DoArithmeticT(instr->op(), instr);
+    ASSERT(instr->representation().IsTagged());
+    ASSERT(instr->left()->representation().IsTagged());
+    ASSERT(instr->right()->representation().IsTagged());
+
+    LOperand* left = UseFixed(instr->left(), r1);
+    LOperand* right = UseFixed(instr->right(), r0);
+    LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right);
+    return MarkAsCall(DefineFixed(result, r0), instr);
   }
 }
 
 
 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
+  if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::DIV, instr);
+  } else if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
     if (instr->HasPowerOf2Divisor()) {
       ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
       LOperand* value = UseRegisterAtStart(instr->left());
-      LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL);
-      return AssignEnvironment(DefineAsRegister(div));
+      LDivI* div =
+          new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL);
+      return AssignEnvironment(DefineSameAsFirst(div));
     }
     LOperand* dividend = UseRegister(instr->left());
     LOperand* divisor = UseRegister(instr->right());
     LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
     LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
     return AssignEnvironment(DefineAsRegister(div));
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::DIV, instr);
   } else {
     return DoArithmeticT(Token::DIV, instr);
   }
@@ -1492,10 +1502,17 @@
           ? AssignEnvironment(result)
           : result;
     }
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::MOD, instr);
-  } else {
+  } else if (instr->representation().IsTagged()) {
     return DoArithmeticT(Token::MOD, instr);
+  } else {
+    ASSERT(instr->representation().IsDouble());
+    // We call a C function for double modulo. It can't trigger a GC. We need
+    // to use fixed result register for the call.
+    // TODO(fschneider): Allow any register as input registers.
+    LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD,
+                                                 UseFixedDouble(left, d1),
+                                                 UseFixedDouble(right, d2));
+    return MarkAsCall(DefineFixedDouble(mod, d1), instr);
   }
 }
 
@@ -1662,6 +1679,7 @@
 
     return DoArithmeticD(Token::ADD, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::ADD, instr);
   }
 }
@@ -1865,9 +1883,11 @@
 
 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
   LOperand* string = UseRegister(instr->string());
-  LOperand* index = UseRegisterOrConstant(instr->index());
-  LOperand* value = UseRegister(instr->value());
-  return new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value);
+  LOperand* index = UseRegister(instr->index());
+  LOperand* value = UseTempRegister(instr->value());
+  LSeqStringSetChar* result =
+      new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value);
+  return DefineAsRegister(result);
 }
 
 
@@ -2020,6 +2040,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) {
+  return new(zone())
+    LIsNumberAndBranch(UseRegisterOrConstantAtStart(instr->value()));
+}
+
+
 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
   LInstruction* result = new(zone()) LCheckInstanceType(value);
@@ -2223,6 +2249,8 @@
 
 
 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
+  ElementsKind elements_kind = instr->elements_kind();
+
   if (!instr->is_external()) {
     ASSERT(instr->elements()->representation().IsTagged());
     bool needs_write_barrier = instr->NeedsWriteBarrier();
@@ -2232,19 +2260,15 @@
 
     if (instr->value()->representation().IsDouble()) {
       object = UseRegisterAtStart(instr->elements());
-      val = UseRegister(instr->value());
+      val = UseTempRegister(instr->value());
       key = UseRegisterOrConstantAtStart(instr->key());
     } else {
       ASSERT(instr->value()->representation().IsSmiOrTagged());
-      if (needs_write_barrier) {
-        object = UseTempRegister(instr->elements());
-        val = UseTempRegister(instr->value());
-        key = UseTempRegister(instr->key());
-      } else {
-        object = UseRegisterAtStart(instr->elements());
-        val = UseRegisterAtStart(instr->value());
-        key = UseRegisterOrConstantAtStart(instr->key());
-      }
+      object = UseTempRegister(instr->elements());
+      val = needs_write_barrier ? UseTempRegister(instr->value())
+          : UseRegisterAtStart(instr->value());
+      key = needs_write_barrier ? UseTempRegister(instr->key())
+          : UseRegisterOrConstantAtStart(instr->key());
     }
 
     return new(zone()) LStoreKeyed(object, key, val);
@@ -2252,13 +2276,17 @@
 
   ASSERT(
       (instr->value()->representation().IsInteger32() &&
-       (instr->elements_kind() != EXTERNAL_FLOAT_ELEMENTS) &&
-       (instr->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS)) ||
+       (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
       (instr->value()->representation().IsDouble() &&
-       ((instr->elements_kind() == EXTERNAL_FLOAT_ELEMENTS) ||
-        (instr->elements_kind() == EXTERNAL_DOUBLE_ELEMENTS))));
+       ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
+        (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->elements()->representation().IsExternal());
-  LOperand* val = UseRegister(instr->value());
+  bool val_is_temp_register =
+      elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
+      elements_kind == EXTERNAL_FLOAT_ELEMENTS;
+  LOperand* val = val_is_temp_register ? UseTempRegister(instr->value())
+      : UseRegister(instr->value());
   LOperand* key = UseRegisterOrConstantAtStart(instr->key());
   LOperand* external_pointer = UseRegister(instr->elements());
   return new(zone()) LStoreKeyed(external_pointer, key, val);
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 5eab354..98cacac 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -113,6 +113,7 @@
   V(IsConstructCallAndBranch)                   \
   V(IsObjectAndBranch)                          \
   V(IsStringAndBranch)                          \
+  V(IsNumberAndBranch)                          \
   V(IsSmiAndBranch)                             \
   V(IsUndetectableAndBranch)                    \
   V(Label)                                      \
@@ -938,6 +939,19 @@
 };
 
 
+class LIsNumberAndBranch V8_FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LIsNumberAndBranch(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch, "is-number-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsNumberAndBranch)
+};
+
+
 class LIsStringAndBranch V8_FINAL : public LControlInstruction<1, 1> {
  public:
   LIsStringAndBranch(LOperand* value, LOperand* temp) {
@@ -2105,7 +2119,7 @@
   LOperand* temp2() { return temps_[1]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -2764,7 +2778,7 @@
   LInstruction* DoArithmeticD(Token::Value op,
                               HArithmeticBinaryOperation* instr);
   LInstruction* DoArithmeticT(Token::Value op,
-                              HBinaryOperation* instr);
+                              HArithmeticBinaryOperation* instr);
 
   LPlatformChunk* chunk_;
   CompilationInfo* info_;
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 8d82303..7f65023 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1383,8 +1383,7 @@
 
 void LCodeGen::DoDivI(LDivI* instr) {
   if (instr->hydrogen()->HasPowerOf2Divisor()) {
-    const Register dividend = ToRegister(instr->left());
-    const Register result = ToRegister(instr->result());
+    Register dividend = ToRegister(instr->left());
     int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant();
     int32_t test_value = 0;
     int32_t power = 0;
@@ -1395,7 +1394,7 @@
     } else {
       // Check for (0 / -x) that will produce negative zero.
       if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-        __ cmp(dividend, Operand::Zero());
+        __ tst(dividend, Operand(dividend));
         DeoptimizeIf(eq, instr->environment());
       }
       // Check for (kMinInt / -1).
@@ -1410,26 +1409,20 @@
     if (test_value != 0) {
       if (instr->hydrogen()->CheckFlag(
           HInstruction::kAllUsesTruncatingToInt32)) {
-        __ sub(result, dividend, Operand::Zero(), SetCC);
-        __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
-        __ mov(result, Operand(result, ASR, power));
-        if (divisor > 0) __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
-        if (divisor < 0) __ rsb(result, result, Operand::Zero(), LeaveCC, gt);
+        __ cmp(dividend, Operand(0));
+        __ rsb(dividend, dividend, Operand(0), LeaveCC, lt);
+        __ mov(dividend, Operand(dividend, ASR, power));
+        if (divisor > 0) __ rsb(dividend, dividend, Operand(0), LeaveCC, lt);
+        if (divisor < 0) __ rsb(dividend, dividend, Operand(0), LeaveCC, gt);
         return;  // Don't fall through to "__ rsb" below.
       } else {
         // Deoptimize if remainder is not 0.
         __ tst(dividend, Operand(test_value));
         DeoptimizeIf(ne, instr->environment());
-        __ mov(result, Operand(dividend, ASR, power));
-        if (divisor < 0) __ rsb(result, result, Operand(0));
-      }
-    } else {
-      if (divisor < 0) {
-        __ rsb(result, dividend, Operand(0));
-      } else {
-        __ Move(result, dividend);
+        __ mov(dividend, Operand(dividend, ASR, power));
       }
     }
+    if (divisor < 0) __ rsb(dividend, dividend, Operand(0));
 
     return;
   }
@@ -1446,15 +1439,12 @@
 
   // Check for (0 / -x) that will produce negative zero.
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    Label positive;
-    if (!instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
-      // Do the test only if it hadn't be done above.
-      __ cmp(right, Operand::Zero());
-    }
-    __ b(pl, &positive);
+    Label left_not_zero;
     __ cmp(left, Operand::Zero());
-    DeoptimizeIf(eq, instr->environment());
-    __ bind(&positive);
+    __ b(ne, &left_not_zero);
+    __ cmp(right, Operand::Zero());
+    DeoptimizeIf(mi, instr->environment());
+    __ bind(&left_not_zero);
   }
 
   // Check for (kMinInt / -1).
@@ -1985,42 +1975,32 @@
 
 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
   Register string = ToRegister(instr->string());
-  LOperand* index_op = instr->index();
+  Register index = ToRegister(instr->index());
   Register value = ToRegister(instr->value());
-  Register scratch = scratch0();
   String::Encoding encoding = instr->encoding();
 
   if (FLAG_debug_code) {
-    __ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
-    __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+    __ ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset));
+    __ ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset));
 
-    __ and_(scratch, scratch,
-            Operand(kStringRepresentationMask | kStringEncodingMask));
+    __ and_(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask));
     static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
     static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
-    __ cmp(scratch, Operand(encoding == String::ONE_BYTE_ENCODING
-                            ? one_byte_seq_type : two_byte_seq_type));
+    __ cmp(ip, Operand(encoding == String::ONE_BYTE_ENCODING
+                           ? one_byte_seq_type : two_byte_seq_type));
     __ Check(eq, kUnexpectedStringType);
   }
 
-  if (index_op->IsConstantOperand()) {
-    int constant_index = ToInteger32(LConstantOperand::cast(index_op));
-    if (encoding == String::ONE_BYTE_ENCODING) {
-      __ strb(value,
-              FieldMemOperand(string, SeqString::kHeaderSize + constant_index));
-    } else {
-      __ strh(value,
-          FieldMemOperand(string, SeqString::kHeaderSize + constant_index * 2));
-    }
+  __ add(ip,
+         string,
+         Operand(SeqString::kHeaderSize - kHeapObjectTag));
+  if (encoding == String::ONE_BYTE_ENCODING) {
+    __ strb(value, MemOperand(ip, index));
   } else {
-    Register index = ToRegister(index_op);
-    if (encoding == String::ONE_BYTE_ENCODING) {
-      __ add(scratch, string, Operand(index));
-      __ strb(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
-    } else {
-      __ add(scratch, string, Operand(index, LSL, 1));
-      __ strh(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
-    }
+    // MemOperand with ip as the base register is not allowed for strh, so
+    // we do the address calculation explicitly.
+    __ add(ip, ip, Operand(index, LSL, 1));
+    __ strh(value, MemOperand(ip));
   }
 }
 
@@ -2217,6 +2197,25 @@
 }
 
 
+void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
+  Representation r = instr->hydrogen()->value()->representation();
+  if (r.IsSmiOrInteger32() || r.IsDouble()) {
+    EmitBranch(instr, al);
+  } else {
+    ASSERT(r.IsTagged());
+    Register reg = ToRegister(instr->value());
+    HType type = instr->hydrogen()->value()->type();
+    if (type.IsTaggedNumber()) {
+      EmitBranch(instr, al);
+    }
+    __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
+    __ ldr(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset));
+    __ CompareRoot(scratch0(), Heap::kHeapNumberMapRootIndex);
+    EmitBranch(instr, eq);
+  }
+}
+
+
 void LCodeGen::DoBranch(LBranch* instr) {
   Representation r = instr->hydrogen()->value()->representation();
   if (r.IsInteger32() || r.IsSmi()) {
@@ -4312,23 +4311,16 @@
 
   if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
       elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
-    Register address = scratch0();
     DwVfpRegister value(ToDoubleRegister(instr->value()));
-    if (key_is_constant) {
-      if (constant_key != 0) {
-        __ add(address, external_pointer,
-               Operand(constant_key << element_size_shift));
-      } else {
-        address = external_pointer;
-      }
-    } else {
-      __ add(address, external_pointer, Operand(key, LSL, shift_size));
-    }
+    Operand operand(key_is_constant
+                    ? Operand(constant_key << element_size_shift)
+                    : Operand(key, LSL, shift_size));
+    __ add(scratch0(), external_pointer, operand);
     if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
       __ vcvt_f32_f64(double_scratch0().low(), value);
-      __ vstr(double_scratch0().low(), address, additional_offset);
+      __ vstr(double_scratch0().low(), scratch0(), additional_offset);
     } else {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
-      __ vstr(value, address, additional_offset);
+      __ vstr(value, scratch0(), additional_offset);
     }
   } else {
     Register value(ToRegister(instr->value()));
@@ -4370,28 +4362,32 @@
 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
   DwVfpRegister value = ToDoubleRegister(instr->value());
   Register elements = ToRegister(instr->elements());
+  Register key = no_reg;
   Register scratch = scratch0();
-  DwVfpRegister double_scratch = double_scratch0();
   bool key_is_constant = instr->key()->IsConstantOperand();
+  int constant_key = 0;
 
   // Calculate the effective address of the slot in the array to store the
   // double value.
-  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
   if (key_is_constant) {
-    int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
     if (constant_key & 0xF0000000) {
       Abort(kArrayIndexConstantValueTooBig);
     }
-    __ add(scratch, elements,
-           Operand((constant_key << element_size_shift) +
-                   FixedDoubleArray::kHeaderSize - kHeapObjectTag));
   } else {
-    int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
-        ? (element_size_shift - kSmiTagSize) : element_size_shift;
-    __ add(scratch, elements,
-           Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+    key = ToRegister(instr->key());
+  }
+  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+  int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
+      ? (element_size_shift - kSmiTagSize) : element_size_shift;
+  Operand operand = key_is_constant
+      ? Operand((constant_key << element_size_shift) +
+                FixedDoubleArray::kHeaderSize - kHeapObjectTag)
+      : Operand(key, LSL, shift_size);
+  __ add(scratch, elements, operand);
+  if (!key_is_constant) {
     __ add(scratch, scratch,
-           Operand(ToRegister(instr->key()), LSL, shift_size));
+           Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
   }
 
   if (instr->NeedsCanonicalization()) {
@@ -4401,12 +4397,9 @@
       __ tst(ip, Operand(kVFPDefaultNaNModeControlBit));
       __ Assert(ne, kDefaultNaNModeNotSet);
     }
-    __ VFPCanonicalizeNaN(double_scratch, value);
-    __ vstr(double_scratch, scratch,
-            instr->additional_index() << element_size_shift);
-  } else {
-    __ vstr(value, scratch, instr->additional_index() << element_size_shift);
+    __ VFPCanonicalizeNaN(value);
   }
+  __ vstr(value, scratch, instr->additional_index() << element_size_shift);
 }
 
 
@@ -4994,19 +4987,15 @@
 
   Register input_reg = ToRegister(input);
 
-  if (instr->hydrogen()->value()->representation().IsSmi()) {
-    __ SmiUntag(input_reg);
-  } else {
-    DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
+  DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
 
-    // Optimistically untag the input.
-    // If the input is a HeapObject, SmiUntag will set the carry flag.
-    __ SmiUntag(input_reg, SetCC);
-    // Branch to deferred code if the input was tagged.
-    // The deferred code will take care of restoring the tag.
-    __ b(cs, deferred->entry());
-    __ bind(deferred->exit());
-  }
+  // Optimistically untag the input.
+  // If the input is a HeapObject, SmiUntag will set the carry flag.
+  __ SmiUntag(input_reg, SetCC);
+  // Branch to deferred code if the input was tagged.
+  // The deferred code will take care of restoring the tag.
+  __ b(cs, deferred->entry());
+  __ bind(deferred->exit());
 }
 
 
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 9286666..7df7857 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -733,11 +733,9 @@
   bind(&fpscr_done);
 }
 
-
-void MacroAssembler::VFPCanonicalizeNaN(const DwVfpRegister dst,
-                                        const DwVfpRegister src,
+void MacroAssembler::VFPCanonicalizeNaN(const DwVfpRegister value,
                                         const Condition cond) {
-  vsub(dst, src, kDoubleRegZero, cond);
+  vsub(value, value, kDoubleRegZero, cond);
 }
 
 
@@ -1022,8 +1020,7 @@
 
 
 void MacroAssembler::LeaveExitFrame(bool save_doubles,
-                                    Register argument_count,
-                                    bool restore_context) {
+                                    Register argument_count) {
   // Optionally restore all double registers.
   if (save_doubles) {
     // Calculate the stack location of the saved doubles and restore them.
@@ -1038,14 +1035,10 @@
   mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
   str(r3, MemOperand(ip));
 
-
   // Restore current context from top and clear it in debug mode.
-  if (restore_context) {
-    mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
-    ldr(cp, MemOperand(ip));
-  }
-#ifdef DEBUG
   mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
+  ldr(cp, MemOperand(ip));
+#ifdef DEBUG
   str(r3, MemOperand(ip));
 #endif
 
@@ -2287,14 +2280,12 @@
 }
 
 
-void MacroAssembler::CallApiFunctionAndReturn(
-    ExternalReference function,
-    Address function_address,
-    ExternalReference thunk_ref,
-    Register thunk_last_arg,
-    int stack_space,
-    MemOperand return_value_operand,
-    MemOperand* context_restore_operand) {
+void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
+                                              Address function_address,
+                                              ExternalReference thunk_ref,
+                                              Register thunk_last_arg,
+                                              int stack_space,
+                                              int return_value_offset) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
   const int kNextOffset = 0;
@@ -2358,13 +2349,12 @@
   }
 
   Label promote_scheduled_exception;
-  Label exception_handled;
   Label delete_allocated_handles;
   Label leave_exit_frame;
   Label return_value_loaded;
 
   // load value from ReturnValue
-  ldr(r0, return_value_operand);
+  ldr(r0, MemOperand(fp, return_value_offset*kPointerSize));
   bind(&return_value_loaded);
   // No more valid handles (the result handle was the last one). Restore
   // previous handle scope.
@@ -2387,25 +2377,17 @@
   ldr(r5, MemOperand(ip));
   cmp(r4, r5);
   b(ne, &promote_scheduled_exception);
-  bind(&exception_handled);
 
-  bool restore_context = context_restore_operand != NULL;
-  if (restore_context) {
-    ldr(cp, *context_restore_operand);
-  }
   // LeaveExitFrame expects unwind space to be in a register.
   mov(r4, Operand(stack_space));
-  LeaveExitFrame(false, r4, !restore_context);
+  LeaveExitFrame(false, r4);
   mov(pc, lr);
 
   bind(&promote_scheduled_exception);
-  {
-    FrameScope frame(this, StackFrame::INTERNAL);
-    CallExternalReference(
-        ExternalReference(Runtime::kPromoteScheduledException, isolate()),
-        0);
-  }
-  jmp(&exception_handled);
+  TailCallExternalReference(
+      ExternalReference(Runtime::kPromoteScheduledException, isolate()),
+      0,
+      1);
 
   // HandleScope limit has changed. Delete allocated extensions.
   bind(&delete_allocated_handles);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 5b18ad4..9abd5a0 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -469,13 +469,8 @@
   void VFPEnsureFPSCRState(Register scratch);
 
   // If the value is a NaN, canonicalize the value else, do nothing.
-  void VFPCanonicalizeNaN(const DwVfpRegister dst,
-                          const DwVfpRegister src,
-                          const Condition cond = al);
   void VFPCanonicalizeNaN(const DwVfpRegister value,
-                          const Condition cond = al) {
-    VFPCanonicalizeNaN(value, value, cond);
-  }
+                          const Condition cond = al);
 
   // Compare double values and move the result to the normal condition flags.
   void VFPCompareAndSetFlags(const DwVfpRegister src1,
@@ -546,9 +541,7 @@
   // Leave the current exit frame. Expects the return value in r0.
   // Expect the number of values, pushed prior to the exit frame, to
   // remove in a register (or no_reg, if there is nothing to remove).
-  void LeaveExitFrame(bool save_doubles,
-                      Register argument_count,
-                      bool restore_context);
+  void LeaveExitFrame(bool save_doubles, Register argument_count);
 
   // Get the actual activation frame alignment for target environment.
   static int ActivationFrameAlignment();
@@ -1118,8 +1111,7 @@
                                 ExternalReference thunk_ref,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                MemOperand return_value_operand,
-                                MemOperand* context_restore_operand);
+                                int return_value_offset_from_fp);
 
   // Jump to a runtime routine.
   void JumpToExternalReference(const ExternalReference& builtin);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 567eb63..085af3f 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -380,27 +380,31 @@
                                             Register receiver,
                                             Register scratch1,
                                             Register scratch2,
-                                            Label* miss) {
+                                            Label* miss,
+                                            bool support_wrappers) {
   Label check_wrapper;
 
   // Check if the object is a string leaving the instance type in the
   // scratch1 register.
-  GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper);
+  GenerateStringCheck(masm, receiver, scratch1, scratch2, miss,
+                      support_wrappers ? &check_wrapper : miss);
 
   // Load length directly from the string.
   __ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset));
   __ Ret();
 
-  // Check if the object is a JSValue wrapper.
-  __ bind(&check_wrapper);
-  __ cmp(scratch1, Operand(JS_VALUE_TYPE));
-  __ b(ne, miss);
+  if (support_wrappers) {
+    // Check if the object is a JSValue wrapper.
+    __ bind(&check_wrapper);
+    __ cmp(scratch1, Operand(JS_VALUE_TYPE));
+    __ b(ne, miss);
 
-  // Unwrap the value and check if the wrapped value is a string.
-  __ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
-  GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
-  __ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset));
-  __ Ret();
+    // Unwrap the value and check if the wrapped value is a string.
+    __ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
+    GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
+    __ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset));
+    __ Ret();
+  }
 }
 
 
@@ -839,28 +843,23 @@
 
 static void GenerateFastApiDirectCall(MacroAssembler* masm,
                                       const CallOptimization& optimization,
-                                      int argc,
-                                      bool restore_context) {
+                                      int argc) {
   // ----------- S t a t e -------------
-  //  -- sp[0]              : context
-  //  -- sp[4]              : holder (set by CheckPrototypes)
-  //  -- sp[8]              : callee JS function
-  //  -- sp[12]             : call data
-  //  -- sp[16]             : isolate
-  //  -- sp[20]             : ReturnValue default value
-  //  -- sp[24]             : ReturnValue
-  //  -- sp[28]             : last JS argument
+  //  -- sp[0]              : holder (set by CheckPrototypes)
+  //  -- sp[4]              : callee JS function
+  //  -- sp[8]              : call data
+  //  -- sp[12]             : isolate
+  //  -- sp[16]             : ReturnValue default value
+  //  -- sp[20]             : ReturnValue
+  //  -- sp[24]             : last JS argument
   //  -- ...
-  //  -- sp[(argc + 6) * 4] : first JS argument
-  //  -- sp[(argc + 7) * 4] : receiver
+  //  -- sp[(argc + 5) * 4] : first JS argument
+  //  -- sp[(argc + 6) * 4] : receiver
   // -----------------------------------
-  // Save calling context.
-  __ str(cp, MemOperand(sp));
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(r5, function);
   __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
-  __ str(r5, MemOperand(sp, 2 * kPointerSize));
 
   // Pass the additional arguments.
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
@@ -871,18 +870,15 @@
   } else {
     __ Move(r6, call_data);
   }
-  // Store call data.
-  __ str(r6, MemOperand(sp, 3 * kPointerSize));
-  // Store isolate.
   __ mov(r7, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ str(r7, MemOperand(sp, 4 * kPointerSize));
-  // Store ReturnValue default and ReturnValue.
+  // Store JS function, call data, isolate ReturnValue default and ReturnValue.
+  __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit());
   __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+  __ str(r5, MemOperand(sp, 4 * kPointerSize));
   __ str(r5, MemOperand(sp, 5 * kPointerSize));
-  __ str(r5, MemOperand(sp, 6 * kPointerSize));
 
   // Prepare arguments.
-  __ add(r2, sp, Operand((kFastApiCallArguments - 1) * kPointerSize));
+  __ add(r2, sp, Operand(5 * kPointerSize));
 
   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
@@ -920,18 +916,12 @@
       masm->isolate());
 
   AllowExternalCallThatCantCauseGC scope(masm);
-  MemOperand context_restore_operand(
-      fp, 2 * kPointerSize);
-  MemOperand return_value_operand(
-      fp, (kFastApiCallArguments + 1) * kPointerSize);
   __ CallApiFunctionAndReturn(ref,
                               function_address,
                               thunk_ref,
                               r1,
                               kStackUnwindSpace,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+                              kFastApiCallArguments + 1);
 }
 
 
@@ -946,12 +936,10 @@
   ASSERT(!receiver.is(scratch));
 
   const int stack_space = kFastApiCallArguments + argc + 1;
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex - 1;
   // Assign stack space for the call arguments.
   __ sub(sp, sp, Operand(stack_space * kPointerSize));
   // Write holder to stack frame.
-  __ str(receiver, MemOperand(sp, kHolderIndex * kPointerSize));
+  __ str(receiver, MemOperand(sp, 0));
   // Write receiver to stack frame.
   int index = stack_space - 1;
   __ str(receiver, MemOperand(sp, index * kPointerSize));
@@ -962,7 +950,7 @@
     __ str(receiver, MemOperand(sp, index-- * kPointerSize));
   }
 
-  GenerateFastApiDirectCall(masm, optimization, argc, true);
+  GenerateFastApiDirectCall(masm, optimization, argc);
 }
 
 
@@ -1076,8 +1064,7 @@
 
     // Invoke function.
     if (can_do_fast_api_call) {
-      GenerateFastApiDirectCall(
-          masm, optimization, arguments_.immediate(), false);
+      GenerateFastApiDirectCall(masm, optimization, arguments_.immediate());
     } else {
       CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
           ? CALL_AS_FUNCTION
@@ -1201,8 +1188,6 @@
                                        int save_at_depth,
                                        Label* miss,
                                        PrototypeCheckType check) {
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex - 1;
   // Make sure that the type feedback oracle harvests the receiver map.
   // TODO(svenpanne) Remove this hack when all ICs are reworked.
   __ mov(scratch1, Operand(Handle<Map>(object->map())));
@@ -1218,7 +1203,7 @@
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ str(reg, MemOperand(sp, kHolderIndex * kPointerSize));
+    __ str(reg, MemOperand(sp));
   }
 
   // Check the maps in the prototype chain.
@@ -1277,7 +1262,7 @@
     }
 
     if (save_at_depth == depth) {
-      __ str(reg, MemOperand(sp, kHolderIndex * kPointerSize));
+      __ str(reg, MemOperand(sp));
     }
 
     // Go to the next object in the prototype chain.
@@ -1472,7 +1457,7 @@
   __ str(scratch2(), MemOperand(sp, 1 * kPointerSize));
   __ add(r1, sp, Operand(1 * kPointerSize));  // r1 = AccessorInfo&
 
-  const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
+  const int kStackUnwindSpace = kFastApiCallArguments + 1;
   Address getter_address = v8::ToCData<Address>(callback->getter());
 
   ApiFunction fun(getter_address);
@@ -1490,8 +1475,7 @@
                               thunk_ref,
                               r2,
                               kStackUnwindSpace,
-                              MemOperand(fp, 6 * kPointerSize),
-                              NULL);
+                              6);
 }
 
 
@@ -2555,7 +2539,7 @@
   CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, name,
                   depth, &miss);
 
-  GenerateFastApiDirectCall(masm(), optimization, argc, false);
+  GenerateFastApiDirectCall(masm(), optimization, argc);
 
   __ bind(&miss);
   FreeSpaceForFastApiCall(masm());
diff --git a/src/array.js b/src/array.js
index 4a7aea5..5f89ebb 100644
--- a/src/array.js
+++ b/src/array.js
@@ -399,13 +399,14 @@
   n--;
   var value = this[n];
 
+  EnqueueSpliceRecord(this, n, [value], 0);
+
   try {
     BeginPerformSplice(this);
     delete this[n];
     this.length = n;
   } finally {
     EndPerformSplice(this);
-    EnqueueSpliceRecord(this, n, [value], 0);
   }
 
   return value;
@@ -440,6 +441,8 @@
   var n = TO_UINT32(this.length);
   var m = %_ArgumentsLength();
 
+  EnqueueSpliceRecord(this, n, [], m);
+
   try {
     BeginPerformSplice(this);
     for (var i = 0; i < m; i++) {
@@ -448,7 +451,6 @@
     this.length = n + m;
   } finally {
     EndPerformSplice(this);
-    EnqueueSpliceRecord(this, n, [], m);
   }
 
   return this.length;
@@ -579,13 +581,14 @@
 function ObservedArrayShift(len) {
   var first = this[0];
 
+  EnqueueSpliceRecord(this, 0, [first], 0);
+
   try {
     BeginPerformSplice(this);
     SimpleMove(this, 0, 1, len, 0);
     this.length = len - 1;
   } finally {
     EndPerformSplice(this);
-    EnqueueSpliceRecord(this, 0, [first], 0);
   }
 
   return first;
@@ -624,6 +627,8 @@
   var len = TO_UINT32(this.length);
   var num_arguments = %_ArgumentsLength();
 
+  EnqueueSpliceRecord(this, 0, [], num_arguments);
+
   try {
     BeginPerformSplice(this);
     SimpleMove(this, 0, 0, len, num_arguments);
@@ -633,7 +638,6 @@
     this.length = len + num_arguments;
   } finally {
     EndPerformSplice(this);
-    EnqueueSpliceRecord(this, 0, [], num_arguments);
   }
 
   return len + num_arguments;
diff --git a/src/assembler.cc b/src/assembler.cc
index 6581aa1..fbff62d 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -207,26 +207,6 @@
 
 
 // -----------------------------------------------------------------------------
-// Implementation of PlatformFeatureScope
-
-PlatformFeatureScope::PlatformFeatureScope(CpuFeature f)
-    : old_supported_(CpuFeatures::supported_),
-      old_found_by_runtime_probing_only_(
-          CpuFeatures::found_by_runtime_probing_only_) {
-  uint64_t mask = static_cast<uint64_t>(1) << f;
-  CpuFeatures::supported_ |= mask;
-  CpuFeatures::found_by_runtime_probing_only_ &= ~mask;
-}
-
-
-PlatformFeatureScope::~PlatformFeatureScope() {
-  CpuFeatures::supported_ = old_supported_;
-  CpuFeatures::found_by_runtime_probing_only_ =
-      old_found_by_runtime_probing_only_;
-}
-
-
-// -----------------------------------------------------------------------------
 // Implementation of Label
 
 int Label::pos() const {
diff --git a/src/assembler.h b/src/assembler.h
index 1220074..6b399f2 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -134,19 +134,6 @@
 };
 
 
-// Enable a unsupported feature within a scope for cross-compiling for a
-// different CPU.
-class PlatformFeatureScope BASE_EMBEDDED {
- public:
-  explicit PlatformFeatureScope(CpuFeature f);
-  ~PlatformFeatureScope();
-
- private:
-  uint64_t old_supported_;
-  uint64_t old_found_by_runtime_probing_only_;
-};
-
-
 // -----------------------------------------------------------------------------
 // Labels represent pc locations; they are typically jump or call targets.
 // After declaration, a label can be freely used to denote known or (yet)
diff --git a/src/ast.cc b/src/ast.cc
index 5f085d3..823dede 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -460,7 +460,10 @@
   receiver_types_.Clear();
   if (key()->IsPropertyName()) {
     FunctionPrototypeStub proto_stub(Code::LOAD_IC);
-    if (oracle->LoadIsStub(this, &proto_stub)) {
+    StringLengthStub string_stub(Code::LOAD_IC, false);
+    if (oracle->LoadIsStub(this, &string_stub)) {
+      is_string_length_ = true;
+    } else if (oracle->LoadIsStub(this, &proto_stub)) {
       is_function_prototype_ = true;
     } else {
       Literal* lit_key = key()->AsLiteral();
diff --git a/src/ast.h b/src/ast.h
index 71a51ab..c630906 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1646,6 +1646,7 @@
 
   BailoutId LoadId() const { return load_id_; }
 
+  bool IsStringLength() const { return is_string_length_; }
   bool IsStringAccess() const { return is_string_access_; }
   bool IsFunctionPrototype() const { return is_function_prototype_; }
 
@@ -1673,6 +1674,7 @@
         load_id_(GetNextId(isolate)),
         is_monomorphic_(false),
         is_uninitialized_(false),
+        is_string_length_(false),
         is_string_access_(false),
         is_function_prototype_(false) { }
 
@@ -1685,6 +1687,7 @@
   SmallMapList receiver_types_;
   bool is_monomorphic_ : 1;
   bool is_uninitialized_ : 1;
+  bool is_string_length_ : 1;
   bool is_string_access_ : 1;
   bool is_function_prototype_ : 1;
 };
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 1a6ae00..23d4269 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -357,45 +357,40 @@
 
   HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo();
   HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
-  HValue* push_value;
   if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) {
     HValue* elements = AddLoadElements(boilerplate);
 
     IfBuilder if_fixed_cow(this);
     if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
     if_fixed_cow.Then();
-    push_value = BuildCloneShallowArray(boilerplate,
-                                        allocation_site,
-                                        alloc_site_mode,
-                                        FAST_ELEMENTS,
-                                        0/*copy-on-write*/);
-    environment()->Push(push_value);
+    environment()->Push(BuildCloneShallowArray(boilerplate,
+                                               allocation_site,
+                                               alloc_site_mode,
+                                               FAST_ELEMENTS,
+                                               0/*copy-on-write*/));
     if_fixed_cow.Else();
 
     IfBuilder if_fixed(this);
     if_fixed.If<HCompareMap>(elements, factory->fixed_array_map());
     if_fixed.Then();
-    push_value = BuildCloneShallowArray(boilerplate,
-                                        allocation_site,
-                                        alloc_site_mode,
-                                        FAST_ELEMENTS,
-                                        length);
-    environment()->Push(push_value);
+    environment()->Push(BuildCloneShallowArray(boilerplate,
+                                               allocation_site,
+                                               alloc_site_mode,
+                                               FAST_ELEMENTS,
+                                               length));
     if_fixed.Else();
-    push_value = BuildCloneShallowArray(boilerplate,
-                                        allocation_site,
-                                        alloc_site_mode,
-                                        FAST_DOUBLE_ELEMENTS,
-                                        length);
-    environment()->Push(push_value);
+    environment()->Push(BuildCloneShallowArray(boilerplate,
+                                               allocation_site,
+                                               alloc_site_mode,
+                                               FAST_DOUBLE_ELEMENTS,
+                                               length));
   } else {
     ElementsKind elements_kind = casted_stub()->ComputeElementsKind();
-    push_value = BuildCloneShallowArray(boilerplate,
-                                        allocation_site,
-                                        alloc_site_mode,
-                                        elements_kind,
-                                        length);
-    environment()->Push(push_value);
+    environment()->Push(BuildCloneShallowArray(boilerplate,
+                                               allocation_site,
+                                               alloc_site_mode,
+                                               elements_kind,
+                                               length));
   }
 
   checker.ElseDeopt("Uninitialized boilerplate literals");
@@ -923,7 +918,8 @@
     HValue* native_context,
     HValue* code_object) {
   Counters* counters = isolate()->counters();
-  AddIncrementCounter(counters->fast_new_closure_install_optimized());
+  AddIncrementCounter(counters->fast_new_closure_install_optimized(),
+                      context());
 
   // TODO(fschneider): Idea: store proper code pointers in the optimized code
   // map and either unmangle them on marking or do nothing as the whole map is
@@ -971,7 +967,7 @@
   }
   is_optimized.Else();
   {
-    AddIncrementCounter(counters->fast_new_closure_try_optimized());
+    AddIncrementCounter(counters->fast_new_closure_try_optimized(), context());
     // optimized_map points to fixed array of 3-element entries
     // (native context, optimized code, literals).
     // Map must never be empty, so check the first elements.
@@ -1060,7 +1056,7 @@
   HValue* size = Add<HConstant>(JSFunction::kSize);
   HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(),
                                              NOT_TENURED, JS_FUNCTION_TYPE);
-  AddIncrementCounter(counters->fast_new_closure_total());
+  AddIncrementCounter(counters->fast_new_closure_total(), context());
 
   int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
                                             casted_stub()->is_generator());
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 30ec1c7..946eb76 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -830,12 +830,19 @@
 
 class StringLengthStub: public ICStub {
  public:
-  explicit StringLengthStub(Code::Kind kind) : ICStub(kind) { }
+  StringLengthStub(Code::Kind kind, bool support_wrapper)
+      : ICStub(kind), support_wrapper_(support_wrapper) { }
   virtual void Generate(MacroAssembler* masm);
 
  private:
   STATIC_ASSERT(KindBits::kSize == 4);
-    virtual CodeStub::Major MajorKey() { return StringLength; }
+  class WrapperModeBits: public BitField<bool, 4, 1> {};
+  virtual CodeStub::Major MajorKey() { return StringLength; }
+  virtual int MinorKey() {
+    return KindBits::encode(kind()) | WrapperModeBits::encode(support_wrapper_);
+  }
+
+  bool support_wrapper_;
 };
 
 
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index 3d9dc67..e0f7aea 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -435,18 +435,8 @@
     logger->is_logging_ = false;
     generator_ = new ProfileGenerator(profiles_);
     Sampler* sampler = logger->sampler();
-#if V8_CC_MSVC && (_MSC_VER >= 1800)
-    // VS2013 reports "warning C4316: 'v8::internal::ProfilerEventsProcessor'
-    // : object allocated on the heap may not be aligned 64".  We need to
-    // figure out if this is a legitimate warning or a compiler bug.
-    #pragma warning(push)
-    #pragma warning(disable:4316)
-#endif
     processor_ = new ProfilerEventsProcessor(
         generator_, sampler, sampling_interval_);
-#if V8_CC_MSVC && (_MSC_VER >= 1800)
-    #pragma warning(pop)
-#endif
     is_profiling_ = true;
     // Enumerate stuff we already have in the heap.
     ASSERT(isolate_->heap()->HasBeenSetUp());
diff --git a/src/d8.cc b/src/d8.cc
index 6e4e61d..fb75d81 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -939,8 +939,8 @@
   i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory();
   i::JSArguments js_args = i::FLAG_js_arguments;
   i::Handle<i::FixedArray> arguments_array =
-      factory->NewFixedArray(js_args.argc);
-  for (int j = 0; j < js_args.argc; j++) {
+      factory->NewFixedArray(js_args.argc());
+  for (int j = 0; j < js_args.argc(); j++) {
     i::Handle<i::String> arg =
         factory->NewStringFromUtf8(i::CStrVector(js_args[j]));
     arguments_array->set(j, *arg);
diff --git a/src/d8.gyp b/src/d8.gyp
index c033fd7..15d342d 100644
--- a/src/d8.gyp
+++ b/src/d8.gyp
@@ -81,13 +81,13 @@
         }],
         ['v8_enable_i18n_support==1', {
           'dependencies': [
-            '<(icu_gyp_path):icui18n',
-            '<(icu_gyp_path):icuuc',
+            '<(DEPTH)/third_party/icu/icu.gyp:icui18n',
+            '<(DEPTH)/third_party/icu/icu.gyp:icuuc',
           ],
         }],
         ['OS=="win" and v8_enable_i18n_support==1', {
           'dependencies': [
-            '<(icu_gyp_path):icudata',
+            '<(DEPTH)/third_party/icu/icu.gyp:icudata',
           ],
         }],
       ],
diff --git a/src/debug.cc b/src/debug.cc
index 63d33eb..0496b8c 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1793,14 +1793,10 @@
         // function to be called and not the code for Builtins::FunctionApply or
         // Builtins::FunctionCall. The receiver of call/apply is the target
         // function.
-        if (!holder.is_null() && holder->IsJSFunction()) {
+        if (!holder.is_null() && holder->IsJSFunction() &&
+            !JSFunction::cast(*holder)->IsBuiltin()) {
           Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
-          if (!js_function->IsBuiltin()) {
-            Debug::FloodWithOneShot(js_function);
-          } else if (js_function->shared()->bound()) {
-            // Handle Function.prototype.bind
-            Debug::FloodBoundFunctionWithOneShot(js_function);
-          }
+          Debug::FloodWithOneShot(js_function);
         }
       } else {
         Debug::FloodWithOneShot(function);
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 0c9760e..c979a53 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -1617,10 +1617,9 @@
     Handle<Map> map = Handle<Map>::cast(MaterializeNextValue());
     switch (map->instance_type()) {
       case HEAP_NUMBER_TYPE: {
-        Handle<HeapNumber> object = isolate_->factory()->NewHeapNumber(0.0);
-        materialized_objects_->Add(object);
-        Handle<Object> number = MaterializeNextValue();
-        object->set_value(number->Number());
+        Handle<HeapNumber> number =
+            Handle<HeapNumber>::cast(MaterializeNextValue());
+        materialized_objects_->Add(number);
         materialization_value_index_ += kDoubleSize / kPointerSize - 1;
         break;
       }
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index e734c7d..08cd830 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -90,34 +90,44 @@
 #define DEFINE_implication(whenflag, thenflag)
 #endif
 
-#define COMMA ,
 
 #ifdef FLAG_MODE_DECLARE
 // Structure used to hold a collection of arguments to the JavaScript code.
+#define JSARGUMENTS_INIT {{}}
 struct JSArguments {
 public:
+  inline int argc() const {
+    return static_cast<int>(storage_[0]);
+  }
+  inline const char** argv() const {
+    return reinterpret_cast<const char**>(storage_[1]);
+  }
   inline const char*& operator[] (int idx) const {
-    return argv[idx];
+    return argv()[idx];
+  }
+  inline JSArguments& operator=(JSArguments args) {
+    set_argc(args.argc());
+    set_argv(args.argv());
+    return *this;
   }
   static JSArguments Create(int argc, const char** argv) {
     JSArguments args;
-    args.argc = argc;
-    args.argv = argv;
+    args.set_argc(argc);
+    args.set_argv(argv);
     return args;
   }
-  int argc;
-  const char** argv;
-};
-
-struct MaybeBoolFlag {
-  static MaybeBoolFlag Create(bool has_value, bool value) {
-    MaybeBoolFlag flag;
-    flag.has_value = has_value;
-    flag.value = value;
-    return flag;
+private:
+  void set_argc(int argc) {
+    storage_[0] = argc;
   }
-  bool has_value;
-  bool value;
+  void set_argv(const char** argv) {
+    storage_[1] = reinterpret_cast<AtomicWord>(argv);
+  }
+public:
+  // Contains argc and argv. Unfortunately we have to store these two fields
+  // into a single one to avoid making the initialization macro (which would be
+  // "{ 0, NULL }") contain a coma.
+  AtomicWord storage_[2];
 };
 #endif
 
@@ -138,13 +148,10 @@
 #endif
 
 #define DEFINE_bool(nam, def, cmt)   FLAG(BOOL, bool, nam, def, cmt)
-#define DEFINE_maybe_bool(nam, cmt)  FLAG(MAYBE_BOOL, MaybeBoolFlag, nam,  \
-                                          { false COMMA false }, cmt)
 #define DEFINE_int(nam, def, cmt)    FLAG(INT, int, nam, def, cmt)
 #define DEFINE_float(nam, def, cmt)  FLAG(FLOAT, double, nam, def, cmt)
 #define DEFINE_string(nam, def, cmt) FLAG(STRING, const char*, nam, def, cmt)
-#define DEFINE_args(nam, cmt)        FLAG(ARGS, JSArguments, nam, \
-                                          { 0 COMMA NULL }, cmt)
+#define DEFINE_args(nam, def, cmt)   FLAG(ARGS, JSArguments, nam, def, cmt)
 
 #define DEFINE_ALIAS_bool(alias, nam)  FLAG_ALIAS(BOOL, bool, alias, nam)
 #define DEFINE_ALIAS_int(alias, nam)   FLAG_ALIAS(INT, int, alias, nam)
@@ -233,7 +240,7 @@
 DEFINE_bool(use_gvn, true, "use hydrogen global value numbering")
 DEFINE_bool(use_canonicalizing, true, "use hydrogen instruction canonicalizing")
 DEFINE_bool(use_inlining, true, "use function inlining")
-DEFINE_bool(use_escape_analysis, true, "use hydrogen escape analysis")
+DEFINE_bool(use_escape_analysis, false, "use hydrogen escape analysis")
 DEFINE_bool(use_allocation_folding, true, "use allocation folding")
 DEFINE_int(max_inlining_levels, 5, "maximum number of inlining levels")
 DEFINE_int(max_inlined_source_size, 600,
@@ -254,7 +261,6 @@
 DEFINE_string(trace_hydrogen_file, NULL, "trace hydrogen to given file name")
 DEFINE_string(trace_phase, "HLZ", "trace generated IR for specified phases")
 DEFINE_bool(trace_inlining, false, "trace inlining decisions")
-DEFINE_bool(trace_load_elimination, false, "trace load elimination")
 DEFINE_bool(trace_alloc, false, "trace register allocator")
 DEFINE_bool(trace_all_uses, false, "trace all use positions")
 DEFINE_bool(trace_range, false, "trace range analysis")
@@ -289,7 +295,6 @@
             "perform array index dehoisting")
 DEFINE_bool(analyze_environment_liveness, true,
             "analyze liveness of environment slots and zap dead values")
-DEFINE_bool(load_elimination, false, "use load elimination")
 DEFINE_bool(dead_code_elimination, true, "use dead code elimination")
 DEFINE_bool(fold_constants, true, "use constant folding")
 DEFINE_bool(trace_dead_code_elimination, false, "trace dead code elimination")
@@ -539,6 +544,7 @@
             "Use idle notification to reduce memory footprint.")
 // ic.cc
 DEFINE_bool(use_ic, true, "use inline caching")
+DEFINE_bool(js_accessor_ics, false, "create ics for js accessors")
 
 // macro-assembler-ia32.cc
 DEFINE_bool(native_code_counters, false,
@@ -594,9 +600,6 @@
            0,
            "Fixed seed to use to hash property keys (0 means random)"
            "(with snapshots this option cannot override the baked-in seed)")
-DEFINE_maybe_bool(force_memory_constrained,
-           "force (if true) or prevent (if false) the runtime from treating "
-           "the device as being memory constrained.")
 
 // v8.cc
 DEFINE_bool(preemption, false,
@@ -607,7 +610,6 @@
 
 // Testing flags test/cctest/test-{flags,api,serialization}.cc
 DEFINE_bool(testing_bool_flag, true, "testing_bool_flag")
-DEFINE_maybe_bool(testing_maybe_bool_flag, "testing_maybe_bool_flag")
 DEFINE_int(testing_int_flag, 13, "testing_int_flag")
 DEFINE_float(testing_float_flag, 2.5, "float-flag")
 DEFINE_string(testing_string_flag, "Hello, world!", "string-flag")
@@ -640,7 +642,7 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 DEFINE_string(map_counters, "", "Map counters to a file")
-DEFINE_args(js_arguments,
+DEFINE_args(js_arguments, JSARGUMENTS_INIT,
             "Pass all remaining arguments to the script. Alias for \"--\".")
 
 #if defined(WEBOS__)
@@ -832,7 +834,6 @@
 #undef FLAG_ALIAS
 
 #undef DEFINE_bool
-#undef DEFINE_maybe_bool
 #undef DEFINE_int
 #undef DEFINE_string
 #undef DEFINE_float
@@ -849,5 +850,3 @@
 #undef FLAG_MODE_DEFINE_DEFAULTS
 #undef FLAG_MODE_META
 #undef FLAG_MODE_DEFINE_IMPLICATIONS
-
-#undef COMMA
diff --git a/src/flags.cc b/src/flags.cc
index 0c36aed..4e18cc8 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -55,8 +55,7 @@
 // to the actual flag, default value, comment, etc.  This is designed to be POD
 // initialized as to avoid requiring static constructors.
 struct Flag {
-  enum FlagType { TYPE_BOOL, TYPE_MAYBE_BOOL, TYPE_INT, TYPE_FLOAT,
-                  TYPE_STRING, TYPE_ARGS };
+  enum FlagType { TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS };
 
   FlagType type_;           // What type of flag, bool, int, or string.
   const char* name_;        // Name of the flag, ex "my_flag".
@@ -76,11 +75,6 @@
     return reinterpret_cast<bool*>(valptr_);
   }
 
-  MaybeBoolFlag* maybe_bool_variable() const {
-    ASSERT(type_ == TYPE_MAYBE_BOOL);
-    return reinterpret_cast<MaybeBoolFlag*>(valptr_);
-  }
-
   int* int_variable() const {
     ASSERT(type_ == TYPE_INT);
     return reinterpret_cast<int*>(valptr_);
@@ -139,8 +133,6 @@
     switch (type_) {
       case TYPE_BOOL:
         return *bool_variable() == bool_default();
-      case TYPE_MAYBE_BOOL:
-        return maybe_bool_variable()->has_value == false;
       case TYPE_INT:
         return *int_variable() == int_default();
       case TYPE_FLOAT:
@@ -153,7 +145,7 @@
         return strcmp(str1, str2) == 0;
       }
       case TYPE_ARGS:
-        return args_variable()->argc == 0;
+        return args_variable()->argc() == 0;
     }
     UNREACHABLE();
     return true;
@@ -165,9 +157,6 @@
       case TYPE_BOOL:
         *bool_variable() = bool_default();
         break;
-      case TYPE_MAYBE_BOOL:
-        *maybe_bool_variable() = MaybeBoolFlag::Create(false, false);
-        break;
       case TYPE_INT:
         *int_variable() = int_default();
         break;
@@ -197,7 +186,6 @@
 static const char* Type2String(Flag::FlagType type) {
   switch (type) {
     case Flag::TYPE_BOOL: return "bool";
-    case Flag::TYPE_MAYBE_BOOL: return "maybe_bool";
     case Flag::TYPE_INT: return "int";
     case Flag::TYPE_FLOAT: return "float";
     case Flag::TYPE_STRING: return "string";
@@ -215,11 +203,6 @@
     case Flag::TYPE_BOOL:
       buffer.Add("%s", (*flag->bool_variable() ? "true" : "false"));
       break;
-    case Flag::TYPE_MAYBE_BOOL:
-      buffer.Add("%s", flag->maybe_bool_variable()->has_value
-                       ? (flag->maybe_bool_variable()->value ? "true" : "false")
-                       : "unset");
-      break;
     case Flag::TYPE_INT:
       buffer.Add("%d", *flag->int_variable());
       break;
@@ -233,9 +216,9 @@
     }
     case Flag::TYPE_ARGS: {
       JSArguments args = *flag->args_variable();
-      if (args.argc > 0) {
+      if (args.argc() > 0) {
         buffer.Add("%s",  args[0]);
-        for (int i = 1; i < args.argc; i++) {
+        for (int i = 1; i < args.argc(); i++) {
           buffer.Add(" %s", args[i]);
         }
       }
@@ -277,7 +260,7 @@
     buffer.Add("--%s", args_flag->name());
     args->Add(buffer.ToCString().Detach());
     JSArguments jsargs = *args_flag->args_variable();
-    for (int j = 0; j < jsargs.argc; j++) {
+    for (int j = 0; j < jsargs.argc(); j++) {
       args->Add(StrDup(jsargs[j]));
     }
   }
@@ -397,7 +380,6 @@
 
       // if we still need a flag value, use the next argument if available
       if (flag->type() != Flag::TYPE_BOOL &&
-          flag->type() != Flag::TYPE_MAYBE_BOOL &&
           flag->type() != Flag::TYPE_ARGS &&
           value == NULL) {
         if (i < *argc) {
@@ -417,9 +399,6 @@
         case Flag::TYPE_BOOL:
           *flag->bool_variable() = !is_bool;
           break;
-        case Flag::TYPE_MAYBE_BOOL:
-          *flag->maybe_bool_variable() = MaybeBoolFlag::Create(true, !is_bool);
-          break;
         case Flag::TYPE_INT:
           *flag->int_variable() = strtol(value, &endp, 10);  // NOLINT
           break;
@@ -446,9 +425,8 @@
       }
 
       // handle errors
-      bool is_bool_type = flag->type() == Flag::TYPE_BOOL ||
-          flag->type() == Flag::TYPE_MAYBE_BOOL;
-      if ((is_bool_type && value != NULL) || (!is_bool_type && is_bool) ||
+      if ((flag->type() == Flag::TYPE_BOOL && value != NULL) ||
+          (flag->type() != Flag::TYPE_BOOL && is_bool) ||
           *endp != '\0') {
         PrintF(stderr, "Error: illegal value for flag %s of type %s\n"
                "Try --help for options\n",
@@ -571,7 +549,6 @@
 }
 
 
-// static
 void FlagList::EnforceFlagImplications() {
 #define FLAG_MODE_DEFINE_IMPLICATIONS
 #include "flag-definitions.h"
diff --git a/src/handles.cc b/src/handles.cc
index 033fdab..b3704df 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -294,6 +294,21 @@
 }
 
 
+Handle<JSObject> Copy(Handle<JSObject> obj) {
+  Isolate* isolate = obj->GetIsolate();
+  CALL_HEAP_FUNCTION(isolate,
+                     isolate->heap()->CopyJSObject(*obj), JSObject);
+}
+
+
+Handle<JSObject> DeepCopy(Handle<JSObject> obj) {
+  Isolate* isolate = obj->GetIsolate();
+  CALL_HEAP_FUNCTION(isolate,
+                     obj->DeepCopy(isolate),
+                     JSObject);
+}
+
+
 // Wrappers for scripts are kept alive and cached in weak global
 // handles referred from foreign objects held by the scripts as long as
 // they are used. When they are not used anymore, the garbage
diff --git a/src/handles.h b/src/handles.h
index 585f7b4..c3e4dca 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -255,6 +255,10 @@
 Handle<Object> LookupSingleCharacterStringFromCode(Isolate* isolate,
                                                    uint32_t index);
 
+Handle<JSObject> Copy(Handle<JSObject> obj);
+
+Handle<JSObject> DeepCopy(Handle<JSObject> obj);
+
 Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray>,
                                       Handle<JSArray> array);
 
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 2d31ca4..bd47eec 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -2472,7 +2472,7 @@
 
 int HeapSnapshotJSONSerializer::GetStringId(const char* s) {
   HashMap::Entry* cache_entry = strings_.Lookup(
-      const_cast<char*>(s), StringHash(s), true);
+      const_cast<char*>(s), ObjectHash(s), true);
   if (cache_entry->value == NULL) {
     cache_entry->value = reinterpret_cast<void*>(next_string_id_++);
   }
@@ -2693,21 +2693,37 @@
 
 
 void HeapSnapshotJSONSerializer::SerializeStrings() {
-  ScopedVector<const unsigned char*> sorted_strings(
-      strings_.occupancy() + 1);
-  for (HashMap::Entry* entry = strings_.Start();
-       entry != NULL;
-       entry = strings_.Next(entry)) {
-    int index = static_cast<int>(reinterpret_cast<uintptr_t>(entry->value));
-    sorted_strings[index] = reinterpret_cast<const unsigned char*>(entry->key);
-  }
+  List<HashMap::Entry*> sorted_strings;
+  SortHashMap(&strings_, &sorted_strings);
   writer_->AddString("\"<dummy>\"");
-  for (int i = 1; i < sorted_strings.length(); ++i) {
+  for (int i = 0; i < sorted_strings.length(); ++i) {
     writer_->AddCharacter(',');
-    SerializeString(sorted_strings[i]);
+    SerializeString(
+        reinterpret_cast<const unsigned char*>(sorted_strings[i]->key));
     if (writer_->aborted()) return;
   }
 }
 
 
+template<typename T>
+inline static int SortUsingEntryValue(const T* x, const T* y) {
+  uintptr_t x_uint = reinterpret_cast<uintptr_t>((*x)->value);
+  uintptr_t y_uint = reinterpret_cast<uintptr_t>((*y)->value);
+  if (x_uint > y_uint) {
+    return 1;
+  } else if (x_uint == y_uint) {
+    return 0;
+  } else {
+    return -1;
+  }
+}
+
+
+void HeapSnapshotJSONSerializer::SortHashMap(
+    HashMap* map, List<HashMap::Entry*>* sorted_entries) {
+  for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p))
+    sorted_entries->Add(p);
+  sorted_entries->Sort(SortUsingEntryValue);
+}
+
 } }  // namespace v8::internal
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index c323f3c..7b0cf8f 100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -628,7 +628,7 @@
  public:
   explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot)
       : snapshot_(snapshot),
-        strings_(StringsMatch),
+        strings_(ObjectsMatch),
         next_node_id_(1),
         next_string_id_(1),
         writer_(NULL) {
@@ -636,16 +636,14 @@
   void Serialize(v8::OutputStream* stream);
 
  private:
-  INLINE(static bool StringsMatch(void* key1, void* key2)) {
-    return strcmp(reinterpret_cast<char*>(key1),
-                  reinterpret_cast<char*>(key2)) == 0;
+  INLINE(static bool ObjectsMatch(void* key1, void* key2)) {
+    return key1 == key2;
   }
 
-  INLINE(static uint32_t StringHash(const void* string)) {
-    const char* s = reinterpret_cast<const char*>(string);
-    int len = static_cast<int>(strlen(s));
-    return StringHasher::HashSequentialString(
-        s, len, v8::internal::kZeroHashSeed);
+  INLINE(static uint32_t ObjectHash(const void* key)) {
+    return ComputeIntegerHash(
+        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)),
+        v8::internal::kZeroHashSeed);
   }
 
   int GetStringId(const char* s);
@@ -658,6 +656,7 @@
   void SerializeSnapshot();
   void SerializeString(const unsigned char* s);
   void SerializeStrings();
+  void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries);
 
   static const int kEdgeFieldsCount;
   static const int kNodeFieldsCount;
diff --git a/src/heap.cc b/src/heap.cc
index b3e8cd7..24e4039 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -129,6 +129,8 @@
       old_gen_exhausted_(false),
       store_buffer_rebuilder_(store_buffer()),
       hidden_string_(NULL),
+      global_gc_prologue_callback_(NULL),
+      global_gc_epilogue_callback_(NULL),
       gc_safe_size_of_old_object_(NULL),
       total_regexp_code_generated_(0),
       tracer_(NULL),
@@ -1053,17 +1055,12 @@
 
 
 void Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
+  if (gc_type == kGCTypeMarkSweepCompact && global_gc_prologue_callback_) {
+    global_gc_prologue_callback_();
+  }
   for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
     if (gc_type & gc_prologue_callbacks_[i].gc_type) {
-      if (!gc_prologue_callbacks_[i].pass_isolate_) {
-        v8::GCPrologueCallback callback =
-            reinterpret_cast<v8::GCPrologueCallback>(
-                gc_prologue_callbacks_[i].callback);
-        callback(gc_type, flags);
-      } else {
-        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
-        gc_prologue_callbacks_[i].callback(isolate, gc_type, flags);
-      }
+      gc_prologue_callbacks_[i].callback(gc_type, flags);
     }
   }
 }
@@ -1072,18 +1069,12 @@
 void Heap::CallGCEpilogueCallbacks(GCType gc_type) {
   for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
     if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
-      if (!gc_epilogue_callbacks_[i].pass_isolate_) {
-        v8::GCPrologueCallback callback =
-            reinterpret_cast<v8::GCPrologueCallback>(
-                gc_epilogue_callbacks_[i].callback);
-        callback(gc_type, kNoGCCallbackFlags);
-      } else {
-        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
-        gc_epilogue_callbacks_[i].callback(
-            isolate, gc_type, kNoGCCallbackFlags);
-      }
+      gc_epilogue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags);
     }
   }
+  if (gc_type == kGCTypeMarkSweepCompact && global_gc_epilogue_callback_) {
+    global_gc_epilogue_callback_();
+  }
 }
 
 
@@ -4319,7 +4310,6 @@
   AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
       reinterpret_cast<Address>(result) + map->instance_size());
   alloc_memento->set_map_no_write_barrier(allocation_memento_map());
-  ASSERT(allocation_site->map() == allocation_site_map());
   alloc_memento->set_allocation_site(*allocation_site, SKIP_WRITE_BARRIER);
   return result;
 }
@@ -5063,7 +5053,6 @@
       AllocationMemento* alloc_memento;
       if (maybe_alloc_memento->To(&alloc_memento)) {
         alloc_memento->set_map_no_write_barrier(allocation_memento_map());
-        ASSERT(site->map() == allocation_site_map());
         alloc_memento->set_allocation_site(site, SKIP_WRITE_BARRIER);
       }
     }
@@ -5086,7 +5075,6 @@
     AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
         reinterpret_cast<Address>(clone) + object_size);
     alloc_memento->set_map_no_write_barrier(allocation_memento_map());
-    ASSERT(site->map() == allocation_site_map());
     alloc_memento->set_allocation_site(site, SKIP_WRITE_BARRIER);
   }
 
@@ -7080,17 +7068,15 @@
 }
 
 
-void Heap::AddGCPrologueCallback(v8::Isolate::GCPrologueCallback callback,
-                                 GCType gc_type,
-                                 bool pass_isolate) {
+void Heap::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
   ASSERT(callback != NULL);
-  GCPrologueCallbackPair pair(callback, gc_type, pass_isolate);
+  GCPrologueCallbackPair pair(callback, gc_type);
   ASSERT(!gc_prologue_callbacks_.Contains(pair));
   return gc_prologue_callbacks_.Add(pair);
 }
 
 
-void Heap::RemoveGCPrologueCallback(v8::Isolate::GCPrologueCallback callback) {
+void Heap::RemoveGCPrologueCallback(GCPrologueCallback callback) {
   ASSERT(callback != NULL);
   for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
     if (gc_prologue_callbacks_[i].callback == callback) {
@@ -7102,17 +7088,15 @@
 }
 
 
-void Heap::AddGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback,
-                                 GCType gc_type,
-                                 bool pass_isolate) {
+void Heap::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
   ASSERT(callback != NULL);
-  GCEpilogueCallbackPair pair(callback, gc_type, pass_isolate);
+  GCEpilogueCallbackPair pair(callback, gc_type);
   ASSERT(!gc_epilogue_callbacks_.Contains(pair));
   return gc_epilogue_callbacks_.Add(pair);
 }
 
 
-void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback) {
+void Heap::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
   ASSERT(callback != NULL);
   for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
     if (gc_epilogue_callbacks_[i].callback == callback) {
diff --git a/src/heap.h b/src/heap.h
index 2f91ebc..4dfa076 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1272,15 +1272,22 @@
   void GarbageCollectionGreedyCheck();
 #endif
 
-  void AddGCPrologueCallback(v8::Isolate::GCPrologueCallback callback,
-                             GCType gc_type_filter,
-                             bool pass_isolate = true);
-  void RemoveGCPrologueCallback(v8::Isolate::GCPrologueCallback callback);
+  void AddGCPrologueCallback(
+      GCPrologueCallback callback, GCType gc_type_filter);
+  void RemoveGCPrologueCallback(GCPrologueCallback callback);
 
-  void AddGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback,
-                             GCType gc_type_filter,
-                             bool pass_isolate = true);
-  void RemoveGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback);
+  void AddGCEpilogueCallback(
+      GCEpilogueCallback callback, GCType gc_type_filter);
+  void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
+
+  void SetGlobalGCPrologueCallback(GCCallback callback) {
+    ASSERT((callback == NULL) ^ (global_gc_prologue_callback_ == NULL));
+    global_gc_prologue_callback_ = callback;
+  }
+  void SetGlobalGCEpilogueCallback(GCCallback callback) {
+    ASSERT((callback == NULL) ^ (global_gc_epilogue_callback_ == NULL));
+    global_gc_epilogue_callback_ = callback;
+  }
 
   // Heap root getters.  We have versions with and without type::cast() here.
   // You can't use type::cast during GC because the assert fails.
@@ -2025,37 +2032,32 @@
   // GC callback function, called before and after mark-compact GC.
   // Allocations in the callback function are disallowed.
   struct GCPrologueCallbackPair {
-    GCPrologueCallbackPair(v8::Isolate::GCPrologueCallback callback,
-                           GCType gc_type,
-                           bool pass_isolate)
-        : callback(callback), gc_type(gc_type), pass_isolate_(pass_isolate) {
+    GCPrologueCallbackPair(GCPrologueCallback callback, GCType gc_type)
+        : callback(callback), gc_type(gc_type) {
     }
     bool operator==(const GCPrologueCallbackPair& pair) const {
       return pair.callback == callback;
     }
-    v8::Isolate::GCPrologueCallback callback;
+    GCPrologueCallback callback;
     GCType gc_type;
-    // TODO(dcarney): remove variable
-    bool pass_isolate_;
   };
   List<GCPrologueCallbackPair> gc_prologue_callbacks_;
 
   struct GCEpilogueCallbackPair {
-    GCEpilogueCallbackPair(v8::Isolate::GCPrologueCallback callback,
-                           GCType gc_type,
-                           bool pass_isolate)
-        : callback(callback), gc_type(gc_type), pass_isolate_(pass_isolate) {
+    GCEpilogueCallbackPair(GCEpilogueCallback callback, GCType gc_type)
+        : callback(callback), gc_type(gc_type) {
     }
     bool operator==(const GCEpilogueCallbackPair& pair) const {
       return pair.callback == callback;
     }
-    v8::Isolate::GCPrologueCallback callback;
+    GCEpilogueCallback callback;
     GCType gc_type;
-    // TODO(dcarney): remove variable
-    bool pass_isolate_;
   };
   List<GCEpilogueCallbackPair> gc_epilogue_callbacks_;
 
+  GCCallback global_gc_prologue_callback_;
+  GCCallback global_gc_epilogue_callback_;
+
   // Support for computing object sizes during GC.
   HeapObjectCallback gc_safe_size_of_old_object_;
   static int GcSafeSizeOfOldObject(HeapObject* object);
diff --git a/src/hydrogen-alias-analysis.h b/src/hydrogen-alias-analysis.h
index 21a5462..73e116e 100644
--- a/src/hydrogen-alias-analysis.h
+++ b/src/hydrogen-alias-analysis.h
@@ -88,6 +88,15 @@
   inline bool NoAlias(HValue* a, HValue* b) {
     return Query(a, b) == kNoAlias;
   }
+
+  // Returns the actual value of an instruction. In the case of a chain
+  // of informative definitions, return the root of the chain.
+  HValue* ActualValue(HValue* obj) {
+    while (obj->IsInformativeDefinition()) {  // Walk a chain of idefs.
+      obj = obj->RedefinedOperand();
+    }
+    return obj;
+  }
 };
 
 
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 4936a16..cca95b9 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -2526,11 +2526,9 @@
 
 bool HConstant::EmitAtUses() {
   ASSERT(IsLinked());
-  if (block()->graph()->has_osr() &&
-      block()->graph()->IsStandardConstant(this)) {
-    return true;
+  if (block()->graph()->has_osr()) {
+    return block()->graph()->IsStandardConstant(this);
   }
-  if (UseCount() == 0) return true;
   if (IsCell()) return false;
   if (representation().IsDouble()) return false;
   return true;
@@ -2575,6 +2573,10 @@
                               Representation::Integer32(),
                               is_not_in_new_space_,
                               handle_);
+  } else {
+    ASSERT(!HasNumberValue());
+    Maybe<HConstant*> number = CopyToTruncatedNumber(zone);
+    if (number.has_value) return number.value->CopyToTruncatedInt32(zone);
   }
   return Maybe<HConstant*>(res != NULL, res);
 }
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index aed2b4b..7d33141 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -128,6 +128,7 @@
   V(InvokeFunction)                            \
   V(IsConstructCallAndBranch)                  \
   V(IsObjectAndBranch)                         \
+  V(IsNumberAndBranch)                         \
   V(IsStringAndBranch)                         \
   V(IsSmiAndBranch)                            \
   V(IsUndetectableAndBranch)                   \
@@ -781,15 +782,11 @@
   // phase (so that live ranges will be shorter).
   virtual bool IsPurelyInformativeDefinition() { return false; }
 
-  // This method must always return the original HValue SSA definition,
-  // regardless of any chain of iDefs of this value.
+  // This method must always return the original HValue SSA definition
+  // (regardless of any iDef of this value).
   HValue* ActualValue() {
-    HValue* value = this;
-    int index;
-    while ((index = value->RedefinedOperandIndex()) != kNoRedefinedOperand) {
-      value = value->OperandAt(index);
-    }
-    return value;
+    int index = RedefinedOperandIndex();
+    return index == kNoRedefinedOperand ? this : OperandAt(index);
   }
 
   bool IsInteger32Constant();
@@ -1306,8 +1303,6 @@
 // Inserts an int3/stop break instruction for debugging purposes.
 class HDebugBreak V8_FINAL : public HTemplateInstruction<0> {
  public:
-  DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak);
-
   virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     return Representation::None();
   }
@@ -2789,6 +2784,21 @@
 };
 
 
+class HIsNumberAndBranch V8_FINAL : public HUnaryControlInstruction {
+ public:
+  explicit HIsNumberAndBranch(HValue* value)
+    : HUnaryControlInstruction(value, NULL, NULL) {
+    SetFlag(kFlexibleRepresentation);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
+    return Representation::None();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch)
+};
+
+
 class HCheckHeapObject V8_FINAL : public HUnaryOperation {
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc
deleted file mode 100644
index 6d01ae5..0000000
--- a/src/hydrogen-load-elimination.cc
+++ /dev/null
@@ -1,327 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "hydrogen-alias-analysis.h"
-#include "hydrogen-load-elimination.h"
-#include "hydrogen-instructions.h"
-
-namespace v8 {
-namespace internal {
-
-static const int kMaxTrackedFields = 16;
-static const int kMaxTrackedObjects = 5;
-
-// An element in the field approximation list.
-class HFieldApproximation : public ZoneObject {
- public:  // Just a data blob.
-  HValue* object_;
-  HLoadNamedField* last_load_;
-  HValue* last_value_;
-  HFieldApproximation* next_;
-};
-
-
-// The main datastructure used during load/store elimination. Each in-object
-// field is tracked separately. For each field, store a list of known field
-// values for known objects.
-class HLoadEliminationTable BASE_EMBEDDED {
- public:
-  HLoadEliminationTable(Zone* zone, HAliasAnalyzer* aliasing)
-    : zone_(zone), fields_(kMaxTrackedFields, zone), aliasing_(aliasing) { }
-
-  // Process a load instruction, updating internal table state. If a previous
-  // load or store for this object and field exists, return the new value with
-  // which the load should be replaced. Otherwise, return {instr}.
-  HValue* load(HLoadNamedField* instr) {
-    int field = FieldOf(instr->access());
-    if (field < 0) return instr;
-
-    HValue* object = instr->object()->ActualValue();
-    HFieldApproximation* approx = FindOrCreate(object, field);
-
-    if (approx->last_value_ == NULL) {
-      // Load is not redundant. Fill out a new entry.
-      approx->last_load_ = instr;
-      approx->last_value_ = instr;
-      return instr;
-    } else {
-      // Eliminate the load. Reuse previously stored value or load instruction.
-      return approx->last_value_;
-    }
-  }
-
-  // Process a store instruction, updating internal table state. If a previous
-  // store to the same object and field makes this store redundant (e.g. because
-  // the stored values are the same), return NULL indicating that this store
-  // instruction is redundant. Otherwise, return {instr}.
-  HValue* store(HStoreNamedField* instr) {
-    int field = FieldOf(instr->access());
-    if (field < 0) return instr;
-
-    HValue* object = instr->object()->ActualValue();
-    HValue* value = instr->value();
-
-    // Kill non-equivalent may-alias entries.
-    KillFieldInternal(object, field, value);
-    if (instr->has_transition()) {
-      // A transition store alters the map of the object.
-      // TODO(titzer): remember the new map (a constant) for the object.
-      KillFieldInternal(object, FieldOf(JSObject::kMapOffset), NULL);
-    }
-    HFieldApproximation* approx = FindOrCreate(object, field);
-
-    if (Equal(approx->last_value_, value)) {
-      // The store is redundant because the field already has this value.
-      return NULL;
-    } else {
-      // The store is not redundant. Update the entry.
-      approx->last_load_ = NULL;
-      approx->last_value_ = value;
-      return instr;
-    }
-  }
-
-  // Kill everything in this table.
-  void Kill() {
-    fields_.Rewind(0);
-  }
-
-  // Kill all entries matching the given offset.
-  void KillOffset(int offset) {
-    int field = FieldOf(offset);
-    if (field >= 0 && field < fields_.length()) {
-      fields_[field] = NULL;
-    }
-  }
-
-  // Compute the field index for the given object access; -1 if not tracked.
-  int FieldOf(HObjectAccess access) {
-    // Only track kMaxTrackedFields in-object fields.
-    if (!access.IsInobject()) return -1;
-    return FieldOf(access.offset());
-  }
-
-  // Print this table to stdout.
-  void Print() {
-    for (int i = 0; i < fields_.length(); i++) {
-      PrintF("  field %d: ", i);
-      for (HFieldApproximation* a = fields_[i]; a != NULL; a = a->next_) {
-        PrintF("[o%d =", a->object_->id());
-        if (a->last_load_ != NULL) PrintF(" L%d", a->last_load_->id());
-        if (a->last_value_ != NULL) PrintF(" v%d", a->last_value_->id());
-        PrintF("] ");
-      }
-      PrintF("\n");
-    }
-  }
-
- private:
-  // Find or create an entry for the given object and field pair.
-  HFieldApproximation* FindOrCreate(HValue* object, int field) {
-    EnsureFields(field + 1);
-
-    // Search for a field approximation for this object.
-    HFieldApproximation* approx = fields_[field];
-    int count = 0;
-    while (approx != NULL) {
-      if (aliasing_->MustAlias(object, approx->object_)) return approx;
-      count++;
-      approx = approx->next_;
-    }
-
-    if (count >= kMaxTrackedObjects) {
-      // Pull the last entry off the end and repurpose it for this object.
-      approx = ReuseLastApproximation(field);
-    } else {
-      // Allocate a new entry.
-      approx = new(zone_) HFieldApproximation();
-    }
-
-    // Insert the entry at the head of the list.
-    approx->object_ = object;
-    approx->last_load_ = NULL;
-    approx->last_value_ = NULL;
-    approx->next_ = fields_[field];
-    fields_[field] = approx;
-
-    return approx;
-  }
-
-  // Kill all entries for a given field that _may_ alias the given object
-  // and do _not_ have the given value.
-  void KillFieldInternal(HValue* object, int field, HValue* value) {
-    if (field >= fields_.length()) return;  // Nothing to do.
-
-    HFieldApproximation* approx = fields_[field];
-    HFieldApproximation* prev = NULL;
-    while (approx != NULL) {
-      if (aliasing_->MayAlias(object, approx->object_)) {
-        if (!Equal(approx->last_value_, value)) {
-          // Kill an aliasing entry that doesn't agree on the value.
-          if (prev != NULL) {
-            prev->next_ = approx->next_;
-          } else {
-            fields_[field] = approx->next_;
-          }
-          approx = approx->next_;
-          continue;
-        }
-      }
-      prev = approx;
-      approx = approx->next_;
-    }
-  }
-
-  bool Equal(HValue* a, HValue* b) {
-    if (a == b) return true;
-    if (a != NULL && b != NULL) return a->Equals(b);
-    return false;
-  }
-
-  // Remove the last approximation for a field so that it can be reused.
-  // We reuse the last entry because it was the first inserted and is thus
-  // farthest away from the current instruction.
-  HFieldApproximation* ReuseLastApproximation(int field) {
-    HFieldApproximation* approx = fields_[field];
-    ASSERT(approx != NULL);
-
-    HFieldApproximation* prev = NULL;
-    while (approx->next_ != NULL) {
-      prev = approx;
-      approx = approx->next_;
-    }
-    if (prev != NULL) prev->next_ = NULL;
-    return approx;
-  }
-
-  // Ensure internal storage for the given number of fields.
-  void EnsureFields(int num_fields) {
-    while (fields_.length() < num_fields) fields_.Add(NULL, zone_);
-  }
-
-  // Compute the field index for the given in-object offset.
-  int FieldOf(int offset) {
-    if (offset >= kMaxTrackedFields * kPointerSize) return -1;
-    ASSERT((offset % kPointerSize) == 0);  // Assume aligned accesses.
-    return offset / kPointerSize;
-  }
-
-  Zone* zone_;
-  ZoneList<HFieldApproximation*> fields_;
-  HAliasAnalyzer* aliasing_;
-};
-
-
-void HLoadEliminationPhase::Run() {
-  for (int i = 0; i < graph()->blocks()->length(); i++) {
-    HBasicBlock* block = graph()->blocks()->at(i);
-    EliminateLoads(block);
-  }
-}
-
-
-// For code de-uglification.
-#define TRACE(x) if (FLAG_trace_load_elimination) PrintF x
-
-
-// Eliminate loads and stores local to a block.
-void HLoadEliminationPhase::EliminateLoads(HBasicBlock* block) {
-  HAliasAnalyzer aliasing;
-  HLoadEliminationTable table(zone(), &aliasing);
-
-  TRACE(("-- load-elim B%d -------------------------------------------------\n",
-         block->block_id()));
-
-  for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
-    bool changed = false;
-    HInstruction* instr = it.Current();
-
-    switch (instr->opcode()) {
-      case HValue::kLoadNamedField: {
-        HLoadNamedField* load = HLoadNamedField::cast(instr);
-        TRACE((" process L%d field %d (o%d)\n",
-               instr->id(),
-               table.FieldOf(load->access()),
-               load->object()->ActualValue()->id()));
-        HValue* result = table.load(load);
-        if (result != instr) {
-          // The load can be replaced with a previous load or a value.
-          TRACE(("  replace L%d -> v%d\n", instr->id(), result->id()));
-          instr->DeleteAndReplaceWith(result);
-        }
-        changed = true;
-        break;
-      }
-      case HValue::kStoreNamedField: {
-        HStoreNamedField* store = HStoreNamedField::cast(instr);
-        TRACE((" process S%d field %d (o%d) = v%d\n",
-               instr->id(),
-               table.FieldOf(store->access()),
-               store->object()->ActualValue()->id(),
-               store->value()->id()));
-        HValue* result = table.store(store);
-        if (result == NULL) {
-          // The store is redundant. Remove it.
-          TRACE(("  remove S%d\n", instr->id()));
-          instr->DeleteAndReplaceWith(NULL);
-        }
-        changed = true;
-        break;
-      }
-      default: {
-        if (instr->CheckGVNFlag(kChangesInobjectFields)) {
-          TRACE((" kill-all i%d\n", instr->id()));
-          table.Kill();
-          continue;
-        }
-        if (instr->CheckGVNFlag(kChangesMaps)) {
-          TRACE((" kill-maps i%d\n", instr->id()));
-          table.KillOffset(JSObject::kMapOffset);
-        }
-        if (instr->CheckGVNFlag(kChangesElementsKind)) {
-          TRACE((" kill-elements-kind i%d\n", instr->id()));
-          table.KillOffset(JSObject::kMapOffset);
-          table.KillOffset(JSObject::kElementsOffset);
-        }
-        if (instr->CheckGVNFlag(kChangesElementsPointer)) {
-          TRACE((" kill-elements i%d\n", instr->id()));
-          table.KillOffset(JSObject::kElementsOffset);
-        }
-      }
-    // Improvements possible:
-    // - learn from HCheckMaps for field 0
-    // - remove unobservable stores (write-after-write)
-    }
-
-    if (changed && FLAG_trace_load_elimination) {
-      table.Print();
-    }
-  }
-}
-
-
-} }  // namespace v8::internal
diff --git a/src/hydrogen-load-elimination.h b/src/hydrogen-load-elimination.h
deleted file mode 100644
index ef6f71f..0000000
--- a/src/hydrogen-load-elimination.h
+++ /dev/null
@@ -1,50 +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_HYDROGEN_LOAD_ELIMINATION_H_
-#define V8_HYDROGEN_LOAD_ELIMINATION_H_
-
-#include "hydrogen.h"
-
-namespace v8 {
-namespace internal {
-
-class HLoadEliminationPhase : public HPhase {
- public:
-  explicit HLoadEliminationPhase(HGraph* graph)
-      : HPhase("H_Load elimination", graph) { }
-
-  void Run();
-
- private:
-  void EliminateLoads(HBasicBlock* block);
-};
-
-
-} }  // namespace v8::internal
-
-#endif  // V8_HYDROGEN_LOAD_ELIMINATION_H_
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 184d2ff..23c373f 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -43,7 +43,6 @@
 #include "hydrogen-escape-analysis.h"
 #include "hydrogen-infer-representation.h"
 #include "hydrogen-infer-types.h"
-#include "hydrogen-load-elimination.h"
 #include "hydrogen-gvn.h"
 #include "hydrogen-mark-deoptimize.h"
 #include "hydrogen-minus-zero.h"
@@ -1033,7 +1032,8 @@
 }
 
 
-void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
+void HGraphBuilder::AddIncrementCounter(StatsCounter* counter,
+                                        HValue* context) {
   if (FLAG_native_code_counters && counter->Enabled()) {
     HValue* reference = Add<HConstant>(ExternalReference(counter));
     HValue* old_value = Add<HLoadNamedField>(reference,
@@ -1824,7 +1824,8 @@
 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
                                                     int previous_object_size,
                                                     HValue* alloc_site) {
-  ASSERT(alloc_site != NULL);
+  // TODO(mvstanton): ASSERT altered to CHECK to diagnose chromium bug 284577
+  CHECK(alloc_site != NULL);
   HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>(
       previous_object, previous_object_size);
   Handle<Map> alloc_memento_map(
@@ -2972,8 +2973,6 @@
 
   if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>();
 
-  if (FLAG_load_elimination) Run<HLoadEliminationPhase>();
-
   CollectPhis();
 
   if (has_osr()) osr()->FinishOsrValues();
@@ -4173,7 +4172,8 @@
       IsFastLiteral(Handle<JSObject>::cast(boilerplate),
                     kMaxFastLiteralDepth,
                     &max_properties)) {
-    Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate);
+    Handle<JSObject> boilerplate_object =
+        Handle<JSObject>::cast(boilerplate);
 
     literal = BuildFastLiteral(boilerplate_object,
                                Handle<Object>::null(),
@@ -5136,7 +5136,9 @@
     CHECK_ALIVE(VisitForValue(prop->obj()));
     HValue* object = Top();
     HValue* key = NULL;
-    if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) ||
+    if ((!prop->IsStringLength() &&
+         !prop->IsFunctionPrototype() &&
+         !prop->key()->IsPropertyName()) ||
         prop->IsStringAccess()) {
       CHECK_ALIVE(VisitForValue(prop->key()));
       key = Top();
@@ -5826,20 +5828,17 @@
 }
 
 
-static bool AreStringTypes(SmallMapList* types) {
-  if (types == NULL || types->length() == 0) return false;
-  for (int i = 0; i < types->length(); i++) {
-    if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
-  }
-  return true;
-}
-
-
 void HOptimizedGraphBuilder::BuildLoad(Property* expr,
                                        int position,
                                        BailoutId ast_id) {
   HInstruction* instr = NULL;
-  if (expr->IsStringAccess()) {
+  if (expr->IsStringLength()) {
+    HValue* string = Pop();
+    BuildCheckHeapObject(string);
+    HInstruction* checkstring =
+        AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
+    instr = BuildLoadStringLength(string, checkstring);
+  } else if (expr->IsStringAccess()) {
     HValue* index = Pop();
     HValue* string = Pop();
     HValue* context = environment()->context();
@@ -5875,12 +5874,6 @@
       } else {
         instr = BuildLoadNamedMonomorphic(Pop(), name, map);
       }
-    } else if (AreStringTypes(types) &&
-               name->Equals(isolate()->heap()->length_string())) {
-      BuildCheckHeapObject(Pop());
-      HValue* checked_object =
-          AddInstruction(HCheckInstanceType::NewIsString(object, zone()));
-      instr = BuildLoadStringLength(object, checked_object);
     } else if (types != NULL && types->length() > 1) {
       return HandlePolymorphicLoadNamedField(
           position, ast_id, Pop(), types, name);
@@ -5921,7 +5914,9 @@
   if (TryArgumentsAccess(expr)) return;
 
   CHECK_ALIVE(VisitForValue(expr->obj()));
-  if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) ||
+  if ((!expr->IsStringLength() &&
+       !expr->IsFunctionPrototype() &&
+       !expr->key()->IsPropertyName()) ||
       expr->IsStringAccess()) {
     CHECK_ALIVE(VisitForValue(expr->key()));
   }
@@ -7572,7 +7567,9 @@
   HValue* object = Top();
 
   HValue* key = NULL;
-  if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) ||
+  if ((!prop->IsStringLength() &&
+       !prop->IsFunctionPrototype() &&
+       !prop->key()->IsPropertyName()) ||
       prop->IsStringAccess()) {
     CHECK_ALIVE(VisitForValue(prop->key()));
     key = Top();
@@ -7622,16 +7619,9 @@
 }
 
 
-// Checks if the given shift amounts have following forms:
-// (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa).
+// Checks if the given shift amounts have form: (sa) and (32 - sa).
 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
                                              HValue* const32_minus_sa) {
-  if (sa->IsConstant() && const32_minus_sa->IsConstant()) {
-    const HConstant* c1 = HConstant::cast(sa);
-    const HConstant* c2 = HConstant::cast(const32_minus_sa);
-    return c1->HasInteger32Value() && c2->HasInteger32Value() &&
-        (c1->Integer32Value() + c2->Integer32Value() == 32);
-  }
   if (!const32_minus_sa->IsSub()) return false;
   HSub* sub = HSub::cast(const32_minus_sa);
   if (sa != sub->right()) return false;
diff --git a/src/hydrogen.h b/src/hydrogen.h
index af36c50..c1dafa8 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1271,7 +1271,8 @@
   void FinishExitWithHardDeoptimization(const char* reason,
                                         HBasicBlock* continuation);
 
-  void AddIncrementCounter(StatsCounter* counter);
+  void AddIncrementCounter(StatsCounter* counter,
+                           HValue* context);
 
   class IfBuilder V8_FINAL {
    public:
diff --git a/src/i18n.cc b/src/i18n.cc
index dbff6e5..0ae19c8 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -464,7 +464,7 @@
 
   Handle<String> key = isolate->factory()->NewStringFromAscii(
       CStrVector("minimumSignificantDigits"));
-  if (JSReceiver::HasLocalProperty(resolved, key)) {
+  if (resolved->HasLocalProperty(*key)) {
     JSObject::SetProperty(
         resolved,
         isolate->factory()->NewStringFromAscii(
@@ -477,7 +477,7 @@
 
   key = isolate->factory()->NewStringFromAscii(
       CStrVector("maximumSignificantDigits"));
-  if (JSReceiver::HasLocalProperty(resolved, key)) {
+  if (resolved->HasLocalProperty(*key)) {
     JSObject::SetProperty(
         resolved,
         isolate->factory()->NewStringFromAscii(
@@ -855,7 +855,7 @@
     Handle<JSObject> obj) {
   Handle<String> key =
       isolate->factory()->NewStringFromAscii(CStrVector("dateFormat"));
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (obj->HasLocalProperty(*key)) {
     return reinterpret_cast<icu::SimpleDateFormat*>(
         obj->GetInternalField(0));
   }
@@ -920,7 +920,7 @@
     Handle<JSObject> obj) {
   Handle<String> key =
       isolate->factory()->NewStringFromAscii(CStrVector("numberFormat"));
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (obj->HasLocalProperty(*key)) {
     return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0));
   }
 
@@ -981,7 +981,7 @@
                                         Handle<JSObject> obj) {
   Handle<String> key =
       isolate->factory()->NewStringFromAscii(CStrVector("collator"));
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (obj->HasLocalProperty(*key)) {
     return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0));
   }
 
@@ -1045,7 +1045,7 @@
                                                        Handle<JSObject> obj) {
   Handle<String> key =
       isolate->factory()->NewStringFromAscii(CStrVector("breakIterator"));
-  if (JSReceiver::HasLocalProperty(obj, key)) {
+  if (obj->HasLocalProperty(*key)) {
     return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0));
   }
 
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 736dd3b..55eff93 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -561,7 +561,6 @@
   static uint64_t found_by_runtime_probing_only_;
 
   friend class ExternalReference;
-  friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
 };
 
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 91eba98..a159748 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -539,12 +539,10 @@
   __ mov(eax, Operand(esp, 8 * kPointerSize));
   {
     FrameScope scope(masm, StackFrame::MANUAL);
-    __ PrepareCallCFunction(2, ebx);
-    __ mov(Operand(esp, 1 * kPointerSize),
-           Immediate(ExternalReference::isolate_address(masm->isolate())));
+    __ PrepareCallCFunction(1, ebx);
     __ mov(Operand(esp, 0), eax);
     __ CallCFunction(
-        ExternalReference::get_make_code_young_function(masm->isolate()), 2);
+        ExternalReference::get_make_code_young_function(masm->isolate()), 1);
   }
   __ popad();
   __ ret(0);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index c113dfb..a83c1ae 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -984,7 +984,7 @@
           ASSERT_EQ(Token::SHL, op);
           if (CpuFeatures::IsSupported(SSE2)) {
             CpuFeatureScope use_sse2(masm, SSE2);
-            __ Cvtsi2sd(xmm0, left);
+            __ cvtsi2sd(xmm0, left);
             __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
           } else {
             __ mov(Operand(esp, 1 * kPointerSize), left);
@@ -1370,7 +1370,7 @@
         // Store the result in the HeapNumber and return.
         if (CpuFeatures::IsSupported(SSE2)) {
           CpuFeatureScope use_sse2(masm, SSE2);
-          __ Cvtsi2sd(xmm0, ebx);
+          __ cvtsi2sd(xmm0, ebx);
           __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
         } else {
           __ mov(Operand(esp, 1 * kPointerSize), ebx);
@@ -1594,7 +1594,7 @@
         // Store the result in the HeapNumber and return.
         if (CpuFeatures::IsSupported(SSE2)) {
           CpuFeatureScope use_sse2(masm, SSE2);
-          __ Cvtsi2sd(xmm0, ebx);
+          __ cvtsi2sd(xmm0, ebx);
           __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
         } else {
           __ mov(Operand(esp, 1 * kPointerSize), ebx);
@@ -1782,7 +1782,7 @@
         // Store the result in the HeapNumber and return.
         if (CpuFeatures::IsSupported(SSE2)) {
           CpuFeatureScope use_sse2(masm, SSE2);
-          __ Cvtsi2sd(xmm0, ebx);
+          __ cvtsi2sd(xmm0, ebx);
           __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
         } else {
           __ mov(Operand(esp, 1 * kPointerSize), ebx);
@@ -2329,12 +2329,12 @@
   __ jmp(not_numbers);  // Argument in eax is not a number.
   __ bind(&load_smi_edx);
   __ SmiUntag(edx);  // Untag smi before converting to float.
-  __ Cvtsi2sd(xmm0, edx);
+  __ cvtsi2sd(xmm0, edx);
   __ SmiTag(edx);  // Retag smi for heap number overwriting test.
   __ jmp(&load_eax);
   __ bind(&load_smi_eax);
   __ SmiUntag(eax);  // Untag smi before converting to float.
-  __ Cvtsi2sd(xmm1, eax);
+  __ cvtsi2sd(xmm1, eax);
   __ SmiTag(eax);  // Retag smi for heap number overwriting test.
   __ jmp(&done, Label::kNear);
   __ bind(&load_float_eax);
@@ -2350,11 +2350,11 @@
   __ mov(scratch, left);
   ASSERT(!scratch.is(right));  // We're about to clobber scratch.
   __ SmiUntag(scratch);
-  __ Cvtsi2sd(xmm0, scratch);
+  __ cvtsi2sd(xmm0, scratch);
 
   __ mov(scratch, right);
   __ SmiUntag(scratch);
-  __ Cvtsi2sd(xmm1, scratch);
+  __ cvtsi2sd(xmm1, scratch);
 }
 
 
@@ -2365,7 +2365,7 @@
                                                   Register scratch,
                                                   XMMRegister xmm_scratch) {
   __ cvttsd2si(int32_result, Operand(operand));
-  __ Cvtsi2sd(xmm_scratch, int32_result);
+  __ cvtsi2sd(xmm_scratch, int32_result);
   __ pcmpeqd(xmm_scratch, operand);
   __ movmskps(scratch, xmm_scratch);
   // Two least significant bits should be both set.
@@ -2470,7 +2470,7 @@
 
   // Save 1 in double_result - we need this several times later on.
   __ mov(scratch, Immediate(1));
-  __ Cvtsi2sd(double_result, scratch);
+  __ cvtsi2sd(double_result, scratch);
 
   if (exponent_type_ == ON_STACK) {
     Label base_is_smi, unpack_exponent;
@@ -2490,7 +2490,7 @@
 
     __ bind(&base_is_smi);
     __ SmiUntag(base);
-    __ Cvtsi2sd(double_base, base);
+    __ cvtsi2sd(double_base, base);
 
     __ bind(&unpack_exponent);
     __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
@@ -2683,7 +2683,7 @@
   // and may not have contained the exponent value in the first place when the
   // exponent is a smi.  We reset it with exponent value before bailing out.
   __ j(not_equal, &done);
-  __ Cvtsi2sd(double_exponent, exponent);
+  __ cvtsi2sd(double_exponent, exponent);
 
   // Returning or bailing out.
   Counters* counters = masm->isolate()->counters();
@@ -2756,7 +2756,8 @@
     __ j(not_equal, &miss);
   }
 
-  StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss);
+  StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss,
+                                         support_wrapper_);
   __ bind(&miss);
   StubCompiler::TailCallBuiltin(
       masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
@@ -3494,7 +3495,7 @@
   __ call(edx);
 
   // Drop arguments and come back to JS mode.
-  __ LeaveApiExitFrame(true);
+  __ LeaveApiExitFrame();
 
   // Check the result.
   Label success;
@@ -4507,8 +4508,6 @@
     // stack alignment is known to be correct. This function takes one argument
     // which is passed on the stack, and we know that the stack has been
     // prepared to pass at least one argument.
-    __ mov(Operand(esp, 1 * kPointerSize),
-           Immediate(ExternalReference::isolate_address(masm->isolate())));
     __ mov(Operand(esp, 0 * kPointerSize), eax);  // Result.
     __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY);
   }
@@ -6259,7 +6258,7 @@
     __ bind(&right_smi);
     __ mov(ecx, eax);  // Can't clobber eax because we can still jump away.
     __ SmiUntag(ecx);
-    __ Cvtsi2sd(xmm1, ecx);
+    __ cvtsi2sd(xmm1, ecx);
 
     __ bind(&left);
     __ JumpIfSmi(edx, &left_smi, Label::kNear);
@@ -6271,7 +6270,7 @@
     __ bind(&left_smi);
     __ mov(ecx, edx);  // Can't clobber edx because we can still jump away.
     __ SmiUntag(ecx);
-    __ Cvtsi2sd(xmm0, ecx);
+    __ cvtsi2sd(xmm0, ecx);
 
     __ bind(&done);
     // Compare operands.
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 9385423..84a4d23 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -768,7 +768,7 @@
   __ SmiUntag(ebx);
   if (CpuFeatures::IsSupported(SSE2)) {
     CpuFeatureScope fscope(masm, SSE2);
-    __ Cvtsi2sd(xmm0, ebx);
+    __ cvtsi2sd(xmm0, ebx);
     __ movdbl(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize),
               xmm0);
   } else {
@@ -1165,8 +1165,7 @@
 }
 
 
-void Code::PatchPlatformCodeAge(Isolate* isolate,
-                                byte* sequence,
+void Code::PatchPlatformCodeAge(byte* sequence,
                                 Code::Age age,
                                 MarkingParity parity) {
   uint32_t young_length;
@@ -1175,7 +1174,7 @@
     CopyBytes(sequence, young_sequence, young_length);
     CPU::FlushICache(sequence, young_length);
   } else {
-    Code* stub = GetCodeAgeStub(isolate, age, parity);
+    Code* stub = GetCodeAgeStub(age, parity);
     CodePatcher patcher(sequence, young_length);
     patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32);
   }
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 06628ff..d50b780 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1733,9 +1733,9 @@
         case 9:
           __ lea(left, Operand(left, left, times_8, 0));
           break;
-        case 16:
-          __ shl(left, 4);
-          break;
+       case 16:
+         __ shl(left, 4);
+         break;
         default:
           __ imul(left, left, constant);
           break;
@@ -2208,6 +2208,8 @@
     XMMRegister left = ToDoubleRegister(instr->left());
     XMMRegister right = ToDoubleRegister(instr->right());
     XMMRegister result = ToDoubleRegister(instr->result());
+    // Modulo uses a fixed result register.
+    ASSERT(instr->op() == Token::MOD || left.is(result));
     switch (instr->op()) {
       case Token::ADD:
         __ addsd(left, right);
@@ -2234,7 +2236,7 @@
             4);
 
         // Return value is in st(0) on ia32.
-        // Store it into the result register.
+        // Store it into the (fixed) result register.
         __ sub(Operand(esp), Immediate(kDoubleSize));
         __ fstp_d(Operand(esp, 0));
         __ movdbl(result, Operand(esp, 0));
@@ -2338,6 +2340,25 @@
 }
 
 
+void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
+  Representation r = instr->hydrogen()->value()->representation();
+  if (r.IsSmiOrInteger32() || r.IsDouble()) {
+    EmitBranch(instr, no_condition);
+  } else {
+    ASSERT(r.IsTagged());
+    Register reg = ToRegister(instr->value());
+    HType type = instr->hydrogen()->value()->type();
+    if (type.IsTaggedNumber()) {
+      EmitBranch(instr, no_condition);
+    }
+    __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
+    __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
+           factory()->heap_number_map());
+    EmitBranch(instr, equal);
+  }
+}
+
+
 void LCodeGen::DoBranch(LBranch* instr) {
   Representation r = instr->hydrogen()->value()->representation();
   if (r.IsSmiOrInteger32()) {
@@ -2535,18 +2556,10 @@
     EmitGoto(next_block);
   } else {
     if (instr->is_double()) {
-      if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
-        CpuFeatureScope scope(masm(), SSE2);
-        __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
-      } else {
-        X87Fxch(ToX87Register(right));
-        X87Fxch(ToX87Register(left), 1);
-        __ fld(0);
-        __ fld(2);
-        __ FCmp();
-      }
+      CpuFeatureScope scope(masm(), SSE2);
       // Don't base result on EFLAGS when a NaN is involved. Instead
       // jump to the false block.
+      __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
       __ j(parity_even, instr->FalseLabel(chunk_));
     } else {
       if (right->IsConstantOperand()) {
@@ -3964,7 +3977,7 @@
     __ bind(&negative_sign);
     // Truncate, then compare and compensate.
     __ cvttsd2si(output_reg, Operand(input_reg));
-    __ Cvtsi2sd(xmm_scratch, output_reg);
+    __ cvtsi2sd(xmm_scratch, output_reg);
     __ ucomisd(input_reg, xmm_scratch);
     __ j(equal, &done, Label::kNear);
     __ sub(output_reg, Immediate(1));
@@ -4014,7 +4027,7 @@
   __ RecordComment("D2I conversion overflow");
   DeoptimizeIf(equal, instr->environment());
 
-  __ Cvtsi2sd(xmm_scratch, output_reg);
+  __ cvtsi2sd(xmm_scratch, output_reg);
   __ ucomisd(xmm_scratch, input_temp);
   __ j(equal, &done);
   __ sub(output_reg, Immediate(1));
@@ -4965,7 +4978,7 @@
   ASSERT(output->IsDoubleRegister());
   if (CpuFeatures::IsSupported(SSE2)) {
     CpuFeatureScope scope(masm(), SSE2);
-    __ Cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
+    __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
   } else if (input->IsRegister()) {
     Register input_reg = ToRegister(input);
     __ push(input_reg);
@@ -5074,7 +5087,7 @@
     __ xor_(reg, 0x80000000);
     if (CpuFeatures::IsSupported(SSE2)) {
       CpuFeatureScope feature_scope(masm(), SSE2);
-      __ Cvtsi2sd(xmm0, Operand(reg));
+      __ cvtsi2sd(xmm0, Operand(reg));
     } else {
       __ push(reg);
       __ fild_s(Operand(esp, 0));
@@ -5295,7 +5308,7 @@
                                 bool deoptimize_on_minus_zero,
                                 LEnvironment* env,
                                 NumberUntagDMode mode) {
-  Label convert, load_smi, done;
+  Label load_smi, done;
 
   if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
     // Smi check.
@@ -5304,15 +5317,26 @@
     // Heap number map check.
     __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
            factory()->heap_number_map());
-    if (can_convert_undefined_to_nan) {
-      __ j(not_equal, &convert, Label::kNear);
-    } else {
+    if (!can_convert_undefined_to_nan) {
       DeoptimizeIf(not_equal, env);
-    }
+    } else {
+      Label heap_number, convert;
+      __ j(equal, &heap_number, Label::kNear);
 
+      // Convert undefined (and hole) to NaN.
+      __ cmp(input_reg, factory()->undefined_value());
+      DeoptimizeIf(not_equal, env);
+
+      __ bind(&convert);
+      ExternalReference nan =
+          ExternalReference::address_of_canonical_non_hole_nan();
+      __ movdbl(result_reg, Operand::StaticVariable(nan));
+      __ jmp(&done, Label::kNear);
+
+      __ bind(&heap_number);
+    }
     // Heap number to XMM conversion.
     __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
-
     if (deoptimize_on_minus_zero) {
       XMMRegister xmm_scratch = xmm0;
       __ xorps(xmm_scratch, xmm_scratch);
@@ -5323,19 +5347,6 @@
       DeoptimizeIf(not_zero, env);
     }
     __ jmp(&done, Label::kNear);
-
-    if (can_convert_undefined_to_nan) {
-      __ bind(&convert);
-
-      // Convert undefined (and hole) to NaN.
-      __ cmp(input_reg, factory()->undefined_value());
-      DeoptimizeIf(not_equal, env);
-
-      ExternalReference nan =
-          ExternalReference::address_of_canonical_non_hole_nan();
-      __ movdbl(result_reg, Operand::StaticVariable(nan));
-      __ jmp(&done, Label::kNear);
-    }
   } else {
     ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
   }
@@ -5345,7 +5356,7 @@
   // input register since we avoid dependencies.
   __ mov(temp_reg, input_reg);
   __ SmiUntag(temp_reg);  // Untag smi before converting to float.
-  __ Cvtsi2sd(result_reg, Operand(temp_reg));
+  __ cvtsi2sd(result_reg, Operand(temp_reg));
   __ bind(&done);
 }
 
@@ -5406,16 +5417,12 @@
   Register input_reg = ToRegister(input);
   ASSERT(input_reg.is(ToRegister(instr->result())));
 
-  if (instr->hydrogen()->value()->representation().IsSmi()) {
-    __ SmiUntag(input_reg);
-  } else {
-    DeferredTaggedToI* deferred =
-        new(zone()) DeferredTaggedToI(this, instr, x87_stack_);
+  DeferredTaggedToI* deferred =
+      new(zone()) DeferredTaggedToI(this, instr, x87_stack_);
 
-    __ JumpIfNotSmi(input_reg, deferred->entry());
-    __ SmiUntag(input_reg);
-    __ bind(deferred->exit());
-  }
+  __ JumpIfNotSmi(input_reg, deferred->entry());
+  __ SmiUntag(input_reg);
+  __ bind(deferred->exit());
 }
 
 
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index a47b525..ca1e60d 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -762,44 +762,52 @@
 
 LInstruction* LChunkBuilder::DoShift(Token::Value op,
                                      HBitwiseBinaryOperation* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
-    ASSERT(instr->left()->representation().Equals(instr->representation()));
-    ASSERT(instr->right()->representation().Equals(instr->representation()));
-    LOperand* left = UseRegisterAtStart(instr->left());
+  if (instr->representation().IsTagged()) {
+    ASSERT(instr->left()->representation().IsSmiOrTagged());
+    ASSERT(instr->right()->representation().IsSmiOrTagged());
 
-    HValue* right_value = instr->right();
-    LOperand* right = NULL;
-    int constant_value = 0;
-    bool does_deopt = false;
-    if (right_value->IsConstant()) {
-      HConstant* constant = HConstant::cast(right_value);
-      right = chunk_->DefineConstantOperand(constant);
-      constant_value = constant->Integer32Value() & 0x1f;
-      // Left shifts can deoptimize if we shift by > 0 and the result cannot be
-      // truncated to smi.
-      if (instr->representation().IsSmi() && constant_value > 0) {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
-      }
-    } else {
-      right = UseFixed(right_value, ecx);
-    }
-
-    // Shift operations can only deoptimize if we do a logical shift by 0 and
-    // the result cannot be truncated to int32.
-    if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
-    }
-
-    LInstruction* result =
-        DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt));
-    return does_deopt ? AssignEnvironment(result) : result;
-  } else {
-    return DoArithmeticT(op, instr);
+    LOperand* context = UseFixed(instr->context(), esi);
+    LOperand* left = UseFixed(instr->left(), edx);
+    LOperand* right = UseFixed(instr->right(), eax);
+    LArithmeticT* result = new(zone()) LArithmeticT(op, context, left, right);
+    return MarkAsCall(DefineFixed(result, eax), instr);
   }
+
+  ASSERT(instr->representation().IsSmiOrInteger32());
+  ASSERT(instr->left()->representation().Equals(instr->representation()));
+  ASSERT(instr->right()->representation().Equals(instr->representation()));
+  LOperand* left = UseRegisterAtStart(instr->left());
+
+  HValue* right_value = instr->right();
+  LOperand* right = NULL;
+  int constant_value = 0;
+  bool does_deopt = false;
+  if (right_value->IsConstant()) {
+    HConstant* constant = HConstant::cast(right_value);
+    right = chunk_->DefineConstantOperand(constant);
+    constant_value = constant->Integer32Value() & 0x1f;
+    // Left shifts can deoptimize if we shift by > 0 and the result cannot be
+    // truncated to smi.
+    if (instr->representation().IsSmi() && constant_value > 0) {
+      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
+    }
+  } else {
+    right = UseFixed(right_value, ecx);
+  }
+
+  // Shift operations can only deoptimize if we do a logical shift by 0 and
+  // the result cannot be truncated to int32.
+  if (op == Token::SHR && constant_value == 0) {
+    if (FLAG_opt_safe_uint32_operations) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    } else {
+      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
+    }
+  }
+
+  LInstruction* result =
+      DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt));
+  return does_deopt ? AssignEnvironment(result) : result;
 }
 
 
@@ -808,22 +816,21 @@
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->left()->representation().IsDouble());
   ASSERT(instr->right()->representation().IsDouble());
-  if (op == Token::MOD) {
-    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
-    LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    return MarkAsCall(DefineSameAsFirst(result), instr);
-  } else {
-    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
-    LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    return DefineSameAsFirst(result);
-  }
+  ASSERT(op != Token::MOD);
+  LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
+  LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
+  LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
+  return DefineSameAsFirst(result);
 }
 
 
 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
-                                           HBinaryOperation* instr) {
+                                           HArithmeticBinaryOperation* instr) {
+  ASSERT(op == Token::ADD ||
+         op == Token::DIV ||
+         op == Token::MOD ||
+         op == Token::MUL ||
+         op == Token::SUB);
   HValue* left = instr->left();
   HValue* right = instr->right();
   ASSERT(left->representation().IsTagged());
@@ -1435,19 +1442,29 @@
   if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
-    ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
 
     LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
     LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
     return DefineSameAsFirst(new(zone()) LBitI(left, right));
   } else {
-    return DoArithmeticT(instr->op(), instr);
+    ASSERT(instr->representation().IsSmiOrTagged());
+    ASSERT(instr->left()->representation().IsSmiOrTagged());
+    ASSERT(instr->right()->representation().IsSmiOrTagged());
+
+    LOperand* context = UseFixed(instr->context(), esi);
+    LOperand* left = UseFixed(instr->left(), edx);
+    LOperand* right = UseFixed(instr->right(), eax);
+    LArithmeticT* result =
+        new(zone()) LArithmeticT(instr->op(), context, left, right);
+    return MarkAsCall(DefineFixed(result, eax), instr);
   }
 }
 
 
 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
+  if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::DIV, instr);
+  } else if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
     if (instr->HasPowerOf2Divisor()) {
@@ -1464,9 +1481,8 @@
     LOperand* divisor = UseRegister(instr->right());
     LDivI* result = new(zone()) LDivI(dividend, divisor, temp);
     return AssignEnvironment(DefineFixed(result, eax));
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::DIV, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::DIV, instr);
   }
 }
@@ -1568,10 +1584,17 @@
           ? AssignEnvironment(result)
           : result;
     }
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::MOD, instr);
-  } else {
+  } else if (instr->representation().IsSmiOrTagged()) {
     return DoArithmeticT(Token::MOD, instr);
+  } else {
+    ASSERT(instr->representation().IsDouble());
+    // We call a C function for double modulo. It can't trigger a GC. We need
+    // to use fixed result register for the call.
+    // TODO(fschneider): Allow any register as input registers.
+    LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD,
+                                                 UseFixedDouble(left, xmm2),
+                                                 UseFixedDouble(right, xmm1));
+    return MarkAsCall(DefineFixedDouble(mod, xmm1), instr);
   }
 }
 
@@ -1595,6 +1618,7 @@
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::MUL, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::MUL, instr);
   }
 }
@@ -1615,6 +1639,7 @@
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::SUB, instr);
   } else {
+    ASSERT(instr->representation().IsSmiOrTagged());
     return DoArithmeticT(Token::SUB, instr);
   }
 }
@@ -1646,6 +1671,7 @@
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::ADD, instr);
   } else {
+    ASSERT(instr->representation().IsSmiOrTagged());
     return DoArithmeticT(Token::ADD, instr);
   }
 }
@@ -2024,6 +2050,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) {
+  return new(zone())
+    LIsNumberAndBranch(UseRegisterOrConstantAtStart(instr->value()));
+}
+
+
 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
   LOperand* temp = TempRegister();
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 83c4c8d..3a609c9 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -116,6 +116,7 @@
   V(IsObjectAndBranch)                          \
   V(IsStringAndBranch)                          \
   V(IsSmiAndBranch)                             \
+  V(IsNumberAndBranch)                          \
   V(IsUndetectableAndBranch)                    \
   V(Label)                                      \
   V(LazyBailout)                                \
@@ -921,6 +922,19 @@
 };
 
 
+class LIsNumberAndBranch V8_FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LIsNumberAndBranch(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch, "is-number-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsNumberAndBranch)
+};
+
+
 class LIsStringAndBranch V8_FINAL : public LControlInstruction<1, 1> {
  public:
   LIsStringAndBranch(LOperand* value, LOperand* temp) {
@@ -1620,6 +1634,11 @@
     return hydrogen()->is_external();
   }
 
+  virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
+    return !CpuFeatures::IsSupported(SSE2) &&
+        !IsDoubleOrFloatElementsKind(hydrogen()->elements_kind());
+  }
+
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
@@ -2170,7 +2189,7 @@
   LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -2888,7 +2907,7 @@
   LInstruction* DoArithmeticD(Token::Value op,
                               HArithmeticBinaryOperation* instr);
   LInstruction* DoArithmeticT(Token::Value op,
-                              HBinaryOperation* instr);
+                              HArithmeticBinaryOperation* instr);
 
   LOperand* GetStoreKeyedValueOperand(HStoreKeyed* instr);
 
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 2ae0612..b65d328 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -283,7 +283,7 @@
                                Label::Distance dst) {
   ASSERT(!input_reg.is(scratch));
   cvttsd2si(result_reg, Operand(input_reg));
-  Cvtsi2sd(scratch, Operand(result_reg));
+  cvtsi2sd(scratch, Operand(result_reg));
   ucomisd(scratch, input_reg);
   j(not_equal, conversion_failed, dst);
   j(parity_even, conversion_failed, dst);  // NaN.
@@ -392,7 +392,7 @@
 
     movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
     cvttsd2si(result_reg, Operand(xmm0));
-    Cvtsi2sd(temp, Operand(result_reg));
+    cvtsi2sd(temp, Operand(result_reg));
     ucomisd(xmm0, temp);
     RecordComment("Deferred TaggedToI: lost precision");
     j(not_equal, lost_precision, Label::kNear);
@@ -457,7 +457,7 @@
   cmp(src, Immediate(0));
   movdbl(scratch,
          Operand(reinterpret_cast<int32_t>(&kUint32Bias), RelocInfo::NONE32));
-  Cvtsi2sd(dst, src);
+  cvtsi2sd(dst, src);
   j(not_sign, &done, Label::kNear);
   addsd(dst, scratch);
   bind(&done);
@@ -676,12 +676,6 @@
 #endif
 
 
-void MacroAssembler::Cvtsi2sd(XMMRegister dst, const Operand& src) {
-  xorps(dst, dst);
-  cvtsi2sd(dst, src);
-}
-
-
 void MacroAssembler::Set(Register dst, const Immediate& x) {
   if (x.is_zero()) {
     xor_(dst, dst);  // Shorter than mov.
@@ -840,7 +834,7 @@
   SmiUntag(scratch1);
   if (CpuFeatures::IsSupported(SSE2) && specialize_for_processor) {
     CpuFeatureScope fscope(this, SSE2);
-    Cvtsi2sd(scratch2, scratch1);
+    cvtsi2sd(scratch2, scratch1);
     movdbl(FieldOperand(elements, key, times_4,
                         FixedDoubleArray::kHeaderSize - elements_offset),
            scratch2);
@@ -1115,16 +1109,14 @@
   // Push the return address to get ready to return.
   push(ecx);
 
-  LeaveExitFrameEpilogue(true);
+  LeaveExitFrameEpilogue();
 }
 
 
-void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
+void MacroAssembler::LeaveExitFrameEpilogue() {
   // Restore current context from top and clear it in debug mode.
   ExternalReference context_address(Isolate::kContextAddress, isolate());
-  if (restore_context) {
-    mov(esi, Operand::StaticVariable(context_address));
-  }
+  mov(esi, Operand::StaticVariable(context_address));
 #ifdef DEBUG
   mov(Operand::StaticVariable(context_address), Immediate(0));
 #endif
@@ -1136,11 +1128,11 @@
 }
 
 
-void MacroAssembler::LeaveApiExitFrame(bool restore_context) {
+void MacroAssembler::LeaveApiExitFrame() {
   mov(esp, ebp);
   pop(ebp);
 
-  LeaveExitFrameEpilogue(restore_context);
+  LeaveExitFrameEpilogue();
 }
 
 
@@ -2229,13 +2221,11 @@
 }
 
 
-void MacroAssembler::CallApiFunctionAndReturn(
-    Address function_address,
-    Address thunk_address,
-    Operand thunk_last_arg,
-    int stack_space,
-    Operand return_value_operand,
-    Operand* context_restore_operand) {
+void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
+                                              Address thunk_address,
+                                              Operand thunk_last_arg,
+                                              int stack_space,
+                                              int return_value_offset) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
   ExternalReference limit_address =
@@ -2291,10 +2281,9 @@
 
   Label prologue;
   // Load the value from ReturnValue
-  mov(eax, return_value_operand);
+  mov(eax, Operand(ebp, return_value_offset * kPointerSize));
 
   Label promote_scheduled_exception;
-  Label exception_handled;
   Label delete_allocated_handles;
   Label leave_exit_frame;
 
@@ -2314,7 +2303,6 @@
   cmp(Operand::StaticVariable(scheduled_exception_address),
       Immediate(isolate()->factory()->the_hole_value()));
   j(not_equal, &promote_scheduled_exception);
-  bind(&exception_handled);
 
 #if ENABLE_EXTRA_CHECKS
   // Check if the function returned a valid JavaScript value.
@@ -2351,19 +2339,11 @@
   bind(&ok);
 #endif
 
-  bool restore_context = context_restore_operand != NULL;
-  if (restore_context) {
-    mov(esi, *context_restore_operand);
-  }
-  LeaveApiExitFrame(!restore_context);
+  LeaveApiExitFrame();
   ret(stack_space * kPointerSize);
 
   bind(&promote_scheduled_exception);
-  {
-    FrameScope frame(this, StackFrame::INTERNAL);
-    CallRuntime(Runtime::kPromoteScheduledException, 0);
-  }
-  jmp(&exception_handled);
+  TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
 
   // HandleScope limit has changed. Delete allocated extensions.
   ExternalReference delete_extensions =
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index adda9fe..e4e4533 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -240,7 +240,7 @@
 
   // Leave the current exit frame. Expects the return value in
   // register eax (untouched).
-  void LeaveApiExitFrame(bool restore_context);
+  void LeaveApiExitFrame();
 
   // Find the function context up the context chain.
   void LoadContext(Register dst, int context_chain_length);
@@ -366,12 +366,6 @@
   void Set(Register dst, const Immediate& x);
   void Set(const Operand& dst, const Immediate& x);
 
-  // cvtsi2sd instruction only writes to the low 64-bit of dst register, which
-  // hinders register renaming and makes dependence chains longer. So we use
-  // xorps to clear the dst register before cvtsi2sd to solve this issue.
-  void Cvtsi2sd(XMMRegister dst, Register src) { Cvtsi2sd(dst, Operand(src)); }
-  void Cvtsi2sd(XMMRegister dst, const Operand& src);
-
   // Support for constant splitting.
   bool IsUnsafeImmediate(const Immediate& x);
   void SafeSet(Register dst, const Immediate& x);
@@ -813,8 +807,7 @@
                                 Address thunk_address,
                                 Operand thunk_last_arg,
                                 int stack_space,
-                                Operand return_value_operand,
-                                Operand* context_restore_operand);
+                                int return_value_offset_from_ebp);
 
   // Jump to a runtime routine.
   void JumpToExternalReference(const ExternalReference& ext);
@@ -964,7 +957,7 @@
   void EnterExitFramePrologue();
   void EnterExitFrameEpilogue(int argc, bool save_doubles);
 
-  void LeaveExitFrameEpilogue(bool restore_context);
+  void LeaveExitFrameEpilogue();
 
   // Allocation support helpers.
   void LoadAllocationTopHelper(Register result,
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index d339da9..354c2fd 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -329,28 +329,32 @@
                                             Register receiver,
                                             Register scratch1,
                                             Register scratch2,
-                                            Label* miss) {
+                                            Label* miss,
+                                            bool support_wrappers) {
   Label check_wrapper;
 
   // Check if the object is a string leaving the instance type in the
   // scratch register.
-  GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
+  GenerateStringCheck(masm, receiver, scratch1, miss,
+                      support_wrappers ? &check_wrapper : miss);
 
   // Load length from the string and convert to a smi.
   __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
   __ ret(0);
 
-  // Check if the object is a JSValue wrapper.
-  __ bind(&check_wrapper);
-  __ cmp(scratch1, JS_VALUE_TYPE);
-  __ j(not_equal, miss);
+  if (support_wrappers) {
+    // Check if the object is a JSValue wrapper.
+    __ bind(&check_wrapper);
+    __ cmp(scratch1, JS_VALUE_TYPE);
+    __ j(not_equal, miss);
 
-  // Check if the wrapped value is a string and load the length
-  // directly if it is.
-  __ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
-  GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
-  __ mov(eax, FieldOperand(scratch2, String::kLengthOffset));
-  __ ret(0);
+    // Check if the wrapped value is a string and load the length
+    // directly if it is.
+    __ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
+    GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
+    __ mov(eax, FieldOperand(scratch2, String::kLengthOffset));
+    __ ret(0);
+  }
 }
 
 
@@ -458,54 +462,48 @@
 // Generates call to API function.
 static void GenerateFastApiCall(MacroAssembler* masm,
                                 const CallOptimization& optimization,
-                                int argc,
-                                bool restore_context) {
+                                int argc) {
   // ----------- S t a t e -------------
   //  -- esp[0]              : return address
-  //  -- esp[4]              : context
-  //  -- esp[8]              : object passing the type check
+  //  -- esp[4]              : object passing the type check
   //                           (last fast api call extra argument,
   //                            set by CheckPrototypes)
-  //  -- esp[12]             : api function
+  //  -- esp[8]              : api function
   //                           (first fast api call extra argument)
-  //  -- esp[16]             : api call data
-  //  -- esp[20]             : isolate
-  //  -- esp[24]             : ReturnValue default value
-  //  -- esp[28]             : ReturnValue
-  //  -- esp[32]             : last argument
+  //  -- esp[12]             : api call data
+  //  -- esp[16]             : isolate
+  //  -- esp[20]             : ReturnValue default value
+  //  -- esp[24]             : ReturnValue
+  //  -- esp[28]             : last argument
   //  -- ...
-  //  -- esp[(argc + 7) * 4] : first argument
-  //  -- esp[(argc + 8) * 4] : receiver
+  //  -- esp[(argc + 6) * 4] : first argument
+  //  -- esp[(argc + 7) * 4] : receiver
   // -----------------------------------
-
-  // Save calling context.
-  __ mov(Operand(esp, kPointerSize), esi);
-
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(edi, function);
   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
 
   // Pass the additional arguments.
-  __ mov(Operand(esp, 3 * kPointerSize), edi);
+  __ mov(Operand(esp, 2 * kPointerSize), edi);
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
     __ mov(ecx, api_call_info);
     __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
-    __ mov(Operand(esp, 4 * kPointerSize), ebx);
+    __ mov(Operand(esp, 3 * kPointerSize), ebx);
   } else {
-    __ mov(Operand(esp, 4 * kPointerSize), Immediate(call_data));
+    __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data));
   }
-  __ mov(Operand(esp, 5 * kPointerSize),
+  __ mov(Operand(esp, 4 * kPointerSize),
          Immediate(reinterpret_cast<int>(masm->isolate())));
-  __ mov(Operand(esp, 6 * kPointerSize),
+  __ mov(Operand(esp, 5 * kPointerSize),
          masm->isolate()->factory()->undefined_value());
-  __ mov(Operand(esp, 7 * kPointerSize),
+  __ mov(Operand(esp, 6 * kPointerSize),
          masm->isolate()->factory()->undefined_value());
 
   // Prepare arguments.
-  STATIC_ASSERT(kFastApiCallArguments == 7);
+  STATIC_ASSERT(kFastApiCallArguments == 6);
   __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
 
 
@@ -539,16 +537,11 @@
 
   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
-  Operand context_restore_operand(ebp, 2 * kPointerSize);
-  Operand return_value_operand(
-      ebp, (kFastApiCallArguments + 1) * kPointerSize);
   __ CallApiFunctionAndReturn(function_address,
                               thunk_address,
                               ApiParameterOperand(1),
                               argc + kFastApiCallArguments + 1,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+                              kFastApiCallArguments + 1);
 }
 
 
@@ -563,8 +556,6 @@
   ASSERT(!receiver.is(scratch));
 
   const int stack_space = kFastApiCallArguments + argc + 1;
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Copy return value.
   __ mov(scratch, Operand(esp, 0));
   // Assign stack space for the call arguments.
@@ -572,7 +563,7 @@
   // Move the return address on top of the stack.
   __ mov(Operand(esp, 0), scratch);
   // Write holder to stack frame.
-  __ mov(Operand(esp, kHolderIndex * kPointerSize), receiver);
+  __ mov(Operand(esp, 1 * kPointerSize), receiver);
   // Write receiver to stack frame.
   int index = stack_space;
   __ mov(Operand(esp, index-- * kPointerSize), receiver);
@@ -583,7 +574,7 @@
     __ mov(Operand(esp, index-- * kPointerSize), values[i]);
   }
 
-  GenerateFastApiCall(masm, optimization, argc, true);
+  GenerateFastApiCall(masm, optimization, argc);
 }
 
 
@@ -697,7 +688,7 @@
 
     // Invoke function.
     if (can_do_fast_api_call) {
-      GenerateFastApiCall(masm, optimization, arguments_.immediate(), false);
+      GenerateFastApiCall(masm, optimization, arguments_.immediate());
     } else {
       CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
           ? CALL_AS_FUNCTION
@@ -871,7 +862,7 @@
     __ SmiUntag(value_reg);
     if (CpuFeatures::IsSupported(SSE2)) {
       CpuFeatureScope use_sse2(masm, SSE2);
-      __ Cvtsi2sd(xmm0, value_reg);
+      __ cvtsi2sd(xmm0, value_reg);
     } else {
       __ push(value_reg);
       __ fild_s(Operand(esp, 0));
@@ -1050,7 +1041,7 @@
     __ SmiUntag(value_reg);
     if (CpuFeatures::IsSupported(SSE2)) {
       CpuFeatureScope use_sse2(masm, SSE2);
-      __ Cvtsi2sd(xmm0, value_reg);
+      __ cvtsi2sd(xmm0, value_reg);
     } else {
       __ push(value_reg);
       __ fild_s(Operand(esp, 0));
@@ -1169,8 +1160,6 @@
                                        int save_at_depth,
                                        Label* miss,
                                        PrototypeCheckType check) {
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Make sure that the type feedback oracle harvests the receiver map.
   // TODO(svenpanne) Remove this hack when all ICs are reworked.
   __ mov(scratch1, Handle<Map>(object->map()));
@@ -1187,7 +1176,7 @@
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
+    __ mov(Operand(esp, kPointerSize), reg);
   }
 
   // Traverse the prototype chain and check the maps in the prototype chain for
@@ -1248,7 +1237,7 @@
     }
 
     if (save_at_depth == depth) {
-      __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
+      __ mov(Operand(esp, kPointerSize), reg);
     }
 
     // Go to the next object in the prototype chain.
@@ -1471,8 +1460,7 @@
                               thunk_address,
                               ApiParameterOperand(2),
                               kStackSpace,
-                              Operand(ebp, 7 * kPointerSize),
-                              NULL);
+                              7);
 }
 
 
@@ -2635,7 +2623,7 @@
 
   // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
   // duplicate of return address and will be overwritten.
-  GenerateFastApiCall(masm(), optimization, argc, false);
+  GenerateFastApiCall(masm(), optimization, argc);
 
   __ bind(&miss);
   __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
diff --git a/src/ic.cc b/src/ic.cc
index 163172d..5518751 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -549,11 +549,9 @@
                                       Code::ExtraICState extra_ic_state,
                                       Handle<Object> object,
                                       Handle<String> name) {
-  bool use_ic = FLAG_use_ic;
   if (object->IsJSObject()) {
     Handle<JSObject> receiver = Handle<JSObject>::cast(object);
     if (receiver->map()->is_deprecated()) {
-      use_ic = false;
       JSObject::MigrateInstance(receiver);
     }
   }
@@ -592,7 +590,9 @@
   }
 
   // Lookup is valid: Update inline cache and stub cache.
-  if (use_ic) UpdateCaches(&lookup, state, extra_ic_state, object, name);
+  if (FLAG_use_ic) {
+    UpdateCaches(&lookup, state, extra_ic_state, object, name);
+  }
 
   // Get the property.
   PropertyAttributes attr;
@@ -819,11 +819,9 @@
                                     Handle<String>::cast(key));
   }
 
-  bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
   if (object->IsJSObject()) {
     Handle<JSObject> receiver = Handle<JSObject>::cast(object);
     if (receiver->map()->is_deprecated()) {
-      use_ic = false;
       JSObject::MigrateInstance(receiver);
     }
   }
@@ -832,6 +830,7 @@
     return TypeError("non_object_property_call", object, key);
   }
 
+  bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
   ASSERT(!(use_ic && object->IsJSGlobalProxy()));
 
   if (use_ic && state != MEGAMORPHIC) {
@@ -875,20 +874,21 @@
     return TypeError("non_object_property_load", object, name);
   }
 
-  bool use_ic = FLAG_use_ic;
-
-  if (use_ic) {
+  if (FLAG_use_ic) {
     // Use specialized code for getting the length of strings and
     // string wrapper objects.  The length property of string wrapper
     // objects is read-only and therefore always returns the length of
     // the underlying string value.  See ECMA-262 15.5.5.1.
-    if (object->IsStringWrapper() &&
+    if ((object->IsString() || object->IsStringWrapper()) &&
         name->Equals(isolate()->heap()->length_string())) {
       Handle<Code> stub;
       if (state == UNINITIALIZED) {
         stub = pre_monomorphic_stub();
-      } else if (state == PREMONOMORPHIC || state == MONOMORPHIC) {
-        StringLengthStub string_length_stub(kind());
+      } else if (state == PREMONOMORPHIC) {
+        StringLengthStub string_length_stub(kind(), !object->IsString());
+        stub = string_length_stub.GetCode(isolate());
+      } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
+        StringLengthStub string_length_stub(kind(), true);
         stub = string_length_stub.GetCode(isolate());
       } else if (state != MEGAMORPHIC) {
         ASSERT(state != GENERIC);
@@ -897,12 +897,14 @@
       if (!stub.is_null()) {
         set_target(*stub);
 #ifdef DEBUG
-        if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n");
+        if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
 #endif
       }
       // Get the string if we have a string wrapper object.
-      String* string = String::cast(JSValue::cast(*object)->value());
-      return Smi::FromInt(string->length());
+      Handle<Object> string = object->IsJSValue()
+          ? Handle<Object>(Handle<JSValue>::cast(object)->value(), isolate())
+          : object;
+      return Smi::FromInt(String::cast(*string)->length());
     }
 
     // Use specialized code for getting prototype of functions.
@@ -934,14 +936,13 @@
   uint32_t index;
   if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
     // Rewrite to the generic keyed load stub.
-    if (use_ic) set_target(*generic_stub());
+    if (FLAG_use_ic) set_target(*generic_stub());
     return Runtime::GetElementOrCharAtOrFail(isolate(), object, index);
   }
 
   if (object->IsJSObject()) {
     Handle<JSObject> receiver = Handle<JSObject>::cast(object);
     if (receiver->map()->is_deprecated()) {
-      use_ic = false;
       JSObject::MigrateInstance(receiver);
     }
   }
@@ -959,7 +960,7 @@
   }
 
   // Update inline cache and stub cache.
-  if (use_ic) UpdateCaches(&lookup, state, object, name);
+  if (FLAG_use_ic) UpdateCaches(&lookup, state, object, name);
 
   PropertyAttributes attr;
   if (lookup.IsInterceptor() || lookup.IsHandler()) {
@@ -1264,8 +1265,6 @@
                           State state,
                           Handle<Object> object,
                           Handle<String> name) {
-  // TODO(verwaest): It would be nice to support loading fields from smis as
-  // well. For now just fail to update the cache.
   if (!object->IsHeapObject()) return;
 
   Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
@@ -1279,16 +1278,6 @@
   } else if (!lookup->IsCacheable()) {
     // Bail out if the result is not cacheable.
     code = slow_stub();
-  } else if (object->IsString() &&
-             name->Equals(isolate()->heap()->length_string())) {
-    int length_index = String::kLengthOffset / kPointerSize;
-    if (target()->is_load_stub()) {
-      LoadFieldStub stub(true, length_index, Representation::Tagged());
-      code = stub.GetCode(isolate());
-    } else {
-      KeyedLoadFieldStub stub(true, length_index, Representation::Tagged());
-      code = stub.GetCode(isolate());
-    }
   } else if (!object->IsJSObject()) {
     // TODO(jkummerow): It would be nice to support non-JSObjects in
     // ComputeLoadHandler, then we wouldn't need to go generic here.
@@ -1365,16 +1354,17 @@
         Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
         CallOptimization call_optimization(function);
         if (call_optimization.is_simple_api_call() &&
-            call_optimization.IsCompatibleReceiver(*receiver)) {
+            call_optimization.IsCompatibleReceiver(*receiver) &&
+            FLAG_js_accessor_ics) {
           return isolate()->stub_cache()->ComputeLoadCallback(
               name, receiver, holder, call_optimization);
         }
         return isolate()->stub_cache()->ComputeLoadViaGetter(
             name, receiver, holder, function);
       } else if (receiver->IsJSArray() &&
-                 name->Equals(isolate()->heap()->length_string())) {
-        PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex(
-            JSArray::kLengthOffset / kPointerSize);
+          name->Equals(isolate()->heap()->length_string())) {
+        PropertyIndex lengthIndex =
+          PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize);
         return isolate()->stub_cache()->ComputeLoadField(
             name, receiver, holder, lengthIndex, Representation::Tagged());
       }
@@ -1506,7 +1496,6 @@
       } else if (object->IsJSObject()) {
         Handle<JSObject> receiver = Handle<JSObject>::cast(object);
         if (receiver->map()->is_deprecated()) {
-          use_ic = false;
           JSObject::MigrateInstance(receiver);
         }
 
@@ -1523,11 +1512,9 @@
     } else {
       TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic");
     }
-    if (use_ic) {
-      ASSERT(!stub.is_null());
-      set_target(*stub);
-      TRACE_IC("KeyedLoadIC", key, state, target());
-    }
+    ASSERT(!stub.is_null());
+    set_target(*stub);
+    TRACE_IC("KeyedLoadIC", key, state, target());
   }
 
 
@@ -1576,7 +1563,8 @@
         Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
         CallOptimization call_optimization(function);
         if (call_optimization.is_simple_api_call() &&
-            call_optimization.IsCompatibleReceiver(*receiver)) {
+            call_optimization.IsCompatibleReceiver(*receiver) &&
+            FLAG_js_accessor_ics) {
           return isolate()->stub_cache()->ComputeKeyedLoadCallback(
               name, receiver, holder, call_optimization);
         }
@@ -1668,10 +1656,8 @@
                             JSReceiver::StoreFromKeyed store_mode) {
   // Handle proxies.
   if (object->IsJSProxy()) {
-    Handle<Object> result = JSReceiver::SetProperty(
+    return JSReceiver::SetPropertyOrFail(
         Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode);
-    RETURN_IF_EMPTY_HANDLE(isolate(), result);
-    return *result;
   }
 
   // If the object is undefined or null it's illegal to try to set any
@@ -1692,9 +1678,7 @@
 
   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
 
-  bool use_ic = FLAG_use_ic;
   if (receiver->map()->is_deprecated()) {
-    use_ic = false;
     JSObject::MigrateInstance(receiver);
   }
 
@@ -1709,17 +1693,15 @@
 
   // Observed objects are always modified through the runtime.
   if (FLAG_harmony_observation && receiver->map()->is_observed()) {
-    Handle<Object> result = JSReceiver::SetProperty(
+    return JSReceiver::SetPropertyOrFail(
         receiver, name, value, NONE, strict_mode, store_mode);
-    RETURN_IF_EMPTY_HANDLE(isolate(), result);
-    return *result;
   }
 
   // Use specialized code for setting the length of arrays with fast
   // properties. Slow properties might indicate redefinition of the length
   // property. Note that when redefined using Object.freeze, it's possible
   // to have fast properties but a read-only length.
-  if (use_ic &&
+  if (FLAG_use_ic &&
       receiver->IsJSArray() &&
       name->Equals(isolate()->heap()->length_string()) &&
       Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
@@ -1729,14 +1711,12 @@
         StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate());
     set_target(*stub);
     TRACE_IC("StoreIC", name, state, *stub);
-    Handle<Object> result = JSReceiver::SetProperty(
+    return JSReceiver::SetPropertyOrFail(
         receiver, name, value, NONE, strict_mode, store_mode);
-    RETURN_IF_EMPTY_HANDLE(isolate(), result);
-    return *result;
   }
 
   if (receiver->IsJSGlobalProxy()) {
-    if (use_ic && kind() != Code::KEYED_STORE_IC) {
+    if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
       // Generate a generic stub that goes to the runtime when we see a global
       // proxy as receiver.
       Handle<Code> stub = (strict_mode == kStrictMode)
@@ -1745,10 +1725,8 @@
       set_target(*stub);
       TRACE_IC("StoreIC", name, state, *stub);
     }
-    Handle<Object> result = JSReceiver::SetProperty(
+    return JSReceiver::SetPropertyOrFail(
         receiver, name, value, NONE, strict_mode, store_mode);
-    RETURN_IF_EMPTY_HANDLE(isolate(), result);
-    return *result;
   }
 
   LookupResult lookup(isolate());
@@ -1760,7 +1738,7 @@
     // Strict mode doesn't allow setting non-existent global property.
     return ReferenceError("not_defined", name);
   }
-  if (use_ic) {
+  if (FLAG_use_ic) {
     if (state == UNINITIALIZED) {
       Handle<Code> stub = (strict_mode == kStrictMode)
           ? pre_monomorphic_stub_strict()
@@ -1779,10 +1757,8 @@
   }
 
   // Set the property.
-  Handle<Object> result = JSReceiver::SetProperty(
+  return JSReceiver::SetPropertyOrFail(
       receiver, name, value, NONE, strict_mode, store_mode);
-  RETURN_IF_EMPTY_HANDLE(isolate(), result);
-  return *result;
 }
 
 
@@ -1854,7 +1830,8 @@
         Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
         CallOptimization call_optimization(function);
         if (call_optimization.is_simple_api_call() &&
-            call_optimization.IsCompatibleReceiver(*receiver)) {
+            call_optimization.IsCompatibleReceiver(*receiver) &&
+            FLAG_js_accessor_ics) {
           return isolate()->stub_cache()->ComputeStoreCallback(
               name, receiver, holder, call_optimization, strict_mode);
         }
diff --git a/src/isolate.cc b/src/isolate.cc
index 479fe2f..6fa496a 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1087,7 +1087,7 @@
   Handle<String> key = factory()->stack_overflow_string();
   Handle<JSObject> boilerplate =
       Handle<JSObject>::cast(GetProperty(this, js_builtins_object(), key));
-  Handle<JSObject> exception = JSObject::Copy(boilerplate);
+  Handle<JSObject> exception = Copy(boilerplate);
   DoThrow(*exception, NULL);
 
   // Get stack trace limit.
@@ -1776,9 +1776,6 @@
       // TODO(bmeurer) Initialized lazily because it depends on flags; can
       // be fixed once the default isolate cleanup is done.
       random_number_generator_(NULL),
-      // TODO(rmcilroy) Currently setting this based on
-      // FLAG_force_memory_constrained in Isolate::Init; move to here when
-      // isolate cleanup is done
       is_memory_constrained_(false),
       has_fatal_error_(false),
       use_crankshaft_(true),
@@ -2138,8 +2135,6 @@
   TRACE_ISOLATE(init);
 
   stress_deopt_count_ = FLAG_deopt_every_n_times;
-  if (FLAG_force_memory_constrained.has_value)
-    is_memory_constrained_ = FLAG_force_memory_constrained.value;
 
   has_fatal_error_ = false;
 
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index 2e25a56..cb0896a 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -426,7 +426,6 @@
   static unsigned found_by_runtime_probing_only_;
 
   friend class ExternalReference;
-  friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
 };
 
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 400292e..3aabd97 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -833,15 +833,14 @@
   // The following registers must be saved and restored when calling through to
   // the runtime:
   //   a0 - contains return address (beginning of patch sequence)
-  //   a1 - isolate
+  //   a1 - function object
   RegList saved_regs =
       (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit();
   FrameScope scope(masm, StackFrame::MANUAL);
   __ MultiPush(saved_regs);
-  __ PrepareCallCFunction(1, 0, a2);
-  __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ PrepareCallCFunction(1, 0, a1);
   __ CallCFunction(
-      ExternalReference::get_make_code_young_function(masm->isolate()), 2);
+      ExternalReference::get_make_code_young_function(masm->isolate()), 1);
   __ MultiPop(saved_regs);
   __ Jump(a0);
 }
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index ee49b25..0589bf0 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -2795,9 +2795,8 @@
   if (do_gc) {
     // Move result passed in v0 into a0 to call PerformGC.
     __ mov(a0, v0);
-    __ PrepareCallCFunction(2, 0, a1);
-    __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
-    __ CallCFunction(ExternalReference::perform_gc_function(isolate), 2, 0);
+    __ PrepareCallCFunction(1, 0, a1);
+    __ CallCFunction(ExternalReference::perform_gc_function(isolate), 1, 0);
   }
 
   ExternalReference scope_depth =
@@ -2876,7 +2875,7 @@
   // v0:v1: result
   // sp: stack pointer
   // fp: frame pointer
-  __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
+  __ LeaveExitFrame(save_doubles_, s0, true);
 
   // Check if we should retry or throw exception.
   Label retry;
@@ -3409,7 +3408,8 @@
     receiver = a0;
   }
 
-  StubCompiler::GenerateLoadStringLength(masm, receiver, a3, t0, &miss);
+  StubCompiler::GenerateLoadStringLength(masm, receiver, a3, t0, &miss,
+                                         support_wrapper_);
 
   __ bind(&miss);
   StubCompiler::TailCallBuiltin(
@@ -4156,7 +4156,7 @@
   DirectCEntryStub stub;
   stub.GenerateCall(masm, t9);
 
-  __ LeaveExitFrame(false, no_reg, true);
+  __ LeaveExitFrame(false, no_reg);
 
   // v0: result
   // subject: subject string (callee saved)
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index a12faee..5c847fc 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -635,8 +635,7 @@
 }
 
 
-void Code::PatchPlatformCodeAge(Isolate* isolate,
-                                byte* sequence,
+void Code::PatchPlatformCodeAge(byte* sequence,
                                 Code::Age age,
                                 MarkingParity parity) {
   uint32_t young_length;
@@ -645,7 +644,7 @@
     CopyBytes(sequence, young_sequence, young_length);
     CPU::FlushICache(sequence, young_length);
   } else {
-    Code* stub = GetCodeAgeStub(isolate, age, parity);
+    Code* stub = GetCodeAgeStub(age, parity);
     CodePatcher patcher(sequence, young_length / Assembler::kInstrSize);
     // Mark this code sequence for FindPlatformCodeAgeSequence()
     patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP);
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 42701b9..b37c7e0 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -1789,43 +1789,33 @@
 
 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
   Register string = ToRegister(instr->string());
-  LOperand* index_op = instr->index();
+  Register index = ToRegister(instr->index());
   Register value = ToRegister(instr->value());
   Register scratch = scratch0();
   String::Encoding encoding = instr->encoding();
 
   if (FLAG_debug_code) {
-    __ lw(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
-    __ lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+    __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset));
+    __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset));
 
-    __ And(scratch, scratch,
-           Operand(kStringRepresentationMask | kStringEncodingMask));
+    __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask));
     static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
     static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
-    __ Subu(at, scratch, Operand(encoding == String::ONE_BYTE_ENCODING
+    __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING
                                 ? one_byte_seq_type : two_byte_seq_type));
     __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg));
   }
 
-  if (index_op->IsConstantOperand()) {
-    int constant_index = ToInteger32(LConstantOperand::cast(index_op));
-    if (encoding == String::ONE_BYTE_ENCODING) {
-      __ sb(value,
-          FieldMemOperand(string, SeqString::kHeaderSize + constant_index));
-    } else {
-      __ sh(value,
-          FieldMemOperand(string, SeqString::kHeaderSize + constant_index * 2));
-    }
+  __ Addu(scratch,
+          string,
+          Operand(SeqString::kHeaderSize - kHeapObjectTag));
+  if (encoding == String::ONE_BYTE_ENCODING) {
+    __ Addu(at, scratch, index);
+    __ sb(value, MemOperand(at));
   } else {
-    Register index = ToRegister(index_op);
-    if (encoding == String::ONE_BYTE_ENCODING) {
-      __ Addu(scratch, string, Operand(index));
-      __ sb(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
-    } else {
-      __ sll(scratch, index, 1);
-      __ Addu(scratch, string, scratch);
-      __ sh(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
-    }
+    __ sll(at, index, 1);
+    __ Addu(at, scratch, at);
+    __ sh(value, MemOperand(at));
   }
 }
 
@@ -2067,6 +2057,25 @@
 }
 
 
+void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
+  Representation r = instr->hydrogen()->value()->representation();
+  if (r.IsSmiOrInteger32() || r.IsDouble()) {
+    EmitBranch(instr, al, zero_reg, Operand(zero_reg));
+  } else {
+    ASSERT(r.IsTagged());
+    Register reg = ToRegister(instr->value());
+    HType type = instr->hydrogen()->value()->type();
+    if (type.IsTaggedNumber()) {
+      EmitBranch(instr, al, zero_reg, Operand(zero_reg));
+    }
+    __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
+    __ lw(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset));
+    __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
+    EmitBranch(instr, eq, scratch0(), Operand(at));
+  }
+}
+
+
 void LCodeGen::DoBranch(LBranch* instr) {
   Representation r = instr->hydrogen()->value()->representation();
   if (r.IsInteger32() || r.IsSmi()) {
@@ -4232,25 +4241,20 @@
 
   if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
       elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
-    Register address = scratch0();
     FPURegister value(ToDoubleRegister(instr->value()));
     if (key_is_constant) {
-      if (constant_key != 0) {
-        __ Addu(address, external_pointer,
-                Operand(constant_key << element_size_shift));
-      } else {
-        address = external_pointer;
-      }
+      __ Addu(scratch0(), external_pointer, constant_key <<
+          element_size_shift);
     } else {
-      __ sll(address, key, shift_size);
-      __ Addu(address, external_pointer, address);
+      __ sll(scratch0(), key, shift_size);
+      __ Addu(scratch0(), scratch0(), external_pointer);
     }
 
     if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
       __ cvt_s_d(double_scratch0(), value);
-      __ swc1(double_scratch0(), MemOperand(address, additional_offset));
+      __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset));
     } else {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
-      __ sdc1(value, MemOperand(address, additional_offset));
+      __ sdc1(value, MemOperand(scratch0(), additional_offset));
     }
   } else {
     Register value(ToRegister(instr->value()));
@@ -4292,29 +4296,33 @@
 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
   DoubleRegister value = ToDoubleRegister(instr->value());
   Register elements = ToRegister(instr->elements());
+  Register key = no_reg;
   Register scratch = scratch0();
-  DoubleRegister double_scratch = double_scratch0();
   bool key_is_constant = instr->key()->IsConstantOperand();
-  Label not_nan, done;
+  int constant_key = 0;
+  Label not_nan;
 
   // Calculate the effective address of the slot in the array to store the
   // double value.
-  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
   if (key_is_constant) {
-    int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
     if (constant_key & 0xF0000000) {
       Abort(kArrayIndexConstantValueTooBig);
     }
-    __ Addu(scratch, elements,
-            Operand((constant_key << element_size_shift) +
-                    FixedDoubleArray::kHeaderSize - kHeapObjectTag));
   } else {
-    int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
-        ? (element_size_shift - kSmiTagSize) : element_size_shift;
-    __ Addu(scratch, elements,
+    key = ToRegister(instr->key());
+  }
+  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+  int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
+      ? (element_size_shift - kSmiTagSize) : element_size_shift;
+  if (key_is_constant) {
+    __ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
+            FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+  } else {
+    __ sll(scratch, key, shift_size);
+    __ Addu(scratch, elements, Operand(scratch));
+    __ Addu(scratch, scratch,
             Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
-    __ sll(at, ToRegister(instr->key()), shift_size);
-    __ Addu(scratch, scratch, at);
   }
 
   if (instr->NeedsCanonicalization()) {
@@ -4325,17 +4333,12 @@
 
     // Only load canonical NaN if the comparison above set the overflow.
     __ bind(&is_nan);
-    __ Move(double_scratch,
-            FixedDoubleArray::canonical_not_the_hole_nan_as_double());
-    __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() <<
-        element_size_shift));
-    __ Branch(&done);
+    __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
   }
 
   __ bind(&not_nan);
   __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
       element_size_shift));
-  __ bind(&done);
 }
 
 
@@ -4931,18 +4934,14 @@
 
   Register input_reg = ToRegister(input);
 
-  if (instr->hydrogen()->value()->representation().IsSmi()) {
-    __ SmiUntag(input_reg);
-  } else {
-    DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
+  DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
 
-    // Let the deferred code handle the HeapObject case.
-    __ JumpIfNotSmi(input_reg, deferred->entry());
+  // Let the deferred code handle the HeapObject case.
+  __ JumpIfNotSmi(input_reg, deferred->entry());
 
-    // Smi to int32 conversion.
-    __ SmiUntag(input_reg);
-    __ bind(deferred->exit());
-  }
+  // Smi to int32 conversion.
+  __ SmiUntag(input_reg);
+  __ bind(deferred->exit());
 }
 
 
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index a7319ae..4dc8022 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -715,44 +715,51 @@
 
 LInstruction* LChunkBuilder::DoShift(Token::Value op,
                                      HBitwiseBinaryOperation* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
-    ASSERT(instr->left()->representation().Equals(instr->representation()));
-    ASSERT(instr->right()->representation().Equals(instr->representation()));
-    LOperand* left = UseRegisterAtStart(instr->left());
+  if (instr->representation().IsTagged()) {
+    ASSERT(instr->left()->representation().IsTagged());
+    ASSERT(instr->right()->representation().IsTagged());
 
-    HValue* right_value = instr->right();
-    LOperand* right = NULL;
-    int constant_value = 0;
-    bool does_deopt = false;
-    if (right_value->IsConstant()) {
-      HConstant* constant = HConstant::cast(right_value);
-      right = chunk_->DefineConstantOperand(constant);
-      constant_value = constant->Integer32Value() & 0x1f;
-      // Left shifts can deoptimize if we shift by > 0 and the result cannot be
-      // truncated to smi.
-      if (instr->representation().IsSmi() && constant_value > 0) {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
-      }
-    } else {
-      right = UseRegisterAtStart(right_value);
-    }
-
-    // Shift operations can only deoptimize if we do a logical shift
-    // by 0 and the result cannot be truncated to int32.
-    if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
-    }
-
-    LInstruction* result =
-        DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt));
-    return does_deopt ? AssignEnvironment(result) : result;
-  } else {
-    return DoArithmeticT(op, instr);
+    LOperand* left = UseFixed(instr->left(), a1);
+    LOperand* right = UseFixed(instr->right(), a0);
+    LArithmeticT* result = new(zone()) LArithmeticT(op, left, right);
+    return MarkAsCall(DefineFixed(result, v0), instr);
   }
+
+  ASSERT(instr->representation().IsSmiOrInteger32());
+  ASSERT(instr->left()->representation().Equals(instr->representation()));
+  ASSERT(instr->right()->representation().Equals(instr->representation()));
+  LOperand* left = UseRegisterAtStart(instr->left());
+
+  HValue* right_value = instr->right();
+  LOperand* right = NULL;
+  int constant_value = 0;
+  bool does_deopt = false;
+  if (right_value->IsConstant()) {
+    HConstant* constant = HConstant::cast(right_value);
+    right = chunk_->DefineConstantOperand(constant);
+    constant_value = constant->Integer32Value() & 0x1f;
+    // Left shifts can deoptimize if we shift by > 0 and the result cannot be
+    // truncated to smi.
+    if (instr->representation().IsSmi() && constant_value > 0) {
+      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
+    }
+  } else {
+    right = UseRegisterAtStart(right_value);
+  }
+
+  // Shift operations can deoptimize if we do a logical shift
+  // by 0 and the result cannot be truncated to int32.
+  if (op == Token::SHR && constant_value == 0) {
+    if (FLAG_opt_safe_uint32_operations) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    } else {
+      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
+    }
+  }
+
+  LInstruction* result =
+      DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt));
+  return does_deopt ? AssignEnvironment(result) : result;
 }
 
 
@@ -761,25 +768,21 @@
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->left()->representation().IsDouble());
   ASSERT(instr->right()->representation().IsDouble());
-  if (op == Token::MOD) {
-    LOperand* left = UseFixedDouble(instr->left(), f2);
-    LOperand* right = UseFixedDouble(instr->right(), f4);
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    // We call a C function for double modulo. It can't trigger a GC. We need
-    // to use fixed result register for the call.
-    // TODO(fschneider): Allow any register as input registers.
-    return MarkAsCall(DefineFixedDouble(result, f2), instr);
-  } else {
-    LOperand* left = UseRegisterAtStart(instr->left());
-    LOperand* right = UseRegisterAtStart(instr->right());
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    return DefineAsRegister(result);
-  }
+  ASSERT(op != Token::MOD);
+  LOperand* left = UseRegisterAtStart(instr->left());
+  LOperand* right = UseRegisterAtStart(instr->right());
+  LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
+  return DefineAsRegister(result);
 }
 
 
 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
-                                           HBinaryOperation* instr) {
+                                           HArithmeticBinaryOperation* instr) {
+  ASSERT(op == Token::ADD ||
+         op == Token::DIV ||
+         op == Token::MOD ||
+         op == Token::MUL ||
+         op == Token::SUB);
   HValue* left = instr->left();
   HValue* right = instr->right();
   ASSERT(left->representation().IsTagged());
@@ -1346,27 +1349,33 @@
   if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
-    ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
 
     LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
     LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
     return DefineAsRegister(new(zone()) LBitI(left, right));
   } else {
-    return DoArithmeticT(instr->op(), instr);
+    ASSERT(instr->representation().IsTagged());
+    ASSERT(instr->left()->representation().IsTagged());
+    ASSERT(instr->right()->representation().IsTagged());
+
+    LOperand* left = UseFixed(instr->left(), a1);
+    LOperand* right = UseFixed(instr->right(), a0);
+    LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right);
+    return MarkAsCall(DefineFixed(result, v0), instr);
   }
 }
 
 
 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
+  if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::DIV, instr);
+  } else if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
     LOperand* dividend = UseRegister(instr->left());
     LOperand* divisor = UseRegister(instr->right());
     LDivI* div = new(zone()) LDivI(dividend, divisor);
     return AssignEnvironment(DefineAsRegister(div));
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::DIV, instr);
   } else {
     return DoArithmeticT(Token::DIV, instr);
   }
@@ -1457,10 +1466,17 @@
           ? AssignEnvironment(result)
           : result;
     }
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::MOD, instr);
-  } else {
+  } else if (instr->representation().IsTagged()) {
     return DoArithmeticT(Token::MOD, instr);
+  } else {
+    ASSERT(instr->representation().IsDouble());
+    // We call a C function for double modulo. It can't trigger a GC. We need
+    // to use fixed result register for the call.
+    // TODO(fschneider): Allow any register as input registers.
+    LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD,
+                                                 UseFixedDouble(left, f2),
+                                                 UseFixedDouble(right, f4));
+    return MarkAsCall(DefineFixedDouble(mod, f2), instr);
   }
 }
 
@@ -1563,6 +1579,7 @@
     }
     return DoArithmeticD(Token::ADD, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::ADD, instr);
   }
 }
@@ -1766,9 +1783,11 @@
 
 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
   LOperand* string = UseRegister(instr->string());
-  LOperand* index = UseRegisterOrConstant(instr->index());
-  LOperand* value = UseRegister(instr->value());
-  return new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value);
+  LOperand* index = UseRegister(instr->index());
+  LOperand* value = UseTempRegister(instr->value());
+  LSeqStringSetChar* result =
+      new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value);
+  return DefineAsRegister(result);
 }
 
 
@@ -1921,6 +1940,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) {
+  return new(zone())
+    LIsNumberAndBranch(UseRegisterOrConstantAtStart(instr->value()));
+}
+
+
 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
   LInstruction* result = new(zone()) LCheckInstanceType(value);
@@ -2125,6 +2150,8 @@
 
 
 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
+  ElementsKind elements_kind = instr->elements_kind();
+
   if (!instr->is_external()) {
     ASSERT(instr->elements()->representation().IsTagged());
     bool needs_write_barrier = instr->NeedsWriteBarrier();
@@ -2135,18 +2162,14 @@
     if (instr->value()->representation().IsDouble()) {
       object = UseRegisterAtStart(instr->elements());
       key = UseRegisterOrConstantAtStart(instr->key());
-      val = UseRegister(instr->value());
+      val = UseTempRegister(instr->value());
     } else {
       ASSERT(instr->value()->representation().IsSmiOrTagged());
-      if (needs_write_barrier) {
-        object = UseTempRegister(instr->elements());
-        val = UseTempRegister(instr->value());
-        key = UseTempRegister(instr->key());
-      } else {
-        object = UseRegisterAtStart(instr->elements());
-        val = UseRegisterAtStart(instr->value());
-        key = UseRegisterOrConstantAtStart(instr->key());
-      }
+      object = UseTempRegister(instr->elements());
+      val = needs_write_barrier ? UseTempRegister(instr->value())
+          : UseRegisterAtStart(instr->value());
+      key = needs_write_barrier ? UseTempRegister(instr->key())
+          : UseRegisterOrConstantAtStart(instr->key());
     }
 
     return new(zone()) LStoreKeyed(object, key, val);
@@ -2154,13 +2177,17 @@
 
   ASSERT(
       (instr->value()->representation().IsInteger32() &&
-       (instr->elements_kind() != EXTERNAL_FLOAT_ELEMENTS) &&
-       (instr->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS)) ||
+       (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
+       (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
       (instr->value()->representation().IsDouble() &&
-       ((instr->elements_kind() == EXTERNAL_FLOAT_ELEMENTS) ||
-        (instr->elements_kind() == EXTERNAL_DOUBLE_ELEMENTS))));
+       ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
+        (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
   ASSERT(instr->elements()->representation().IsExternal());
-  LOperand* val = UseRegister(instr->value());
+  bool val_is_temp_register =
+      elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
+      elements_kind == EXTERNAL_FLOAT_ELEMENTS;
+  LOperand* val = val_is_temp_register ? UseTempRegister(instr->value())
+      : UseRegister(instr->value());
   LOperand* key = UseRegisterOrConstantAtStart(instr->key());
   LOperand* external_pointer = UseRegister(instr->elements());
 
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 3ab8f37..29a8eac 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -113,6 +113,7 @@
   V(IsConstructCallAndBranch)                   \
   V(IsObjectAndBranch)                          \
   V(IsStringAndBranch)                          \
+  V(IsNumberAndBranch)                          \
   V(IsSmiAndBranch)                             \
   V(IsUndetectableAndBranch)                    \
   V(Label)                                      \
@@ -935,6 +936,19 @@
 };
 
 
+class LIsNumberAndBranch V8_FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LIsNumberAndBranch(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch, "is-number-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsNumberAndBranch)
+};
+
+
 class LIsStringAndBranch V8_FINAL : public LControlInstruction<1, 1> {
  public:
   LIsStringAndBranch(LOperand* value, LOperand* temp) {
@@ -2085,7 +2099,7 @@
   LOperand* temp2() { return temps_[1]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -2739,7 +2753,7 @@
   LInstruction* DoArithmeticD(Token::Value op,
                               HArithmeticBinaryOperation* instr);
   LInstruction* DoArithmeticT(Token::Value op,
-                              HBinaryOperation* instr);
+                              HArithmeticBinaryOperation* instr);
 
   LPlatformChunk* chunk_;
   CompilationInfo* info_;
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 465e8ab..a85b0d8 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -3847,14 +3847,12 @@
 }
 
 
-void MacroAssembler::CallApiFunctionAndReturn(
-    ExternalReference function,
-    Address function_address,
-    ExternalReference thunk_ref,
-    Register thunk_last_arg,
-    int stack_space,
-    MemOperand return_value_operand,
-    MemOperand* context_restore_operand) {
+void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
+                                              Address function_address,
+                                              ExternalReference thunk_ref,
+                                              Register thunk_last_arg,
+                                              int stack_space,
+                                              int return_value_offset_from_fp) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
   const int kNextOffset = 0;
@@ -3917,13 +3915,12 @@
   }
 
   Label promote_scheduled_exception;
-  Label exception_handled;
   Label delete_allocated_handles;
   Label leave_exit_frame;
   Label return_value_loaded;
 
   // Load value from ReturnValue.
-  lw(v0, return_value_operand);
+  lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize));
   bind(&return_value_loaded);
 
   // No more valid handles (the result handle was the last one). Restore
@@ -3944,23 +3941,14 @@
   li(at, Operand(ExternalReference::scheduled_exception_address(isolate())));
   lw(t1, MemOperand(at));
   Branch(&promote_scheduled_exception, ne, t0, Operand(t1));
-  bind(&exception_handled);
-
-  bool restore_context = context_restore_operand != NULL;
-  if (restore_context) {
-    lw(cp, *context_restore_operand);
-  }
   li(s0, Operand(stack_space));
-  LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN);
+  LeaveExitFrame(false, s0, true);
 
   bind(&promote_scheduled_exception);
-  {
-    FrameScope frame(this, StackFrame::INTERNAL);
-    CallExternalReference(
-        ExternalReference(Runtime::kPromoteScheduledException, isolate()),
-        0);
-  }
-  jmp(&exception_handled);
+  TailCallExternalReference(
+      ExternalReference(Runtime::kPromoteScheduledException, isolate()),
+      0,
+      1);
 
   // HandleScope limit has changed. Delete allocated extensions.
   bind(&delete_allocated_handles);
@@ -4696,7 +4684,6 @@
 
 void MacroAssembler::LeaveExitFrame(bool save_doubles,
                                     Register argument_count,
-                                    bool restore_context,
                                     bool do_return) {
   // Optionally restore all double registers.
   if (save_doubles) {
@@ -4713,12 +4700,9 @@
   sw(zero_reg, MemOperand(t8));
 
   // Restore current context from top and clear it in debug mode.
-  if (restore_context) {
-    li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
-    lw(cp, MemOperand(t8));
-  }
-#ifdef DEBUG
   li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
+  lw(cp, MemOperand(t8));
+#ifdef DEBUG
   sw(a3, MemOperand(t8));
 #endif
 
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 2d9c950..75ded88 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -51,12 +51,6 @@
 // MIPS generated code calls C code, it must be via t9 register.
 
 
-// Flags used for LeaveExitFrame function.
-enum LeaveExitFrameMode {
-  EMIT_RETURN = true,
-  NO_EMIT_RETURN = false
-};
-
 // Flags used for AllocateHeapNumber
 enum TaggingMode {
   // Tag the result.
@@ -854,8 +848,7 @@
   // Leave the current exit frame.
   void LeaveExitFrame(bool save_doubles,
                       Register arg_count,
-                      bool restore_context,
-                      bool do_return = NO_EMIT_RETURN);
+                      bool do_return = false);
 
   // Get the actual activation frame alignment for target environment.
   static int ActivationFrameAlignment();
@@ -1278,8 +1271,7 @@
                                 ExternalReference thunk_ref,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                MemOperand return_value_operand,
-                                MemOperand* context_restore_operand);
+                                int return_value_offset_from_fp);
 
   // Jump to the builtin routine.
   void JumpToExternalReference(const ExternalReference& builtin,
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index e0cf1b6..58452ca 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -374,26 +374,30 @@
                                             Register receiver,
                                             Register scratch1,
                                             Register scratch2,
-                                            Label* miss) {
+                                            Label* miss,
+                                            bool support_wrappers) {
   Label check_wrapper;
 
   // Check if the object is a string leaving the instance type in the
   // scratch1 register.
-  GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper);
+  GenerateStringCheck(masm, receiver, scratch1, scratch2, miss,
+                      support_wrappers ? &check_wrapper : miss);
 
   // Load length directly from the string.
   __ Ret(USE_DELAY_SLOT);
   __ lw(v0, FieldMemOperand(receiver, String::kLengthOffset));
 
-  // Check if the object is a JSValue wrapper.
-  __ bind(&check_wrapper);
-  __ Branch(miss, ne, scratch1, Operand(JS_VALUE_TYPE));
+  if (support_wrappers) {
+    // Check if the object is a JSValue wrapper.
+    __ bind(&check_wrapper);
+    __ Branch(miss, ne, scratch1, Operand(JS_VALUE_TYPE));
 
-  // Unwrap the value and check if the wrapped value is a string.
-  __ lw(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
-  GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
-  __ Ret(USE_DELAY_SLOT);
-  __ lw(v0, FieldMemOperand(scratch1, String::kLengthOffset));
+    // Unwrap the value and check if the wrapped value is a string.
+    __ lw(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
+    GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
+    __ Ret(USE_DELAY_SLOT);
+    __ lw(v0, FieldMemOperand(scratch1, String::kLengthOffset));
+  }
 }
 
 
@@ -829,28 +833,23 @@
 
 static void GenerateFastApiDirectCall(MacroAssembler* masm,
                                       const CallOptimization& optimization,
-                                      int argc,
-                                      bool restore_context) {
+                                      int argc) {
   // ----------- S t a t e -------------
-  //  -- sp[0]              : context
-  //  -- sp[4]              : holder (set by CheckPrototypes)
-  //  -- sp[8]              : callee JS function
-  //  -- sp[12]             : call data
-  //  -- sp[16]             : isolate
-  //  -- sp[20]             : ReturnValue default value
-  //  -- sp[24]             : ReturnValue
-  //  -- sp[28]             : last JS argument
+  //  -- sp[0]              : holder (set by CheckPrototypes)
+  //  -- sp[4]              : callee JS function
+  //  -- sp[8]              : call data
+  //  -- sp[12]             : isolate
+  //  -- sp[16]             : ReturnValue default value
+  //  -- sp[20]             : ReturnValue
+  //  -- sp[24]             : last JS argument
   //  -- ...
-  //  -- sp[(argc + 6) * 4] : first JS argument
-  //  -- sp[(argc + 7) * 4] : receiver
+  //  -- sp[(argc + 5) * 4] : first JS argument
+  //  -- sp[(argc + 6) * 4] : receiver
   // -----------------------------------
-  // Save calling context.
-  __ sw(cp, MemOperand(sp));
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(t1, function);
   __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
-  __ sw(t1, MemOperand(sp, 2 * kPointerSize));
 
   // Pass the additional arguments.
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
@@ -861,18 +860,18 @@
   } else {
     __ li(t2, call_data);
   }
-  // Store call data.
-  __ sw(t2, MemOperand(sp, 3 * kPointerSize));
-  // Store isolate.
+
   __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ sw(t3, MemOperand(sp, 4 * kPointerSize));
-  // Store ReturnValue default and ReturnValue.
+  // Store JS function, call data, isolate ReturnValue default and ReturnValue.
+  __ sw(t1, MemOperand(sp, 1 * kPointerSize));
+  __ sw(t2, MemOperand(sp, 2 * kPointerSize));
+  __ sw(t3, MemOperand(sp, 3 * kPointerSize));
   __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
+  __ sw(t1, MemOperand(sp, 4 * kPointerSize));
   __ sw(t1, MemOperand(sp, 5 * kPointerSize));
-  __ sw(t1, MemOperand(sp, 6 * kPointerSize));
 
   // Prepare arguments.
-  __ Addu(a2, sp, Operand((kFastApiCallArguments - 1) * kPointerSize));
+  __ Addu(a2, sp, Operand(5 * kPointerSize));
 
   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
@@ -911,18 +910,12 @@
       masm->isolate());
 
   AllowExternalCallThatCantCauseGC scope(masm);
-  MemOperand context_restore_operand(
-      fp, 2 * kPointerSize);
-  MemOperand return_value_operand(
-      fp, (kFastApiCallArguments + 1) * kPointerSize);
   __ CallApiFunctionAndReturn(ref,
                               function_address,
                               thunk_ref,
                               a1,
                               kStackUnwindSpace,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+                              kFastApiCallArguments + 1);
 }
 
 
@@ -937,12 +930,10 @@
   ASSERT(!receiver.is(scratch));
 
   const int stack_space = kFastApiCallArguments + argc + 1;
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex - 1;
   // Assign stack space for the call arguments.
   __ Subu(sp, sp, Operand(stack_space * kPointerSize));
   // Write holder to stack frame.
-  __ sw(receiver, MemOperand(sp, kHolderIndex * kPointerSize));
+  __ sw(receiver, MemOperand(sp, 0));
   // Write receiver to stack frame.
   int index = stack_space - 1;
   __ sw(receiver, MemOperand(sp, index * kPointerSize));
@@ -953,7 +944,7 @@
     __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
   }
 
-  GenerateFastApiDirectCall(masm, optimization, argc, true);
+  GenerateFastApiDirectCall(masm, optimization, argc);
 }
 
 
@@ -1067,8 +1058,7 @@
 
     // Invoke function.
     if (can_do_fast_api_call) {
-      GenerateFastApiDirectCall(
-          masm, optimization, arguments_.immediate(), false);
+      GenerateFastApiDirectCall(masm, optimization, arguments_.immediate());
     } else {
       CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
           ? CALL_AS_FUNCTION
@@ -1195,8 +1185,6 @@
                                        int save_at_depth,
                                        Label* miss,
                                        PrototypeCheckType check) {
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex - 1;
   // Make sure that the type feedback oracle harvests the receiver map.
   // TODO(svenpanne) Remove this hack when all ICs are reworked.
   __ li(scratch1, Operand(Handle<Map>(object->map())));
@@ -1212,7 +1200,7 @@
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize));
+    __ sw(reg, MemOperand(sp));
   }
 
   // Check the maps in the prototype chain.
@@ -1270,7 +1258,7 @@
     }
 
     if (save_at_depth == depth) {
-      __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize));
+      __ sw(reg, MemOperand(sp));
     }
 
     // Go to the next object in the prototype chain.
@@ -1470,7 +1458,7 @@
   // (second argument - a1) = AccessorInfo&
   __ Addu(a1, sp, kPointerSize);
 
-  const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
+  const int kStackUnwindSpace = kFastApiCallArguments + 1;
   Address getter_address = v8::ToCData<Address>(callback->getter());
   ApiFunction fun(getter_address);
   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
@@ -1487,8 +1475,7 @@
                               thunk_ref,
                               a2,
                               kStackUnwindSpace,
-                              MemOperand(fp, 6 * kPointerSize),
-                              NULL);
+                              6);
 }
 
 
@@ -2571,7 +2558,7 @@
   CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name,
                   depth, &miss);
 
-  GenerateFastApiDirectCall(masm(), optimization, argc, false);
+  GenerateFastApiDirectCall(masm(), optimization, argc);
 
   __ bind(&miss);
   FreeSpaceForFastApiCall(masm());
diff --git a/src/object-observe.js b/src/object-observe.js
index b09c42d..1035792 100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -284,6 +284,11 @@
       arg.length < 0)
     return false;
 
+  var length = arg.length;
+  for (var i = 0; i < length; i++) {
+    if (!IS_STRING(arg[i]))
+      return false;
+  }
   return true;
 }
 
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index ad13d7f..5d9e161 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -330,11 +330,10 @@
     }
   }
 
-  // If a GC was caused while constructing this object, the elements
-  // pointer may point to a one pointer filler map.
-  if ((FLAG_use_gvn && FLAG_use_allocation_folding) ||
-      (reinterpret_cast<Map*>(elements()) !=
-      GetHeap()->one_pointer_filler_map())) {
+  // TODO(hpayer): deal gracefully with partially constructed JSObjects, when
+  // allocation folding is turned off.
+  if (reinterpret_cast<Map*>(elements()) !=
+      GetHeap()->one_pointer_filler_map()) {
     CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
               (elements() == GetHeap()->empty_fixed_array())),
              (elements()->map() == GetHeap()->fixed_array_map() ||
@@ -684,11 +683,10 @@
 void JSArray::JSArrayVerify() {
   JSObjectVerify();
   CHECK(length()->IsNumber() || length()->IsUndefined());
-  // If a GC was caused while constructing this array, the elements
-  // pointer may point to a one pointer filler map.
-  if ((FLAG_use_gvn && FLAG_use_allocation_folding) ||
-      (reinterpret_cast<Map*>(elements()) !=
-      GetHeap()->one_pointer_filler_map())) {
+  // TODO(hpayer): deal gracefully with partially constructed JSObjects, when
+  // allocation folding is turned off.
+  if (reinterpret_cast<Map*>(elements()) !=
+      GetHeap()->one_pointer_filler_map()) {
     CHECK(elements()->IsUndefined() ||
           elements()->IsFixedArray() ||
           elements()->IsFixedDoubleArray());
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 56fde30..89abe50 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1566,6 +1566,21 @@
 }
 
 
+MaybeObject* JSObject::MigrateInstance() {
+  // Converting any field to the most specific type will cause the
+  // GeneralizeFieldRepresentation algorithm to create the most general existing
+  // transition that matches the object. This achieves what is needed.
+  Map* original_map = map();
+  MaybeObject* maybe_result = GeneralizeFieldRepresentation(
+      0, Representation::None(), ALLOW_AS_CONSTANT);
+  JSObject* result;
+  if (FLAG_trace_migration && maybe_result->To(&result)) {
+    PrintInstanceMigration(stdout, original_map, result->map());
+  }
+  return maybe_result;
+}
+
+
 MaybeObject* JSObject::TryMigrateInstance() {
   Map* new_map = map()->CurrentMapForDeprecated();
   if (new_map == NULL) return Smi::FromInt(0);
@@ -5714,23 +5729,19 @@
 }
 
 
-bool JSReceiver::HasProperty(Handle<JSReceiver> object,
-                             Handle<Name> name) {
-  if (object->IsJSProxy()) {
-    Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
-    return JSProxy::HasPropertyWithHandler(proxy, name);
+bool JSReceiver::HasProperty(Name* name) {
+  if (IsJSProxy()) {
+    return JSProxy::cast(this)->HasPropertyWithHandler(name);
   }
-  return object->GetPropertyAttribute(*name) != ABSENT;
+  return GetPropertyAttribute(name) != ABSENT;
 }
 
 
-bool JSReceiver::HasLocalProperty(Handle<JSReceiver> object,
-                                  Handle<Name> name) {
-  if (object->IsJSProxy()) {
-    Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
-    return JSProxy::HasPropertyWithHandler(proxy, name);
+bool JSReceiver::HasLocalProperty(Name* name) {
+  if (IsJSProxy()) {
+    return JSProxy::cast(this)->HasPropertyWithHandler(name);
   }
-  return object->GetLocalPropertyAttribute(*name) != ABSENT;
+  return GetLocalPropertyAttribute(name) != ABSENT;
 }
 
 
@@ -5772,23 +5783,21 @@
 }
 
 
-bool JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
-  if (object->IsJSProxy()) {
-    Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
-    return JSProxy::HasElementWithHandler(proxy, index);
+bool JSReceiver::HasElement(uint32_t index) {
+  if (IsJSProxy()) {
+    return JSProxy::cast(this)->HasElementWithHandler(index);
   }
-  return Handle<JSObject>::cast(object)->GetElementAttributeWithReceiver(
-      *object, index, true) != ABSENT;
+  return JSObject::cast(this)->GetElementAttributeWithReceiver(
+      this, index, true) != ABSENT;
 }
 
 
-bool JSReceiver::HasLocalElement(Handle<JSReceiver> object, uint32_t index) {
-  if (object->IsJSProxy()) {
-    Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
-    return JSProxy::HasElementWithHandler(proxy, index);
+bool JSReceiver::HasLocalElement(uint32_t index) {
+  if (IsJSProxy()) {
+    return JSProxy::cast(this)->HasElementWithHandler(index);
   }
-  return Handle<JSObject>::cast(object)->GetElementAttributeWithReceiver(
-      *object, index, false) != ABSENT;
+  return JSObject::cast(this)->GetElementAttributeWithReceiver(
+      this, index, false) != ABSENT;
 }
 
 
diff --git a/src/objects.cc b/src/objects.cc
index b3a264e..ca9e396 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -455,15 +455,18 @@
                                               StrictModeFlag strict_mode) {
   Isolate* isolate = proxy->GetIsolate();
   Handle<String> name = isolate->factory()->Uint32ToString(index);
-  return SetPropertyWithHandler(
-      proxy, receiver, name, value, NONE, strict_mode);
+  CALL_HEAP_FUNCTION(isolate,
+                     proxy->SetPropertyWithHandler(
+                         *receiver, *name, *value, NONE, strict_mode),
+                     Object);
 }
 
 
-bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
-  Isolate* isolate = proxy->GetIsolate();
-  Handle<String> name = isolate->factory()->Uint32ToString(index);
-  return HasPropertyWithHandler(proxy, name);
+bool JSProxy::HasElementWithHandler(uint32_t index) {
+  String* name;
+  MaybeObject* maybe = GetHeap()->Uint32ToString(index);
+  if (!maybe->To<String>(&name)) return maybe;
+  return HasPropertyWithHandler(name);
 }
 
 
@@ -1868,20 +1871,6 @@
 }
 
 
-Handle<Object> JSObject::AddFastPropertyUsingMap(
-    Handle<JSObject> object,
-    Handle<Map> new_map,
-    Handle<Name> name,
-    Handle<Object> value,
-    int field_index,
-    Representation representation) {
-  CALL_HEAP_FUNCTION(object->GetIsolate(),
-                     object->AddFastPropertyUsingMap(
-                         *new_map, *name, *value, field_index, representation),
-                     Object);
-}
-
-
 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
                                                Name* name,
                                                Object* value,
@@ -1911,215 +1900,182 @@
 }
 
 
-static MaybeObject* CopyAddFieldDescriptor(Map* map,
-                                           Name* name,
-                                           int index,
-                                           PropertyAttributes attributes,
-                                           Representation representation,
-                                           TransitionFlag flag) {
-  Map* new_map;
-  FieldDescriptor new_field_desc(name, index, attributes, representation);
-  MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag);
-  if (!maybe_map->To(&new_map)) return maybe_map;
-  int unused_property_fields = map->unused_property_fields() - 1;
-  if (unused_property_fields < 0) {
-    unused_property_fields += JSObject::kFieldsAdded;
-  }
-  new_map->set_unused_property_fields(unused_property_fields);
-  return new_map;
-}
-
-
-static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
-                                          Handle<Name> name,
-                                          int index,
-                                          PropertyAttributes attributes,
-                                          Representation representation,
-                                          TransitionFlag flag) {
-  CALL_HEAP_FUNCTION(map->GetIsolate(),
-                     CopyAddFieldDescriptor(
-                         *map, *name, index, attributes, representation, flag),
-                     Map);
-}
-
-
-void JSObject::AddFastProperty(Handle<JSObject> object,
-                               Handle<Name> name,
-                               Handle<Object> value,
-                               PropertyAttributes attributes,
-                               StoreFromKeyed store_mode,
-                               ValueType value_type,
-                               TransitionFlag flag) {
-  ASSERT(!object->IsJSGlobalProxy());
+MaybeObject* JSObject::AddFastProperty(Name* name,
+                                       Object* value,
+                                       PropertyAttributes attributes,
+                                       StoreFromKeyed store_mode,
+                                       ValueType value_type,
+                                       TransitionFlag flag) {
+  ASSERT(!IsJSGlobalProxy());
   ASSERT(DescriptorArray::kNotFound ==
-         object->map()->instance_descriptors()->Search(
-             *name, object->map()->NumberOfOwnDescriptors()));
+         map()->instance_descriptors()->Search(
+             name, map()->NumberOfOwnDescriptors()));
 
   // Normalize the object if the name is an actual name (not the
   // hidden strings) and is not a real identifier.
   // Normalize the object if it will have too many fast properties.
-  Isolate* isolate = object->GetIsolate();
-  if (!name->IsCacheable(isolate) ||
-      object->TooManyFastProperties(store_mode)) {
-    NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
-    AddSlowProperty(object, name, value, attributes);
-    return;
+  Isolate* isolate = GetHeap()->isolate();
+  if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) {
+    MaybeObject* maybe_failure =
+        NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+    if (maybe_failure->IsFailure()) return maybe_failure;
+    return AddSlowProperty(name, value, attributes);
   }
 
   // Compute the new index for new field.
-  int index = object->map()->NextFreePropertyIndex();
+  int index = map()->NextFreePropertyIndex();
 
   // Allocate new instance descriptors with (name, index) added
-  if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
+  if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
   Representation representation = value->OptimalRepresentation(value_type);
-  Handle<Map> new_map = CopyAddFieldDescriptor(
-      handle(object->map()), name, index, attributes, representation, flag);
 
-  AddFastPropertyUsingMap(object, new_map, name, value, index, representation);
+  FieldDescriptor new_field(name, index, attributes, representation);
+
+  Map* new_map;
+  MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag);
+  if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
+  int unused_property_fields = map()->unused_property_fields() - 1;
+  if (unused_property_fields < 0) {
+    unused_property_fields += kFieldsAdded;
+  }
+  new_map->set_unused_property_fields(unused_property_fields);
+
+  return AddFastPropertyUsingMap(new_map, name, value, index, representation);
 }
 
 
-static MaybeObject* CopyAddConstantDescriptor(Map* map,
-                                              Name* name,
-                                              Object* value,
-                                              PropertyAttributes attributes,
-                                              TransitionFlag flag) {
-  ConstantDescriptor new_constant_desc(name, value, attributes);
-  return map->CopyAddDescriptor(&new_constant_desc, flag);
-}
+MaybeObject* JSObject::AddConstantProperty(
+    Name* name,
+    Object* constant,
+    PropertyAttributes attributes,
+    TransitionFlag initial_flag) {
+  // Allocate new instance descriptors with (name, constant) added
+  ConstantDescriptor d(name, constant, attributes);
 
-
-static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map,
-                                             Handle<Name> name,
-                                             Handle<Object> value,
-                                             PropertyAttributes attributes,
-                                             TransitionFlag flag) {
-  CALL_HEAP_FUNCTION(map->GetIsolate(),
-                     CopyAddConstantDescriptor(
-                         *map, *name, *value, attributes, flag),
-                     Map);
-}
-
-
-void JSObject::AddConstantProperty(Handle<JSObject> object,
-                                   Handle<Name> name,
-                                   Handle<Object> constant,
-                                   PropertyAttributes attributes,
-                                   TransitionFlag initial_flag) {
   TransitionFlag flag =
       // Do not add transitions to global objects.
-      (object->IsGlobalObject() ||
+      (IsGlobalObject() ||
       // Don't add transitions to special properties with non-trivial
       // attributes.
        attributes != NONE)
       ? OMIT_TRANSITION
       : initial_flag;
 
-  // Allocate new instance descriptors with (name, constant) added.
-  Handle<Map> new_map = CopyAddConstantDescriptor(
-      handle(object->map()), name, constant, attributes, flag);
+  Map* new_map;
+  MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
+  if (!maybe_new_map->To(&new_map)) return maybe_new_map;
 
-  object->set_map(*new_map);
+  set_map(new_map);
+  return constant;
 }
 
 
-// TODO(mstarzinger): Temporary wrapper until handlified.
-static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
-                                                Handle<Name> name,
-                                                Handle<Object> value,
-                                                PropertyDetails details) {
-  CALL_HEAP_FUNCTION(dict->GetIsolate(),
-                     dict->Add(*name, *value, details),
-                     NameDictionary);
-}
-
-
-void JSObject::AddSlowProperty(Handle<JSObject> object,
-                               Handle<Name> name,
-                               Handle<Object> value,
-                               PropertyAttributes attributes) {
-  ASSERT(!object->HasFastProperties());
-  Isolate* isolate = object->GetIsolate();
-  Handle<NameDictionary> dict(object->property_dictionary());
-  if (object->IsGlobalObject()) {
+// Add property in slow mode
+MaybeObject* JSObject::AddSlowProperty(Name* name,
+                                       Object* value,
+                                       PropertyAttributes attributes) {
+  ASSERT(!HasFastProperties());
+  NameDictionary* dict = property_dictionary();
+  Object* store_value = value;
+  if (IsGlobalObject()) {
     // In case name is an orphaned property reuse the cell.
-    int entry = dict->FindEntry(*name);
+    int entry = dict->FindEntry(name);
     if (entry != NameDictionary::kNotFound) {
-      Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry)));
-      PropertyCell::SetValueInferType(cell, value);
+      store_value = dict->ValueAt(entry);
+      MaybeObject* maybe_type =
+          PropertyCell::cast(store_value)->SetValueInferType(value);
+      if (maybe_type->IsFailure()) return maybe_type;
       // Assign an enumeration index to the property and update
       // SetNextEnumerationIndex.
       int index = dict->NextEnumerationIndex();
       PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
       dict->SetNextEnumerationIndex(index + 1);
-      dict->SetEntry(entry, *name, *cell, details);
-      return;
+      dict->SetEntry(entry, name, store_value, details);
+      return value;
     }
-    Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value);
-    PropertyCell::SetValueInferType(cell, value);
-    value = cell;
+    Heap* heap = GetHeap();
+    { MaybeObject* maybe_store_value =
+          heap->AllocatePropertyCell(value);
+      if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
+    }
+    MaybeObject* maybe_type =
+        PropertyCell::cast(store_value)->SetValueInferType(value);
+    if (maybe_type->IsFailure()) return maybe_type;
   }
   PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
-  Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details);
-  if (*dict != *result) object->set_properties(*result);
+  Object* result;
+  { MaybeObject* maybe_result = dict->Add(name, store_value, details);
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+  }
+  if (dict != result) set_properties(NameDictionary::cast(result));
+  return value;
 }
 
 
-Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
-                                     Handle<Name> name,
-                                     Handle<Object> value,
-                                     PropertyAttributes attributes,
-                                     StrictModeFlag strict_mode,
-                                     JSReceiver::StoreFromKeyed store_mode,
-                                     ExtensibilityCheck extensibility_check,
-                                     ValueType value_type,
-                                     StoreMode mode,
-                                     TransitionFlag transition_flag) {
-  ASSERT(!object->IsJSGlobalProxy());
-  Isolate* isolate = object->GetIsolate();
+MaybeObject* JSObject::AddProperty(Name* name,
+                                   Object* value,
+                                   PropertyAttributes attributes,
+                                   StrictModeFlag strict_mode,
+                                   JSReceiver::StoreFromKeyed store_mode,
+                                   ExtensibilityCheck extensibility_check,
+                                   ValueType value_type,
+                                   StoreMode mode,
+                                   TransitionFlag transition_flag) {
+  ASSERT(!IsJSGlobalProxy());
+  Map* map_of_this = map();
+  Heap* heap = GetHeap();
+  Isolate* isolate = heap->isolate();
+  MaybeObject* result;
   if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
-      !object->map()->is_extensible()) {
+      !map_of_this->is_extensible()) {
     if (strict_mode == kNonStrictMode) {
       return value;
     } else {
-      Handle<Object> args[1] = { name };
-      Handle<Object> error = isolate->factory()->NewTypeError(
-          "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
-      isolate->Throw(*error);
-      return Handle<Object>();
+      Handle<Object> args[1] = {Handle<Name>(name)};
+      return isolate->Throw(
+          *isolate->factory()->NewTypeError("object_not_extensible",
+                                            HandleVector(args, 1)));
     }
   }
 
-  if (object->HasFastProperties()) {
+  if (HasFastProperties()) {
     // Ensure the descriptor array does not get too big.
-    if (object->map()->NumberOfOwnDescriptors() <
+    if (map_of_this->NumberOfOwnDescriptors() <
         DescriptorArray::kMaxNumberOfDescriptors) {
       // TODO(verwaest): Support other constants.
       // if (mode == ALLOW_AS_CONSTANT &&
       //     !value->IsTheHole() &&
       //     !value->IsConsString()) {
       if (value->IsJSFunction()) {
-        AddConstantProperty(object, name, value, attributes, transition_flag);
+        result = AddConstantProperty(name, value, attributes, transition_flag);
       } else {
-        AddFastProperty(object, name, value, attributes, store_mode,
-                        value_type, transition_flag);
+        result = AddFastProperty(
+            name, value, attributes, store_mode, value_type, transition_flag);
       }
     } else {
       // Normalize the object to prevent very large instance descriptors.
       // This eliminates unwanted N^2 allocation and lookup behavior.
-      NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
-      AddSlowProperty(object, name, value, attributes);
+      Object* obj;
+      MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+      if (!maybe->To(&obj)) return maybe;
+      result = AddSlowProperty(name, value, attributes);
     }
   } else {
-    AddSlowProperty(object, name, value, attributes);
+    result = AddSlowProperty(name, value, attributes);
   }
 
-  if (FLAG_harmony_observation && object->map()->is_observed()) {
-    Handle<Object> old_value = isolate->factory()->the_hole_value();
-    EnqueueChangeRecord(object, "new", name, old_value);
+  Handle<Object> hresult;
+  if (!result->ToHandle(&hresult, isolate)) return result;
+
+  if (FLAG_harmony_observation && map()->is_observed()) {
+    EnqueueChangeRecord(handle(this, isolate),
+                        "new",
+                        handle(name, isolate),
+                        handle(heap->the_hole_value(), isolate));
   }
 
-  return value;
+  return *hresult;
 }
 
 
@@ -2159,39 +2115,37 @@
 }
 
 
-Handle<Object> JSObject::SetPropertyPostInterceptor(
-    Handle<JSObject> object,
-    Handle<Name> name,
-    Handle<Object> value,
+MaybeObject* JSObject::SetPropertyPostInterceptor(
+    Name* name,
+    Object* value,
     PropertyAttributes attributes,
-    StrictModeFlag strict_mode) {
+    StrictModeFlag strict_mode,
+    StoreMode mode) {
   // Check local property, ignore interceptor.
-  LookupResult result(object->GetIsolate());
-  object->LocalLookupRealNamedProperty(*name, &result);
-  if (!result.IsFound()) {
-    object->map()->LookupTransition(*object, *name, &result);
-  }
+  LookupResult result(GetIsolate());
+  LocalLookupRealNamedProperty(name, &result);
+  if (!result.IsFound()) map()->LookupTransition(this, name, &result);
   if (result.IsFound()) {
     // An existing property or a map transition was found. Use set property to
     // handle all these cases.
-    return SetPropertyForResult(object, &result, name, value, attributes,
-                                strict_mode, MAY_BE_STORE_FROM_KEYED);
+    return SetProperty(&result, name, value, attributes, strict_mode);
   }
   bool done = false;
-  Handle<Object> result_object = SetPropertyViaPrototypes(
-      object, name, value, attributes, strict_mode, &done);
+  MaybeObject* result_object =
+      SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
   if (done) return result_object;
   // Add a new real property.
-  return AddProperty(object, name, value, attributes, strict_mode);
+  return AddProperty(name, value, attributes, strict_mode,
+                     MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
+                     OPTIMAL_REPRESENTATION, mode);
 }
 
 
-static Handle<Object> ReplaceSlowProperty(Handle<JSObject> object,
-                                          Handle<Name> name,
-                                          Handle<Object> value,
-                                          PropertyAttributes attributes) {
-  NameDictionary* dictionary = object->property_dictionary();
-  int old_index = dictionary->FindEntry(*name);
+MaybeObject* JSObject::ReplaceSlowProperty(Name* name,
+                                           Object* value,
+                                           PropertyAttributes attributes) {
+  NameDictionary* dictionary = property_dictionary();
+  int old_index = dictionary->FindEntry(name);
   int new_enumeration_index = 0;  // 0 means "Use the next available index."
   if (old_index != -1) {
     // All calls to ReplaceSlowProperty have had all transitions removed.
@@ -2199,7 +2153,7 @@
   }
 
   PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
-  return JSObject::SetNormalizedProperty(object, name, value, new_details);
+  return SetNormalizedProperty(name, value, new_details);
 }
 
 
@@ -2306,11 +2260,6 @@
 }
 
 
-void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
-  CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*new_map));
-}
-
-
 // To migrate an instance to a map:
 // - First check whether the instance needs to be rewritten. If not, simply
 //   change the map.
@@ -2412,14 +2361,17 @@
 }
 
 
-void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
-                                             int modify_index,
-                                             Representation new_representation,
-                                             StoreMode store_mode) {
-  Handle<Map> new_map = Map::GeneralizeRepresentation(
-      handle(object->map()), modify_index, new_representation, store_mode);
-  if (object->map() == *new_map) return;
-  return MigrateToMap(object, new_map);
+MaybeObject* JSObject::GeneralizeFieldRepresentation(
+    int modify_index,
+    Representation new_representation,
+    StoreMode store_mode) {
+  Map* new_map;
+  MaybeObject* maybe_new_map = map()->GeneralizeRepresentation(
+      modify_index, new_representation, store_mode);
+  if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+  if (map() == new_map) return this;
+
+  return MigrateToMap(new_map);
 }
 
 
@@ -2433,12 +2385,14 @@
 }
 
 
-Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
-                                                  int modify_index,
-                                                  StoreMode store_mode,
-                                                  PropertyAttributes attributes,
-                                                  const char* reason) {
-  Handle<Map> new_map = Copy(map);
+MaybeObject* Map::CopyGeneralizeAllRepresentations(
+    int modify_index,
+    StoreMode store_mode,
+    PropertyAttributes attributes,
+    const char* reason) {
+  Map* new_map;
+  MaybeObject* maybe_map = this->Copy();
+  if (!maybe_map->To(&new_map)) return maybe_map;
 
   DescriptorArray* descriptors = new_map->instance_descriptors();
   descriptors->InitializeRepresentations(Representation::Tagged());
@@ -2460,7 +2414,7 @@
   }
 
   if (FLAG_trace_generalization) {
-    map->PrintGeneralization(stdout, reason, modify_index,
+    PrintGeneralization(stdout, reason, modify_index,
                         new_map->NumberOfOwnDescriptors(),
                         new_map->NumberOfOwnDescriptors(),
                         details.type() == CONSTANT && store_mode == FORCE_FIELD,
@@ -2608,11 +2562,11 @@
 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
 // - Otherwise, invalidate the outdated transition target from |updated|, and
 //   replace its transition tree with a new branch for the updated descriptors.
-Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
-                                          int modify_index,
-                                          Representation new_representation,
-                                          StoreMode store_mode) {
-  Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
+MaybeObject* Map::GeneralizeRepresentation(int modify_index,
+                                           Representation new_representation,
+                                           StoreMode store_mode) {
+  Map* old_map = this;
+  DescriptorArray* old_descriptors = old_map->instance_descriptors();
   PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
   Representation old_representation = old_details.representation();
 
@@ -2628,37 +2582,37 @@
   }
 
   int descriptors = old_map->NumberOfOwnDescriptors();
-  Handle<Map> root_map(old_map->FindRootMap());
+  Map* root_map = old_map->FindRootMap();
 
   // Check the state of the root map.
-  if (!old_map->EquivalentToForTransition(*root_map)) {
-    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
-        old_details.attributes(), "not equivalent");
+  if (!old_map->EquivalentToForTransition(root_map)) {
+    return CopyGeneralizeAllRepresentations(
+        modify_index, store_mode, old_details.attributes(), "not equivalent");
   }
 
   int verbatim = root_map->NumberOfOwnDescriptors();
 
   if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
-    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
+    return CopyGeneralizeAllRepresentations(
+        modify_index, store_mode,
         old_details.attributes(), "root modification");
   }
 
-  Map* raw_updated = root_map->FindUpdatedMap(
-      verbatim, descriptors, *old_descriptors);
-  if (raw_updated == NULL) {
-    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
-        old_details.attributes(), "incompatible");
+  Map* updated = root_map->FindUpdatedMap(
+      verbatim, descriptors, old_descriptors);
+  if (updated == NULL) {
+    return CopyGeneralizeAllRepresentations(
+        modify_index, store_mode, old_details.attributes(), "incompatible");
   }
 
-  Handle<Map> updated(raw_updated);
-  Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
+  DescriptorArray* updated_descriptors = updated->instance_descriptors();
 
   int valid = updated->NumberOfOwnDescriptors();
 
   // Directly change the map if the target map is more general. Ensure that the
   // target type of the modify_index is a FIELD, unless we are migrating.
   if (updated_descriptors->IsMoreGeneralThan(
-          verbatim, valid, descriptors, *old_descriptors) &&
+          verbatim, valid, descriptors, old_descriptors) &&
       (store_mode == ALLOW_AS_CONSTANT ||
        updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
     Representation updated_representation =
@@ -2666,9 +2620,10 @@
     if (new_representation.fits_into(updated_representation)) return updated;
   }
 
-  Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
-      updated_descriptors, verbatim, valid, descriptors, modify_index,
-      store_mode, old_descriptors);
+  DescriptorArray* new_descriptors;
+  MaybeObject* maybe_descriptors = updated_descriptors->Merge(
+      verbatim, valid, descriptors, modify_index, store_mode, old_descriptors);
+  if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
   ASSERT(store_mode == ALLOW_AS_CONSTANT ||
          new_descriptors->GetDetails(modify_index).type() == FIELD);
 
@@ -2680,8 +2635,8 @@
     new_descriptors->SetRepresentation(modify_index, updated_representation);
   }
 
-  Handle<Map> split_map(root_map->FindLastMatchMap(
-      verbatim, descriptors, *new_descriptors));
+  Map* split_map = root_map->FindLastMatchMap(
+      verbatim, descriptors, new_descriptors);
 
   int split_descriptors = split_map->NumberOfOwnDescriptors();
   // This is shadowed by |updated_descriptors| being more general than
@@ -2690,20 +2645,28 @@
 
   int descriptor = split_descriptors;
   split_map->DeprecateTarget(
-      old_descriptors->GetKey(descriptor), *new_descriptors);
+      old_descriptors->GetKey(descriptor), new_descriptors);
 
   if (FLAG_trace_generalization) {
-    old_map->PrintGeneralization(
+    PrintGeneralization(
         stdout, "", modify_index, descriptor, descriptors,
         old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
             store_mode == FORCE_FIELD,
         old_representation, updated_representation);
   }
 
+  Map* new_map = split_map;
   // Add missing transitions.
-  Handle<Map> new_map = split_map;
   for (; descriptor < descriptors; descriptor++) {
-    new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
+    MaybeObject* maybe_map = new_map->CopyInstallDescriptors(
+        descriptor, new_descriptors);
+    if (!maybe_map->To(&new_map)) {
+      // Create a handle for the last created map to ensure it stays alive
+      // during GC. Its descriptor array is too large, but it will be
+      // overwritten during retry anyway.
+      Handle<Map>(new_map);
+      return maybe_map;
+    }
     new_map->set_migration_target(true);
   }
 
@@ -2740,52 +2703,79 @@
 }
 
 
-Handle<Object> JSObject::SetPropertyWithInterceptor(
-    Handle<JSObject> object,
-    Handle<Name> name,
-    Handle<Object> value,
+MaybeObject* JSObject::SetPropertyWithInterceptor(
+    Name* name,
+    Object* value,
     PropertyAttributes attributes,
     StrictModeFlag strict_mode) {
   // TODO(rossberg): Support symbols in the API.
   if (name->IsSymbol()) return value;
-  Isolate* isolate = object->GetIsolate();
-  Handle<String> name_string = Handle<String>::cast(name);
-  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<JSObject> this_handle(this);
+  Handle<String> name_handle(String::cast(name));
+  Handle<Object> value_handle(value, isolate);
+  Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
   if (!interceptor->setter()->IsUndefined()) {
-    LOG(isolate,
-        ApiNamedPropertyAccess("interceptor-named-set", *object, *name));
-    PropertyCallbackArguments args(
-        isolate, interceptor->data(), *object, *object);
+    LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
+    PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
     v8::NamedPropertySetterCallback setter =
         v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
-    Handle<Object> value_unhole = value->IsTheHole()
-        ? Handle<Object>(isolate->factory()->undefined_value()) : value;
+    Handle<Object> value_unhole(value->IsTheHole() ?
+                                isolate->heap()->undefined_value() :
+                                value,
+                                isolate);
     v8::Handle<v8::Value> result = args.Call(setter,
-                                             v8::Utils::ToLocal(name_string),
+                                             v8::Utils::ToLocal(name_handle),
                                              v8::Utils::ToLocal(value_unhole));
-    RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
-    if (!result.IsEmpty()) return value;
+    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+    if (!result.IsEmpty()) return *value_handle;
   }
-  Handle<Object> result =
-      SetPropertyPostInterceptor(object, name, value, attributes, strict_mode);
-  RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
-  return result;
+  MaybeObject* raw_result =
+      this_handle->SetPropertyPostInterceptor(*name_handle,
+                                              *value_handle,
+                                              attributes,
+                                              strict_mode);
+  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+  return raw_result;
 }
 
 
 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
-                                       Handle<Name> name,
+                                       Handle<Name> key,
                                        Handle<Object> value,
                                        PropertyAttributes attributes,
-                                       StrictModeFlag strict_mode,
-                                       StoreFromKeyed store_mode) {
-  LookupResult result(object->GetIsolate());
-  object->LocalLookup(*name, &result, true);
+                                       StrictModeFlag strict_mode) {
+  CALL_HEAP_FUNCTION(object->GetIsolate(),
+                     object->SetProperty(*key, *value, attributes, strict_mode),
+                     Object);
+}
+
+
+MaybeObject* JSReceiver::SetPropertyOrFail(
+    Handle<JSReceiver> object,
+    Handle<Name> key,
+    Handle<Object> value,
+    PropertyAttributes attributes,
+    StrictModeFlag strict_mode,
+    JSReceiver::StoreFromKeyed store_mode) {
+  CALL_HEAP_FUNCTION_PASS_EXCEPTION(
+      object->GetIsolate(),
+      object->SetProperty(*key, *value, attributes, strict_mode, store_mode));
+}
+
+
+MaybeObject* JSReceiver::SetProperty(Name* name,
+                                     Object* value,
+                                     PropertyAttributes attributes,
+                                     StrictModeFlag strict_mode,
+                                     JSReceiver::StoreFromKeyed store_mode) {
+  LookupResult result(GetIsolate());
+  LocalLookup(name, &result, true);
   if (!result.IsFound()) {
-    object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
+    map()->LookupTransition(JSObject::cast(this), name, &result);
   }
-  return SetProperty(object, &result, name, value, attributes, strict_mode,
-                     store_mode);
+  return SetProperty(&result, name, value, attributes, strict_mode, store_mode);
 }
 
 
@@ -2940,20 +2930,21 @@
   return heap->the_hole_value();
 }
 
-Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
-                                                  Handle<Name> name,
-                                                  Handle<Object> value,
-                                                  PropertyAttributes attributes,
-                                                  StrictModeFlag strict_mode,
-                                                  bool* done) {
-  Isolate* isolate = object->GetIsolate();
+MaybeObject* JSObject::SetPropertyViaPrototypes(
+    Name* name,
+    Object* value,
+    PropertyAttributes attributes,
+    StrictModeFlag strict_mode,
+    bool* done) {
+  Heap* heap = GetHeap();
+  Isolate* isolate = heap->isolate();
 
   *done = false;
   // We could not find a local property so let's check whether there is an
   // accessor that wants to handle the property, or whether the property is
   // read-only on the prototype chain.
   LookupResult result(isolate);
-  object->LookupRealNamedPropertyInPrototypes(*name, &result);
+  LookupRealNamedPropertyInPrototypes(name, &result);
   if (result.IsFound()) {
     switch (result.type()) {
       case NORMAL:
@@ -2964,25 +2955,19 @@
       case INTERCEPTOR: {
         PropertyAttributes attr =
             result.holder()->GetPropertyAttributeWithInterceptor(
-                *object, *name, true);
+                this, name, true);
         *done = !!(attr & READ_ONLY);
         break;
       }
       case CALLBACKS: {
         if (!FLAG_es5_readonly && result.IsReadOnly()) break;
         *done = true;
-        CALL_HEAP_FUNCTION(isolate,
-                           object->SetPropertyWithCallback(
-                               result.GetCallbackObject(),
-                               *name, *value, result.holder(), strict_mode),
-                           Object);
+        return SetPropertyWithCallback(result.GetCallbackObject(),
+            name, value, result.holder(), strict_mode);
       }
       case HANDLER: {
-        CALL_HEAP_FUNCTION(isolate,
-                           result.proxy()->SetPropertyViaPrototypesWithHandler(
-                               *object, *name, *value, attributes, strict_mode,
-                               done),
-                           Object);
+        return result.proxy()->SetPropertyViaPrototypesWithHandler(
+            this, name, value, attributes, strict_mode, done);
       }
       case TRANSITION:
       case NONEXISTENT:
@@ -2995,13 +2980,12 @@
   if (!FLAG_es5_readonly) *done = false;
   if (*done) {
     if (strict_mode == kNonStrictMode) return value;
-    Handle<Object> args[] = { name, object };
-    Handle<Object> error = isolate->factory()->NewTypeError(
-        "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
-    isolate->Throw(*error);
-    return Handle<Object>();
+    Handle<Object> args[] = { Handle<Object>(name, isolate),
+                              Handle<Object>(this, isolate)};
+    return isolate->Throw(*isolate->factory()->NewTypeError(
+      "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
   }
-  return isolate->factory()->the_hole_value();
+  return heap->the_hole_value();
 }
 
 
@@ -3422,31 +3406,33 @@
 }
 
 
-Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
-                                       LookupResult* result,
-                                       Handle<Name> key,
-                                       Handle<Object> value,
-                                       PropertyAttributes attributes,
-                                       StrictModeFlag strict_mode,
-                                       StoreFromKeyed store_mode) {
+MaybeObject* JSReceiver::SetProperty(LookupResult* result,
+                                     Name* key,
+                                     Object* value,
+                                     PropertyAttributes attributes,
+                                     StrictModeFlag strict_mode,
+                                     JSReceiver::StoreFromKeyed store_mode) {
   if (result->IsHandler()) {
-    return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
-        object, key, value, attributes, strict_mode);
+    return result->proxy()->SetPropertyWithHandler(
+        this, key, value, attributes, strict_mode);
   } else {
-    return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object),
+    return JSObject::cast(this)->SetPropertyForResult(
         result, key, value, attributes, strict_mode, store_mode);
   }
 }
 
 
-bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) {
-  Isolate* isolate = proxy->GetIsolate();
+bool JSProxy::HasPropertyWithHandler(Name* name_raw) {
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<Object> receiver(this, isolate);
+  Handle<Object> name(name_raw, isolate);
 
   // TODO(rossberg): adjust once there is a story for symbols vs proxies.
   if (name->IsSymbol()) return false;
 
   Handle<Object> args[] = { name };
-  Handle<Object> result = proxy->CallTrap(
+  Handle<Object> result = CallTrap(
     "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
   if (isolate->has_pending_exception()) return false;
 
@@ -3454,22 +3440,26 @@
 }
 
 
-Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
-                                               Handle<JSReceiver> receiver,
-                                               Handle<Name> name,
-                                               Handle<Object> value,
-                                               PropertyAttributes attributes,
-                                               StrictModeFlag strict_mode) {
-  Isolate* isolate = proxy->GetIsolate();
+MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
+    JSReceiver* receiver_raw,
+    Name* name_raw,
+    Object* value_raw,
+    PropertyAttributes attributes,
+    StrictModeFlag strict_mode) {
+  Isolate* isolate = GetIsolate();
+  HandleScope scope(isolate);
+  Handle<JSReceiver> receiver(receiver_raw);
+  Handle<Object> name(name_raw, isolate);
+  Handle<Object> value(value_raw, isolate);
 
   // TODO(rossberg): adjust once there is a story for symbols vs proxies.
-  if (name->IsSymbol()) return value;
+  if (name->IsSymbol()) return *value;
 
   Handle<Object> args[] = { receiver, name, value };
-  proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
-  if (isolate->has_pending_exception()) return Handle<Object>();
+  CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
+  if (isolate->has_pending_exception()) return Failure::Exception();
 
-  return value;
+  return *value;
 }
 
 
@@ -3744,31 +3734,36 @@
 
 
 void JSObject::MigrateInstance(Handle<JSObject> object) {
-  // Converting any field to the most specific type will cause the
-  // GeneralizeFieldRepresentation algorithm to create the most general existing
-  // transition that matches the object. This achieves what is needed.
-  Handle<Map> original_map(object->map());
-  GeneralizeFieldRepresentation(
-      object, 0, Representation::None(), ALLOW_AS_CONSTANT);
-  if (FLAG_trace_migration) {
-    object->PrintInstanceMigration(stdout, *original_map, object->map());
-  }
+  CALL_HEAP_FUNCTION_VOID(
+      object->GetIsolate(),
+      object->MigrateInstance());
 }
 
 
 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
-  MigrateInstance(object);
-  return object;
+  CALL_HEAP_FUNCTION(
+      object->GetIsolate(),
+      object->MigrateInstance(),
+      Object);
 }
 
 
-Handle<Object> JSObject::SetPropertyUsingTransition(
-    Handle<JSObject> object,
-    LookupResult* lookup,
-    Handle<Name> name,
-    Handle<Object> value,
-    PropertyAttributes attributes) {
-  Handle<Map> transition_map(lookup->GetTransitionTarget());
+Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
+                                          int modify_index,
+                                          Representation representation,
+                                          StoreMode store_mode) {
+  CALL_HEAP_FUNCTION(
+      map->GetIsolate(),
+      map->GeneralizeRepresentation(modify_index, representation, store_mode),
+      Map);
+}
+
+
+static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
+                                               Handle<Name> name,
+                                               Handle<Object> value,
+                                               PropertyAttributes attributes) {
+  Map* transition_map = lookup->GetTransitionTarget();
   int descriptor = transition_map->LastAdded();
 
   DescriptorArray* descriptors = transition_map->instance_descriptors();
@@ -3778,8 +3773,8 @@
     // AddProperty will either normalize the object, or create a new fast copy
     // of the map. If we get a fast copy of the map, all field representations
     // will be tagged since the transition is omitted.
-    return JSObject::AddProperty(
-        object, name, value, attributes, kNonStrictMode,
+    return lookup->holder()->AddProperty(
+        *name, *value, attributes, kNonStrictMode,
         JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
         JSReceiver::OMIT_EXTENSIBILITY_CHECK,
         JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
@@ -3790,40 +3785,45 @@
   // (value->IsUninitialized) as constant.
   if (details.type() == CONSTANT &&
       descriptors->GetValue(descriptor) == *value) {
-    object->set_map(*transition_map);
-    return value;
+    lookup->holder()->set_map(transition_map);
+    return *value;
   }
 
   Representation representation = details.representation();
 
   if (!value->FitsRepresentation(representation) ||
       details.type() == CONSTANT) {
-    transition_map = Map::GeneralizeRepresentation(transition_map,
+    MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
         descriptor, value->OptimalRepresentation(), FORCE_FIELD);
+    if (!maybe_map->To(&transition_map)) return maybe_map;
     Object* back = transition_map->GetBackPointer();
     if (back->IsMap()) {
-      MigrateToMap(object, handle(Map::cast(back)));
+      MaybeObject* maybe_failure =
+          lookup->holder()->MigrateToMap(Map::cast(back));
+      if (maybe_failure->IsFailure()) return maybe_failure;
     }
     descriptors = transition_map->instance_descriptors();
     representation = descriptors->GetDetails(descriptor).representation();
   }
 
   int field_index = descriptors->GetFieldIndex(descriptor);
-  return AddFastPropertyUsingMap(
-      object, transition_map, name, value, field_index, representation);
+  return lookup->holder()->AddFastPropertyUsingMap(
+      transition_map, *name, *value, field_index, representation);
 }
 
 
-static Handle<Object> SetPropertyToField(LookupResult* lookup,
-                                         Handle<Name> name,
-                                         Handle<Object> value) {
+static MaybeObject* SetPropertyToField(LookupResult* lookup,
+                                       Handle<Name> name,
+                                       Handle<Object> value) {
   Representation representation = lookup->representation();
   if (!value->FitsRepresentation(representation) ||
       lookup->type() == CONSTANT) {
-    JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
-                                            lookup->GetDescriptorIndex(),
-                                            value->OptimalRepresentation(),
-                                            FORCE_FIELD);
+    MaybeObject* maybe_failure =
+        lookup->holder()->GeneralizeFieldRepresentation(
+            lookup->GetDescriptorIndex(),
+            value->OptimalRepresentation(),
+            FORCE_FIELD);
+    if (maybe_failure->IsFailure()) return maybe_failure;
     DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
     int descriptor = lookup->GetDescriptorIndex();
     representation = desc->GetDetails(descriptor).representation();
@@ -3833,189 +3833,199 @@
     HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
         lookup->GetFieldIndex().field_index()));
     storage->set_value(value->Number());
-    return value;
+    return *value;
   }
 
   lookup->holder()->FastPropertyAtPut(
       lookup->GetFieldIndex().field_index(), *value);
-  return value;
+  return *value;
 }
 
 
-static Handle<Object> ConvertAndSetLocalProperty(
-    LookupResult* lookup,
-    Handle<Name> name,
-    Handle<Object> value,
-    PropertyAttributes attributes) {
-  Handle<JSObject> object(lookup->holder());
+static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup,
+                                               Name* name,
+                                               Object* value,
+                                               PropertyAttributes attributes) {
+  JSObject* object = lookup->holder();
   if (object->TooManyFastProperties()) {
-    JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
+    MaybeObject* maybe_failure = object->NormalizeProperties(
+        CLEAR_INOBJECT_PROPERTIES, 0);
+    if (maybe_failure->IsFailure()) return maybe_failure;
   }
 
   if (!object->HasFastProperties()) {
-    return ReplaceSlowProperty(object, name, value, attributes);
+    return object->ReplaceSlowProperty(name, value, attributes);
   }
 
   int descriptor_index = lookup->GetDescriptorIndex();
   if (lookup->GetAttributes() == attributes) {
-    JSObject::GeneralizeFieldRepresentation(
-        object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
+    MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation(
+        descriptor_index, Representation::Tagged(), FORCE_FIELD);
+    if (maybe_failure->IsFailure()) return maybe_failure;
   } else {
-    Handle<Map> old_map(object->map());
-    Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
+    Map* map;
+    MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations(
         descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
-    JSObject::MigrateToMap(object, new_map);
+    if (!maybe_map->To(&map)) return maybe_map;
+    MaybeObject* maybe_failure = object->MigrateToMap(map);
+    if (maybe_failure->IsFailure()) return maybe_failure;
   }
 
   DescriptorArray* descriptors = object->map()->instance_descriptors();
   int index = descriptors->GetDetails(descriptor_index).field_index();
-  object->FastPropertyAtPut(index, *value);
+  object->FastPropertyAtPut(index, value);
   return value;
 }
 
 
-static Handle<Object> SetPropertyToFieldWithAttributes(
+static MaybeObject* SetPropertyToFieldWithAttributes(
     LookupResult* lookup,
     Handle<Name> name,
     Handle<Object> value,
     PropertyAttributes attributes) {
   if (lookup->GetAttributes() == attributes) {
-    if (value->IsUninitialized()) return value;
+    if (value->IsUninitialized()) return *value;
     return SetPropertyToField(lookup, name, value);
   } else {
-    return ConvertAndSetLocalProperty(lookup, name, value, attributes);
+    return ConvertAndSetLocalProperty(lookup, *name, *value, attributes);
   }
 }
 
 
-Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
-                                              LookupResult* lookup,
-                                              Handle<Name> name,
-                                              Handle<Object> value,
-                                              PropertyAttributes attributes,
-                                              StrictModeFlag strict_mode,
-                                              StoreFromKeyed store_mode) {
-  Isolate* isolate = object->GetIsolate();
+MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
+                                            Name* name_raw,
+                                            Object* value_raw,
+                                            PropertyAttributes attributes,
+                                            StrictModeFlag strict_mode,
+                                            StoreFromKeyed store_mode) {
+  Heap* heap = GetHeap();
+  Isolate* isolate = heap->isolate();
 
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
-  AssertNoContextChange ncc;
+  AssertNoContextChangeWithHandleScope ncc;
 
   // Optimization for 2-byte strings often used as keys in a decompression
   // dictionary.  We internalize these short keys to avoid constantly
   // reallocating them.
-  if (name->IsString() && !name->IsInternalizedString() &&
-      Handle<String>::cast(name)->length() <= 2) {
-    name = isolate->factory()->InternalizeString(Handle<String>::cast(name));
-  }
-
-  // Check access rights if needed.
-  if (object->IsAccessCheckNeeded()) {
-    if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
-      CALL_HEAP_FUNCTION(
-          isolate,
-          object->SetPropertyWithFailedAccessCheck(
-              lookup, *name, *value, true, strict_mode),
-          Object);
+  if (name_raw->IsString() && !name_raw->IsInternalizedString() &&
+      String::cast(name_raw)->length() <= 2) {
+    Object* internalized_version;
+    { MaybeObject* maybe_string_version =
+        heap->InternalizeString(String::cast(name_raw));
+      if (maybe_string_version->ToObject(&internalized_version)) {
+        name_raw = String::cast(internalized_version);
+      }
     }
   }
 
-  if (object->IsJSGlobalProxy()) {
-    Handle<Object> proto(object->GetPrototype(), isolate);
-    if (proto->IsNull()) return value;
-    ASSERT(proto->IsJSGlobalObject());
-    return SetPropertyForResult(Handle<JSObject>::cast(proto),
-        lookup, name, value, attributes, strict_mode, store_mode);
+  // Check access rights if needed.
+  if (IsAccessCheckNeeded()) {
+    if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
+      return SetPropertyWithFailedAccessCheck(
+          lookup, name_raw, value_raw, true, strict_mode);
+    }
   }
 
-  ASSERT(!lookup->IsFound() || lookup->holder() == *object ||
+  if (IsJSGlobalProxy()) {
+    Object* proto = GetPrototype();
+    if (proto->IsNull()) return value_raw;
+    ASSERT(proto->IsJSGlobalObject());
+    return JSObject::cast(proto)->SetPropertyForResult(
+        lookup, name_raw, value_raw, attributes, strict_mode, store_mode);
+  }
+
+  ASSERT(!lookup->IsFound() || lookup->holder() == this ||
          lookup->holder()->map()->is_hidden_prototype());
 
-  if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) {
+  // From this point on everything needs to be handlified, because
+  // SetPropertyViaPrototypes might call back into JavaScript.
+  HandleScope scope(isolate);
+  Handle<JSObject> self(this);
+  Handle<Name> name(name_raw);
+  Handle<Object> value(value_raw, isolate);
+
+  if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) {
     bool done = false;
-    Handle<Object> result_object = SetPropertyViaPrototypes(
-        object, name, value, attributes, strict_mode, &done);
+    MaybeObject* result_object = self->SetPropertyViaPrototypes(
+        *name, *value, attributes, strict_mode, &done);
     if (done) return result_object;
   }
 
   if (!lookup->IsFound()) {
     // Neither properties nor transitions found.
-    return AddProperty(
-        object, name, value, attributes, strict_mode, store_mode);
+    return self->AddProperty(
+        *name, *value, attributes, strict_mode, store_mode);
   }
 
   if (lookup->IsProperty() && lookup->IsReadOnly()) {
     if (strict_mode == kStrictMode) {
-      Handle<Object> args[] = { name, object };
-      Handle<Object> error = isolate->factory()->NewTypeError(
-          "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
-      isolate->Throw(*error);
-      return Handle<Object>();
+      Handle<Object> args[] = { name, self };
+      return isolate->Throw(*isolate->factory()->NewTypeError(
+          "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
     } else {
-      return value;
+      return *value;
     }
   }
 
-  Handle<Object> old_value = isolate->factory()->the_hole_value();
+  Handle<Object> old_value(heap->the_hole_value(), isolate);
   if (FLAG_harmony_observation &&
-      object->map()->is_observed() && lookup->IsDataProperty()) {
-    old_value = Object::GetProperty(object, name);
+      map()->is_observed() && lookup->IsDataProperty()) {
+    old_value = Object::GetProperty(self, name);
   }
 
   // This is a real property that is not read-only, or it is a
   // transition or null descriptor and there are no setters in the prototypes.
-  Handle<Object> result = value;
+  MaybeObject* result = *value;
   switch (lookup->type()) {
     case NORMAL:
-      result = SetNormalizedProperty(handle(lookup->holder()), lookup, value);
+      result = lookup->holder()->SetNormalizedProperty(lookup, *value);
       break;
     case FIELD:
       result = SetPropertyToField(lookup, name, value);
       break;
     case CONSTANT:
       // Only replace the constant if necessary.
-      if (*value == lookup->GetConstant()) return value;
+      if (*value == lookup->GetConstant()) return *value;
       result = SetPropertyToField(lookup, name, value);
       break;
     case CALLBACKS: {
-      Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
-      CALL_HEAP_FUNCTION(
-          isolate,
-          object->SetPropertyWithCallback(*callback_object, *name, *value,
-                                          lookup->holder(), strict_mode),
-          Object);
+      Object* callback_object = lookup->GetCallbackObject();
+      return self->SetPropertyWithCallback(
+          callback_object, *name, *value, lookup->holder(), strict_mode);
     }
     case INTERCEPTOR:
-      result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value,
-                                          attributes, strict_mode);
+      result = lookup->holder()->SetPropertyWithInterceptor(
+          *name, *value, attributes, strict_mode);
       break;
-    case TRANSITION:
-      result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
-                                          name, value, attributes);
+    case TRANSITION: {
+      result = SetPropertyUsingTransition(lookup, name, value, attributes);
       break;
+    }
     case HANDLER:
     case NONEXISTENT:
       UNREACHABLE();
   }
 
-  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
+  Handle<Object> hresult;
+  if (!result->ToHandle(&hresult, isolate)) return result;
 
-  if (FLAG_harmony_observation && object->map()->is_observed()) {
+  if (FLAG_harmony_observation && self->map()->is_observed()) {
     if (lookup->IsTransition()) {
-      EnqueueChangeRecord(object, "new", name, old_value);
+      EnqueueChangeRecord(self, "new", name, old_value);
     } else {
       LookupResult new_lookup(isolate);
-      object->LocalLookup(*name, &new_lookup, true);
+      self->LocalLookup(*name, &new_lookup, true);
       if (new_lookup.IsDataProperty()) {
-        Handle<Object> new_value = Object::GetProperty(object, name);
+        Handle<Object> new_value = Object::GetProperty(self, name);
         if (!new_value->SameValue(*old_value)) {
-          EnqueueChangeRecord(object, "updated", name, old_value);
+          EnqueueChangeRecord(self, "updated", name, old_value);
         }
       }
     }
   }
 
-  return result;
+  return *hresult;
 }
 
 
@@ -4053,69 +4063,91 @@
 // doesn't handle function prototypes correctly.
 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
     Handle<JSObject> object,
-    Handle<Name> name,
+    Handle<Name> key,
     Handle<Object> value,
     PropertyAttributes attributes,
     ValueType value_type,
     StoreMode mode,
     ExtensibilityCheck extensibility_check) {
-  Isolate* isolate = object->GetIsolate();
+  CALL_HEAP_FUNCTION(
+    object->GetIsolate(),
+    object->SetLocalPropertyIgnoreAttributes(
+        *key, *value, attributes, value_type, mode, extensibility_check),
+    Object);
+}
 
+
+MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
+    Name* name_raw,
+    Object* value_raw,
+    PropertyAttributes attributes,
+    ValueType value_type,
+    StoreMode mode,
+    ExtensibilityCheck extensibility_check) {
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
-  AssertNoContextChange ncc;
-
+  AssertNoContextChangeWithHandleScope ncc;
+  Isolate* isolate = GetIsolate();
   LookupResult lookup(isolate);
-  object->LocalLookup(*name, &lookup, true);
-  if (!lookup.IsFound()) {
-    object->map()->LookupTransition(*object, *name, &lookup);
-  }
-
+  LocalLookup(name_raw, &lookup, true);
+  if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup);
   // Check access rights if needed.
-  if (object->IsAccessCheckNeeded()) {
-    if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
-      CALL_HEAP_FUNCTION(
-          isolate,
-          object->SetPropertyWithFailedAccessCheck(
-              &lookup, *name, *value, false, kNonStrictMode),
-          Object);
+  if (IsAccessCheckNeeded()) {
+    if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
+      return SetPropertyWithFailedAccessCheck(&lookup,
+                                              name_raw,
+                                              value_raw,
+                                              false,
+                                              kNonStrictMode);
     }
   }
 
-  if (object->IsJSGlobalProxy()) {
-    Handle<Object> proto(object->GetPrototype(), isolate);
-    if (proto->IsNull()) return value;
+  if (IsJSGlobalProxy()) {
+    Object* proto = GetPrototype();
+    if (proto->IsNull()) return value_raw;
     ASSERT(proto->IsJSGlobalObject());
-    return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
-        name, value, attributes, value_type, mode, extensibility_check);
+    return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes(
+        name_raw,
+        value_raw,
+        attributes,
+        value_type,
+        mode,
+        extensibility_check);
   }
 
   if (lookup.IsFound() &&
       (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) {
-    object->LocalLookupRealNamedProperty(*name, &lookup);
+    LocalLookupRealNamedProperty(name_raw, &lookup);
   }
 
   // Check for accessor in prototype chain removed here in clone.
   if (!lookup.IsFound()) {
     // Neither properties nor transitions found.
-    return AddProperty(object, name, value, attributes, kNonStrictMode,
+    return AddProperty(
+        name_raw, value_raw, attributes, kNonStrictMode,
         MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
   }
 
-  Handle<Object> old_value = isolate->factory()->the_hole_value();
+  // From this point on everything needs to be handlified.
+  HandleScope scope(isolate);
+  Handle<JSObject> self(this);
+  Handle<Name> name(name_raw);
+  Handle<Object> value(value_raw, isolate);
+
+  Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate);
   PropertyAttributes old_attributes = ABSENT;
-  bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
+  bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
   if (is_observed && lookup.IsProperty()) {
     if (lookup.IsDataProperty()) old_value =
-        Object::GetProperty(object, name);
+        Object::GetProperty(self, name);
     old_attributes = lookup.GetAttributes();
   }
 
   // Check of IsReadOnly removed from here in clone.
-  Handle<Object> result = value;
+  MaybeObject* result = *value;
   switch (lookup.type()) {
     case NORMAL:
-      result = ReplaceSlowProperty(object, name, value, attributes);
+      result = self->ReplaceSlowProperty(*name, *value, attributes);
       break;
     case FIELD:
       result = SetPropertyToFieldWithAttributes(
@@ -4130,11 +4162,10 @@
       }
       break;
     case CALLBACKS:
-      result = ConvertAndSetLocalProperty(&lookup, name, value, attributes);
+      result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes);
       break;
     case TRANSITION:
-      result = SetPropertyUsingTransition(handle(lookup.holder()), &lookup,
-                                          name, value, attributes);
+      result = SetPropertyUsingTransition(&lookup, name, value, attributes);
       break;
     case NONEXISTENT:
     case HANDLER:
@@ -4142,31 +4173,32 @@
       UNREACHABLE();
   }
 
-  if (result.is_null()) return result;
+  Handle<Object> hresult;
+  if (!result->ToHandle(&hresult, isolate)) return result;
 
   if (is_observed) {
     if (lookup.IsTransition()) {
-      EnqueueChangeRecord(object, "new", name, old_value);
+      EnqueueChangeRecord(self, "new", name, old_value);
     } else if (old_value->IsTheHole()) {
-      EnqueueChangeRecord(object, "reconfigured", name, old_value);
+      EnqueueChangeRecord(self, "reconfigured", name, old_value);
     } else {
       LookupResult new_lookup(isolate);
-      object->LocalLookup(*name, &new_lookup, true);
+      self->LocalLookup(*name, &new_lookup, true);
       bool value_changed = false;
       if (new_lookup.IsDataProperty()) {
-        Handle<Object> new_value = Object::GetProperty(object, name);
+        Handle<Object> new_value = Object::GetProperty(self, name);
         value_changed = !old_value->SameValue(*new_value);
       }
       if (new_lookup.GetAttributes() != old_attributes) {
         if (!value_changed) old_value = isolate->factory()->the_hole_value();
-        EnqueueChangeRecord(object, "reconfigured", name, old_value);
+        EnqueueChangeRecord(self, "reconfigured", name, old_value);
       } else if (value_changed) {
-        EnqueueChangeRecord(object, "updated", name, old_value);
+        EnqueueChangeRecord(self, "updated", name, old_value);
       }
     }
   }
 
-  return result;
+  return *hresult;
 }
 
 
@@ -5120,7 +5152,7 @@
   Handle<Object> old_value;
   bool should_enqueue_change_record = false;
   if (FLAG_harmony_observation && object->map()->is_observed()) {
-    should_enqueue_change_record = HasLocalElement(object, index);
+    should_enqueue_change_record = object->HasLocalElement(index);
     if (should_enqueue_change_record) {
       old_value = object->GetLocalElementAccessorPair(index) != NULL
           ? Handle<Object>::cast(factory->the_hole_value())
@@ -5136,7 +5168,7 @@
     result = AccessorDelete(object, index, mode);
   }
 
-  if (should_enqueue_change_record && !HasLocalElement(object, index)) {
+  if (should_enqueue_change_record && !object->HasLocalElement(index)) {
     Handle<String> name = factory->Uint32ToString(index);
     EnqueueChangeRecord(object, "deleted", name, old_value);
   }
@@ -5211,7 +5243,7 @@
     result = DeleteNormalizedProperty(object, name, mode);
   }
 
-  if (is_observed && !HasLocalProperty(object, name)) {
+  if (is_observed && !object->HasLocalProperty(*name)) {
     EnqueueChangeRecord(object, "deleted", name, old_value);
   }
 
@@ -5603,80 +5635,71 @@
 }
 
 
-// TODO(mstarzinger): Temporary wrapper until handlified.
-static Handle<Object> NewStorageFor(Isolate* isolate,
-                                    Handle<Object> object,
-                                    Representation representation) {
-  Heap* heap = isolate->heap();
-  CALL_HEAP_FUNCTION(isolate,
-                     object->AllocateNewStorageFor(heap, representation),
-                     Object);
-}
-
-
-Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
-  Isolate* isolate = object->GetIsolate();
-  CALL_HEAP_FUNCTION(isolate,
-                     isolate->heap()->CopyJSObject(*object), JSObject);
-}
-
-
-Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
-  Isolate* isolate = object->GetIsolate();
+MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
   StackLimitCheck check(isolate);
-  if (check.HasOverflowed()) {
-    isolate->StackOverflow();
-    return Handle<JSObject>::null();
+  if (check.HasOverflowed()) return isolate->StackOverflow();
+
+  if (map()->is_deprecated()) {
+    MaybeObject* maybe_failure = MigrateInstance();
+    if (maybe_failure->IsFailure()) return maybe_failure;
   }
 
-  if (object->map()->is_deprecated()) {
-    MigrateInstance(object);
+  Heap* heap = isolate->heap();
+  Object* result;
+  { MaybeObject* maybe_result = heap->CopyJSObject(this);
+    if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-
-  Handle<JSObject> copy = Copy(object);
-
-  HandleScope scope(isolate);
+  JSObject* copy = JSObject::cast(result);
 
   // Deep copy local properties.
   if (copy->HasFastProperties()) {
-    Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
+    DescriptorArray* descriptors = copy->map()->instance_descriptors();
     int limit = copy->map()->NumberOfOwnDescriptors();
     for (int i = 0; i < limit; i++) {
       PropertyDetails details = descriptors->GetDetails(i);
       if (details.type() != FIELD) continue;
       int index = descriptors->GetFieldIndex(i);
-      Handle<Object> value(object->RawFastPropertyAt(index), isolate);
+      Object* value = RawFastPropertyAt(index);
       if (value->IsJSObject()) {
-        value = DeepCopy(Handle<JSObject>::cast(value));
-        RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>());
+        JSObject* js_object = JSObject::cast(value);
+        MaybeObject* maybe_copy = js_object->DeepCopy(isolate);
+        if (!maybe_copy->To(&value)) return maybe_copy;
       } else {
         Representation representation = details.representation();
-        value = NewStorageFor(isolate, value, representation);
+        MaybeObject* maybe_storage =
+            value->AllocateNewStorageFor(heap, representation);
+        if (!maybe_storage->To(&value)) return maybe_storage;
       }
-      copy->FastPropertyAtPut(index, *value);
+      copy->FastPropertyAtPut(index, value);
     }
   } else {
-    Handle<FixedArray> names =
-        isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties());
-    copy->GetLocalPropertyNames(*names, 0);
+    { MaybeObject* maybe_result =
+          heap->AllocateFixedArray(copy->NumberOfLocalProperties());
+      if (!maybe_result->ToObject(&result)) return maybe_result;
+    }
+    FixedArray* names = FixedArray::cast(result);
+    copy->GetLocalPropertyNames(names, 0);
     for (int i = 0; i < names->length(); i++) {
       ASSERT(names->get(i)->IsString());
-      Handle<String> key_string(String::cast(names->get(i)));
+      String* key_string = String::cast(names->get(i));
       PropertyAttributes attributes =
-          copy->GetLocalPropertyAttribute(*key_string);
+          copy->GetLocalPropertyAttribute(key_string);
       // Only deep copy fields from the object literal expression.
       // In particular, don't try to copy the length attribute of
       // an array.
       if (attributes != NONE) continue;
-      Handle<Object> value(
-          copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
-          isolate);
+      Object* value =
+          copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
       if (value->IsJSObject()) {
-        Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
-        RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-        // Creating object copy for literals. No strict mode needed.
-        CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty(
-            copy, key_string, result, NONE, kNonStrictMode));
+        JSObject* js_object = JSObject::cast(value);
+        { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+          if (!maybe_result->ToObject(&result)) return maybe_result;
+        }
+        { MaybeObject* maybe_result =
+              // Creating object copy for literals. No strict mode needed.
+              copy->SetProperty(key_string, result, NONE, kNonStrictMode);
+          if (!maybe_result->ToObject(&result)) return maybe_result;
+        }
       }
     }
   }
@@ -5689,8 +5712,8 @@
     case FAST_ELEMENTS:
     case FAST_HOLEY_SMI_ELEMENTS:
     case FAST_HOLEY_ELEMENTS: {
-      Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
-      if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
+      FixedArray* elements = FixedArray::cast(copy->elements());
+      if (elements->map() == heap->fixed_cow_array_map()) {
         isolate->counters()->cow_arrays_created_runtime()->Increment();
 #ifdef DEBUG
         for (int i = 0; i < elements->length(); i++) {
@@ -5699,31 +5722,34 @@
 #endif
       } else {
         for (int i = 0; i < elements->length(); i++) {
-          Handle<Object> value(elements->get(i), isolate);
+          Object* value = elements->get(i);
           ASSERT(value->IsSmi() ||
                  value->IsTheHole() ||
                  (IsFastObjectElementsKind(copy->GetElementsKind())));
           if (value->IsJSObject()) {
-            Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
-            RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-            elements->set(i, *result);
+            JSObject* js_object = JSObject::cast(value);
+            { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+              if (!maybe_result->ToObject(&result)) return maybe_result;
+            }
+            elements->set(i, result);
           }
         }
       }
       break;
     }
     case DICTIONARY_ELEMENTS: {
-      Handle<SeededNumberDictionary> element_dictionary(
-          copy->element_dictionary());
+      SeededNumberDictionary* element_dictionary = copy->element_dictionary();
       int capacity = element_dictionary->Capacity();
       for (int i = 0; i < capacity; i++) {
         Object* k = element_dictionary->KeyAt(i);
         if (element_dictionary->IsKey(k)) {
-          Handle<Object> value(element_dictionary->ValueAt(i), isolate);
+          Object* value = element_dictionary->ValueAt(i);
           if (value->IsJSObject()) {
-            Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
-            RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-            element_dictionary->ValueAtPut(i, *result);
+            JSObject* js_object = JSObject::cast(value);
+            { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
+              if (!maybe_result->ToObject(&result)) return maybe_result;
+            }
+            element_dictionary->ValueAtPut(i, result);
           }
         }
       }
@@ -6164,7 +6190,7 @@
   bool preexists = false;
   if (is_observed) {
     if (is_element) {
-      preexists = HasLocalElement(object, index);
+      preexists = object->HasLocalElement(index);
       if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
         old_value = Object::GetElement(isolate, object, index);
       }
@@ -6660,15 +6686,6 @@
 }
 
 
-Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
-                                        int new_descriptor,
-                                        Handle<DescriptorArray> descriptors) {
-  CALL_HEAP_FUNCTION(map->GetIsolate(),
-                     map->CopyInstallDescriptors(new_descriptor, *descriptors),
-                     Map);
-}
-
-
 // Since this method is used to rewrite an existing transition tree, it can
 // always insert transitions without checking.
 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor,
@@ -7781,20 +7798,6 @@
 }
 
 
-Handle<DescriptorArray> DescriptorArray::Merge(Handle<DescriptorArray> desc,
-                                               int verbatim,
-                                               int valid,
-                                               int new_size,
-                                               int modify_index,
-                                               StoreMode store_mode,
-                                               Handle<DescriptorArray> other) {
-  CALL_HEAP_FUNCTION(desc->GetIsolate(),
-                     desc->Merge(verbatim, valid, new_size, modify_index,
-                                 store_mode, *other),
-                     DescriptorArray);
-}
-
-
 // Generalize the |other| descriptor array by merging it into the (at least
 // partly) updated |this| descriptor array.
 // The method merges two descriptor array in three parts. Both descriptor arrays
@@ -10433,8 +10436,8 @@
 }
 
 
-void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) {
-  PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY);
+void Code::MakeCodeAgeSequenceYoung(byte* sequence) {
+  PatchPlatformCodeAge(sequence, kNoAge, NO_MARKING_PARITY);
 }
 
 
@@ -10445,9 +10448,7 @@
     MarkingParity code_parity;
     GetCodeAgeAndParity(sequence, &age, &code_parity);
     if (age != kLastCodeAge && code_parity != current_parity) {
-      PatchPlatformCodeAge(GetIsolate(),
-                           sequence,
-                           static_cast<Age>(age + 1),
+      PatchPlatformCodeAge(sequence, static_cast<Age>(age + 1),
                            current_parity);
     }
   }
@@ -10510,7 +10511,8 @@
 }
 
 
-Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) {
+Code* Code::GetCodeAgeStub(Age age, MarkingParity parity) {
+  Isolate* isolate = Isolate::Current();
   Builtins* builtins = isolate->builtins();
   switch (age) {
 #define HANDLE_CODE_AGE(AGE)                                            \
@@ -10781,7 +10783,7 @@
     case CONSTANT: return "CONSTANT";
     case CALLBACKS: return "CALLBACKS";
     case INTERCEPTOR: return "INTERCEPTOR";
-    case TRANSITION: return "TRANSITION";
+    case MAP_TRANSITION: return "MAP_TRANSITION";
     case NONEXISTENT: return "NONEXISTENT";
   }
   UNREACHABLE();  // keep the compiler happy
@@ -14517,6 +14519,17 @@
 }
 
 
+// TODO(mstarzinger): Temporary wrapper until handlified.
+static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
+                                                Handle<Name> name,
+                                                Handle<Object> value,
+                                                PropertyDetails details) {
+  CALL_HEAP_FUNCTION(dict->GetIsolate(),
+                     dict->Add(*name, *value, details),
+                     NameDictionary);
+}
+
+
 Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
     Handle<GlobalObject> global,
     Handle<Name> name) {
@@ -16095,14 +16108,6 @@
 }
 
 
-void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
-                                     Handle<Object> value,
-                                     WriteBarrierMode mode) {
-  CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(),
-                          cell->SetValueInferType(*value, mode));
-}
-
-
 MaybeObject* PropertyCell::SetValueInferType(Object* value,
                                              WriteBarrierMode ignored) {
   set_value(value, ignored);
diff --git a/src/objects.h b/src/objects.h
index 46d65b1..d3593b6 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1950,30 +1950,42 @@
   // Casting.
   static inline JSReceiver* cast(Object* obj);
 
-  // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
   static Handle<Object> SetProperty(Handle<JSReceiver> object,
                                     Handle<Name> key,
                                     Handle<Object> value,
                                     PropertyAttributes attributes,
-                                    StrictModeFlag strict_mode,
-                                    StoreFromKeyed store_mode =
-                                        MAY_BE_STORE_FROM_KEYED);
+                                    StrictModeFlag strict_mode);
   static Handle<Object> SetElement(Handle<JSReceiver> object,
                                    uint32_t index,
                                    Handle<Object> value,
                                    PropertyAttributes attributes,
                                    StrictModeFlag strict_mode);
 
+  MUST_USE_RESULT static MaybeObject* SetPropertyOrFail(
+      Handle<JSReceiver> object,
+      Handle<Name> key,
+      Handle<Object> value,
+      PropertyAttributes attributes,
+      StrictModeFlag strict_mode,
+      StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
+
+  // Can cause GC.
+  MUST_USE_RESULT MaybeObject* SetProperty(
+      Name* key,
+      Object* value,
+      PropertyAttributes attributes,
+      StrictModeFlag strict_mode,
+      StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
+  MUST_USE_RESULT MaybeObject* SetProperty(
+      LookupResult* result,
+      Name* key,
+      Object* value,
+      PropertyAttributes attributes,
+      StrictModeFlag strict_mode,
+      StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
   MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSReceiver* setter,
                                                             Object* value);
 
-  // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
-  static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
-  static inline bool HasLocalProperty(Handle<JSReceiver>, Handle<Name> name);
-  static inline bool HasElement(Handle<JSReceiver> object, uint32_t index);
-  static inline bool HasLocalElement(Handle<JSReceiver> object, uint32_t index);
-
-  // Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
   static Handle<Object> DeleteProperty(Handle<JSReceiver> object,
                                        Handle<Name> name,
                                        DeleteMode mode = NORMAL_DELETION);
@@ -1999,6 +2011,12 @@
   inline PropertyAttributes GetElementAttribute(uint32_t index);
   inline PropertyAttributes GetLocalElementAttribute(uint32_t index);
 
+  // Can cause a GC.
+  inline bool HasProperty(Name* name);
+  inline bool HasLocalProperty(Name* name);
+  inline bool HasElement(uint32_t index);
+  inline bool HasLocalElement(uint32_t index);
+
   // Return the object's prototype (might be Heap::null_value()).
   inline Object* GetPrototype();
 
@@ -2024,14 +2042,6 @@
                                                    Name* name,
                                                    bool continue_search);
 
-  static Handle<Object> SetProperty(Handle<JSReceiver> receiver,
-                                    LookupResult* result,
-                                    Handle<Name> key,
-                                    Handle<Object> value,
-                                    PropertyAttributes attributes,
-                                    StrictModeFlag strict_mode,
-                                    StoreFromKeyed store_from_keyed);
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
 };
 
@@ -2125,6 +2135,13 @@
                                                        Object* structure,
                                                        Name* name);
 
+  // Can cause GC.
+  MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result,
+                                           Name* key,
+                                           Object* value,
+                                           PropertyAttributes attributes,
+                                           StrictModeFlag strict_mode,
+                                           StoreFromKeyed store_mode);
   MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck(
       LookupResult* result,
       Name* name,
@@ -2137,21 +2154,17 @@
       Object* value,
       JSObject* holder,
       StrictModeFlag strict_mode);
-  static Handle<Object> SetPropertyWithInterceptor(
-      Handle<JSObject> object,
-      Handle<Name> name,
-      Handle<Object> value,
+  MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
+      Name* name,
+      Object* value,
       PropertyAttributes attributes,
       StrictModeFlag strict_mode);
-
-  static Handle<Object> SetPropertyForResult(
-      Handle<JSObject> object,
-      LookupResult* result,
-      Handle<Name> name,
-      Handle<Object> value,
+  MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor(
+      Name* name,
+      Object* value,
       PropertyAttributes attributes,
       StrictModeFlag strict_mode,
-      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
+      StoreMode mode = ALLOW_AS_CONSTANT);
 
   static Handle<Object> SetLocalPropertyIgnoreAttributes(
       Handle<JSObject> object,
@@ -2178,6 +2191,7 @@
   inline MUST_USE_RESULT MaybeObject* AllocateStorageForMap(Map* map);
 
   static void MigrateInstance(Handle<JSObject> instance);
+  inline MUST_USE_RESULT MaybeObject* MigrateInstance();
 
   static Handle<Object> TryMigrateInstance(Handle<JSObject> instance);
   inline MUST_USE_RESULT MaybeObject* TryMigrateInstance();
@@ -2469,6 +2483,32 @@
   // Returns the number of enumerable elements.
   int GetEnumElementKeys(FixedArray* storage);
 
+  // Add a property to a fast-case object using a map transition to
+  // new_map.
+  MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(
+      Map* new_map,
+      Name* name,
+      Object* value,
+      int field_index,
+      Representation representation);
+
+  // Add a constant function property to a fast-case object.
+  // This leaves a CONSTANT_TRANSITION in the old map, and
+  // if it is called on a second object with this map, a
+  // normal property is added instead, with a map transition.
+  // This avoids the creation of many maps with the same constant
+  // function, all orphaned.
+  MUST_USE_RESULT MaybeObject* AddConstantProperty(
+      Name* name,
+      Object* constant,
+      PropertyAttributes attributes,
+      TransitionFlag flag);
+
+  MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
+      Name* name,
+      Object* value,
+      PropertyAttributes attributes);
+
   // Returns a new map with all transitions dropped from the object's current
   // map and the ElementsKind set.
   static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
@@ -2485,12 +2525,37 @@
   MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
   MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind);
 
-  static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map);
   MUST_USE_RESULT MaybeObject* MigrateToMap(Map* new_map);
-  static void GeneralizeFieldRepresentation(Handle<JSObject> object,
-                                            int modify_index,
-                                            Representation new_representation,
-                                            StoreMode store_mode);
+  MUST_USE_RESULT MaybeObject* GeneralizeFieldRepresentation(
+      int modify_index,
+      Representation new_representation,
+      StoreMode store_mode);
+
+  // Add a property to a fast-case object.
+  MUST_USE_RESULT MaybeObject* AddFastProperty(
+      Name* name,
+      Object* value,
+      PropertyAttributes attributes,
+      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
+      ValueType value_type = OPTIMAL_REPRESENTATION,
+      TransitionFlag flag = INSERT_TRANSITION);
+
+  // Add a property to a slow-case object.
+  MUST_USE_RESULT MaybeObject* AddSlowProperty(Name* name,
+                                               Object* value,
+                                               PropertyAttributes attributes);
+
+  // Add a property to an object. May cause GC.
+  MUST_USE_RESULT MaybeObject* AddProperty(
+      Name* name,
+      Object* value,
+      PropertyAttributes attributes,
+      StrictModeFlag strict_mode,
+      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
+      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
+      ValueType value_type = OPTIMAL_REPRESENTATION,
+      StoreMode mode = ALLOW_AS_CONSTANT,
+      TransitionFlag flag = INSERT_TRANSITION);
 
   // Convert the object to use the canonical dictionary
   // representation. If the object is expected to have additional properties
@@ -2565,9 +2630,8 @@
   // Called the first time an object is observed with ES7 Object.observe.
   MUST_USE_RESULT MaybeObject* SetObserved(Isolate* isolate);
 
-  // Copy object.
-  static Handle<JSObject> Copy(Handle<JSObject> object);
-  static Handle<JSObject> DeepCopy(Handle<JSObject> object);
+  // Copy object
+  MUST_USE_RESULT MaybeObject* DeepCopy(Isolate* isolate);
 
   // Dispatched behavior.
   void JSObjectShortPrint(StringStream* accumulator);
@@ -2670,6 +2734,15 @@
   friend class DictionaryElementsAccessor;
   friend class JSReceiver;
 
+  // TODO(mstarzinger): Soon to be handlified.
+  MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
+      Name* key,
+      Object* value,
+      PropertyAttributes attributes,
+      ValueType value_type = OPTIMAL_REPRESENTATION,
+      StoreMode mode = ALLOW_AS_CONSTANT,
+      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
+
   MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
                                                       Object* structure,
                                                       uint32_t index,
@@ -2706,81 +2779,13 @@
   // Searches the prototype chain for property 'name'. If it is found and
   // has a setter, invoke it and set '*done' to true. If it is found and is
   // read-only, reject and set '*done' to true. Otherwise, set '*done' to
-  // false. Can throw and return an empty handle with '*done==true'.
-  static Handle<Object> SetPropertyViaPrototypes(
-      Handle<JSObject> object,
-      Handle<Name> name,
-      Handle<Object> value,
+  // false. Can cause GC and can return a failure result with '*done==true'.
+  MUST_USE_RESULT MaybeObject* SetPropertyViaPrototypes(
+      Name* name,
+      Object* value,
       PropertyAttributes attributes,
       StrictModeFlag strict_mode,
       bool* done);
-  static Handle<Object> SetPropertyPostInterceptor(
-      Handle<JSObject> object,
-      Handle<Name> name,
-      Handle<Object> value,
-      PropertyAttributes attributes,
-      StrictModeFlag strict_mode);
-  static Handle<Object> SetPropertyUsingTransition(
-      Handle<JSObject> object,
-      LookupResult* lookup,
-      Handle<Name> name,
-      Handle<Object> value,
-      PropertyAttributes attributes);
-
-  // Add a property to an object.
-  static Handle<Object> AddProperty(
-      Handle<JSObject> object,
-      Handle<Name> name,
-      Handle<Object> value,
-      PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
-      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
-      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
-      ValueType value_type = OPTIMAL_REPRESENTATION,
-      StoreMode mode = ALLOW_AS_CONSTANT,
-      TransitionFlag flag = INSERT_TRANSITION);
-
-  // Add a constant function property to a fast-case object.
-  // This leaves a CONSTANT_TRANSITION in the old map, and
-  // if it is called on a second object with this map, a
-  // normal property is added instead, with a map transition.
-  // This avoids the creation of many maps with the same constant
-  // function, all orphaned.
-  static void AddConstantProperty(Handle<JSObject> object,
-                                  Handle<Name> name,
-                                  Handle<Object> constant,
-                                  PropertyAttributes attributes,
-                                  TransitionFlag flag);
-
-  // Add a property to a fast-case object.
-  static void AddFastProperty(Handle<JSObject> object,
-                              Handle<Name> name,
-                              Handle<Object> value,
-                              PropertyAttributes attributes,
-                              StoreFromKeyed store_mode,
-                              ValueType value_type,
-                              TransitionFlag flag);
-
-  // Add a property to a fast-case object using a map transition to
-  // new_map.
-  static Handle<Object> AddFastPropertyUsingMap(Handle<JSObject> object,
-                                                Handle<Map> new_map,
-                                                Handle<Name> name,
-                                                Handle<Object> value,
-                                                int field_index,
-                                                Representation representation);
-  MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(
-      Map* new_map,
-      Name* name,
-      Object* value,
-      int field_index,
-      Representation representation);
-
-  // Add a property to a slow-case object.
-  static void AddSlowProperty(Handle<JSObject> object,
-                              Handle<Name> name,
-                              Handle<Object> value,
-                              PropertyAttributes attributes);
 
   static Handle<Object> DeleteProperty(Handle<JSObject> object,
                                        Handle<Name> name,
@@ -3170,13 +3175,6 @@
                 DescriptorArray* src,
                 int src_index,
                 const WhitenessWitness&);
-  static Handle<DescriptorArray> Merge(Handle<DescriptorArray> desc,
-                                       int verbatim,
-                                       int valid,
-                                       int new_size,
-                                       int modify_index,
-                                       StoreMode store_mode,
-                                       Handle<DescriptorArray> other);
   MUST_USE_RESULT MaybeObject* Merge(int verbatim,
                                      int valid,
                                      int new_size,
@@ -4813,7 +4811,7 @@
     CONSTANT,
     CALLBACKS,
     INTERCEPTOR,
-    TRANSITION,
+    MAP_TRANSITION,
     NONEXISTENT
   };
 
@@ -5156,7 +5154,7 @@
   // being entered through the prologue.  Used to determine when it is
   // relatively safe to flush this code object and replace it with the lazy
   // compilation stub.
-  static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
+  static void MakeCodeAgeSequenceYoung(byte* sequence);
   void MakeOlder(MarkingParity);
   static bool IsYoungSequence(byte* sequence);
   bool IsOld();
@@ -5302,11 +5300,10 @@
                                   MarkingParity* parity);
   static void GetCodeAgeAndParity(byte* sequence, Age* age,
                                   MarkingParity* parity);
-  static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
+  static Code* GetCodeAgeStub(Age age, MarkingParity parity);
 
   // Code aging -- platform-specific
-  static void PatchPlatformCodeAge(Isolate* isolate,
-                                   byte* sequence, Age age,
+  static void PatchPlatformCodeAge(byte* sequence, Age age,
                                    MarkingParity parity);
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
@@ -5619,8 +5616,11 @@
       int modify_index,
       Representation new_representation,
       StoreMode store_mode);
-  static Handle<Map> CopyGeneralizeAllRepresentations(
-      Handle<Map> map,
+  MUST_USE_RESULT MaybeObject* GeneralizeRepresentation(
+      int modify_index,
+      Representation representation,
+      StoreMode store_mode);
+  MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations(
       int modify_index,
       StoreMode store_mode,
       PropertyAttributes attributes,
@@ -5800,10 +5800,6 @@
       TransitionFlag flag,
       Name* name = NULL,
       SimpleTransitionFlag simple_flag = FULL_TRANSITION);
-  static Handle<Map> CopyInstallDescriptors(
-      Handle<Map> map,
-      int new_descriptor,
-      Handle<DescriptorArray> descriptors);
   MUST_USE_RESULT MaybeObject* CopyInstallDescriptors(
       int new_descriptor,
       DescriptorArray* descriptors);
@@ -9022,9 +9018,6 @@
   // of the cell's current type and the value's type. If the change causes
   // a change of the type of the cell's contents, code dependent on the cell
   // will be deoptimized.
-  static void SetValueInferType(Handle<PropertyCell> cell,
-                                Handle<Object> value,
-                                WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   MUST_USE_RESULT MaybeObject* SetValueInferType(
       Object* value,
       WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
@@ -9077,6 +9070,9 @@
   // Casting.
   static inline JSProxy* cast(Object* obj);
 
+  bool HasPropertyWithHandler(Name* name);
+  bool HasElementWithHandler(uint32_t index);
+
   MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(
       Object* receiver,
       Name* name);
@@ -9084,6 +9080,13 @@
       Object* receiver,
       uint32_t index);
 
+  MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
+      JSReceiver* receiver,
+      Name* name,
+      Object* value,
+      PropertyAttributes attributes,
+      StrictModeFlag strict_mode);
+
   // If the handler defines an accessor property with a setter, invoke it.
   // If it defines an accessor property without a setter, or a data property
   // that is read-only, throw. In all these cases set '*done' to true,
@@ -9139,21 +9142,12 @@
  private:
   friend class JSReceiver;
 
-  static Handle<Object> SetPropertyWithHandler(Handle<JSProxy> proxy,
-                                               Handle<JSReceiver> receiver,
-                                               Handle<Name> name,
-                                               Handle<Object> value,
-                                               PropertyAttributes attributes,
-                                               StrictModeFlag strict_mode);
   static Handle<Object> SetElementWithHandler(Handle<JSProxy> proxy,
                                               Handle<JSReceiver> receiver,
                                               uint32_t index,
                                               Handle<Object> value,
                                               StrictModeFlag strict_mode);
 
-  static bool HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name);
-  static bool HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index);
-
   static Handle<Object> DeletePropertyWithHandler(Handle<JSProxy> proxy,
                                                   Handle<Name> name,
                                                   DeleteMode mode);
diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
index 029c115..085143d 100644
--- a/src/optimizing-compiler-thread.cc
+++ b/src/optimizing-compiler-thread.cc
@@ -74,6 +74,7 @@
         { AllowHandleDereference allow_handle_dereference;
           FlushInputQueue(true);
         }
+        Release_Store(&queue_length_, static_cast<AtomicWord>(0));
         Release_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE));
         stop_semaphore_.Signal();
         // Return to start of consumer loop.
@@ -113,7 +114,6 @@
     osr_candidates_.RemoveElement(optimizing_compiler);
     ready_for_osr_.Add(optimizing_compiler);
   } else {
-    LockGuard<Mutex> access_queue(&queue_mutex_);
     output_queue_.Enqueue(optimizing_compiler);
     isolate_->stack_guard()->RequestInstallCode();
   }
@@ -134,20 +134,13 @@
     }
     delete info;
   }
-  Release_Store(&queue_length_, static_cast<AtomicWord>(0));
-
-  LockGuard<Mutex> access_osr_lists(&osr_list_mutex_);
-  osr_candidates_.Clear();
 }
 
 
 void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) {
   OptimizingCompiler* optimizing_compiler;
   // The optimizing compiler is allocated in the CompilationInfo's zone.
-  while (true) {
-    { LockGuard<Mutex> access_queue(&queue_mutex_);
-      if (!output_queue_.Dequeue(&optimizing_compiler)) break;
-    }
+  while (output_queue_.Dequeue(&optimizing_compiler)) {
     CompilationInfo* info = optimizing_compiler->info();
     if (restore_function_code) {
       Handle<JSFunction> function = info->closure();
@@ -156,6 +149,7 @@
     delete info;
   }
 
+  osr_candidates_.Clear();
   RemoveStaleOSRCandidates(0);
 }
 
@@ -202,12 +196,9 @@
 void OptimizingCompilerThread::InstallOptimizedFunctions() {
   ASSERT(!IsOptimizerThread());
   HandleScope handle_scope(isolate_);
-
   OptimizingCompiler* compiler;
   while (true) {
-    { LockGuard<Mutex> access_queue(&queue_mutex_);
-      if (!output_queue_.Dequeue(&compiler)) break;
-    }
+    if (!output_queue_.Dequeue(&compiler)) return;
     Compiler::InstallOptimizedCode(compiler);
   }
 
diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compiler-thread.h
index 4231765..d1ed6a2 100644
--- a/src/optimizing-compiler-thread.h
+++ b/src/optimizing-compiler-thread.h
@@ -115,7 +115,7 @@
   UnboundQueue<OptimizingCompiler*> input_queue_;
   // Queue of recompilation tasks ready to be installed (excluding OSR).
   UnboundQueue<OptimizingCompiler*> output_queue_;
-  // List of recompilation tasks for OSR in the input queue.
+  // List of all OSR related recompilation tasks (both incoming and ready ones).
   List<OptimizingCompiler*> osr_candidates_;
   // List of recompilation tasks ready for OSR.
   List<OptimizingCompiler*> ready_for_osr_;
@@ -125,8 +125,6 @@
   TimeDelta time_spent_compiling_;
   TimeDelta time_spent_total_;
 
-  // TODO(yangguo): remove this once the memory leak has been figured out.
-  Mutex queue_mutex_;
   Mutex osr_list_mutex_;
   int osr_hits_;
   int osr_attempts_;
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index 5903438..4d3b1e3 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -205,6 +205,12 @@
 }
 
 
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  // Not supported on Cygwin.
+  return 0;
+}
+
+
 // The VirtualMemory implementation is taken from platform-win32.cc.
 // The mmap-based virtual memory implementation as it is used on most posix
 // platforms does not work well because Cygwin does not support MAP_FIXED.
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 518ad31..d818278 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -199,6 +199,10 @@
 }
 
 
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
+}
+
 
 // Constants used for mmap.
 static const int kMmapFd = -1;
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 74d473f..b8b9602 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -313,6 +313,16 @@
 }
 
 
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  // backtrace is a glibc extension.
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+  return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
+#else
+  return 0;
+#endif
+}
+
+
 // Constants used for mmap.
 static const int kMmapFd = -1;
 static const int kMmapFdOffset = 0;
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index a58bc1a..67cc96f 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -220,6 +220,14 @@
 }
 
 
+int OS::StackWalk(Vector<StackFrame> frames) {
+  // If weak link to execinfo lib has failed, ie because we are on 10.4, abort.
+  if (backtrace == NULL) return 0;
+
+  return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
+}
+
+
 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
 
 
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index 4f5420e..30a484f 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -231,6 +231,34 @@
 }
 
 
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  // backtrace is a glibc extension.
+  int frames_size = frames.length();
+  ScopedVector<void*> addresses(frames_size);
+
+  int frames_count = backtrace(addresses.start(), frames_size);
+
+  char** symbols = backtrace_symbols(addresses.start(), frames_count);
+  if (symbols == NULL) {
+    return kStackWalkError;
+  }
+
+  for (int i = 0; i < frames_count; i++) {
+    frames[i].address = addresses[i];
+    // Format a text representation of the frame based on the information
+    // available.
+    SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen),
+             "%s",
+             symbols[i]);
+    // Make sure line termination is in place.
+    frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
+  }
+
+  free(symbols);
+
+  return frames_count;
+}
+
 
 // Constants used for mmap.
 static const int kMmapFd = -1;
diff --git a/src/platform-posix.h b/src/platform-posix.h
index e0fbc0c..6b73387 100644
--- a/src/platform-posix.h
+++ b/src/platform-posix.h
@@ -39,6 +39,7 @@
 namespace internal {
 
 // Used by platform implementation files during OS::DumpBacktrace()
+// and OS::StackWalk().
 template<int (*backtrace)(void**, int),
          char** (*backtrace_symbols)(void* const*, int)>
 struct POSIXBacktraceHelper {
@@ -72,6 +73,32 @@
     fflush(stderr);
     free(symbols);
   }
+
+  static int StackWalk(Vector<OS::StackFrame> frames) {
+    int frames_size = frames.length();
+    ScopedVector<void*> addresses(frames_size);
+
+    int frames_count = backtrace(addresses.start(), frames_size);
+
+    char** symbols = backtrace_symbols(addresses.start(), frames_count);
+    if (symbols == NULL) {
+      return OS::kStackWalkError;
+    }
+
+    for (int i = 0; i < frames_count; i++) {
+      frames[i].address = addresses[i];
+      // Format a text representation of the frame based on the information
+      // available.
+      OS::SNPrintF(MutableCStrVector(frames[i].text, OS::kStackWalkMaxTextLen),
+                   "%s", symbols[i]);
+      // Make sure line termination is in place.
+      frames[i].text[OS::kStackWalkMaxTextLen - 1] = '\0';
+    }
+
+    free(symbols);
+
+    return frames_count;
+  }
 };
 
 } }  // namespace v8::internal
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index df81c3a..f082af1 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -211,6 +211,20 @@
 }
 
 
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  ucontext_t ctx;
+  struct StackWalker walker = { frames, 0 };
+
+  if (getcontext(&ctx) < 0) return kStackWalkError;
+
+  if (!walkcontext(&ctx, StackWalkCallback, &walker)) {
+    return kStackWalkError;
+  }
+
+  return walker.index;
+}
+
+
 // Constants used for mmap.
 static const int kMmapFd = -1;
 static const int kMmapFdOffset = 0;
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 073b21a..ea4f7ea 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1208,9 +1208,133 @@
 }
 
 
+// Walk the stack using the facilities in dbghelp.dll and tlhelp32.dll
+
+// Switch off warning 4748 (/GS can not protect parameters and local variables
+// from local buffer overrun because optimizations are disabled in function) as
+// it is triggered by the use of inline assembler.
+#pragma warning(push)
+#pragma warning(disable : 4748)
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  BOOL ok;
+
+  // Load the required functions from DLL's.
+  if (!LoadDbgHelpAndTlHelp32()) return kStackWalkError;
+
+  // Get the process and thread handles.
+  HANDLE process_handle = GetCurrentProcess();
+  HANDLE thread_handle = GetCurrentThread();
+
+  // Read the symbols.
+  if (!LoadSymbols(Isolate::Current(), process_handle)) return kStackWalkError;
+
+  // Capture current context.
+  CONTEXT context;
+  RtlCaptureContext(&context);
+
+  // Initialize the stack walking
+  STACKFRAME64 stack_frame;
+  memset(&stack_frame, 0, sizeof(stack_frame));
+#ifdef  _WIN64
+  stack_frame.AddrPC.Offset = context.Rip;
+  stack_frame.AddrFrame.Offset = context.Rbp;
+  stack_frame.AddrStack.Offset = context.Rsp;
+#else
+  stack_frame.AddrPC.Offset = context.Eip;
+  stack_frame.AddrFrame.Offset = context.Ebp;
+  stack_frame.AddrStack.Offset = context.Esp;
+#endif
+  stack_frame.AddrPC.Mode = AddrModeFlat;
+  stack_frame.AddrFrame.Mode = AddrModeFlat;
+  stack_frame.AddrStack.Mode = AddrModeFlat;
+  int frames_count = 0;
+
+  // Collect stack frames.
+  int frames_size = frames.length();
+  while (frames_count < frames_size) {
+    ok = _StackWalk64(
+        IMAGE_FILE_MACHINE_I386,    // MachineType
+        process_handle,             // hProcess
+        thread_handle,              // hThread
+        &stack_frame,               // StackFrame
+        &context,                   // ContextRecord
+        NULL,                       // ReadMemoryRoutine
+        _SymFunctionTableAccess64,  // FunctionTableAccessRoutine
+        _SymGetModuleBase64,        // GetModuleBaseRoutine
+        NULL);                      // TranslateAddress
+    if (!ok) break;
+
+    // Store the address.
+    ASSERT((stack_frame.AddrPC.Offset >> 32) == 0);  // 32-bit address.
+    frames[frames_count].address =
+        reinterpret_cast<void*>(stack_frame.AddrPC.Offset);
+
+    // Try to locate a symbol for this frame.
+    DWORD64 symbol_displacement;
+    SmartArrayPointer<IMAGEHLP_SYMBOL64> symbol(
+        NewArray<IMAGEHLP_SYMBOL64>(kStackWalkMaxNameLen));
+    if (symbol.is_empty()) return kStackWalkError;  // Out of memory.
+    memset(*symbol, 0, sizeof(IMAGEHLP_SYMBOL64) + kStackWalkMaxNameLen);
+    (*symbol)->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+    (*symbol)->MaxNameLength = kStackWalkMaxNameLen;
+    ok = _SymGetSymFromAddr64(process_handle,             // hProcess
+                              stack_frame.AddrPC.Offset,  // Address
+                              &symbol_displacement,       // Displacement
+                              *symbol);                   // Symbol
+    if (ok) {
+      // Try to locate more source information for the symbol.
+      IMAGEHLP_LINE64 Line;
+      memset(&Line, 0, sizeof(Line));
+      Line.SizeOfStruct = sizeof(Line);
+      DWORD line_displacement;
+      ok = _SymGetLineFromAddr64(
+          process_handle,             // hProcess
+          stack_frame.AddrPC.Offset,  // dwAddr
+          &line_displacement,         // pdwDisplacement
+          &Line);                     // Line
+      // Format a text representation of the frame based on the information
+      // available.
+      if (ok) {
+        SNPrintF(MutableCStrVector(frames[frames_count].text,
+                                   kStackWalkMaxTextLen),
+                 "%s %s:%d:%d",
+                 (*symbol)->Name, Line.FileName, Line.LineNumber,
+                 line_displacement);
+      } else {
+        SNPrintF(MutableCStrVector(frames[frames_count].text,
+                                   kStackWalkMaxTextLen),
+                 "%s",
+                 (*symbol)->Name);
+      }
+      // Make sure line termination is in place.
+      frames[frames_count].text[kStackWalkMaxTextLen - 1] = '\0';
+    } else {
+      // No text representation of this frame
+      frames[frames_count].text[0] = '\0';
+
+      // Continue if we are just missing a module (for non C/C++ frames a
+      // module will never be found).
+      int err = GetLastError();
+      if (err != ERROR_MOD_NOT_FOUND) {
+        break;
+      }
+    }
+
+    frames_count++;
+  }
+
+  // Return the number of frames filled in.
+  return frames_count;
+}
+
+
+// Restore warnings to previous settings.
+#pragma warning(pop)
+
 #else  // __MINGW32__
 void OS::LogSharedLibraryAddresses(Isolate* isolate) { }
 void OS::SignalCodeMovingGC() { }
+int OS::StackWalk(Vector<OS::StackFrame> frames) { return 0; }
 #endif  // __MINGW32__
 
 
diff --git a/src/platform.h b/src/platform.h
index e0e62fa..ee8fb92 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -67,8 +67,6 @@
 
 int strncasecmp(const char* s1, const char* s2, int n);
 
-// Visual C++ 2013 and higher implement this function.
-#if (_MSC_VER < 1800)
 inline int lrint(double flt) {
   int intgr;
 #if V8_TARGET_ARCH_IA32
@@ -86,8 +84,6 @@
   return intgr;
 }
 
-#endif  // _MSC_VER < 1800
-
 #endif  // V8_CC_MSVC
 
 namespace v8 {
@@ -268,6 +264,8 @@
     char text[kStackWalkMaxTextLen];
   };
 
+  static int StackWalk(Vector<StackFrame> frames);
+
   class MemoryMappedFile {
    public:
     static MemoryMappedFile* open(const char* name);
diff --git a/src/preparser.cc b/src/preparser.cc
index 2486632..36a94a3 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -42,10 +42,10 @@
 #include "unicode.h"
 #include "utils.h"
 
-#if V8_CC_MSVC && (_MSC_VER < 1800)
+#ifdef _MSC_VER
 namespace std {
 
-// Usually defined in math.h, but not in MSVC until VS2013+.
+// Usually defined in math.h, but not in MSVC.
 // Abstracted to work
 int isfinite(double value);
 
diff --git a/src/runtime.cc b/src/runtime.cc
index 7c240e2..c09fb1d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -499,10 +499,7 @@
     // Update the functions literal and return the boilerplate.
     literals->set(literals_index, *boilerplate);
   }
-
-  Handle<Object> copy = JSObject::DeepCopy(Handle<JSObject>::cast(boilerplate));
-  RETURN_IF_EMPTY_HANDLE(isolate, copy);
-  return *copy;
+  return JSObject::cast(*boilerplate)->DeepCopy(isolate);
 }
 
 
@@ -567,10 +564,8 @@
       literals_index, elements);
   RETURN_IF_EMPTY_HANDLE(isolate, site);
 
-  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
-  Handle<JSObject> copy = JSObject::DeepCopy(boilerplate);
-  RETURN_IF_EMPTY_HANDLE(isolate, copy);
-  return *copy;
+  JSObject* boilerplate = JSObject::cast(site->transition_info());
+  return boilerplate->DeepCopy(isolate);
 }
 
 
@@ -2169,7 +2164,7 @@
     // Declare the property by setting it to the initial value if provided,
     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
     // constant declarations).
-    ASSERT(!JSReceiver::HasLocalProperty(object, name));
+    ASSERT(!object->HasLocalProperty(*name));
     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
     if (*initial_value != NULL) value = initial_value;
     // Declaring a const context slot is a conflicting declaration if
@@ -2201,7 +2196,7 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
-  HandleScope scope(isolate);
+  SealHandleScope shs(isolate);
   // args[0] == name
   // args[1] == language_mode
   // args[2] == value (optional)
@@ -2212,6 +2207,7 @@
   bool assign = args.length() == 3;
 
   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+  GlobalObject* global = isolate->context()->global_object();
   RUNTIME_ASSERT(args[1]->IsSmi());
   CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
   StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
@@ -2228,33 +2224,28 @@
   // to assign to the property.
   // Note that objects can have hidden prototypes, so we need to traverse
   // the whole chain of hidden prototypes to do a 'local' lookup.
+  Object* object = global;
   LookupResult lookup(isolate);
-  isolate->context()->global_object()->LocalLookup(*name, &lookup, true);
+  JSObject::cast(object)->LocalLookup(*name, &lookup, true);
   if (lookup.IsInterceptor()) {
+    HandleScope handle_scope(isolate);
     PropertyAttributes intercepted =
         lookup.holder()->GetPropertyAttribute(*name);
     if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
       // Found an interceptor that's not read only.
       if (assign) {
-        CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-        Handle<Object> result = JSObject::SetPropertyForResult(
-            handle(lookup.holder()), &lookup, name, value, attributes,
-            strict_mode_flag);
-        RETURN_IF_EMPTY_HANDLE(isolate, result);
-        return *result;
+        return lookup.holder()->SetProperty(
+            &lookup, *name, args[2], attributes, strict_mode_flag);
       } else {
         return isolate->heap()->undefined_value();
       }
     }
   }
 
+  // Reload global in case the loop above performed a GC.
+  global = isolate->context()->global_object();
   if (assign) {
-    CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-    Handle<GlobalObject> global(isolate->context()->global_object());
-    Handle<Object> result = JSReceiver::SetProperty(
-        global, name, value, attributes, strict_mode_flag);
-    RETURN_IF_EMPTY_HANDLE(isolate, result);
-    return *result;
+    return global->SetProperty(*name, args[2], attributes, strict_mode_flag);
   }
   return isolate->heap()->undefined_value();
 }
@@ -4787,7 +4778,7 @@
   // Check if the given key is an array index.
   uint32_t index;
   if (key->ToArrayIndex(&index)) {
-    return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index));
+    return isolate->heap()->ToBoolean(object->HasElement(index));
   }
 
   // Convert the key to a name - possibly by calling back into JavaScript.
@@ -4802,7 +4793,7 @@
     name = Handle<Name>::cast(converted);
   }
 
-  return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name));
+  return isolate->heap()->ToBoolean(object->HasProperty(*name));
 }
 
 MaybeObject* Runtime::GetObjectPropertyOrFail(
@@ -5137,14 +5128,11 @@
 
   if (object->IsJSProxy()) {
     bool has_pending_exception = false;
-    Handle<Object> name_object = key->IsSymbol()
+    Handle<Object> name = key->IsSymbol()
         ? key : Execution::ToString(isolate, key, &has_pending_exception);
     if (has_pending_exception) return Failure::Exception();
-    Handle<Name> name = Handle<Name>::cast(name_object);
-    Handle<Object> result = JSReceiver::SetProperty(
-        Handle<JSProxy>::cast(object), name, value, attr, strict_mode);
-    RETURN_IF_EMPTY_HANDLE(isolate, result);
-    return *result;
+    return JSProxy::cast(*object)->SetProperty(
+        Name::cast(*name), *value, attr, strict_mode);
   }
 
   // If the object isn't a JavaScript object, we ignore the store.
@@ -5184,6 +5172,7 @@
   }
 
   if (key->IsName()) {
+    MaybeObject* result;
     Handle<Name> name = Handle<Name>::cast(key);
     if (name->AsArrayIndex(&index)) {
       if (js_object->HasExternalArrayElements()) {
@@ -5195,15 +5184,13 @@
           value = number;
         }
       }
-      MaybeObject* result = js_object->SetElement(
+      result = js_object->SetElement(
           index, *value, attr, strict_mode, true, set_mode);
-      if (result->IsFailure()) return result;
     } else {
       if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
-      Handle<Object> result =
-          JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
-      RETURN_IF_EMPTY_HANDLE(isolate, result);
+      result = js_object->SetProperty(*name, *value, attr, strict_mode);
     }
+    if (result->IsFailure()) return result;
     return *value;
   }
 
@@ -5218,10 +5205,7 @@
     return js_object->SetElement(
         index, *value, attr, strict_mode, true, set_mode);
   } else {
-    Handle<Object> result =
-        JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
-    RETURN_IF_EMPTY_HANDLE(isolate, result);
-    return *result;
+    return js_object->SetProperty(*name, *value, attr, strict_mode);
   }
 }
 
@@ -5520,9 +5504,7 @@
 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate,
                                                    Handle<JSObject> object,
                                                    Handle<Name> key) {
-  if (JSReceiver::HasLocalProperty(object, key)) {
-    return isolate->heap()->true_value();
-  }
+  if (object->HasLocalProperty(*key)) return isolate->heap()->true_value();
   // Handle hidden prototypes.  If there's a hidden prototype above this thing
   // then we have to check it for properties, because they are supposed to
   // look like they are on this object.
@@ -5582,12 +5564,12 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
-  HandleScope scope(isolate);
+  SealHandleScope shs(isolate);
   ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
+  CONVERT_ARG_CHECKED(Name, key, 1);
 
-  bool result = JSReceiver::HasProperty(receiver, key);
+  bool result = receiver->HasProperty(key);
   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   if (isolate->has_pending_exception()) return Failure::Exception();
   return isolate->heap()->ToBoolean(result);
@@ -5595,12 +5577,12 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
-  HandleScope scope(isolate);
+  SealHandleScope shs(isolate);
   ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
+  CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
   CONVERT_SMI_ARG_CHECKED(index, 1);
 
-  bool result = JSReceiver::HasElement(receiver, index);
+  bool result = receiver->HasElement(index);
   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   if (isolate->has_pending_exception()) return Failure::Exception();
   return isolate->heap()->ToBoolean(result);
@@ -9211,7 +9193,7 @@
   // property from it.
   if (!holder.is_null()) {
     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
-    ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
+    ASSERT(object->IsJSProxy() || object->HasProperty(*name));
     // GetProperty below can cause GC.
     Handle<Object> receiver_handle(
         object->IsGlobalObject()
@@ -10192,7 +10174,7 @@
         Handle<Object> element_value(elements->get(j), isolate);
         if (!element_value->IsTheHole()) {
           visitor->visit(j, element_value);
-        } else if (JSReceiver::HasElement(receiver, j)) {
+        } else if (receiver->HasElement(j)) {
           // Call GetElement on receiver, not its prototype, or getters won't
           // have the correct receiver.
           element_value = Object::GetElement(isolate, receiver, j);
@@ -10217,7 +10199,7 @@
           Handle<Object> element_value =
               isolate->factory()->NewNumber(double_value);
           visitor->visit(j, element_value);
-        } else if (JSReceiver::HasElement(receiver, j)) {
+        } else if (receiver->HasElement(j)) {
           // Call GetElement on receiver, not its prototype, or getters won't
           // have the correct receiver.
           Handle<Object> element_value =
@@ -11533,7 +11515,7 @@
           !function_context->IsNativeContext()) {
         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
 
-        if (JSReceiver::HasProperty(ext, variable_name)) {
+        if (ext->HasProperty(*variable_name)) {
           // We don't expect this to do anything except replacing
           // property value.
           SetProperty(isolate,
@@ -11621,7 +11603,7 @@
   // be variables introduced by eval.
   if (context->has_extension()) {
     Handle<JSObject> ext(JSObject::cast(context->extension()));
-    if (JSReceiver::HasProperty(ext, variable_name)) {
+    if (ext->HasProperty(*variable_name)) {
       // We don't expect this to do anything except replacing property value.
       SetProperty(isolate,
                   ext,
@@ -12664,8 +12646,7 @@
   // Do not materialize the arguments object for eval or top-level code.
   // Skip if "arguments" is already taken.
   if (!function->shared()->is_function() ||
-      JSReceiver::HasLocalProperty(target,
-                                   isolate->factory()->arguments_string())) {
+      target->HasLocalProperty(isolate->heap()->arguments_string())) {
     return target;
   }
 
@@ -14805,7 +14786,8 @@
 }
 
 
-void Runtime::PerformGC(Object* result, Isolate* isolate) {
+void Runtime::PerformGC(Object* result) {
+  Isolate* isolate = Isolate::Current();
   Failure* failure = Failure::cast(result);
   if (failure->IsRetryAfterGC()) {
     if (isolate->heap()->new_space()->AddFreshPage()) {
diff --git a/src/runtime.h b/src/runtime.h
index 959d13f..60c6677 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -838,7 +838,7 @@
       JSArrayBuffer* phantom_array_buffer);
 
   // Helper functions used stubs.
-  static void PerformGC(Object* result, Isolate* isolate);
+  static void PerformGC(Object* result);
 
   // Used in runtime.cc and hydrogen's VisitArrayLiteral.
   static Handle<Object> CreateArrayLiteralBoilerplate(
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index f136083..7b23d0c 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -520,7 +520,7 @@
                                                Handle<Map> transition,
                                                StrictModeFlag strict_mode) {
   Handle<Code> stub = FindStoreHandler(
-      name, receiver, Code::STORE_IC, Code::TRANSITION, strict_mode);
+      name, receiver, Code::STORE_IC, Code::MAP_TRANSITION, strict_mode);
   if (!stub.is_null()) return stub;
 
   StoreStubCompiler compiler(isolate_, strict_mode);
@@ -702,7 +702,7 @@
     Handle<Map> transition,
     StrictModeFlag strict_mode) {
   Handle<Code> stub = FindStoreHandler(
-      name, receiver, Code::KEYED_STORE_IC, Code::TRANSITION, strict_mode);
+      name, receiver, Code::KEYED_STORE_IC, Code::MAP_TRANSITION, strict_mode);
   if (!stub.is_null()) return stub;
 
   KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
@@ -1395,19 +1395,17 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
-  HandleScope scope(isolate);
   ASSERT(args.length() == 4);
-  Handle<JSObject> recv(JSObject::cast(args[0]));
-  Handle<Name> name(Name::cast(args[1]));
-  Handle<Object> value(args[2], isolate);
+  JSObject* recv = JSObject::cast(args[0]);
+  Name* name = Name::cast(args[1]);
+  Object* value = args[2];
   ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode);
   StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
   ASSERT(recv->HasNamedInterceptor());
   PropertyAttributes attr = NONE;
-  Handle<Object> result = JSObject::SetPropertyWithInterceptor(
-      recv, name, value, attr, strict_mode);
-  RETURN_IF_EMPTY_HANDLE(isolate, result);
-  return *result;
+  MaybeObject* result = recv->SetPropertyWithInterceptor(
+      name, value, attr, strict_mode);
+  return result;
 }
 
 
@@ -1851,7 +1849,7 @@
   TailCallBuiltin(masm(), SlowBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(kind(), Code::TRANSITION, name);
+  return GetCode(kind(), Code::MAP_TRANSITION, name);
 }
 
 
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 16028d8..63cb42b 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -572,7 +572,8 @@
                                        Register receiver,
                                        Register scratch1,
                                        Register scratch2,
-                                       Label* miss_label);
+                                       Label* miss_label,
+                                       bool support_wrappers);
 
   static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
                                             Register receiver,
diff --git a/src/unique.h b/src/unique.h
index 38cc336..7ae704a 100644
--- a/src/unique.h
+++ b/src/unique.h
@@ -64,10 +64,6 @@
     handle_ = handle;
   }
 
-  // TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
-  Unique(Address raw_address, Handle<T> handle)
-    : raw_address_(raw_address), handle_(handle) { }
-
   // Constructor for handling automatic up casting.
   // Ex. Unique<JSFunction> can be passed when Unique<Object> is expected.
   template <class S> Unique(Unique<S> uniq) {
@@ -142,7 +138,7 @@
   }
 
   // Compare this set against another set. O(|this|).
-  bool Equals(UniqueSet<T>* that) const {
+  bool Equals(UniqueSet<T>* that) {
     if (that->size_ != this->size_) return false;
     for (int i = 0; i < this->size_; i++) {
       if (this->array_[i] != that->array_[i]) return false;
@@ -150,17 +146,8 @@
     return true;
   }
 
-  template <typename U>
-  bool Contains(Unique<U> elem) const {
-    // TODO(titzer): use binary search for larger sets.
-    for (int i = 0; i < size_; i++) {
-      if (this->array_[i] == elem) return true;
-    }
-    return false;
-  }
-
   // Check if this set is a subset of the given set. O(|this| + |that|).
-  bool IsSubset(UniqueSet<T>* that) const {
+  bool IsSubset(UniqueSet<T>* that) {
     if (that->size_ < this->size_) return false;
     int j = 0;
     for (int i = 0; i < this->size_; i++) {
@@ -176,7 +163,7 @@
 
   // Returns a new set representing the intersection of this set and the other.
   // O(|this| + |that|).
-  UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) const {
+  UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) {
     if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>();
 
     UniqueSet<T>* out = new(zone) UniqueSet<T>();
@@ -203,7 +190,7 @@
 
   // Returns a new set representing the union of this set and the other.
   // O(|this| + |that|).
-  UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) const {
+  UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) {
     if (that->size_ == 0) return this->Copy(zone);
     if (this->size_ == 0) return that->Copy(zone);
 
@@ -235,7 +222,7 @@
   }
 
   // Makes an exact copy of this set. O(|this| + |that|).
-  UniqueSet<T>* Copy(Zone* zone) const {
+  UniqueSet<T>* Copy(Zone* zone) {
     UniqueSet<T>* copy = new(zone) UniqueSet<T>();
     copy->size_ = this->size_;
     copy->capacity_ = this->size_;
@@ -244,15 +231,10 @@
     return copy;
   }
 
-  inline int size() const {
+  inline int size() {
     return size_;
   }
 
-  inline Unique<T> at(int index) const {
-    ASSERT(index >= 0 && index < size_);
-    return array_[index];
-  }
-
  private:
   // These sets should be small, since operations are implemented with simple
   // linear algorithms. Enforce a maximum size.
diff --git a/src/version.cc b/src/version.cc
index 167770a..91df195 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     21
-#define BUILD_NUMBER      17
+#define BUILD_NUMBER      18
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/win32-math.cc b/src/win32-math.cc
index 8f6d077..88fa3a6 100644
--- a/src/win32-math.cc
+++ b/src/win32-math.cc
@@ -29,7 +29,7 @@
 // refer to The Open Group Base Specification for specification of the correct
 // semantics for these functions.
 // (http://www.opengroup.org/onlinepubs/000095399/)
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
+#ifdef _MSC_VER
 
 #include "win32-headers.h"
 #include <limits.h>        // Required for INT_MAX etc.
diff --git a/src/win32-math.h b/src/win32-math.h
index fd9312b..0397c7e 100644
--- a/src/win32-math.h
+++ b/src/win32-math.h
@@ -37,8 +37,6 @@
 #error Wrong environment, expected MSVC.
 #endif  // _MSC_VER
 
-// MSVC 2013+ provides implementations of all standard math functions.
-#if (_MSC_VER < 1800)
 enum {
   FP_NAN,
   FP_INFINITE,
@@ -60,6 +58,4 @@
 
 }  // namespace std
 
-#endif  // _MSC_VER < 1800
-
 #endif  // V8_WIN32_MATH_H_
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index f4cc4a3..f2e37fe 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -504,7 +504,6 @@
   static uint64_t found_by_runtime_probing_only_;
 
   friend class ExternalReference;
-  friend class PlatformFeatureScope;
   DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
 };
 
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 20895f9..81721c2 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -600,8 +600,6 @@
   // the stub returns.
   __ subq(Operand(rsp, 0), Immediate(5));
   __ Pushad();
-  __ movq(arg_reg_2,
-          ExternalReference::isolate_address(masm->isolate()));
   __ movq(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize));
   {  // NOLINT
     FrameScope scope(masm, StackFrame::MANUAL);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index a201624..51e1a53 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -1009,7 +1009,7 @@
   __ movsd(xmm0, FieldOperand(input, HeapNumber::kValueOffset));
   // Convert, convert back, and compare the two doubles' bits.
   __ cvttsd2siq(scratch2, xmm0);
-  __ Cvtlsi2sd(xmm1, scratch2);
+  __ cvtlsi2sd(xmm1, scratch2);
   __ movq(scratch1, xmm0);
   __ movq(scratch2, xmm1);
   __ cmpq(scratch1, scratch2);
@@ -1145,7 +1145,7 @@
     // Then load the bits of the double into rbx.
     __ SmiToInteger32(rax, rax);
     __ subq(rsp, Immediate(kDoubleSize));
-    __ Cvtlsi2sd(xmm1, rax);
+    __ cvtlsi2sd(xmm1, rax);
     __ movsd(Operand(rsp, 0), xmm1);
     __ movq(rbx, xmm1);
     __ movq(rdx, xmm1);
@@ -1477,9 +1477,9 @@
 
 void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) {
   __ SmiToInteger32(kScratchRegister, rdx);
-  __ Cvtlsi2sd(xmm0, kScratchRegister);
+  __ cvtlsi2sd(xmm0, kScratchRegister);
   __ SmiToInteger32(kScratchRegister, rax);
-  __ Cvtlsi2sd(xmm1, kScratchRegister);
+  __ cvtlsi2sd(xmm1, kScratchRegister);
 }
 
 
@@ -1503,12 +1503,12 @@
 
   __ bind(&load_smi_rdx);
   __ SmiToInteger32(kScratchRegister, rdx);
-  __ Cvtlsi2sd(xmm0, kScratchRegister);
+  __ cvtlsi2sd(xmm0, kScratchRegister);
   __ JumpIfNotSmi(rax, &load_nonsmi_rax);
 
   __ bind(&load_smi_rax);
   __ SmiToInteger32(kScratchRegister, rax);
-  __ Cvtlsi2sd(xmm1, kScratchRegister);
+  __ cvtlsi2sd(xmm1, kScratchRegister);
   __ bind(&done);
 }
 
@@ -1541,7 +1541,7 @@
   __ cvttsd2siq(smi_result, xmm0);
   // Check if conversion was successful by converting back and
   // comparing to the original double's bits.
-  __ Cvtlsi2sd(xmm1, smi_result);
+  __ cvtlsi2sd(xmm1, smi_result);
   __ movq(kScratchRegister, xmm1);
   __ cmpq(scratch2, kScratchRegister);
   __ j(not_equal, on_not_smis);
@@ -1560,7 +1560,7 @@
   __ movsd(xmm0, FieldOperand(second, HeapNumber::kValueOffset));
   __ movq(scratch2, xmm0);
   __ cvttsd2siq(smi_result, xmm0);
-  __ Cvtlsi2sd(xmm1, smi_result);
+  __ cvtlsi2sd(xmm1, smi_result);
   __ movq(kScratchRegister, xmm1);
   __ cmpq(scratch2, kScratchRegister);
   __ j(not_equal, on_not_smis);
@@ -1603,7 +1603,7 @@
 
   // Save 1 in double_result - we need this several times later on.
   __ movq(scratch, Immediate(1));
-  __ Cvtlsi2sd(double_result, scratch);
+  __ cvtlsi2sd(double_result, scratch);
 
   if (exponent_type_ == ON_STACK) {
     Label base_is_smi, unpack_exponent;
@@ -1623,7 +1623,7 @@
 
     __ bind(&base_is_smi);
     __ SmiToInteger32(base, base);
-    __ Cvtlsi2sd(double_base, base);
+    __ cvtlsi2sd(double_base, base);
     __ bind(&unpack_exponent);
 
     __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
@@ -1812,7 +1812,7 @@
   // and may not have contained the exponent value in the first place when the
   // input was a smi.  We reset it with exponent value before bailing out.
   __ j(not_equal, &done);
-  __ Cvtlsi2sd(double_exponent, exponent);
+  __ cvtlsi2sd(double_exponent, exponent);
 
   // Returning or bailing out.
   Counters* counters = masm->isolate()->counters();
@@ -1902,7 +1902,8 @@
     receiver = rax;
   }
 
-  StubCompiler::GenerateLoadStringLength(masm, receiver, r8, r9, &miss);
+  StubCompiler::GenerateLoadStringLength(masm, receiver, r8, r9, &miss,
+                                         support_wrapper_);
   __ bind(&miss);
   StubCompiler::TailCallBuiltin(
       masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
@@ -2648,7 +2649,7 @@
   __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
   __ call(r11);
 
-  __ LeaveApiExitFrame(true);
+  __ LeaveApiExitFrame();
 
   // Check the result.
   Label success;
@@ -3618,7 +3619,6 @@
     // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
     // stack is known to be aligned. This function takes one argument which is
     // passed in register.
-    __ movq(arg_reg_2, ExternalReference::isolate_address(masm->isolate()));
     __ movq(arg_reg_1, rax);
     __ movq(kScratchRegister,
             ExternalReference::perform_gc_function(masm->isolate()));
@@ -5376,7 +5376,7 @@
   __ jmp(&left, Label::kNear);
   __ bind(&right_smi);
   __ SmiToInteger32(rcx, rax);  // Can't clobber rax yet.
-  __ Cvtlsi2sd(xmm1, rcx);
+  __ cvtlsi2sd(xmm1, rcx);
 
   __ bind(&left);
   __ JumpIfSmi(rdx, &left_smi, Label::kNear);
@@ -5386,7 +5386,7 @@
   __ jmp(&done);
   __ bind(&left_smi);
   __ SmiToInteger32(rcx, rdx);  // Can't clobber rdx yet.
-  __ Cvtlsi2sd(xmm0, rcx);
+  __ cvtlsi2sd(xmm0, rcx);
 
   __ bind(&done);
   // Compare operands
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index b3f4eaf..24773c2 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -386,7 +386,7 @@
   // rbx: current element (smi-tagged)
   __ JumpIfNotSmi(rbx, &convert_hole);
   __ SmiToInteger32(rbx, rbx);
-  __ Cvtlsi2sd(xmm0, rbx);
+  __ cvtlsi2sd(xmm0, rbx);
   __ movsd(FieldOperand(r14, r9, times_8, FixedDoubleArray::kHeaderSize),
            xmm0);
   __ jmp(&entry);
@@ -723,8 +723,7 @@
 }
 
 
-void Code::PatchPlatformCodeAge(Isolate* isolate,
-                                byte* sequence,
+void Code::PatchPlatformCodeAge(byte* sequence,
                                 Code::Age age,
                                 MarkingParity parity) {
   uint32_t young_length;
@@ -733,7 +732,7 @@
     CopyBytes(sequence, young_sequence, young_length);
     CPU::FlushICache(sequence, young_length);
   } else {
-    Code* stub = GetCodeAgeStub(isolate, age, parity);
+    Code* stub = GetCodeAgeStub(age, parity);
     CodePatcher patcher(sequence, young_length);
     patcher.masm()->call(stub->instruction_start());
     for (int i = 0;
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index a1b019a..9984a46 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -93,7 +93,7 @@
   { 0x39, OPER_REG_OP_ORDER,      "cmp" },
   { 0x3A, BYTE_REG_OPER_OP_ORDER, "cmp" },
   { 0x3B, REG_OPER_OP_ORDER,      "cmp" },
-  { 0x63, REG_OPER_OP_ORDER,      "movsxl" },
+  { 0x63, REG_OPER_OP_ORDER,      "movsxlq" },
   { 0x84, BYTE_REG_OPER_OP_ORDER, "test" },
   { 0x85, REG_OPER_OP_ORDER,      "test" },
   { 0x86, BYTE_REG_OPER_OP_ORDER, "xchg" },
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 3c6187d..9dca6b3 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1947,6 +1947,25 @@
 }
 
 
+void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
+  Representation r = instr->hydrogen()->value()->representation();
+  if (r.IsSmiOrInteger32() || r.IsDouble()) {
+    EmitBranch(instr, no_condition);
+  } else {
+    ASSERT(r.IsTagged());
+    Register reg = ToRegister(instr->value());
+    HType type = instr->hydrogen()->value()->type();
+    if (type.IsTaggedNumber()) {
+      EmitBranch(instr, no_condition);
+    }
+    __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
+    __ CompareRoot(FieldOperand(reg, HeapObject::kMapOffset),
+                   Heap::kHeapNumberMapRootIndex);
+    EmitBranch(instr, equal);
+  }
+}
+
+
 void LCodeGen::DoBranch(LBranch* instr) {
   Representation r = instr->hydrogen()->value()->representation();
   if (r.IsInteger32()) {
@@ -2780,7 +2799,6 @@
   int offset = access.offset();
 
   if (access.IsExternalMemory()) {
-    ASSERT(!access.representation().IsInteger32());
     Register result = ToRegister(instr->result());
     if (instr->object()->IsConstantOperand()) {
       ASSERT(result.is(rax));
@@ -2802,18 +2820,10 @@
 
   Register result = ToRegister(instr->result());
   if (access.IsInobject()) {
-    if (access.representation().IsInteger32()) {
-      __ movl(result, FieldOperand(object, offset));
-    } else {
-      __ movq(result, FieldOperand(object, offset));
-    }
+    __ movq(result, FieldOperand(object, offset));
   } else {
     __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
-    if (access.representation().IsInteger32()) {
-      __ movl(result, FieldOperand(result, offset));
-    } else {
-      __ movq(result, FieldOperand(result, offset));
-    }
+    __ movq(result, FieldOperand(result, offset));
   }
 }
 
@@ -3510,7 +3520,7 @@
     __ bind(&negative_sign);
     // Truncate, then compare and compensate.
     __ cvttsd2si(output_reg, input_reg);
-    __ Cvtlsi2sd(xmm_scratch, output_reg);
+    __ cvtlsi2sd(xmm_scratch, output_reg);
     __ ucomisd(input_reg, xmm_scratch);
     __ j(equal, &done, Label::kNear);
     __ subl(output_reg, Immediate(1));
@@ -3559,7 +3569,7 @@
   __ RecordComment("D2I conversion overflow");
   DeoptimizeIf(equal, instr->environment());
 
-  __ Cvtlsi2sd(xmm_scratch, output_reg);
+  __ cvtlsi2sd(xmm_scratch, output_reg);
   __ ucomisd(input_reg, xmm_scratch);
   __ j(equal, &restore, Label::kNear);
   __ subl(output_reg, Immediate(1));
@@ -3926,7 +3936,6 @@
   int offset = access.offset();
 
   if (access.IsExternalMemory()) {
-    ASSERT(!access.representation().IsInteger32());
     ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     Register value = ToRegister(instr->value());
     if (instr->object()->IsConstantOperand()) {
@@ -4004,24 +4013,15 @@
   if (instr->value()->IsConstantOperand()) {
     LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
     if (operand_value->IsRegister()) {
-      if (access.representation().IsInteger32()) {
-        __ movl(FieldOperand(write_register, offset),
-                ToRegister(operand_value));
-      } else {
-        __ movq(FieldOperand(write_register, offset),
-                ToRegister(operand_value));
-      }
+      __ movq(FieldOperand(write_register, offset),
+              ToRegister(operand_value));
     } else {
       Handle<Object> handle_value = ToHandle(operand_value);
       ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
       __ Move(FieldOperand(write_register, offset), handle_value);
     }
   } else {
-    if (access.representation().IsInteger32()) {
-      __ movl(FieldOperand(write_register, offset), ToRegister(instr->value()));
-    } else {
-      __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
-    }
+    __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
   }
 
   if (instr->hydrogen()->NeedsWriteBarrier()) {
@@ -4449,9 +4449,9 @@
   LOperand* output = instr->result();
   ASSERT(output->IsDoubleRegister());
   if (input->IsRegister()) {
-    __ Cvtlsi2sd(ToDoubleRegister(output), ToRegister(input));
+    __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input));
   } else {
-    __ Cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
+    __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
   }
 }
 
@@ -4623,7 +4623,7 @@
                                 bool deoptimize_on_minus_zero,
                                 LEnvironment* env,
                                 NumberUntagDMode mode) {
-  Label convert, load_smi, done;
+  Label load_smi, done;
 
   if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
     // Smi check.
@@ -4632,17 +4632,25 @@
     // Heap number map check.
     __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
                    Heap::kHeapNumberMapRootIndex);
-
-    // On x64 it is safe to load at heap number offset before evaluating the map
-    // check, since all heap objects are at least two words long.
-    __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
-
-    if (can_convert_undefined_to_nan) {
-      __ j(not_equal, &convert);
-    } else {
+    if (!can_convert_undefined_to_nan) {
       DeoptimizeIf(not_equal, env);
-    }
+    } else {
+      Label heap_number, convert;
+      __ j(equal, &heap_number, Label::kNear);
 
+      // Convert undefined (and hole) to NaN. Compute NaN as 0/0.
+      __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
+      DeoptimizeIf(not_equal, env);
+
+      __ bind(&convert);
+      __ xorps(result_reg, result_reg);
+      __ divsd(result_reg, result_reg);
+      __ jmp(&done, Label::kNear);
+
+      __ bind(&heap_number);
+    }
+    // Heap number to XMM conversion.
+    __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
     if (deoptimize_on_minus_zero) {
       XMMRegister xmm_scratch = xmm0;
       __ xorps(xmm_scratch, xmm_scratch);
@@ -4653,18 +4661,6 @@
       DeoptimizeIf(not_zero, env);
     }
     __ jmp(&done, Label::kNear);
-
-    if (can_convert_undefined_to_nan) {
-      __ bind(&convert);
-
-      // Convert undefined (and hole) to NaN. Compute NaN as 0/0.
-      __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
-      DeoptimizeIf(not_equal, env);
-
-      __ xorps(result_reg, result_reg);
-      __ divsd(result_reg, result_reg);
-      __ jmp(&done, Label::kNear);
-    }
   } else {
     ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
   }
@@ -4672,7 +4668,7 @@
   // Smi to XMM conversion
   __ bind(&load_smi);
   __ SmiToInteger32(kScratchRegister, input_reg);
-  __ Cvtlsi2sd(result_reg, kScratchRegister);
+  __ cvtlsi2sd(result_reg, kScratchRegister);
   __ bind(&done);
 }
 
@@ -4725,16 +4721,12 @@
   LOperand* input = instr->value();
   ASSERT(input->IsRegister());
   ASSERT(input->Equals(instr->result()));
-  Register input_reg = ToRegister(input);
 
-  if (instr->hydrogen()->value()->representation().IsSmi()) {
-    __ SmiToInteger32(input_reg, input_reg);
-  } else {
-    DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
-    __ JumpIfNotSmi(input_reg, deferred->entry());
-    __ SmiToInteger32(input_reg, input_reg);
-    __ bind(deferred->exit());
-  }
+  Register input_reg = ToRegister(input);
+  DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
+  __ JumpIfNotSmi(input_reg, deferred->entry());
+  __ SmiToInteger32(input_reg, input_reg);
+  __ bind(deferred->exit());
 }
 
 
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index fcf2862..d9daaac 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -719,39 +719,46 @@
 
 LInstruction* LChunkBuilder::DoShift(Token::Value op,
                                      HBitwiseBinaryOperation* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
-    ASSERT(instr->left()->representation().Equals(instr->representation()));
-    ASSERT(instr->right()->representation().Equals(instr->representation()));
-    LOperand* left = UseRegisterAtStart(instr->left());
+  if (instr->representation().IsTagged()) {
+    ASSERT(instr->left()->representation().IsTagged());
+    ASSERT(instr->right()->representation().IsTagged());
 
-    HValue* right_value = instr->right();
-    LOperand* right = NULL;
-    int constant_value = 0;
-    if (right_value->IsConstant()) {
-      HConstant* constant = HConstant::cast(right_value);
-      right = chunk_->DefineConstantOperand(constant);
-      constant_value = constant->Integer32Value() & 0x1f;
-    } else {
-      right = UseFixed(right_value, rcx);
-    }
-
-    // Shift operations can only deoptimize if we do a logical shift by 0 and
-    // the result cannot be truncated to int32.
-    bool does_deopt = false;
-    if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
-    }
-
-    LInstruction* result =
-        DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt));
-    return does_deopt ? AssignEnvironment(result) : result;
-  } else {
-    return DoArithmeticT(op, instr);
+    LOperand* left = UseFixed(instr->left(), rdx);
+    LOperand* right = UseFixed(instr->right(), rax);
+    LArithmeticT* result = new(zone()) LArithmeticT(op, left, right);
+    return MarkAsCall(DefineFixed(result, rax), instr);
   }
+
+  ASSERT(instr->representation().IsSmiOrInteger32());
+  ASSERT(instr->left()->representation().Equals(instr->representation()));
+  ASSERT(instr->right()->representation().Equals(instr->representation()));
+  LOperand* left = UseRegisterAtStart(instr->left());
+
+  HValue* right_value = instr->right();
+  LOperand* right = NULL;
+  int constant_value = 0;
+  if (right_value->IsConstant()) {
+    HConstant* constant = HConstant::cast(right_value);
+    right = chunk_->DefineConstantOperand(constant);
+    constant_value = constant->Integer32Value() & 0x1f;
+  } else {
+    right = UseFixed(right_value, rcx);
+  }
+
+  // Shift operations can only deoptimize if we do a logical shift by 0 and
+  // the result cannot be truncated to int32.
+  bool does_deopt = false;
+  if (op == Token::SHR && constant_value == 0) {
+    if (FLAG_opt_safe_uint32_operations) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    } else {
+      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
+    }
+  }
+
+  LInstruction* result =
+      DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt));
+  return does_deopt ? AssignEnvironment(result) : result;
 }
 
 
@@ -760,22 +767,21 @@
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->left()->representation().IsDouble());
   ASSERT(instr->right()->representation().IsDouble());
-  if (op == Token::MOD) {
-    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
-    LOperand* right = UseFixedDouble(instr->BetterRightOperand(), xmm1);
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    return MarkAsCall(DefineSameAsFirst(result), instr);
-  } else {
-    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
-    LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
-    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
-    return DefineSameAsFirst(result);
-  }
+  ASSERT(op != Token::MOD);
+  LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
+  LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
+  LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
+  return DefineSameAsFirst(result);
 }
 
 
 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
-                                           HBinaryOperation* instr) {
+                                           HArithmeticBinaryOperation* instr) {
+  ASSERT(op == Token::ADD ||
+         op == Token::DIV ||
+         op == Token::MOD ||
+         op == Token::MUL ||
+         op == Token::SUB);
   HValue* left = instr->left();
   HValue* right = instr->right();
   ASSERT(left->representation().IsTagged());
@@ -1342,19 +1348,27 @@
   if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
-    ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
 
     LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
     LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
     return DefineSameAsFirst(new(zone()) LBitI(left, right));
   } else {
-    return DoArithmeticT(instr->op(), instr);
+    ASSERT(instr->representation().IsTagged());
+    ASSERT(instr->left()->representation().IsTagged());
+    ASSERT(instr->right()->representation().IsTagged());
+
+    LOperand* left = UseFixed(instr->left(), rdx);
+    LOperand* right = UseFixed(instr->right(), rax);
+    LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right);
+    return MarkAsCall(DefineFixed(result, rax), instr);
   }
 }
 
 
 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
-  if (instr->representation().IsSmiOrInteger32()) {
+  if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::DIV, instr);
+  } else if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
     if (instr->HasPowerOf2Divisor()) {
@@ -1371,9 +1385,8 @@
     LOperand* divisor = UseRegister(instr->right());
     LDivI* result = new(zone()) LDivI(dividend, divisor, temp);
     return AssignEnvironment(DefineFixed(result, rax));
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::DIV, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::DIV, instr);
   }
 }
@@ -1472,10 +1485,17 @@
           ? AssignEnvironment(result)
           : result;
     }
-  } else if (instr->representation().IsDouble()) {
-    return DoArithmeticD(Token::MOD, instr);
-  } else {
+  } else if (instr->representation().IsTagged()) {
     return DoArithmeticT(Token::MOD, instr);
+  } else {
+    ASSERT(instr->representation().IsDouble());
+    // We call a C function for double modulo. It can't trigger a GC. We need to
+    // use fixed result register for the call.
+    // TODO(fschneider): Allow any register as input registers.
+    LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD,
+                                                 UseFixedDouble(left, xmm2),
+                                                 UseFixedDouble(right, xmm1));
+    return MarkAsCall(DefineFixedDouble(mod, xmm1), instr);
   }
 }
 
@@ -1495,6 +1515,7 @@
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::MUL, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::MUL, instr);
   }
 }
@@ -1515,6 +1536,7 @@
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::SUB, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::SUB, instr);
   }
 }
@@ -1546,6 +1568,7 @@
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::ADD, instr);
   } else {
+    ASSERT(instr->representation().IsTagged());
     return DoArithmeticT(Token::ADD, instr);
   }
   return NULL;
@@ -1911,6 +1934,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) {
+  return new(zone()) LIsNumberAndBranch(
+      UseRegisterOrConstantAtStart(instr->value()));
+}
+
+
 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
   LCheckInstanceType* result = new(zone()) LCheckInstanceType(value);
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index e3faa89..b3d08c8 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -114,6 +114,7 @@
   V(IsObjectAndBranch)                          \
   V(IsStringAndBranch)                          \
   V(IsSmiAndBranch)                             \
+  V(IsNumberAndBranch)                          \
   V(IsUndetectableAndBranch)                    \
   V(Label)                                      \
   V(LazyBailout)                                \
@@ -882,6 +883,19 @@
 };
 
 
+class LIsNumberAndBranch V8_FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LIsNumberAndBranch(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch, "is-number-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsNumberAndBranch)
+};
+
+
 class LIsStringAndBranch V8_FINAL : public LControlInstruction<1, 1> {
  public:
   explicit LIsStringAndBranch(LOperand* value, LOperand* temp) {
@@ -2035,7 +2049,7 @@
   LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
-  DECLARE_HYDROGEN_ACCESSOR(Change)
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
 
   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
 };
@@ -2687,7 +2701,7 @@
   LInstruction* DoArithmeticD(Token::Value op,
                               HArithmeticBinaryOperation* instr);
   LInstruction* DoArithmeticT(Token::Value op,
-                              HBinaryOperation* instr);
+                              HArithmeticBinaryOperation* instr);
 
   LPlatformChunk* chunk_;
   CompilationInfo* info_;
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 2fb0f74..69abc54 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -691,16 +691,13 @@
 }
 
 
-void MacroAssembler::CallApiFunctionAndReturn(
-    Address function_address,
-    Address thunk_address,
-    Register thunk_last_arg,
-    int stack_space,
-    Operand return_value_operand,
-    Operand* context_restore_operand) {
+void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
+                                              Address thunk_address,
+                                              Register thunk_last_arg,
+                                              int stack_space,
+                                              int return_value_offset) {
   Label prologue;
   Label promote_scheduled_exception;
-  Label exception_handled;
   Label delete_allocated_handles;
   Label leave_exit_frame;
   Label write_back;
@@ -771,7 +768,7 @@
   }
 
   // Load the value from ReturnValue
-  movq(rax, return_value_operand);
+  movq(rax, Operand(rbp, return_value_offset * kPointerSize));
   bind(&prologue);
 
   // No more valid handles (the result handle was the last one). Restore
@@ -786,7 +783,6 @@
   movq(rsi, scheduled_exception_address);
   Cmp(Operand(rsi, 0), factory->the_hole_value());
   j(not_equal, &promote_scheduled_exception);
-  bind(&exception_handled);
 
 #if ENABLE_EXTRA_CHECKS
   // Check if the function returned a valid JavaScript value.
@@ -823,19 +819,11 @@
   bind(&ok);
 #endif
 
-  bool restore_context = context_restore_operand != NULL;
-  if (restore_context) {
-    movq(rsi, *context_restore_operand);
-  }
-  LeaveApiExitFrame(!restore_context);
+  LeaveApiExitFrame();
   ret(stack_space * kPointerSize);
 
   bind(&promote_scheduled_exception);
-  {
-    FrameScope frame(this, StackFrame::INTERNAL);
-    CallRuntime(Runtime::kPromoteScheduledException, 0);
-  }
-  jmp(&exception_handled);
+  TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
 
   // HandleScope limit has changed. Delete allocated extensions.
   bind(&delete_allocated_handles);
@@ -948,18 +936,6 @@
 }
 
 
-void MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) {
-  xorps(dst, dst);
-  cvtlsi2sd(dst, src);
-}
-
-
-void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) {
-  xorps(dst, dst);
-  cvtlsi2sd(dst, src);
-}
-
-
 void MacroAssembler::Set(Register dst, int64_t x) {
   if (x == 0) {
     xorl(dst, dst);
@@ -2941,7 +2917,7 @@
   // Value is a smi. convert to a double and store.
   // Preserve original value.
   SmiToInteger32(kScratchRegister, maybe_number);
-  Cvtlsi2sd(xmm_scratch, kScratchRegister);
+  cvtlsi2sd(xmm_scratch, kScratchRegister);
   movsd(FieldOperand(elements, index, times_8,
                      FixedDoubleArray::kHeaderSize - elements_offset),
         xmm_scratch);
@@ -3074,7 +3050,7 @@
                                Label* conversion_failed,
                                Label::Distance dst) {
   cvttsd2si(result_reg, input_reg);
-  Cvtlsi2sd(xmm0, result_reg);
+  cvtlsi2sd(xmm0, result_reg);
   ucomisd(xmm0, input_reg);
   j(not_equal, conversion_failed, dst);
   j(parity_even, conversion_failed, dst);  // NaN.
@@ -3111,7 +3087,7 @@
 
   movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
   cvttsd2si(result_reg, xmm0);
-  Cvtlsi2sd(temp, result_reg);
+  cvtlsi2sd(temp, result_reg);
   ucomisd(xmm0, temp);
   RecordComment("Deferred TaggedToI: lost precision");
   j(not_equal, lost_precision, dst);
@@ -3707,25 +3683,23 @@
 
   PushReturnAddressFrom(rcx);
 
-  LeaveExitFrameEpilogue(true);
+  LeaveExitFrameEpilogue();
 }
 
 
-void MacroAssembler::LeaveApiExitFrame(bool restore_context) {
+void MacroAssembler::LeaveApiExitFrame() {
   movq(rsp, rbp);
   pop(rbp);
 
-  LeaveExitFrameEpilogue(restore_context);
+  LeaveExitFrameEpilogue();
 }
 
 
-void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
+void MacroAssembler::LeaveExitFrameEpilogue() {
   // Restore current context from top and clear it in debug mode.
   ExternalReference context_address(Isolate::kContextAddress, isolate());
   Operand context_operand = ExternalOperand(context_address);
-  if (restore_context) {
-    movq(rsi, context_operand);
-  }
+  movq(rsi, context_operand);
 #ifdef DEBUG
   movq(context_operand, Immediate(0));
 #endif
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 9f8dafc..09c8a80 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -302,7 +302,7 @@
 
   // Leave the current exit frame. Expects/provides the return value in
   // register rax (untouched).
-  void LeaveApiExitFrame(bool restore_context);
+  void LeaveApiExitFrame();
 
   // Push and pop the registers that can hold pointers.
   void PushSafepointRegisters() { Pushad(); }
@@ -784,12 +784,6 @@
   void Set(Register dst, int64_t x);
   void Set(const Operand& dst, int64_t x);
 
-  // cvtsi2sd instruction only writes to the low 64-bit of dst register, which
-  // hinders register renaming and makes dependence chains longer. So we use
-  // xorps to clear the dst register before cvtsi2sd to solve this issue.
-  void Cvtlsi2sd(XMMRegister dst, Register src);
-  void Cvtlsi2sd(XMMRegister dst, const Operand& src);
-
   // Move if the registers are not identical.
   void Move(Register target, Register source);
 
@@ -1280,8 +1274,7 @@
                                 Address thunk_address,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                Operand return_value_operand,
-                                Operand* context_restore_operand);
+                                int return_value_offset_from_rbp);
 
   // Before calling a C-function from generated code, align arguments on stack.
   // After aligning the frame, arguments must be stored in rsp[0], rsp[8],
@@ -1437,7 +1430,7 @@
   // accessible via StackSpaceOperand.
   void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
 
-  void LeaveExitFrameEpilogue(bool restore_context);
+  void LeaveExitFrameEpilogue();
 
   // Allocation support helpers.
   // Loads the top of new-space into the result register.
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index af8e55f..95276d5 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -304,28 +304,32 @@
                                             Register receiver,
                                             Register scratch1,
                                             Register scratch2,
-                                            Label* miss) {
+                                            Label* miss,
+                                            bool support_wrappers) {
   Label check_wrapper;
 
   // Check if the object is a string leaving the instance type in the
   // scratch register.
-  GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
+  GenerateStringCheck(masm, receiver, scratch1, miss,
+                      support_wrappers ? &check_wrapper : miss);
 
   // Load length directly from the string.
   __ movq(rax, FieldOperand(receiver, String::kLengthOffset));
   __ ret(0);
 
-  // Check if the object is a JSValue wrapper.
-  __ bind(&check_wrapper);
-  __ cmpl(scratch1, Immediate(JS_VALUE_TYPE));
-  __ j(not_equal, miss);
+  if (support_wrappers) {
+    // Check if the object is a JSValue wrapper.
+    __ bind(&check_wrapper);
+    __ cmpl(scratch1, Immediate(JS_VALUE_TYPE));
+    __ j(not_equal, miss);
 
-  // Check if the wrapped value is a string and load the length
-  // directly if it is.
-  __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
-  GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
-  __ movq(rax, FieldOperand(scratch2, String::kLengthOffset));
-  __ ret(0);
+    // Check if the wrapped value is a string and load the length
+    // directly if it is.
+    __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
+    GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
+    __ movq(rax, FieldOperand(scratch2, String::kLengthOffset));
+    __ ret(0);
+  }
 }
 
 
@@ -443,61 +447,65 @@
 // Generates call to API function.
 static void GenerateFastApiCall(MacroAssembler* masm,
                                 const CallOptimization& optimization,
-                                int argc,
-                                bool restore_context) {
+                                int argc) {
   // ----------- S t a t e -------------
   //  -- rsp[0]              : return address
-  //  -- rsp[8]              : context save
-  //  -- rsp[16]             : object passing the type check
+  //  -- rsp[8]              : object passing the type check
   //                           (last fast api call extra argument,
   //                            set by CheckPrototypes)
-  //  -- rsp[24]             : api function
+  //  -- rsp[16]             : api function
   //                           (first fast api call extra argument)
-  //  -- rsp[32]             : api call data
-  //  -- rsp[40]             : isolate
-  //  -- rsp[48]             : ReturnValue default value
-  //  -- rsp[56]             : ReturnValue
+  //  -- rsp[24]             : api call data
+  //  -- rsp[32]             : isolate
+  //  -- rsp[40]             : ReturnValue default value
+  //  -- rsp[48]             : ReturnValue
   //
-  //  -- rsp[64]             : last argument
+  //  -- rsp[56]             : last argument
   //  -- ...
-  //  -- rsp[(argc + 7) * 8] : first argument
-  //  -- rsp[(argc + 8) * 8] : receiver
+  //  -- rsp[(argc + 6) * 8] : first argument
+  //  -- rsp[(argc + 7) * 8] : receiver
   // -----------------------------------
-  int api_call_argc = argc + kFastApiCallArguments;
-  StackArgumentsAccessor args(rsp, api_call_argc);
-
-  // Save calling context.
-  __ movq(args.GetArgumentOperand(api_call_argc), rsi);
-
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(rdi, function);
   __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
+
+  int api_call_argc = argc + kFastApiCallArguments;
+  StackArgumentsAccessor args(rsp, api_call_argc);
+
   // Pass the additional arguments.
-  __ movq(args.GetArgumentOperand(api_call_argc - 2), rdi);
+  __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
     __ Move(rcx, api_call_info);
     __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
-    __ movq(args.GetArgumentOperand(api_call_argc - 3), rbx);
+    __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
   } else {
-    __ Move(args.GetArgumentOperand(api_call_argc - 3), call_data);
+    __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
   }
   __ movq(kScratchRegister,
           ExternalReference::isolate_address(masm->isolate()));
-  __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
+  __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister);
   __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
+  __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
   __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
-  __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister);
 
   // Prepare arguments.
-  STATIC_ASSERT(kFastApiCallArguments == 7);
+  STATIC_ASSERT(kFastApiCallArguments == 6);
   __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
 
   // Function address is a foreign pointer outside V8's heap.
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
 
+#if defined(__MINGW64__) || defined(_WIN64)
+  Register arguments_arg = rcx;
+  Register callback_arg = rdx;
+#else
+  Register arguments_arg = rdi;
+  Register callback_arg = rsi;
+#endif
+
   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
   const int kApiStackSpace = 4;
@@ -511,29 +519,16 @@
   // v8::Arguments::is_construct_call_.
   __ Set(StackSpaceOperand(3), 0);
 
-#if defined(__MINGW64__) || defined(_WIN64)
-  Register arguments_arg = rcx;
-  Register callback_arg = rdx;
-#else
-  Register arguments_arg = rdi;
-  Register callback_arg = rsi;
-#endif
-
   // v8::InvocationCallback's argument.
   __ lea(arguments_arg, StackSpaceOperand(0));
 
   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
-  Operand context_restore_operand(rbp, 2 * kPointerSize);
-  Operand return_value_operand(
-      rbp, (kFastApiCallArguments + 1) * kPointerSize);
   __ CallApiFunctionAndReturn(function_address,
                               thunk_address,
                               callback_arg,
                               api_call_argc + 1,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+                              kFastApiCallArguments + 1);
 }
 
 
@@ -548,8 +543,6 @@
   ASSERT(!receiver.is(scratch));
 
   const int stack_space = kFastApiCallArguments + argc + 1;
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Copy return value.
   __ movq(scratch, Operand(rsp, 0));
   // Assign stack space for the call arguments.
@@ -557,7 +550,7 @@
   // Move the return address on top of the stack.
   __ movq(Operand(rsp, 0), scratch);
   // Write holder to stack frame.
-  __ movq(Operand(rsp, kHolderIndex * kPointerSize), receiver);
+  __ movq(Operand(rsp, 1 * kPointerSize), receiver);
   // Write receiver to stack frame.
   int index = stack_space;
   __ movq(Operand(rsp, index-- * kPointerSize), receiver);
@@ -568,7 +561,7 @@
     __ movq(Operand(rsp, index-- * kPointerSize), values[i]);
   }
 
-  GenerateFastApiCall(masm, optimization, argc, true);
+  GenerateFastApiCall(masm, optimization, argc);
 }
 
 
@@ -682,7 +675,7 @@
 
     // Invoke function.
     if (can_do_fast_api_call) {
-      GenerateFastApiCall(masm, optimization, arguments_.immediate(), false);
+      GenerateFastApiCall(masm, optimization, arguments_.immediate());
     } else {
       CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
           ? CALL_AS_FUNCTION
@@ -849,7 +842,7 @@
 
     __ JumpIfNotSmi(value_reg, &heap_number);
     __ SmiToInteger32(scratch1, value_reg);
-    __ Cvtlsi2sd(xmm0, scratch1);
+    __ cvtlsi2sd(xmm0, scratch1);
     __ jmp(&do_store);
 
     __ bind(&heap_number);
@@ -1003,7 +996,7 @@
     Label do_store, heap_number;
     __ JumpIfNotSmi(value_reg, &heap_number);
     __ SmiToInteger32(scratch2, value_reg);
-    __ Cvtlsi2sd(xmm0, scratch2);
+    __ cvtlsi2sd(xmm0, scratch2);
     __ jmp(&do_store);
 
     __ bind(&heap_number);
@@ -1098,8 +1091,6 @@
                                        int save_at_depth,
                                        Label* miss,
                                        PrototypeCheckType check) {
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Make sure that the type feedback oracle harvests the receiver map.
   // TODO(svenpanne) Remove this hack when all ICs are reworked.
   __ Move(scratch1, Handle<Map>(object->map()));
@@ -1117,7 +1108,7 @@
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ movq(Operand(rsp, kHolderIndex * kPointerSize), object_reg);
+    __ movq(Operand(rsp, kPCOnStackSize), object_reg);
   }
 
   // Check the maps in the prototype chain.
@@ -1177,7 +1168,7 @@
     }
 
     if (save_at_depth == depth) {
-      __ movq(Operand(rsp, kHolderIndex * kPointerSize), reg);
+      __ movq(Operand(rsp, kPCOnStackSize), reg);
     }
 
     // Go to the next object in the prototype chain.
@@ -1399,8 +1390,7 @@
                               thunk_address,
                               getter_arg,
                               kStackSpace,
-                              Operand(rbp, 6 * kPointerSize),
-                              NULL);
+                              6);
 }
 
 
@@ -2518,7 +2508,7 @@
           StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
   __ movq(StackOperandForReturnAddress(0), rax);
 
-  GenerateFastApiCall(masm(), optimization, argc, false);
+  GenerateFastApiCall(masm(), optimization, argc);
 
   __ bind(&miss);
   __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc
index ce8ab19..2aaac92 100644
--- a/test/cctest/test-accessors.cc
+++ b/test/cctest/test-accessors.cc
@@ -554,7 +554,7 @@
 }
 
 
-THREADED_TEST(AccessorPropertyCrossContext) {
+THREADED_TEST(CrossContextAccess) {
   LocalContext env;
   v8::Isolate* isolate = env->GetIsolate();
   v8::HandleScope scope(isolate);
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1c24017..f4e40cd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -77,20 +77,12 @@
 using ::v8::Value;
 
 
-// TODO(bmeurer): Don't run profiled tests when using the simulator.
-// This is a temporary work-around, until the profiler is fixed.
-#if USE_SIMULATOR
-#define THREADED_PROFILED_TEST(Name)                                 \
-  THREADED_TEST(Name)
-#else
 #define THREADED_PROFILED_TEST(Name)                                 \
   static void Test##Name();                                          \
   TEST(Name##WithProfiler) {                                         \
     RunWithProfiler(&Test##Name);                                    \
   }                                                                  \
   THREADED_TEST(Name)
-#endif
-
 
 void RunWithProfiler(void (*test)()) {
   LocalContext env;
@@ -14649,12 +14641,11 @@
     // Inject the input as a global variable.
     i::Handle<i::String> input_name =
         factory->NewStringFromAscii(i::Vector<const char>("input", 5));
-    i::JSReceiver::SetProperty(
-        i::handle(i::Isolate::Current()->native_context()->global_object()),
-        input_name,
-        input_,
+    i::Isolate::Current()->native_context()->global_object()->SetProperty(
+        *input_name,
+        *input_,
         NONE,
-        i::kNonStrictMode);
+        i::kNonStrictMode)->ToObjectChecked();
 
     MorphThread morph_thread(this);
     morph_thread.Start();
@@ -17705,73 +17696,32 @@
   }
 }
 
-v8::Isolate* gc_callbacks_isolate = NULL;
 int prologue_call_count = 0;
 int epilogue_call_count = 0;
 int prologue_call_count_second = 0;
 int epilogue_call_count_second = 0;
 
-void PrologueCallback(v8::GCType, v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
+void PrologueCallback(v8::GCType, v8::GCCallbackFlags) {
   ++prologue_call_count;
 }
 
 
-void PrologueCallback(v8::Isolate* isolate,
-                      v8::GCType,
-                      v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
-  CHECK_EQ(gc_callbacks_isolate, isolate);
-  ++prologue_call_count;
-}
-
-
-void EpilogueCallback(v8::GCType, v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
+void EpilogueCallback(v8::GCType, v8::GCCallbackFlags) {
   ++epilogue_call_count;
 }
 
 
-void EpilogueCallback(v8::Isolate* isolate,
-                      v8::GCType,
-                      v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
-  CHECK_EQ(gc_callbacks_isolate, isolate);
-  ++epilogue_call_count;
-}
-
-
-void PrologueCallbackSecond(v8::GCType, v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
+void PrologueCallbackSecond(v8::GCType, v8::GCCallbackFlags) {
   ++prologue_call_count_second;
 }
 
 
-void PrologueCallbackSecond(v8::Isolate* isolate,
-                            v8::GCType,
-                            v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
-  CHECK_EQ(gc_callbacks_isolate, isolate);
-  ++prologue_call_count_second;
-}
-
-
-void EpilogueCallbackSecond(v8::GCType, v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
+void EpilogueCallbackSecond(v8::GCType, v8::GCCallbackFlags) {
   ++epilogue_call_count_second;
 }
 
 
-void EpilogueCallbackSecond(v8::Isolate* isolate,
-                            v8::GCType,
-                            v8::GCCallbackFlags flags) {
-  CHECK_EQ(flags, v8::kNoGCCallbackFlags);
-  CHECK_EQ(gc_callbacks_isolate, isolate);
-  ++epilogue_call_count_second;
-}
-
-
-TEST(GCCallbacksOld) {
+TEST(GCCallbacks) {
   LocalContext context;
 
   v8::V8::AddGCPrologueCallback(PrologueCallback);
@@ -17805,41 +17755,6 @@
 }
 
 
-TEST(GCCallbacks) {
-  LocalContext context;
-  v8::Isolate* isolate = context->GetIsolate();
-  gc_callbacks_isolate = isolate;
-  isolate->AddGCPrologueCallback(PrologueCallback);
-  isolate->AddGCEpilogueCallback(EpilogueCallback);
-  CHECK_EQ(0, prologue_call_count);
-  CHECK_EQ(0, epilogue_call_count);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(1, prologue_call_count);
-  CHECK_EQ(1, epilogue_call_count);
-  isolate->AddGCPrologueCallback(PrologueCallbackSecond);
-  isolate->AddGCEpilogueCallback(EpilogueCallbackSecond);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(2, prologue_call_count);
-  CHECK_EQ(2, epilogue_call_count);
-  CHECK_EQ(1, prologue_call_count_second);
-  CHECK_EQ(1, epilogue_call_count_second);
-  isolate->RemoveGCPrologueCallback(PrologueCallback);
-  isolate->RemoveGCEpilogueCallback(EpilogueCallback);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(2, prologue_call_count);
-  CHECK_EQ(2, epilogue_call_count);
-  CHECK_EQ(2, prologue_call_count_second);
-  CHECK_EQ(2, epilogue_call_count_second);
-  isolate->RemoveGCPrologueCallback(PrologueCallbackSecond);
-  isolate->RemoveGCEpilogueCallback(EpilogueCallbackSecond);
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  CHECK_EQ(2, prologue_call_count);
-  CHECK_EQ(2, epilogue_call_count);
-  CHECK_EQ(2, prologue_call_count_second);
-  CHECK_EQ(2, epilogue_call_count_second);
-}
-
-
 THREADED_TEST(AddToJSFunctionResultCache) {
   i::FLAG_stress_compaction = false;
   i::FLAG_allow_natives_syntax = true;
@@ -20669,15 +20584,6 @@
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
   i::Object* elm = i_isolate->native_context()->function_cache()
       ->GetElementNoExceptionThrown(i_isolate, serial_number);
-  CHECK(elm->IsUndefined());
-  // Verify that each Function::New creates a new function instance
-  Local<Object> data2 = v8::Object::New();
-  function_new_expected_env = data2;
-  Local<Function> func2 = Function::New(isolate, FunctionNewCallback, data2);
-  CHECK(!func2->IsNull());
-  CHECK_NE(func, func2);
-  env->Global()->Set(v8_str("func2"), func2);
-  Local<Value> result2 = CompileRun("func2();");
-  CHECK_EQ(v8::Integer::New(17, isolate), result2);
+  CHECK(elm->IsNull());
 }
 
diff --git a/test/cctest/test-flags.cc b/test/cctest/test-flags.cc
index a1d2405..9cb12c4 100644
--- a/test/cctest/test-flags.cc
+++ b/test/cctest/test-flags.cc
@@ -54,18 +54,15 @@
 
 TEST(Flags2) {
   SetFlagsToDefault();
-  int argc = 8;
-  const char* argv[] = { "Test2", "-notesting-bool-flag",
-                         "--notesting-maybe-bool-flag", "notaflag",
+  int argc = 7;
+  const char* argv[] = { "Test2", "-notesting-bool-flag", "notaflag",
                          "--testing_int_flag=77", "-testing_float_flag=.25",
                          "--testing_string_flag", "no way!" };
   CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc,
                                                 const_cast<char **>(argv),
                                                 false));
-  CHECK_EQ(8, argc);
+  CHECK_EQ(7, argc);
   CHECK(!FLAG_testing_bool_flag);
-  CHECK(FLAG_testing_maybe_bool_flag.has_value);
-  CHECK(!FLAG_testing_maybe_bool_flag.value);
   CHECK_EQ(77, FLAG_testing_int_flag);
   CHECK_EQ(.25, FLAG_testing_float_flag);
   CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "no way!"));
@@ -76,13 +73,10 @@
   SetFlagsToDefault();
   const char* str =
       " -notesting-bool-flag notaflag   --testing_int_flag=77 "
-      "-notesting-maybe-bool-flag   "
       "-testing_float_flag=.25  "
       "--testing_string_flag   no_way!  ";
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str)));
   CHECK(!FLAG_testing_bool_flag);
-  CHECK(FLAG_testing_maybe_bool_flag.has_value);
-  CHECK(!FLAG_testing_maybe_bool_flag.value);
   CHECK_EQ(77, FLAG_testing_int_flag);
   CHECK_EQ(.25, FLAG_testing_float_flag);
   CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "no_way!"));
@@ -91,9 +85,9 @@
 
 TEST(Flags3) {
   SetFlagsToDefault();
-  int argc = 9;
+  int argc = 8;
   const char* argv[] =
-      { "Test3", "--testing_bool_flag", "--testing-maybe-bool-flag", "notaflag",
+      { "Test3", "--testing_bool_flag", "notaflag",
         "--testing_int_flag", "-666",
         "--testing_float_flag", "-12E10", "-testing-string-flag=foo-bar" };
   CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc,
@@ -101,8 +95,6 @@
                                                 true));
   CHECK_EQ(2, argc);
   CHECK(FLAG_testing_bool_flag);
-  CHECK(FLAG_testing_maybe_bool_flag.has_value);
-  CHECK(FLAG_testing_maybe_bool_flag.value);
   CHECK_EQ(-666, FLAG_testing_int_flag);
   CHECK_EQ(-12E10, FLAG_testing_float_flag);
   CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "foo-bar"));
@@ -112,14 +104,11 @@
 TEST(Flags3b) {
   SetFlagsToDefault();
   const char* str =
-      "--testing_bool_flag --testing-maybe-bool-flag notaflag "
-      "--testing_int_flag -666 "
+      "--testing_bool_flag notaflag --testing_int_flag -666 "
       "--testing_float_flag -12E10 "
       "-testing-string-flag=foo-bar";
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str)));
   CHECK(FLAG_testing_bool_flag);
-  CHECK(FLAG_testing_maybe_bool_flag.has_value);
-  CHECK(FLAG_testing_maybe_bool_flag.value);
   CHECK_EQ(-666, FLAG_testing_int_flag);
   CHECK_EQ(-12E10, FLAG_testing_float_flag);
   CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "foo-bar"));
@@ -134,7 +123,6 @@
                                                 const_cast<char **>(argv),
                                                 true));
   CHECK_EQ(2, argc);
-  CHECK(!FLAG_testing_maybe_bool_flag.has_value);
 }
 
 
@@ -142,7 +130,6 @@
   SetFlagsToDefault();
   const char* str = "--testing_bool_flag --foo";
   CHECK_EQ(2, FlagList::SetFlagsFromString(str, StrLength(str)));
-  CHECK(!FLAG_testing_maybe_bool_flag.has_value);
 }
 
 
@@ -194,7 +181,7 @@
                                                 true));
   CHECK_EQ(42, FLAG_testing_int_flag);
   CHECK_EQ(2.5, FLAG_testing_float_flag);
-  CHECK_EQ(2, FLAG_js_arguments.argc);
+  CHECK_EQ(2, FLAG_js_arguments.argc());
   CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag"));
   CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7"));
   CHECK_EQ(1, argc);
@@ -207,7 +194,7 @@
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str)));
   CHECK_EQ(42, FLAG_testing_int_flag);
   CHECK_EQ(2.5, FLAG_testing_float_flag);
-  CHECK_EQ(2, FLAG_js_arguments.argc);
+  CHECK_EQ(2, FLAG_js_arguments.argc());
   CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag"));
   CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7"));
 }
@@ -219,7 +206,7 @@
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str)));
   CHECK_EQ(42, FLAG_testing_int_flag);
   CHECK_EQ(2.5, FLAG_testing_float_flag);
-  CHECK_EQ(2, FLAG_js_arguments.argc);
+  CHECK_EQ(2, FLAG_js_arguments.argc());
   CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag"));
   CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7"));
 }
@@ -231,7 +218,7 @@
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str)));
   CHECK_EQ(42, FLAG_testing_int_flag);
   CHECK_EQ(2.5, FLAG_testing_float_flag);
-  CHECK_EQ(2, FLAG_js_arguments.argc);
+  CHECK_EQ(2, FLAG_js_arguments.argc());
   CHECK_EQ(0, strcmp(FLAG_js_arguments[0], "testing-float-flag"));
   CHECK_EQ(0, strcmp(FLAG_js_arguments[1], "7"));
 }
@@ -242,7 +229,7 @@
   const char* str = "--testing-int-flag 42 --";
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, StrLength(str)));
   CHECK_EQ(42, FLAG_testing_int_flag);
-  CHECK_EQ(0, FLAG_js_arguments.argc);
+  CHECK_EQ(0, FLAG_js_arguments.argc());
 }
 
 
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index e3ce37d..9d74011 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -209,9 +209,10 @@
   CHECK(s->IsString());
   CHECK_EQ(10, s->length());
 
-  Handle<String> object_string = Handle<String>::cast(factory->Object_string());
-  Handle<GlobalObject> global(Isolate::Current()->context()->global_object());
-  CHECK(JSReceiver::HasLocalProperty(global, object_string));
+  String* object_string = String::cast(heap->Object_string());
+  CHECK(
+      Isolate::Current()->context()->global_object()->HasLocalProperty(
+          object_string));
 
   // Check ToString for oddballs
   CheckOddball(isolate, heap->true_value(), "true");
@@ -257,13 +258,10 @@
   // Check GC.
   heap->CollectGarbage(NEW_SPACE);
 
-  Handle<GlobalObject> global(Isolate::Current()->context()->global_object());
   Handle<String> name = factory->InternalizeUtf8String("theFunction");
   Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
   Handle<String> prop_namex = factory->InternalizeUtf8String("theSlotx");
   Handle<String> obj_name = factory->InternalizeUtf8String("theObject");
-  Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
-  Handle<Smi> twenty_four(Smi::FromInt(24), isolate);
 
   {
     HandleScope inner_scope(isolate);
@@ -273,11 +271,14 @@
     Handle<Map> initial_map =
         factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
     function->set_initial_map(*initial_map);
-    JSReceiver::SetProperty(global, name, function, NONE, kNonStrictMode);
+    Isolate::Current()->context()->global_object()->SetProperty(
+        *name, *function, NONE, kNonStrictMode)->ToObjectChecked();
     // Allocate an object.  Unrooted after leaving the scope.
     Handle<JSObject> obj = factory->NewJSObject(function);
-    JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
-    JSReceiver::SetProperty(obj, prop_namex, twenty_four, NONE, kNonStrictMode);
+    obj->SetProperty(
+        *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
+    obj->SetProperty(
+        *prop_namex, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked();
 
     CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
     CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex));
@@ -286,7 +287,8 @@
   heap->CollectGarbage(NEW_SPACE);
 
   // Function should be alive.
-  CHECK(JSReceiver::HasLocalProperty(global, name));
+  CHECK(Isolate::Current()->context()->global_object()->
+        HasLocalProperty(*name));
   // Check function is retained.
   Object* func_value = Isolate::Current()->context()->global_object()->
       GetProperty(*name)->ToObjectChecked();
@@ -297,14 +299,17 @@
     HandleScope inner_scope(isolate);
     // Allocate another object, make it reachable from global.
     Handle<JSObject> obj = factory->NewJSObject(function);
-    JSReceiver::SetProperty(global, obj_name, obj, NONE, kNonStrictMode);
-    JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
+    Isolate::Current()->context()->global_object()->SetProperty(
+        *obj_name, *obj, NONE, kNonStrictMode)->ToObjectChecked();
+    obj->SetProperty(
+        *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
   }
 
   // After gc, it should survive.
   heap->CollectGarbage(NEW_SPACE);
 
-  CHECK(JSReceiver::HasLocalProperty(global, obj_name));
+  CHECK(Isolate::Current()->context()->global_object()->
+        HasLocalProperty(*obj_name));
   CHECK(Isolate::Current()->context()->global_object()->
         GetProperty(*obj_name)->ToObjectChecked()->IsJSObject());
   Object* obj = Isolate::Current()->context()->global_object()->
@@ -623,16 +628,14 @@
       factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   function->set_initial_map(*initial_map);
 
-  Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
-  Handle<Smi> twenty_four(Smi::FromInt(24), isolate);
-
   Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
   Handle<JSObject> obj = factory->NewJSObject(function);
-  JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
+  obj->SetProperty(
+      *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
   CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
   // Check that we can add properties to function objects.
-  JSReceiver::SetProperty(function, prop_name, twenty_four, NONE,
-                          kNonStrictMode);
+  function->SetProperty(
+      *prop_name, Smi::FromInt(24), NONE, kNonStrictMode)->ToObjectChecked();
   CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name));
 }
 
@@ -652,59 +655,63 @@
   Handle<String> first = factory->InternalizeUtf8String("first");
   Handle<String> second = factory->InternalizeUtf8String("second");
 
-  Handle<Smi> one(Smi::FromInt(1), isolate);
-  Handle<Smi> two(Smi::FromInt(2), isolate);
-
   // check for empty
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
+  CHECK(!obj->HasLocalProperty(*first));
 
   // add first
-  JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
+  obj->SetProperty(
+      *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
+  CHECK(obj->HasLocalProperty(*first));
 
   // delete first
   JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION);
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
+  CHECK(!obj->HasLocalProperty(*first));
 
   // add first and then second
-  JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
-  JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode);
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
-  CHECK(JSReceiver::HasLocalProperty(obj, second));
+  obj->SetProperty(
+      *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
+  obj->SetProperty(
+      *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
+  CHECK(obj->HasLocalProperty(*first));
+  CHECK(obj->HasLocalProperty(*second));
 
   // delete first and then second
   JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION);
-  CHECK(JSReceiver::HasLocalProperty(obj, second));
+  CHECK(obj->HasLocalProperty(*second));
   JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION);
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
-  CHECK(!JSReceiver::HasLocalProperty(obj, second));
+  CHECK(!obj->HasLocalProperty(*first));
+  CHECK(!obj->HasLocalProperty(*second));
 
   // add first and then second
-  JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
-  JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode);
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
-  CHECK(JSReceiver::HasLocalProperty(obj, second));
+  obj->SetProperty(
+      *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
+  obj->SetProperty(
+      *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
+  CHECK(obj->HasLocalProperty(*first));
+  CHECK(obj->HasLocalProperty(*second));
 
   // delete second and then first
   JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION);
-  CHECK(JSReceiver::HasLocalProperty(obj, first));
+  CHECK(obj->HasLocalProperty(*first));
   JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION);
-  CHECK(!JSReceiver::HasLocalProperty(obj, first));
-  CHECK(!JSReceiver::HasLocalProperty(obj, second));
+  CHECK(!obj->HasLocalProperty(*first));
+  CHECK(!obj->HasLocalProperty(*second));
 
   // check string and internalized string match
   const char* string1 = "fisk";
   Handle<String> s1 = factory->NewStringFromAscii(CStrVector(string1));
-  JSReceiver::SetProperty(obj, s1, one, NONE, kNonStrictMode);
+  obj->SetProperty(
+      *s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
   Handle<String> s1_string = factory->InternalizeUtf8String(string1);
-  CHECK(JSReceiver::HasLocalProperty(obj, s1_string));
+  CHECK(obj->HasLocalProperty(*s1_string));
 
   // check internalized string and string match
   const char* string2 = "fugl";
   Handle<String> s2_string = factory->InternalizeUtf8String(string2);
-  JSReceiver::SetProperty(obj, s2_string, one, NONE, kNonStrictMode);
+  obj->SetProperty(
+      *s2_string, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
   Handle<String> s2 = factory->NewStringFromAscii(CStrVector(string2));
-  CHECK(JSReceiver::HasLocalProperty(obj, s2));
+  CHECK(obj->HasLocalProperty(*s2));
 }
 
 
@@ -725,8 +732,8 @@
   Handle<JSObject> obj = factory->NewJSObject(function);
 
   // Set a propery
-  Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
-  JSReceiver::SetProperty(obj, prop_name, twenty_three, NONE, kNonStrictMode);
+  obj->SetProperty(
+      *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
   CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
 
   // Check the map has changed
@@ -798,17 +805,16 @@
   Handle<String> first = factory->InternalizeUtf8String("first");
   Handle<String> second = factory->InternalizeUtf8String("second");
 
-  Handle<Smi> one(Smi::FromInt(1), isolate);
-  Handle<Smi> two(Smi::FromInt(2), isolate);
-
-  JSReceiver::SetProperty(obj, first, one, NONE, kNonStrictMode);
-  JSReceiver::SetProperty(obj, second, two, NONE, kNonStrictMode);
+  obj->SetProperty(
+      *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
+  obj->SetProperty(
+      *second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
 
   obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked();
   obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked();
 
   // Make the clone.
-  Handle<JSObject> clone = JSObject::Copy(obj);
+  Handle<JSObject> clone = Copy(obj);
   CHECK(!clone.is_identical_to(obj));
 
   CHECK_EQ(obj->GetElement(isolate, 0), clone->GetElement(isolate, 0));
@@ -818,8 +824,10 @@
   CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second));
 
   // Flip the values.
-  JSReceiver::SetProperty(clone, first, two, NONE, kNonStrictMode);
-  JSReceiver::SetProperty(clone, second, one, NONE, kNonStrictMode);
+  clone->SetProperty(
+      *first, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
+  clone->SetProperty(
+      *second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
 
   clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked();
   clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked();
@@ -3001,10 +3009,9 @@
   // visited later, causing the CallIC to be cleared.
   Handle<String> name = isolate->factory()->InternalizeUtf8String("call");
   Handle<GlobalObject> global(isolate->context()->global_object());
-  Handle<Smi> zero(Smi::FromInt(0), isolate);
   MaybeObject* maybe_call = global->GetProperty(*name);
   JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked());
-  JSReceiver::SetProperty(global, name, zero, NONE, kNonStrictMode);
+  USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode));
   isolate->compilation_cache()->Clear();
   call->shared()->set_ic_age(heap->global_ic_age() + 1);
   Handle<Object> call_code(call->code(), isolate);
@@ -3015,7 +3022,7 @@
 
   // Either heap verification caught the problem already or we go kaboom once
   // the CallIC is executed the next time.
-  JSReceiver::SetProperty(global, name, call_function, NONE, kNonStrictMode);
+  USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode));
   CompileRun("call();");
 }
 
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index c089871..33d9230 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -153,7 +153,6 @@
   Heap* heap = isolate->heap();
 
   v8::HandleScope sc(CcTest::isolate());
-  Handle<GlobalObject> global(isolate->context()->global_object());
 
   // call mark-compact when heap is empty
   heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 1");
@@ -192,8 +191,8 @@
       Map::cast(heap->AllocateMap(JS_OBJECT_TYPE,
                                   JSObject::kHeaderSize)->ToObjectChecked());
   function->set_initial_map(initial_map);
-  JSReceiver::SetProperty(
-      global, handle(func_name), handle(function), NONE, kNonStrictMode);
+  isolate->context()->global_object()->SetProperty(
+      func_name, function, NONE, kNonStrictMode)->ToObjectChecked();
 
   JSObject* obj = JSObject::cast(
       heap->AllocateJSObject(function)->ToObjectChecked());
@@ -201,7 +200,7 @@
 
   func_name = String::cast(
       heap->InternalizeUtf8String("theFunction")->ToObjectChecked());
-  CHECK(JSReceiver::HasLocalProperty(global, handle(func_name)));
+  CHECK(isolate->context()->global_object()->HasLocalProperty(func_name));
   Object* func_value = isolate->context()->global_object()->
       GetProperty(func_name)->ToObjectChecked();
   CHECK(func_value->IsJSFunction());
@@ -210,19 +209,20 @@
   obj = JSObject::cast(heap->AllocateJSObject(function)->ToObjectChecked());
   String* obj_name =
       String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked());
-  JSReceiver::SetProperty(
-      global, handle(obj_name), handle(obj), NONE, kNonStrictMode);
+  isolate->context()->global_object()->SetProperty(
+      obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked();
   String* prop_name =
       String::cast(heap->InternalizeUtf8String("theSlot")->ToObjectChecked());
-  Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
-  JSReceiver::SetProperty(
-      handle(obj), handle(prop_name), twenty_three, NONE, kNonStrictMode);
+  obj->SetProperty(prop_name,
+                   Smi::FromInt(23),
+                   NONE,
+                   kNonStrictMode)->ToObjectChecked();
 
   heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 5");
 
   obj_name =
       String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked());
-  CHECK(JSReceiver::HasLocalProperty(global, handle(obj_name)));
+  CHECK(isolate->context()->global_object()->HasLocalProperty(obj_name));
   CHECK(isolate->context()->global_object()->
         GetProperty(obj_name)->ToObjectChecked()->IsJSObject());
   obj = JSObject::cast(isolate->context()->global_object()->
@@ -267,6 +267,39 @@
 }
 #endif
 
+static int gc_starts = 0;
+static int gc_ends = 0;
+
+static void GCPrologueCallbackFunc() {
+  CHECK(gc_starts == gc_ends);
+  gc_starts++;
+}
+
+
+static void GCEpilogueCallbackFunc() {
+  CHECK(gc_starts == gc_ends + 1);
+  gc_ends++;
+}
+
+
+TEST(GCCallback) {
+  i::FLAG_stress_compaction = false;
+  CcTest::InitializeVM();
+
+  HEAP->SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc);
+  HEAP->SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc);
+
+  // Scavenge does not call GC callback functions.
+  HEAP->PerformScavenge();
+
+  CHECK_EQ(0, gc_starts);
+  CHECK_EQ(gc_ends, gc_starts);
+
+  HEAP->CollectGarbage(OLD_POINTER_SPACE);
+  CHECK_EQ(1, gc_starts);
+  CHECK_EQ(gc_ends, gc_starts);
+}
+
 
 static int NumberOfWeakCalls = 0;
 static void WeakPointerCallback(v8::Isolate* isolate,
diff --git a/test/cctest/test-unique.cc b/test/cctest/test-unique.cc
index d482a33..1d26858 100644
--- a/test/cctest/test-unique.cc
+++ b/test/cctest/test-unique.cc
@@ -146,74 +146,6 @@
 }
 
 
-TEST(UniqueSet_Contains) {
-  CcTest::InitializeVM();
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-  HandleScope sc(isolate);
-
-  Unique<String> A(factory->InternalizeUtf8String("A"));
-  Unique<String> B(factory->InternalizeUtf8String("B"));
-  Unique<String> C(factory->InternalizeUtf8String("C"));
-
-  Zone zone(isolate);
-
-  UniqueSet<String>* set = new(&zone) UniqueSet<String>();
-
-  CHECK_EQ(0, set->size());
-  set->Add(A, &zone);
-  CHECK(set->Contains(A));
-  CHECK(!set->Contains(B));
-  CHECK(!set->Contains(C));
-
-  set->Add(A, &zone);
-  CHECK(set->Contains(A));
-  CHECK(!set->Contains(B));
-  CHECK(!set->Contains(C));
-
-  set->Add(B, &zone);
-  CHECK(set->Contains(A));
-  CHECK(set->Contains(B));
-
-  set->Add(C, &zone);
-  CHECK(set->Contains(A));
-  CHECK(set->Contains(B));
-  CHECK(set->Contains(C));
-}
-
-
-TEST(UniqueSet_At) {
-  CcTest::InitializeVM();
-  Isolate* isolate = Isolate::Current();
-  Factory* factory = isolate->factory();
-  HandleScope sc(isolate);
-
-  Unique<String> A(factory->InternalizeUtf8String("A"));
-  Unique<String> B(factory->InternalizeUtf8String("B"));
-  Unique<String> C(factory->InternalizeUtf8String("C"));
-
-  Zone zone(isolate);
-
-  UniqueSet<String>* set = new(&zone) UniqueSet<String>();
-
-  CHECK_EQ(0, set->size());
-  set->Add(A, &zone);
-  CHECK(A == set->at(0));
-
-  set->Add(A, &zone);
-  CHECK(A == set->at(0));
-
-  set->Add(B, &zone);
-  CHECK(A == set->at(0) || B == set->at(0));
-  CHECK(A == set->at(1) || B == set->at(1));
-
-  set->Add(C, &zone);
-  CHECK(A == set->at(0) || B == set->at(0) || C == set->at(0));
-  CHECK(A == set->at(1) || B == set->at(1) || C == set->at(1));
-  CHECK(A == set->at(2) || B == set->at(2) || C == set->at(2));
-}
-
-
 template <class T>
 static void CHECK_SETS(
     UniqueSet<T>* set1, UniqueSet<T>* set2, bool expected) {
diff --git a/test/mjsunit/compiler/load-elimination.js b/test/mjsunit/compiler/load-elimination.js
deleted file mode 100644
index e019508..0000000
--- a/test/mjsunit/compiler/load-elimination.js
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --load-elimination
-
-// Test local load elimination of redundant loads and stores.
-
-function B(x, y) {
-  this.x = x;
-  this.y = y;
-  return this;
-}
-
-function test_load() {
-  var a = new B(1, 2);
-  return a.x + a.x + a.x + a.x;
-}
-
-function test_store_load() {
-  var a = new B(1, 2);
-  a.x = 4;
-  var f = a.x;
-  a.x = 5;
-  var g = a.x;
-  a.x = 6;
-  var h = a.x;
-  a.x = 7;
-  return f + g + h + a.x;
-}
-
-function test_nonaliasing_store1() {
-  var a = new B(2, 3), b = new B(3, 4);
-  b.x = 4;
-  var f = a.x;
-  b.x = 5;
-  var g = a.x;
-  b.x = 6;
-  var h = a.x;
-  b.x = 7;
-  return f + g + h + a.x;
-}
-
-function killall() {
-  try { } catch(e) { }
-}
-
-%NeverOptimizeFunction(killall);
-
-function test_store_load_kill() {
-  var a = new B(1, 2);
-  a.x = 4;
-  var f = a.x;
-  a.x = 5;
-  var g = a.x;
-  killall();
-  a.x = 6;
-  var h = a.x;
-  a.x = 7;
-  return f + g + h + a.x;
-}
-
-function test_store_store() {
-  var a = new B(6, 7);
-  a.x = 7;
-  a.x = 7;
-  a.x = 7;
-  a.x = 7;
-  return a.x;
-}
-
-function test(x, f) {
-  assertEquals(x, f());
-  assertEquals(x, f());
-  %OptimizeFunctionOnNextCall(f);
-  assertEquals(x, f());
-}
-
-test(4, test_load);
-test(22, test_store_load);
-test(8, test_nonaliasing_store1);
-test(22, test_store_load_kill);
-test(7, test_store_store);
diff --git a/test/mjsunit/compiler/rotate.js b/test/mjsunit/compiler/rotate.js
index 2f4bc5a..14fe9da 100644
--- a/test/mjsunit/compiler/rotate.js
+++ b/test/mjsunit/compiler/rotate.js
@@ -222,89 +222,3 @@
   assertEquals(1 << ((i % 32)), ROR4(1, i));
 }
 
-//---------------------------------------------------------
-// add test cases for constant operand
-//---------------------------------------------------------
-// constant operand: 20
-function ROR1_sa20(x) {
-  return (x >>> 20) | (x << 12);
-}
-
-function ROR2_sa20(x) {
-  return (x >>> 12) | (x << 20);
-}
-
-function ROR3_sa20(x, sa) {
-  return (x << 12) | (x >>> 20);
-}
-
-function ROR4_sa20(x) {
-  return (x << 20) | (x >>> 12);
-}
-
-// constant operand: 40
-function ROR1_sa40(x) {
-  return (x >>> 40) | (x << -8);
-}
-
-function ROR2_sa40(x) {
-  return (x >>> -8) | (x << 40);
-}
-
-function ROR3_sa40(x, sa) {
-  return (x << -8) | (x >>> 40);
-}
-
-function ROR4_sa40(x) {
-  return (x << 40) | (x >>> -8);
-}
-
-// ROR1_sa20
-assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF));
-assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF));
-%OptimizeFunctionOnNextCall(ROR1_sa20);
-assertEquals(ROR1(0x0000FFFF, 20), ROR1_sa20(0x0000FFFF));
-
-// ROR1_sa40
-assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF));
-assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF));
-%OptimizeFunctionOnNextCall(ROR1_sa40);
-assertEquals(ROR1(0x0000FFFF, 40), ROR1_sa40(0x0000FFFF));
-
-// ROR2_sa20
-assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF));
-assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF));
-%OptimizeFunctionOnNextCall(ROR2_sa20);
-assertEquals(ROR2(0xFFFFFFFF, 20), ROR2_sa20(0xFFFFFFFF));
-
-// ROR2_sa40
-assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF));
-assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF));
-%OptimizeFunctionOnNextCall(ROR2_sa40);
-assertEquals(ROR2(0x0000FFFF, 40), ROR2_sa40(0x0000FFFF));
-
-// ROR3_sa20
-assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF));
-assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF));
-%OptimizeFunctionOnNextCall(ROR3_sa20);
-assertEquals(ROR3(0x0000FFFF, 20), ROR3_sa20(0x0000FFFF));
-
-// ROR3_sa40
-assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF));
-assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF));
-%OptimizeFunctionOnNextCall(ROR3_sa40);
-assertEquals(ROR3(0x0000FFFF, 40), ROR3_sa40(0x0000FFFF));
-
-// ROR4_sa20
-assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF));
-assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF));
-%OptimizeFunctionOnNextCall(ROR4_sa20);
-assertEquals(ROR4(0x0000FFFF, 20), ROR4_sa20(0x0000FFFF));
-
-// ROR4_sa40
-assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF));
-assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF));
-%OptimizeFunctionOnNextCall(ROR4_sa40);
-assertEquals(ROR4(0xFFFFFFFF, 40), ROR4_sa40(0xFFFFFFFF));
-
-
diff --git a/test/mjsunit/debug-stepin-function-call.js b/test/mjsunit/debug-stepin-function-call.js
index eaeebce..3b5240c 100644
--- a/test/mjsunit/debug-stepin-function-call.js
+++ b/test/mjsunit/debug-stepin-function-call.js
@@ -142,19 +142,8 @@
   bound();
 }
 
-// Test step into apply of bound function.
-function applyAndBind1() {
-  var bound = g.bind(null, 3);
-  debugger;
-  bound.apply(null, [3]);
-  var aLocalVar = 'test';
-  var anotherLocalVar  = g(aLocalVar) + 's';
-  var yetAnotherLocal = 10;
-}
-
 var testFunctions =
-    [call1, call2, call3, call4, apply1, apply2, apply3, apply4, bind1,
-    applyAndBind1];
+    [call1, call2, call3, call4, apply1, apply2, apply3, apply4, bind1];
 
 for (var i = 0; i < testFunctions.length; i++) {
   state = 0;
@@ -172,4 +161,4 @@
 assertEquals(3, state);
 
 // Get rid of the debug event listener.
-Debug.setListener(null);
+Debug.setListener(null);
\ No newline at end of file
diff --git a/test/mjsunit/harmony/object-observe.js b/test/mjsunit/harmony/object-observe.js
index f982a66..75f0ff8 100644
--- a/test/mjsunit/harmony/object-observe.js
+++ b/test/mjsunit/harmony/object-observe.js
@@ -110,16 +110,14 @@
 
 
 // Object.observe
-assertThrows(function() { Object.observe("non-object", observer.callback); },
-             TypeError);
+assertThrows(function() { Object.observe("non-object", observer.callback); }, TypeError);
 assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError);
 assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError);
-assertEquals(obj, Object.observe(obj, observer.callback, [1]));
-assertEquals(obj, Object.observe(obj, observer.callback, [true]));
-assertEquals(obj, Object.observe(obj, observer.callback, ['foo', null]));
-assertEquals(obj, Object.observe(obj, observer.callback, [undefined]));
-assertEquals(obj, Object.observe(obj, observer.callback,
-             ['foo', 'bar', 'baz']));
+assertThrows(function() { Object.observe(obj, function() {}, 1); }, TypeError);
+assertThrows(function() { Object.observe(obj, function() {}, [undefined]); }, TypeError);
+assertThrows(function() { Object.observe(obj, function() {}, [1]); }, TypeError);
+assertThrows(function() { Object.observe(obj, function() {}, ['foo', null]); }, TypeError);
+assertEquals(obj, Object.observe(obj, observer.callback, ['foo', 'bar', 'baz']));
 assertEquals(obj, Object.observe(obj, observer.callback, []));
 assertEquals(obj, Object.observe(obj, observer.callback, undefined));
 assertEquals(obj, Object.observe(obj, observer.callback));
@@ -204,25 +202,6 @@
   { object: obj, name: 'bar', type: 'deleted', expando2: 'str' }
 ]);
 
-// Non-string accept values are coerced to strings
-reset();
-Object.observe(obj, observer.callback, [true, 1, null, undefined]);
-notifier = Object.getNotifier(obj);
-notifier.notify({ type: 'true' });
-notifier.notify({ type: 'false' });
-notifier.notify({ type: '1' });
-notifier.notify({ type: '-1' });
-notifier.notify({ type: 'null' });
-notifier.notify({ type: 'nill' });
-notifier.notify({ type: 'undefined' });
-notifier.notify({ type: 'defined' });
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: obj, type: 'true' },
-  { object: obj, type: '1' },
-  { object: obj, type: 'null' },
-  { object: obj, type: 'undefined' }
-]);
 
 // No delivery takes place if no records are pending
 reset();
@@ -328,7 +307,7 @@
 
 // Accept
 reset();
-Object.observe(obj, observer.callback, ['somethingElse']);
+Object.observe(obj, observer.callback, []);
 Object.getNotifier(obj).notify({
   type: 'new'
 });
@@ -1254,75 +1233,6 @@
   { object: array, name: '0', type: 'updated', oldValue: 2 },
 ]);
 
-// Splice emitted after Array mutation methods
-function MockArray(initial, observer) {
-  for (var i = 0; i < initial.length; i++)
-    this[i] = initial[i];
-
-  this.length_ = initial.length;
-  this.observer = observer;
-}
-MockArray.prototype = {
-  set length(length) {
-    Object.getNotifier(this).notify({ type: 'lengthChange' });
-    this.length_ = length;
-    Object.observe(this, this.observer.callback, ['splice']);
-  },
-  get length() {
-    return this.length_;
-  }
-}
-
-reset();
-var array = new MockArray([], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.push.call(array, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 },
-]);
-
-reset();
-var array = new MockArray([1], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.pop.call(array);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
-]);
-
-reset();
-var array = new MockArray([1], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.shift.call(array);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
-]);
-
-reset();
-var array = new MockArray([], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.unshift.call(array, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 },
-]);
-
-reset();
-var array = new MockArray([0, 1, 2], observer);
-Object.observe(array, observer.callback, ['lengthChange']);
-Array.prototype.splice.call(array, 1, 1);
-Object.deliverChangeRecords(observer.callback);
-observer.assertCallbackRecords([
-  { object: array, type: 'lengthChange' },
-  { object: array, type: 'splice', index: 1, removed: [1], addedCount: 0 },
-]);
-
 //
 // === PLAIN OBJECTS ===
 //
diff --git a/test/mjsunit/lithium/DivI.js b/test/mjsunit/lithium/DivI.js
deleted file mode 100644
index 5420d8c..0000000
--- a/test/mjsunit/lithium/DivI.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --no-use-osr
-
-function foo(a, b) {
-  var result = a / 35;
-  result += 50 / b;
-  result += a / b;
-  result += a / -1;
-  result += a / 1;
-  result += a / 4;
-  result += a / -4;
-  return result / b;
-}
-
-foo(700, 5);
-var r1 = foo(700, 5);
-%OptimizeFunctionOnNextCall(foo);
-var r2 = foo(700, 5);
-
-assertEquals(r1, r2);
-
-function boo(value) {
-  return value / -1;
-}
-
-// Test deoptimization of MinInt / -1.
-assertEquals(2147483600, boo(-2147483600));
-assertEquals(2147483600, boo(-2147483600));
-%OptimizeFunctionOnNextCall(boo);
-assertEquals(2147483600, boo(-2147483600));
-assertEquals(2147483648, boo(-2147483648));
diff --git a/test/mjsunit/lithium/SeqStringSetChar.js b/test/mjsunit/lithium/SeqStringSetChar.js
deleted file mode 100644
index 3c890a8..0000000
--- a/test/mjsunit/lithium/SeqStringSetChar.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax
-
-function MyStringFromCharCode(code, i) {
-  var one_byte = %NewString(3, true);
-  %_OneByteSeqStringSetChar(one_byte, 0, code);
-  %_OneByteSeqStringSetChar(one_byte, 1, code);
-  %_OneByteSeqStringSetChar(one_byte, i, code);
-  var two_byte = %NewString(3, false);
-  %_TwoByteSeqStringSetChar(two_byte, 0, code);
-  %_TwoByteSeqStringSetChar(two_byte, 1, code);
-  %_TwoByteSeqStringSetChar(two_byte, i, code);
-  return one_byte + two_byte;
-}
-
-MyStringFromCharCode(65, 2);
-var r1 = MyStringFromCharCode(65, 2);
-%OptimizeFunctionOnNextCall(MyStringFromCharCode);
-var r2 = MyStringFromCharCode(65, 2);
-assertEquals(r1, r2);
diff --git a/test/mjsunit/lithium/StoreKeyed.js b/test/mjsunit/lithium/StoreKeyed.js
deleted file mode 100644
index d34f390..0000000
--- a/test/mjsunit/lithium/StoreKeyed.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --no-use-osr
-
-function foo(a, i, v) {
-  a[0] = v;
-  a[i] = v;
-}
-
-function foo_int(a, i, v) {
-  a[0] = v;
-  a[i] = v;
-}
-
-var A1 = [1.2, 2.3];
-var A2 = [1.2, 2.3];
-var A3 = [1.2, 2.3];
-
-var A1_int = [12, 23];
-var A2_int = [12, 23];
-var A3_int = [12, 23];
-
-foo(A1, 1, 3.4);
-foo(A2, 1, 3.4);
-%OptimizeFunctionOnNextCall(foo);
-foo(A3, 1, 3.4);
-
-foo_int(A1_int, 1, 34);
-foo_int(A2_int, 1, 34);
-%OptimizeFunctionOnNextCall(foo_int);
-foo_int(A3_int, 1, 34);
-
-assertEquals(A1[0], A3[0]);
-assertEquals(A1[1], A3[1]);
-assertEquals(A1_int[0], A3_int[0]);
-assertEquals(A1_int[1], A3_int[1]);
diff --git a/test/mjsunit/lithium/StoreKeyedExternal.js b/test/mjsunit/lithium/StoreKeyedExternal.js
deleted file mode 100644
index a5670fe..0000000
--- a/test/mjsunit/lithium/StoreKeyedExternal.js
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --no-use-osr
-
-function foo_pixel(a, i, v) {
-  a[0] = v;
-  a[i] = v;
-}
-
-function foo_uint16(a, i, v) {
-  a[0] = v;
-  a[i] = v;
-}
-
-function foo_uint32(a, i, v) {
-  a[0] = v;
-  a[i] = v;
-}
-
-function foo_float(a, i, v) {
-  a[0] = v;
-  a[i] = v;
-}
-
-function foo_double(a, i, v) {
-  a[0] = v;
-  a[i] = v;
-}
-
-var A1_pixel = new Uint8ClampedArray(2);
-var A2_pixel = new Uint8ClampedArray(2);
-var A3_pixel = new Uint8ClampedArray(2);
-
-var A1_uint16 = new Uint16Array(2);
-var A2_uint16 = new Uint16Array(2);
-var A3_uint16 = new Uint16Array(2);
-
-var A1_uint32 = new Uint32Array(2);
-var A2_uint32 = new Uint32Array(2);
-var A3_uint32 = new Uint32Array(2);
-
-var A1_float = new Float32Array(2);
-var A2_float = new Float32Array(2);
-var A3_float = new Float32Array(2);
-
-var A1_double = new Float64Array(2);
-var A2_double = new Float64Array(2);
-var A3_double = new Float64Array(2);
-
-foo_pixel(A1_pixel, 1, 34);
-foo_pixel(A2_pixel, 1, 34);
-%OptimizeFunctionOnNextCall(foo_pixel);
-foo_pixel(A3_pixel, 1, 34);
-
-foo_uint16(A1_uint16, 1, 3.4);
-foo_uint16(A2_uint16, 1, 3.4);
-%OptimizeFunctionOnNextCall(foo_uint16);
-foo_uint16(A3_uint16, 1, 3.4);
-
-foo_uint32(A1_uint32, 1, 3.4);
-foo_uint32(A2_uint32, 1, 3.4);
-%OptimizeFunctionOnNextCall(foo_uint32);
-foo_uint32(A3_uint32, 1, 3.4);
-
-foo_float(A1_float, 1, 3.4);
-foo_float(A2_float, 1, 3.4);
-%OptimizeFunctionOnNextCall(foo_float);
-foo_float(A3_float, 1, 3.4);
-
-foo_double(A1_double, 1, 3.4);
-foo_double(A2_double, 1, 3.4);
-%OptimizeFunctionOnNextCall(foo_double);
-foo_double(A3_double, 1, 3.4);
-
-assertEquals(A1_pixel[0], A3_pixel[0]);
-assertEquals(A1_pixel[1], A3_pixel[1]);
-assertEquals(A1_uint16[0], A3_uint16[0]);
-assertEquals(A1_uint16[1], A3_uint16[1]);
-assertEquals(A1_uint32[0], A3_uint32[0]);
-assertEquals(A1_uint32[1], A3_uint32[1]);
-assertEquals(A1_float[0], A3_float[0]);
-assertEquals(A1_float[1], A3_float[1]);
-assertEquals(A1_double[0], A3_double[0]);
-assertEquals(A1_double[1], A3_double[1]);
diff --git a/tools/android-sync.sh b/tools/android-sync.sh
index 183b111..5d4ef2e 100755
--- a/tools/android-sync.sh
+++ b/tools/android-sync.sh
@@ -100,7 +100,6 @@
 sync_file tools/logreader.js
 sync_file tools/tickprocessor.js
 echo ""
-sync_dir tools/profviz
 sync_dir test/message
 sync_dir test/mjsunit
 sync_dir test/preparser
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index f5d82df..aa01a84 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -353,8 +353,6 @@
         '../../src/hydrogen-infer-representation.h',
         '../../src/hydrogen-infer-types.cc',
         '../../src/hydrogen-infer-types.h',
-        '../../src/hydrogen-load-elimination.cc',
-        '../../src/hydrogen-load-elimination.h',
         '../../src/hydrogen-mark-deoptimize.cc',
         '../../src/hydrogen-mark-deoptimize.h',
         '../../src/hydrogen-minus-zero.cc',
@@ -857,8 +855,8 @@
         }],
         ['v8_enable_i18n_support==1', {
           'dependencies': [
-            '<(icu_gyp_path):icui18n',
-            '<(icu_gyp_path):icuuc',
+            '<(DEPTH)/third_party/icu/icu.gyp:icui18n',
+            '<(DEPTH)/third_party/icu/icu.gyp:icuuc',
           ]
         }, {  # v8_enable_i18n_support==0
           'sources!': [
@@ -868,7 +866,7 @@
         }],
         ['OS=="win" and v8_enable_i18n_support==1', {
           'dependencies': [
-            '<(icu_gyp_path):icudata',
+            '<(DEPTH)/third_party/icu/icu.gyp:icudata',
           ],
         }],
       ],