Version 3.26.3 (based on bleeding_edge revision r20415)

Support typed arrays in IsMoreGeneralElementsKindTransition (Chromium issue 357054).

Remove debugger_auto_break flag.

Store i18n meta data in hidden symbols instead of js accessible properties (Chromium issue 354967).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@20418 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index 9e24fee..34a431d 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -533,7 +533,7 @@
   LOG_API(isolate, "Persistent::New");
   i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
 #ifdef DEBUG
-  (*obj)->Verify();
+  (*obj)->ObjectVerify();
 #endif  // DEBUG
   return result.location();
 }
@@ -542,7 +542,7 @@
 i::Object** V8::CopyPersistent(i::Object** obj) {
   i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
 #ifdef DEBUG
-  (*obj)->Verify();
+  (*obj)->ObjectVerify();
 #endif  // DEBUG
   return result.location();
 }
@@ -3597,8 +3597,7 @@
   // as optimized code does not always handle access checks.
   i::Deoptimizer::DeoptimizeGlobalObject(*obj);
 
-  i::Handle<i::Map> new_map =
-      isolate->factory()->CopyMap(i::Handle<i::Map>(obj->map()));
+  i::Handle<i::Map> new_map = i::Map::Copy(i::Handle<i::Map>(obj->map()));
   new_map->set_is_access_check_needed(true);
   obj->set_map(*new_map);
 }
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index aadfb29..81691a3 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -1648,7 +1648,7 @@
   __ sub(r6, r6, Operand(kPointerSize));
 
   // Enter the exit frame that transitions from JavaScript to C++.
-  FrameAndConstantPoolScope scope(masm, StackFrame::MANUAL);
+  FrameScope scope(masm, StackFrame::MANUAL);
   __ EnterExitFrame(save_doubles_);
 
   // Set up argc and the builtin function in callee-saved registers.
@@ -5377,7 +5377,7 @@
   // it's not controlled by GC.
   const int kApiStackSpace = 4;
 
-  FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
+  FrameScope frame_scope(masm, StackFrame::MANUAL);
   __ EnterExitFrame(false, kApiStackSpace);
 
   ASSERT(!api_function_address.is(r0) && !scratch.is(r0));
@@ -5437,7 +5437,7 @@
   __ add(r1, r0, Operand(1 * kPointerSize));  // r1 = PCA
 
   const int kApiStackSpace = 1;
-  FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
+  FrameScope frame_scope(masm, StackFrame::MANUAL);
   __ EnterExitFrame(false, kApiStackSpace);
 
   // Create PropertyAccessorInfo instance on the stack above the exit frame with
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index ba44b50..38acd48 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -931,18 +931,20 @@
   if (goto_instr != NULL) return goto_instr;
 
   HValue* value = instr->value();
-  LBranch* result = new(zone()) LBranch(UseRegister(value));
-  // Tagged values that are not known smis or booleans require a
-  // deoptimization environment. If the instruction is generic no
-  // environment is needed since all cases are handled.
-  Representation rep = value->representation();
+  Representation r = value->representation();
   HType type = value->type();
   ToBooleanStub::Types expected = instr->expected_input_types();
-  if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() &&
-      !expected.IsGeneric()) {
-    return AssignEnvironment(result);
+  if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
+
+  bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
+      type.IsJSArray() || type.IsHeapNumber() || type.IsString();
+  LInstruction* branch = new(zone()) LBranch(UseRegister(value));
+  if (!easy_case &&
+      ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
+       !expected.IsGeneric())) {
+    branch = AssignEnvironment(branch);
   }
-  return result;
+  return branch;
 }
 
 
@@ -1138,8 +1140,11 @@
       ? NULL
       : UseFixed(instr->context(), cp);
   LOperand* input = UseRegister(instr->value());
-  LMathAbs* result = new(zone()) LMathAbs(context, input);
-  return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+  LInstruction* result =
+      DefineAsRegister(new(zone()) LMathAbs(context, input));
+  if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
+  if (!r.IsDouble()) result = AssignEnvironment(result);
+  return result;
 }
 
 
@@ -1284,15 +1289,25 @@
 }
 
 
-LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
   ASSERT(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());
   LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
-  LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
-  return AssignEnvironment(DefineAsRegister(div));
+  LInstruction* result =
+      DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      (instr->CheckFlag(HValue::kCanOverflow) &&
+       (!CpuFeatures::IsSupported(SUDIV) ||
+        !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) ||
+      (!instr->IsMathFloorOfDiv() &&
+       !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1346,13 +1361,25 @@
 }
 
 
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+  ASSERT(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());
+  LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
+  LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp);
+  return AssignEnvironment(DefineAsRegister(div));
+}
+
+
 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
   if (instr->RightIsPowerOf2()) {
     return DoFlooringDivByPowerOf2I(instr);
   } else if (instr->right()->IsConstant()) {
     return DoFlooringDivByConstI(instr);
   } else {
-    return DoDivI(instr);
+    return DoFlooringDivI(instr);
   }
 }
 
@@ -1837,20 +1864,21 @@
 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
   Representation from = instr->from();
   Representation to = instr->to();
+  HValue* val = instr->value();
   if (from.IsSmi()) {
     if (to.IsTagged()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return DefineSameAsFirst(new(zone()) LDummyUse(value));
     }
     from = Representation::Tagged();
   }
   if (from.IsTagged()) {
     if (to.IsDouble()) {
-      LOperand* value = UseRegister(instr->value());
-      LNumberUntagD* res = new(zone()) LNumberUntagD(value);
-      return AssignEnvironment(DefineAsRegister(res));
+      LOperand* value = UseRegister(val);
+      LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
+      if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+      return result;
     } else if (to.IsSmi()) {
-      HValue* val = instr->value();
       LOperand* value = UseRegister(val);
       if (val->type().IsSmi()) {
         return DefineSameAsFirst(new(zone()) LDummyUse(value));
@@ -1858,66 +1886,62 @@
       return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      LOperand* value = NULL;
-      LInstruction* res = NULL;
-      HValue* val = instr->value();
       if (val->type().IsSmi() || val->representation().IsSmi()) {
-        value = UseRegisterAtStart(val);
-        res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+        LOperand* value = UseRegisterAtStart(val);
+        return DefineAsRegister(new(zone()) LSmiUntag(value, false));
       } else {
-        value = UseRegister(val);
+        LOperand* value = UseRegister(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = FixedTemp(d11);
-        res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
-                                                       temp1,
-                                                       temp2));
-        res = AssignEnvironment(res);
+        LInstruction* result =
+            DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2));
+        if (!val->representation().IsSmi()) {
+          // Note: Only deopts in deferred code.
+          result = AssignEnvironment(result);
+        }
+        return result;
       }
-      return res;
     }
   } else if (from.IsDouble()) {
     if (to.IsTagged()) {
       info()->MarkAsDeferredCalling();
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       LOperand* temp1 = TempRegister();
       LOperand* temp2 = TempRegister();
-
-      // Make sure that the temp and result_temp registers are
-      // different.
       LUnallocated* result_temp = TempRegister();
       LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
-      Define(result, result_temp);
-      return AssignPointerMap(result);
+      return AssignPointerMap(Define(result, result_temp));
     } else if (to.IsSmi()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return AssignEnvironment(
           DefineAsRegister(new(zone()) LDoubleToSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      LOperand* value = UseRegister(instr->value());
-      LDoubleToI* res = new(zone()) LDoubleToI(value);
-      return AssignEnvironment(DefineAsRegister(res));
+      LOperand* value = UseRegister(val);
+      LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
+      if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
+      return result;
     }
   } else if (from.IsInteger32()) {
     info()->MarkAsDeferredCalling();
     if (to.IsTagged()) {
-      HValue* val = instr->value();
-      LOperand* value = UseRegisterAtStart(val);
       if (!instr->CheckFlag(HValue::kCanOverflow)) {
+        LOperand* value = UseRegisterAtStart(val);
         return DefineAsRegister(new(zone()) LSmiTag(value));
       } else if (val->CheckFlag(HInstruction::kUint32)) {
+        LOperand* value = UseRegisterAtStart(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = TempRegister();
         LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
-        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+        return AssignPointerMap(DefineAsRegister(result));
       } else {
+        LOperand* value = UseRegisterAtStart(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = TempRegister();
         LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
-        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+        return AssignPointerMap(DefineAsRegister(result));
       }
     } else if (to.IsSmi()) {
-      HValue* val = instr->value();
       LOperand* value = UseRegister(val);
       LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
       if (instr->CheckFlag(HValue::kCanOverflow)) {
@@ -1926,12 +1950,10 @@
       return result;
     } else {
       ASSERT(to.IsDouble());
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
-        return DefineAsRegister(
-            new(zone()) LUint32ToDouble(UseRegister(instr->value())));
+      if (val->CheckFlag(HInstruction::kUint32)) {
+        return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
       } else {
-        return DefineAsRegister(
-            new(zone()) LInteger32ToDouble(Use(instr->value())));
+        return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
       }
     }
   }
@@ -1973,6 +1995,7 @@
   }
   LCheckMaps* result = new(zone()) LCheckMaps(value);
   if (!instr->CanOmitMapChecks()) {
+    // Note: Only deopts in deferred code.
     AssignEnvironment(result);
     if (instr->has_migration_target()) return AssignPointerMap(result);
   }
@@ -2072,7 +2095,10 @@
   LOperand* context = UseRegisterAtStart(instr->value());
   LInstruction* result =
       DefineAsRegister(new(zone()) LLoadContextSlot(context));
-  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2087,7 +2113,10 @@
     value = UseRegister(instr->value());
   }
   LInstruction* result = new(zone()) LStoreContextSlot(context, value);
-  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2122,7 +2151,7 @@
   ASSERT(instr->key()->representation().IsSmiOrInteger32());
   ElementsKind elements_kind = instr->elements_kind();
   LOperand* key = UseRegisterOrConstantAtStart(instr->key());
-  LLoadKeyed* result = NULL;
+  LInstruction* result = NULL;
 
   if (!instr->is_typed_elements()) {
     LOperand* obj = NULL;
@@ -2132,24 +2161,28 @@
       ASSERT(instr->representation().IsSmiOrTagged());
       obj = UseRegisterAtStart(instr->elements());
     }
-    result = new(zone()) LLoadKeyed(obj, key);
+    result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key));
   } else {
     ASSERT(
         (instr->representation().IsInteger32() &&
-         !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
+         !IsDoubleOrFloatElementsKind(elements_kind)) ||
         (instr->representation().IsDouble() &&
-         IsDoubleOrFloatElementsKind(instr->elements_kind())));
+         IsDoubleOrFloatElementsKind(elements_kind)));
     LOperand* backing_store = UseRegister(instr->elements());
-    result = new(zone()) LLoadKeyed(backing_store, key);
+    result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
   }
 
-  DefineAsRegister(result);
-  // An unsigned int array load might overflow and cause a deopt, make sure it
-  // has an environment.
-  bool can_deoptimize = instr->RequiresHoleCheck() ||
-      elements_kind == EXTERNAL_UINT32_ELEMENTS ||
-      elements_kind == UINT32_ELEMENTS;
-  return can_deoptimize ? AssignEnvironment(result) : result;
+  if ((instr->is_external() || instr->is_fixed_typed_array()) ?
+      // see LCodeGen::DoLoadKeyedExternalArray
+      ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+        elements_kind == UINT32_ELEMENTS) &&
+       !instr->CheckFlag(HInstruction::kUint32)) :
+      // see LCodeGen::DoLoadKeyedFixedDoubleArray and
+      // LCodeGen::DoLoadKeyedFixedArray
+      instr->RequiresHoleCheck()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2280,11 +2313,11 @@
   // We need a temporary register for write barrier of the map field.
   LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
 
-  LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
-  if (instr->field_representation().IsHeapObject()) {
-    if (!instr->value()->type().IsHeapObject()) {
-      return AssignEnvironment(result);
-    }
+  LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
+  if (!instr->access().IsExternalMemory() &&
+      instr->field_representation().IsHeapObject() &&
+      !instr->value()->type().IsHeapObject()) {
+    result = AssignEnvironment(result);
   }
   return result;
 }
@@ -2316,7 +2349,7 @@
   LOperand* context = UseAny(instr->context());
   LStringCharCodeAt* result =
       new(zone()) LStringCharCodeAt(context, string, index);
-  return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+  return AssignPointerMap(DefineAsRegister(result));
 }
 
 
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 34eb510..a09d6f6 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -97,6 +97,7 @@
   V(DummyUse)                                   \
   V(FlooringDivByConstI)                        \
   V(FlooringDivByPowerOf2I)                     \
+  V(FlooringDivI)                               \
   V(ForInCacheArray)                            \
   V(ForInPrepareMap)                            \
   V(FunctionLiteral)                            \
@@ -713,14 +714,14 @@
 
 class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
  public:
-  LDivI(LOperand* left, LOperand* right, LOperand* temp) {
-    inputs_[0] = left;
-    inputs_[1] = right;
+  LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
     temps_[0] = temp;
   }
 
-  LOperand* left() { return inputs_[0]; }
-  LOperand* right() { return inputs_[1]; }
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
@@ -767,6 +768,23 @@
 };
 
 
+class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+  LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
+    temps_[0] = temp;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
 class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
  public:
   LMulI(LOperand* left, LOperand* right) {
@@ -2722,12 +2740,13 @@
   LInstruction* DoMathClz32(HUnaryMathOperation* instr);
   LInstruction* DoDivByPowerOf2I(HDiv* instr);
   LInstruction* DoDivByConstI(HDiv* instr);
-  LInstruction* DoDivI(HBinaryOperation* instr);
+  LInstruction* DoDivI(HDiv* instr);
   LInstruction* DoModByPowerOf2I(HMod* instr);
   LInstruction* DoModByConstI(HMod* instr);
   LInstruction* DoModI(HMod* instr);
   LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
   LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+  LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
 
  private:
   enum Status {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index b02574b..63e60ba 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1293,7 +1293,7 @@
   Register dividend = ToRegister(instr->dividend());
   int32_t divisor = instr->divisor();
   Register result = ToRegister(instr->result());
-  ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+  ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
   ASSERT(!result.is(dividend));
 
   // Check for (0 / -x) that will produce negative zero.
@@ -1363,15 +1363,16 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
 void LCodeGen::DoDivI(LDivI* instr) {
   HBinaryOperation* hdiv = instr->hydrogen();
-  Register left = ToRegister(instr->left());
-  Register right = ToRegister(instr->right());
+  Register dividend = ToRegister(instr->dividend());
+  Register divisor = ToRegister(instr->divisor());
   Register result = ToRegister(instr->result());
 
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
-    __ cmp(right, Operand::Zero());
+    __ cmp(divisor, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
   }
 
@@ -1380,10 +1381,10 @@
     Label positive;
     if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
       // Do the test only if it hadn't be done above.
-      __ cmp(right, Operand::Zero());
+      __ cmp(divisor, Operand::Zero());
     }
     __ b(pl, &positive);
-    __ cmp(left, Operand::Zero());
+    __ cmp(dividend, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
     __ bind(&positive);
   }
@@ -1394,39 +1395,30 @@
        !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
     // We don't need to check for overflow when truncating with sdiv
     // support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
-    __ cmp(left, Operand(kMinInt));
-    __ cmp(right, Operand(-1), eq);
+    __ cmp(dividend, Operand(kMinInt));
+    __ cmp(divisor, Operand(-1), eq);
     DeoptimizeIf(eq, instr->environment());
   }
 
   if (CpuFeatures::IsSupported(SUDIV)) {
     CpuFeatureScope scope(masm(), SUDIV);
-    __ sdiv(result, left, right);
+    __ sdiv(result, dividend, divisor);
   } else {
     DoubleRegister vleft = ToDoubleRegister(instr->temp());
     DoubleRegister vright = double_scratch0();
-    __ vmov(double_scratch0().low(), left);
+    __ vmov(double_scratch0().low(), dividend);
     __ vcvt_f64_s32(vleft, double_scratch0().low());
-    __ vmov(double_scratch0().low(), right);
+    __ vmov(double_scratch0().low(), divisor);
     __ vcvt_f64_s32(vright, double_scratch0().low());
     __ vdiv(vleft, vleft, vright);  // vleft now contains the result.
     __ vcvt_s32_f64(double_scratch0().low(), vleft);
     __ vmov(result, double_scratch0().low());
   }
 
-  if (hdiv->IsMathFloorOfDiv()) {
-    Label done;
-    Register remainder = scratch0();
-    __ mls(remainder, result, right, left);
-    __ cmp(remainder, Operand::Zero());
-    __ b(eq, &done);
-    __ eor(remainder, remainder, Operand(right));
-    __ add(result, result, Operand(remainder, ASR, 31));
-    __ bind(&done);
-  } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+  if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     // Compute remainder and deopt if it's not zero.
     Register remainder = scratch0();
-    __ mls(remainder, result, right, left);
+    __ mls(remainder, result, divisor, dividend);
     __ cmp(remainder, Operand::Zero());
     DeoptimizeIf(ne, instr->environment());
   }
@@ -1538,6 +1530,69 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
+  Register left = ToRegister(instr->dividend());
+  Register right = ToRegister(instr->divisor());
+  Register result = ToRegister(instr->result());
+
+  // Check for x / 0.
+  if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+    __ cmp(right, Operand::Zero());
+    DeoptimizeIf(eq, instr->environment());
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    Label positive;
+    if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
+      // Do the test only if it hadn't be done above.
+      __ cmp(right, Operand::Zero());
+    }
+    __ b(pl, &positive);
+    __ cmp(left, Operand::Zero());
+    DeoptimizeIf(eq, instr->environment());
+    __ bind(&positive);
+  }
+
+  // Check for (kMinInt / -1).
+  if (hdiv->CheckFlag(HValue::kCanOverflow) &&
+      (!CpuFeatures::IsSupported(SUDIV) ||
+       !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+    // We don't need to check for overflow when truncating with sdiv
+    // support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
+    __ cmp(left, Operand(kMinInt));
+    __ cmp(right, Operand(-1), eq);
+    DeoptimizeIf(eq, instr->environment());
+  }
+
+  if (CpuFeatures::IsSupported(SUDIV)) {
+    CpuFeatureScope scope(masm(), SUDIV);
+    __ sdiv(result, left, right);
+  } else {
+    DoubleRegister vleft = ToDoubleRegister(instr->temp());
+    DoubleRegister vright = double_scratch0();
+    __ vmov(double_scratch0().low(), left);
+    __ vcvt_f64_s32(vleft, double_scratch0().low());
+    __ vmov(double_scratch0().low(), right);
+    __ vcvt_f64_s32(vright, double_scratch0().low());
+    __ vdiv(vleft, vleft, vright);  // vleft now contains the result.
+    __ vcvt_s32_f64(double_scratch0().low(), vleft);
+    __ vmov(result, double_scratch0().low());
+  }
+
+  Label done;
+  Register remainder = scratch0();
+  __ mls(remainder, result, right, left);
+  __ cmp(remainder, Operand::Zero());
+  __ b(eq, &done);
+  __ eor(remainder, remainder, Operand(right));
+  __ add(result, result, Operand(remainder, ASR, 31));
+  __ bind(&done);
+}
+
+
 void LCodeGen::DoMulI(LMulI* instr) {
   Register result = ToRegister(instr->result());
   // Note that result may alias left.
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 2bfe09f..076c042 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -989,7 +989,6 @@
   }
   if (FLAG_enable_ool_constant_pool) {
     str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
-    LoadConstantPoolPointerRegister();
   }
   mov(ip, Operand(CodeObject()));
   str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 6b6ecd3..9230df0 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -1524,11 +1524,12 @@
         type_(type),
         old_has_frame_(masm->has_frame()),
         old_constant_pool_available_(masm->is_constant_pool_available())  {
+    // We only want to enable constant pool access for non-manual frame scopes
+    // to ensure the constant pool pointer is valid throughout the scope.
+    ASSERT(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
     masm->set_has_frame(true);
     masm->set_constant_pool_available(true);
-    if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
-      masm->EnterFrame(type, !old_constant_pool_available_);
-    }
+    masm->EnterFrame(type, !old_constant_pool_available_);
   }
 
   ~FrameAndConstantPoolScope() {
diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc
index 4bed135..1888aff 100644
--- a/src/arm64/lithium-arm64.cc
+++ b/src/arm64/lithium-arm64.cc
@@ -1074,63 +1074,61 @@
 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
   Representation from = instr->from();
   Representation to = instr->to();
-
+  HValue* val = instr->value();
   if (from.IsSmi()) {
     if (to.IsTagged()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return DefineSameAsFirst(new(zone()) LDummyUse(value));
     }
     from = Representation::Tagged();
   }
-
   if (from.IsTagged()) {
     if (to.IsDouble()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       LOperand* temp = TempRegister();
-      LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
-      return AssignEnvironment(DefineAsRegister(res));
+      LInstruction* result =
+          DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
+      if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+      return result;
     } else if (to.IsSmi()) {
-      LOperand* value = UseRegister(instr->value());
-      if (instr->value()->type().IsSmi()) {
+      LOperand* value = UseRegister(val);
+      if (val->type().IsSmi()) {
         return DefineSameAsFirst(new(zone()) LDummyUse(value));
       }
       return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      LInstruction* res = NULL;
-
-      if (instr->value()->type().IsSmi() ||
-          instr->value()->representation().IsSmi()) {
-        LOperand* value = UseRegisterAtStart(instr->value());
-        res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+      if (val->type().IsSmi() || val->representation().IsSmi()) {
+        LOperand* value = UseRegisterAtStart(val);
+        return DefineAsRegister(new(zone()) LSmiUntag(value, false));
       } else {
-        LOperand* value = UseRegister(instr->value());
+        LOperand* value = UseRegister(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24);
-        res = DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
-        res = AssignEnvironment(res);
+        LInstruction* result =
+            DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
+        if (!val->representation().IsSmi()) {
+          // Note: Only deopts in deferred code.
+          result = AssignEnvironment(result);
+        }
+        return result;
       }
-
-      return res;
     }
   } else if (from.IsDouble()) {
     if (to.IsTagged()) {
       info()->MarkAsDeferredCalling();
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       LOperand* temp1 = TempRegister();
       LOperand* temp2 = TempRegister();
-
       LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
       return AssignPointerMap(DefineAsRegister(result));
     } else {
       ASSERT(to.IsSmi() || to.IsInteger32());
-      LOperand* value = UseRegister(instr->value());
-
       if (instr->CanTruncateToInt32()) {
-        LTruncateDoubleToIntOrSmi* result =
-            new(zone()) LTruncateDoubleToIntOrSmi(value);
-        return DefineAsRegister(result);
+        LOperand* value = UseRegister(val);
+        return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value));
       } else {
+        LOperand* value = UseRegister(val);
         LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value);
         return AssignEnvironment(DefineAsRegister(result));
       }
@@ -1138,37 +1136,35 @@
   } else if (from.IsInteger32()) {
     info()->MarkAsDeferredCalling();
     if (to.IsTagged()) {
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
-        LOperand* value = UseRegister(instr->value());
-        LNumberTagU* result = new(zone()) LNumberTagU(value,
-                                                      TempRegister(),
-                                                      TempRegister());
-        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+      if (val->CheckFlag(HInstruction::kUint32)) {
+        LOperand* value = UseRegister(val);
+        LNumberTagU* result =
+            new(zone()) LNumberTagU(value, TempRegister(), TempRegister());
+        return AssignPointerMap(DefineAsRegister(result));
       } else {
         STATIC_ASSERT((kMinInt == Smi::kMinValue) &&
                       (kMaxInt == Smi::kMaxValue));
-        LOperand* value = UseRegisterAtStart(instr->value());
+        LOperand* value = UseRegisterAtStart(val);
         return DefineAsRegister(new(zone()) LSmiTag(value));
       }
     } else if (to.IsSmi()) {
-      LOperand* value = UseRegisterAtStart(instr->value());
+      LOperand* value = UseRegisterAtStart(val);
       LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+      if (val->CheckFlag(HInstruction::kUint32)) {
         result = AssignEnvironment(result);
       }
       return result;
     } else {
       ASSERT(to.IsDouble());
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+      if (val->CheckFlag(HInstruction::kUint32)) {
         return DefineAsRegister(
-            new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value())));
+            new(zone()) LUint32ToDouble(UseRegisterAtStart(val)));
       } else {
         return DefineAsRegister(
-            new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value())));
+            new(zone()) LInteger32ToDouble(UseRegisterAtStart(val)));
       }
     }
   }
-
   UNREACHABLE();
   return NULL;
 }
@@ -1189,21 +1185,20 @@
 
 
 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
-  if (instr->CanOmitMapChecks()) {
-    // LCheckMaps does nothing in this case.
-    return new(zone()) LCheckMaps(NULL);
-  } else {
-    LOperand* value = UseRegisterAtStart(instr->value());
-    LOperand* temp = TempRegister();
-
-    if (instr->has_migration_target()) {
-      info()->MarkAsDeferredCalling();
-      LInstruction* result = new(zone()) LCheckMaps(value, temp);
-      return AssignPointerMap(AssignEnvironment(result));
-    } else {
-      return AssignEnvironment(new(zone()) LCheckMaps(value, temp));
-    }
+  LOperand* value = NULL;
+  LOperand* temp = NULL;
+  if (!instr->CanOmitMapChecks()) {
+    value = UseRegisterAtStart(instr->value());
+    temp = TempRegister();
+    if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
   }
+  LInstruction* result = new(zone()) LCheckMaps(value, temp);
+  if (!instr->CanOmitMapChecks()) {
+    // Note: Only deopts in deferred code.
+    result = AssignEnvironment(result);
+    if (instr->has_migration_target()) return AssignPointerMap(result);
+  }
+  return result;
 }
 
 
@@ -1418,8 +1413,12 @@
   LOperand* divisor = UseRegister(instr->right());
   LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
       ? NULL : TempRegister();
-  LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
-  return AssignEnvironment(DefineAsRegister(div));
+  LInstruction* result =
+      DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp));
+  if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1622,7 +1621,10 @@
   LOperand* context = UseRegisterAtStart(instr->value());
   LInstruction* result =
       DefineAsRegister(new(zone()) LLoadContextSlot(context));
-  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1687,17 +1689,14 @@
             IsDoubleOrFloatElementsKind(instr->elements_kind())));
 
     LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister();
-    LLoadKeyedExternal* result =
-        new(zone()) LLoadKeyedExternal(elements, key, temp);
-    // An unsigned int array load might overflow and cause a deopt. Make sure it
-    // has an environment.
-    if (instr->RequiresHoleCheck() ||
-        elements_kind == EXTERNAL_UINT32_ELEMENTS ||
-        elements_kind == UINT32_ELEMENTS) {
-      return AssignEnvironment(DefineAsRegister(result));
-    } else {
-      return DefineAsRegister(result);
+    LInstruction* result = DefineAsRegister(
+        new(zone()) LLoadKeyedExternal(elements, key, temp));
+    if ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+         elements_kind == UINT32_ELEMENTS) &&
+        !instr->CheckFlag(HInstruction::kUint32)) {
+      result = AssignEnvironment(result);
     }
+    return result;
   }
 }
 
@@ -1885,13 +1884,10 @@
 
     bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
     bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
-    bool needs_environment = can_overflow || bailout_on_minus_zero;
 
     HValue* least_const = instr->BetterLeftOperand();
     HValue* most_const = instr->BetterRightOperand();
 
-    LOperand* left;
-
     // LMulConstI can handle a subset of constants:
     //  With support for overflow detection:
     //    -1, 0, 1, 2
@@ -1911,26 +1907,27 @@
                               IsPowerOf2(constant_abs - 1))))) {
         LConstantOperand* right = UseConstant(most_const);
         bool need_register = IsPowerOf2(constant_abs) && !small_constant;
-        left = need_register ? UseRegister(least_const)
-                             : UseRegisterAtStart(least_const);
-        LMulConstIS* mul = new(zone()) LMulConstIS(left, right);
-        if (needs_environment) AssignEnvironment(mul);
-        return DefineAsRegister(mul);
+        LOperand* left = need_register ? UseRegister(least_const)
+                                       : UseRegisterAtStart(least_const);
+        LInstruction* result =
+            DefineAsRegister(new(zone()) LMulConstIS(left, right));
+        if ((bailout_on_minus_zero && constant <= 0) || can_overflow) {
+          result = AssignEnvironment(result);
+        }
+        return result;
       }
     }
 
-    left = UseRegisterAtStart(least_const);
     // LMulI/S can handle all cases, but it requires that a register is
     // allocated for the second operand.
-    LInstruction* result;
-    if (instr->representation().IsSmi()) {
-      LOperand* right = UseRegisterAtStart(most_const);
-      result = DefineAsRegister(new(zone()) LMulS(left, right));
-    } else {
-      LOperand* right = UseRegisterAtStart(most_const);
-      result = DefineAsRegister(new(zone()) LMulI(left, right));
+    LOperand* left = UseRegisterAtStart(least_const);
+    LOperand* right = UseRegisterAtStart(most_const);
+    LInstruction* result = instr->representation().IsSmi()
+        ? DefineAsRegister(new(zone()) LMulS(left, right))
+        : DefineAsRegister(new(zone()) LMulI(left, right));
+    if ((bailout_on_minus_zero && least_const != most_const) || can_overflow) {
+      result = AssignEnvironment(result);
     }
-    if (needs_environment) AssignEnvironment(result);
     return result;
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::MUL, instr);
@@ -2160,7 +2157,10 @@
     value = UseRegister(instr->value());
   }
   LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp);
-  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2294,7 +2294,7 @@
   LOperand* context = UseAny(instr->context());
   LStringCharCodeAt* result =
       new(zone()) LStringCharCodeAt(context, string, index);
-  return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+  return AssignPointerMap(DefineAsRegister(result));
 }
 
 
@@ -2430,21 +2430,15 @@
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = TempRegister();
         LOperand* temp3 = TempRegister();
-        LMathAbsTagged* result =
-            new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3);
-        return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+        LInstruction* result = DefineAsRegister(
+            new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3));
+        // Note: Only deopts in deferred code.
+        return AssignEnvironment(AssignPointerMap(result));
       } else {
         LOperand* input = UseRegisterAtStart(instr->value());
-        LMathAbs* result = new(zone()) LMathAbs(input);
-        if (r.IsDouble()) {
-          // The Double case can never fail so it doesn't need an environment.
-          return DefineAsRegister(result);
-        } else {
-          ASSERT(r.IsInteger32() || r.IsSmi());
-          // The Integer32 and Smi cases need an environment because they can
-          // deoptimize on minimum representable number.
-          return AssignEnvironment(DefineAsRegister(result));
-        }
+        LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input));
+        if (!r.IsDouble()) result = AssignEnvironment(result);
+        return result;
       }
     }
     case kMathExp: {
diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h
index fcb1552..0b9d6e4 100644
--- a/src/arm64/lithium-arm64.h
+++ b/src/arm64/lithium-arm64.h
@@ -927,7 +927,7 @@
 
 class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 1> {
  public:
-  explicit LCheckMaps(LOperand* value, LOperand* temp = NULL) {
+  explicit LCheckMaps(LOperand* value, LOperand* temp) {
     inputs_[0] = value;
     temps_[0] = temp;
   }
@@ -1324,14 +1324,14 @@
 
 class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
  public:
-  LDivI(LOperand* left, LOperand* right, LOperand* temp) {
-    inputs_[0] = left;
-    inputs_[1] = right;
+  LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
     temps_[0] = temp;
   }
 
-  LOperand* left() { return inputs_[0]; }
-  LOperand* right() { return inputs_[1]; }
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
index bea79ba..9b8156e 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -2636,7 +2636,7 @@
   Register dividend = ToRegister32(instr->dividend());
   int32_t divisor = instr->divisor();
   Register result = ToRegister32(instr->result());
-  ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+  ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
   ASSERT(!result.is(dividend));
 
   // Check for (0 / -x) that will produce negative zero.
@@ -2707,10 +2707,11 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
 void LCodeGen::DoDivI(LDivI* instr) {
   HBinaryOperation* hdiv = instr->hydrogen();
-  Register dividend = ToRegister32(instr->left());
-  Register divisor = ToRegister32(instr->right());
+  Register dividend = ToRegister32(instr->dividend());
+  Register divisor = ToRegister32(instr->divisor());
   Register result = ToRegister32(instr->result());
 
   // Issue the division first, and then check for any deopt cases whilst the
@@ -3936,6 +3937,7 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
   Register dividend = ToRegister32(instr->dividend());
   Register divisor = ToRegister32(instr->divisor());
diff --git a/src/arm64/macro-assembler-arm64-inl.h b/src/arm64/macro-assembler-arm64-inl.h
index 4fd6d76..06bcd11 100644
--- a/src/arm64/macro-assembler-arm64-inl.h
+++ b/src/arm64/macro-assembler-arm64-inl.h
@@ -1513,12 +1513,9 @@
 
 
 void MacroAssembler::Claim(const Register& count, uint64_t unit_size) {
+  if (unit_size == 0) return;
   ASSERT(IsPowerOf2(unit_size));
 
-  if (unit_size == 0) {
-    return;
-  }
-
   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
   const Operand size(count, LSL, shift);
 
@@ -1535,7 +1532,7 @@
 
 
 void MacroAssembler::ClaimBySMI(const Register& count_smi, uint64_t unit_size) {
-  ASSERT(IsPowerOf2(unit_size));
+  ASSERT(unit_size == 0 || IsPowerOf2(unit_size));
   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
   const Operand size(count_smi,
                      (shift >= 0) ? (LSL) : (LSR),
@@ -1574,12 +1571,9 @@
 
 
 void MacroAssembler::Drop(const Register& count, uint64_t unit_size) {
+  if (unit_size == 0) return;
   ASSERT(IsPowerOf2(unit_size));
 
-  if (unit_size == 0) {
-    return;
-  }
-
   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
   const Operand size(count, LSL, shift);
 
@@ -1599,7 +1593,7 @@
 
 
 void MacroAssembler::DropBySMI(const Register& count_smi, uint64_t unit_size) {
-  ASSERT(IsPowerOf2(unit_size));
+  ASSERT(unit_size == 0 || IsPowerOf2(unit_size));
   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
   const Operand size(count_smi,
                      (shift >= 0) ? (LSL) : (LSR),
diff --git a/src/arm64/simulator-arm64.cc b/src/arm64/simulator-arm64.cc
index cd475b4..d8930c9 100644
--- a/src/arm64/simulator-arm64.cc
+++ b/src/arm64/simulator-arm64.cc
@@ -2108,8 +2108,9 @@
   // Rotate source bitfield into place.
   int64_t result = (static_cast<uint64_t>(src) >> R) | (src << (reg_size - R));
   // Determine the sign extension.
-  int64_t topbits = ((1L << (reg_size - diff - 1)) - 1) << (diff + 1);
-  int64_t signbits = extend && ((src >> S) & 1) ? topbits : 0;
+  int64_t topbits_preshift = (1L << (reg_size - diff - 1)) - 1;
+  int64_t signbits = (extend && ((src >> S) & 1) ? topbits_preshift : 0)
+                     << (diff + 1);
 
   // Merge sign extension, dest/zero and bitfield.
   result = signbits | (result & mask) | (dst & ~mask);
diff --git a/src/atomicops_internals_x86_gcc.cc b/src/atomicops_internals_x86_gcc.cc
index 950b423..a119cd2 100644
--- a/src/atomicops_internals_x86_gcc.cc
+++ b/src/atomicops_internals_x86_gcc.cc
@@ -77,10 +77,10 @@
 void AtomicOps_Internalx86CPUFeaturesInit() {
   using v8::internal::AtomicOps_Internalx86CPUFeatures;
 
-  uint32_t eax;
-  uint32_t ebx;
-  uint32_t ecx;
-  uint32_t edx;
+  uint32_t eax = 0;
+  uint32_t ebx = 0;
+  uint32_t ecx = 0;
+  uint32_t edx = 0;
 
   // Get vendor string (issue CPUID with eax = 0)
   cpuid(eax, ebx, ecx, edx, 0);
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index dc0d902..9a42e36 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -328,9 +328,8 @@
 
 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
   // object.__proto__ = proto;
-  Factory* factory = object->GetIsolate()->factory();
   Handle<Map> old_to_map = Handle<Map>(object->map());
-  Handle<Map> new_to_map = factory->CopyMap(old_to_map);
+  Handle<Map> new_to_map = Map::Copy(old_to_map);
   new_to_map->set_prototype(*proto);
   object->set_map(*new_to_map);
 }
@@ -1017,7 +1016,7 @@
     initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
 
     // RegExp prototype object is itself a RegExp.
-    Handle<Map> proto_map = factory->CopyMap(initial_map);
+    Handle<Map> proto_map = Map::Copy(initial_map);
     proto_map->set_prototype(native_context()->initial_object_prototype());
     Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
     proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
@@ -1150,7 +1149,7 @@
 
     Handle<Map> old_map(
         native_context()->sloppy_arguments_boilerplate()->map());
-    Handle<Map> new_map = factory->CopyMap(old_map);
+    Handle<Map> new_map = Map::Copy(old_map);
     new_map->set_pre_allocated_property_fields(2);
     Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
     // Set elements kind after allocating the object because
@@ -1359,15 +1358,15 @@
     // Create maps for generator functions and their prototypes.  Store those
     // maps in the native context.
     Handle<Map> function_map(native_context()->sloppy_function_map());
-    Handle<Map> generator_function_map = factory()->CopyMap(function_map);
+    Handle<Map> generator_function_map = Map::Copy(function_map);
     generator_function_map->set_prototype(*generator_function_prototype);
     native_context()->set_sloppy_generator_function_map(
         *generator_function_map);
 
     Handle<Map> strict_mode_function_map(
         native_context()->strict_function_map());
-    Handle<Map> strict_mode_generator_function_map = factory()->CopyMap(
-        strict_mode_function_map);
+    Handle<Map> strict_mode_generator_function_map =
+        Map::Copy(strict_mode_function_map);
     strict_mode_generator_function_map->set_prototype(
         *generator_function_prototype);
     native_context()->set_strict_generator_function_map(
@@ -1612,7 +1611,7 @@
   array_function->shared()->DontAdaptArguments();
 
   Handle<Map> original_map(array_function->initial_map());
-  Handle<Map> initial_map = factory()->CopyMap(original_map);
+  Handle<Map> initial_map = Map::Copy(original_map);
   initial_map->set_elements_kind(elements_kind);
   array_function->set_initial_map(*initial_map);
 
@@ -2000,7 +1999,7 @@
   }
 
 #ifdef VERIFY_HEAP
-  builtins->Verify();
+  builtins->ObjectVerify();
 #endif
 
   return true;
@@ -2524,7 +2523,7 @@
 
   // Transfer the prototype (new map is needed).
   Handle<Map> old_to_map = Handle<Map>(to->map());
-  Handle<Map> new_to_map = factory()->CopyMap(old_to_map);
+  Handle<Map> new_to_map = Map::Copy(old_to_map);
   new_to_map->set_prototype(from->map()->prototype());
   to->set_map(*new_to_map);
 }
diff --git a/src/elements-kind.cc b/src/elements-kind.cc
index ff458e0..7b1a65a 100644
--- a/src/elements-kind.cc
+++ b/src/elements-kind.cc
@@ -172,8 +172,27 @@
 }
 
 
+static bool IsTypedArrayElementsKind(ElementsKind elements_kind) {
+  return IsFixedTypedArrayElementsKind(elements_kind) ||
+      IsExternalArrayElementsKind(elements_kind);
+}
+
+
 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
                                          ElementsKind to_kind) {
+  if (IsTypedArrayElementsKind(from_kind) ||
+      IsTypedArrayElementsKind(to_kind)) {
+    switch (from_kind) {
+#define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+      case TYPE##_ELEMENTS:                                   \
+        return to_kind == EXTERNAL_##TYPE##_ELEMENTS;
+
+      TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE);
+#undef FIXED_TYPED_ARRAY_CASE
+      default:
+        return false;
+    }
+  }
   switch (from_kind) {
     case FAST_SMI_ELEMENTS:
       return to_kind != FAST_SMI_ELEMENTS;
diff --git a/src/execution.cc b/src/execution.cc
index da07d0f..2e16413 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -519,11 +519,9 @@
 
 
 void StackGuard::DebugCommand() {
-  if (FLAG_debugger_auto_break) {
-    ExecutionAccess access(isolate_);
-    thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
-    set_interrupt_limits(access);
-  }
+  ExecutionAccess access(isolate_);
+  thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
+  set_interrupt_limits(access);
 }
 #endif
 
diff --git a/src/factory.cc b/src/factory.cc
index cd30743..86b72f6 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -845,11 +845,6 @@
 }
 
 
-Handle<Map> Factory::CopyMap(Handle<Map> src) {
-  CALL_HEAP_FUNCTION(isolate(), src->Copy(), Map);
-}
-
-
 Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
   CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedArray);
 }
diff --git a/src/factory.h b/src/factory.h
index da58a71..8b3d2aa 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -261,7 +261,6 @@
   // Copy the map adding more inobject properties if possible without
   // overflowing the instance size.
   Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props);
-  Handle<Map> CopyMap(Handle<Map> map);
 
   Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
 
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 3f0f7ec..f3eaac8 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -471,9 +471,6 @@
             "trace out-of-bounds accesses to all arrays")
 DEFINE_implication(trace_array_abuse, trace_js_array_abuse)
 DEFINE_implication(trace_array_abuse, trace_external_array_abuse)
-DEFINE_bool(debugger_auto_break, true,
-            "automatically set the debug break flag when debugger commands are "
-            "in the queue")
 DEFINE_bool(enable_liveedit, true, "enable liveedit experimental feature")
 DEFINE_bool(hard_abort, true, "abort by crashing")
 
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index afe5b71..1af2784 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -252,8 +252,8 @@
       segment_(segment),
       align_(align),
       flags_(flags) {
-    ASSERT(IsPowerOf2(align));
     if (align_ != 0) {
+      ASSERT(IsPowerOf2(align));
       align_ = WhichPowerOf2(align_);
     }
   }
diff --git a/src/heap.cc b/src/heap.cc
index 6374433..f06b8be 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -4964,8 +4964,6 @@
   switch (string->map()->instance_type()) {
     case STRING_TYPE: return internalized_string_map();
     case ASCII_STRING_TYPE: return ascii_internalized_string_map();
-    case CONS_STRING_TYPE: return cons_internalized_string_map();
-    case CONS_ASCII_STRING_TYPE: return cons_ascii_internalized_string_map();
     case EXTERNAL_STRING_TYPE: return external_internalized_string_map();
     case EXTERNAL_ASCII_STRING_TYPE:
       return external_ascii_internalized_string_map();
diff --git a/src/heap.h b/src/heap.h
index 0f586e9..4b67a95 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -109,8 +109,6 @@
     ShortExternalStringWithOneByteDataMap)                                     \
   V(Map, internalized_string_map, InternalizedStringMap)                       \
   V(Map, ascii_internalized_string_map, AsciiInternalizedStringMap)            \
-  V(Map, cons_internalized_string_map, ConsInternalizedStringMap)              \
-  V(Map, cons_ascii_internalized_string_map, ConsAsciiInternalizedStringMap)   \
   V(Map,                                                                       \
     external_internalized_string_map,                                          \
     ExternalInternalizedStringMap)                                             \
@@ -376,7 +374,9 @@
   V(next_string, "next")                                                 \
   V(byte_length_string, "byteLength")                                    \
   V(byte_offset_string, "byteOffset")                                    \
-  V(buffer_string, "buffer")
+  V(buffer_string, "buffer")                                             \
+  V(intl_initialized_marker_string, "v8::intl_initialized_marker")       \
+  V(intl_impl_object_string, "v8::intl_object")
 
 // Forward declarations.
 class GCTracer;
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 84dcb18..d12d47e 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1561,6 +1561,7 @@
   HUnaryOperation::PrintDataTo(stream);
   stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic());
 
+  if (CanTruncateToSmi()) stream->Add(" truncating-smi");
   if (CanTruncateToInt32()) stream->Add(" truncating-int32");
   if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
   if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan");
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index f920a65..a6a1f86 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1263,6 +1263,7 @@
     position_.set_operand_position(index, pos);
   }
 
+  bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); }
   bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
 
   virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
@@ -1733,7 +1734,7 @@
     set_representation(to);
     SetFlag(kUseGVN);
     SetFlag(kCanOverflow);
-    if (is_truncating_to_smi) {
+    if (is_truncating_to_smi && to.IsSmi()) {
       SetFlag(kTruncatingToSmi);
       SetFlag(kTruncatingToInt32);
     }
@@ -3761,7 +3762,7 @@
   bool RightIsPowerOf2() {
     if (!right()->IsInteger32Constant()) return false;
     int32_t value = right()->GetInteger32Constant();
-    return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
+    return IsPowerOf2(value) || IsPowerOf2(-value);
   }
 
   DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 80eff3b..24c2ab4 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5488,16 +5488,11 @@
     Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
     if (accessor->shared()->IsApiFunction()) {
       CallOptimization call_optimization(accessor);
-      if (!call_optimization.is_simple_api_call()) return false;
-      CallOptimization::HolderLookup holder_lookup;
-      api_holder_ = call_optimization.LookupHolderOfExpectedType(
-          map, &holder_lookup);
-      switch (holder_lookup) {
-        case CallOptimization::kHolderNotFound:
-          return false;
-        case CallOptimization::kHolderIsReceiver:
-        case CallOptimization::kHolderFound:
-          break;
+      if (call_optimization.is_simple_api_call()) {
+        CallOptimization::HolderLookup holder_lookup;
+        Handle<Map> receiver_map = this->map();
+        api_holder_ = call_optimization.LookupHolderOfExpectedType(
+            receiver_map, &holder_lookup);
       }
     }
     accessor_ = accessor;
@@ -7071,6 +7066,11 @@
     return target_shared->inline_builtin() ? 0 : kNotInlinable;
   }
 
+  if (target_shared->IsApiFunction()) {
+    TraceInline(target, caller, "target is api function");
+    return kNotInlinable;
+  }
+
   // Do a quick check on source code length to avoid parsing large
   // inlining candidates.
   if (target_shared->SourceSize() >
diff --git a/src/i18n.js b/src/i18n.js
index 2e54857..edfb065 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -232,8 +232,7 @@
  */
 function addBoundMethod(obj, methodName, implementation, length) {
   function getter() {
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject === undefined) {
+    if (!%IsInitializedIntlObject(this)) {
         throw new $TypeError('Method ' + methodName + ' called on a ' +
                             'non-object or on a wrong type of object.');
     }
@@ -896,7 +895,7 @@
  * Useful for subclassing.
  */
 function initializeCollator(collator, locales, options) {
-  if (collator.hasOwnProperty('__initializedIntlObject')) {
+  if (%IsInitializedIntlObject(collator)) {
     throw new $TypeError('Trying to re-initialize Collator object.');
   }
 
@@ -967,9 +966,7 @@
                                          resolved);
 
   // Writable, configurable and enumerable are set to false by default.
-  $Object.defineProperty(collator, 'collator', {value: internalCollator});
-  $Object.defineProperty(collator, '__initializedIntlObject',
-                         {value: 'collator'});
+  %MarkAsInitializedIntlObjectOfType(collator, 'collator', internalCollator);
   $Object.defineProperty(collator, 'resolved', {value: resolved});
 
   return collator;
@@ -1005,8 +1002,7 @@
       throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
     }
 
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'collator') {
+    if (!%IsInitializedIntlObjectOfType(this, 'collator')) {
       throw new $TypeError('resolvedOptions method called on a non-object ' +
                            'or on a object that is not Intl.Collator.');
     }
@@ -1063,7 +1059,8 @@
  * the sort order, or x comes after y in the sort order, respectively.
  */
 function compare(collator, x, y) {
-  return %InternalCompare(collator.collator, $String(x), $String(y));
+  return %InternalCompare(%GetImplFromInitializedIntlObject(collator),
+                          $String(x), $String(y));
 };
 
 
@@ -1104,7 +1101,7 @@
  * Useful for subclassing.
  */
 function initializeNumberFormat(numberFormat, locales, options) {
-  if (numberFormat.hasOwnProperty('__initializedIntlObject')) {
+  if (%IsInitializedIntlObject(numberFormat)) {
     throw new $TypeError('Trying to re-initialize NumberFormat object.');
   }
 
@@ -1196,10 +1193,8 @@
                                                          writable: true});
   }
 
-  $Object.defineProperty(numberFormat, 'formatter', {value: formatter});
+  %MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat', formatter);
   $Object.defineProperty(numberFormat, 'resolved', {value: resolved});
-  $Object.defineProperty(numberFormat, '__initializedIntlObject',
-                         {value: 'numberformat'});
 
   return numberFormat;
 }
@@ -1234,8 +1229,7 @@
       throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
     }
 
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'numberformat') {
+    if (!%IsInitializedIntlObjectOfType(this, 'numberformat')) {
       throw new $TypeError('resolvedOptions method called on a non-object' +
           ' or on a object that is not Intl.NumberFormat.');
     }
@@ -1309,7 +1303,8 @@
   // Spec treats -0 and +0 as 0.
   var number = $Number(value) + 0;
 
-  return %InternalNumberFormat(formatter.formatter, number);
+  return %InternalNumberFormat(%GetImplFromInitializedIntlObject(formatter),
+                               number);
 }
 
 
@@ -1317,7 +1312,8 @@
  * Returns a Number that represents string value that was passed in.
  */
 function parseNumber(formatter, value) {
-  return %InternalNumberParse(formatter.formatter, $String(value));
+  return %InternalNumberParse(%GetImplFromInitializedIntlObject(formatter),
+                              $String(value));
 }
 
 
@@ -1530,7 +1526,7 @@
  */
 function initializeDateTimeFormat(dateFormat, locales, options) {
 
-  if (dateFormat.hasOwnProperty('__initializedIntlObject')) {
+  if (%IsInitializedIntlObject(dateFormat)) {
     throw new $TypeError('Trying to re-initialize DateTimeFormat object.');
   }
 
@@ -1592,10 +1588,8 @@
     throw new $RangeError('Unsupported time zone specified ' + tz);
   }
 
-  $Object.defineProperty(dateFormat, 'formatter', {value: formatter});
+  %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter);
   $Object.defineProperty(dateFormat, 'resolved', {value: resolved});
-  $Object.defineProperty(dateFormat, '__initializedIntlObject',
-                         {value: 'dateformat'});
 
   return dateFormat;
 }
@@ -1630,8 +1624,7 @@
       throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
     }
 
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'dateformat') {
+    if (!%IsInitializedIntlObjectOfType(this, 'dateformat')) {
       throw new $TypeError('resolvedOptions method called on a non-object or ' +
           'on a object that is not Intl.DateTimeFormat.');
     }
@@ -1713,7 +1706,8 @@
     throw new $RangeError('Provided date is not in valid range.');
   }
 
-  return %InternalDateFormat(formatter.formatter, new $Date(dateMs));
+  return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter),
+                             new $Date(dateMs));
 }
 
 
@@ -1724,7 +1718,8 @@
  * Returns undefined if date string cannot be parsed.
  */
 function parseDate(formatter, value) {
-  return %InternalDateParse(formatter.formatter, $String(value));
+  return %InternalDateParse(%GetImplFromInitializedIntlObject(formatter),
+                            $String(value));
 }
 
 
@@ -1772,7 +1767,7 @@
  * Useful for subclassing.
  */
 function initializeBreakIterator(iterator, locales, options) {
-  if (iterator.hasOwnProperty('__initializedIntlObject')) {
+  if (%IsInitializedIntlObject(iterator)) {
     throw new $TypeError('Trying to re-initialize v8BreakIterator object.');
   }
 
@@ -1798,10 +1793,9 @@
                                               internalOptions,
                                               resolved);
 
-  $Object.defineProperty(iterator, 'iterator', {value: internalIterator});
+  %MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator',
+                                     internalIterator);
   $Object.defineProperty(iterator, 'resolved', {value: resolved});
-  $Object.defineProperty(iterator, '__initializedIntlObject',
-                         {value: 'breakiterator'});
 
   return iterator;
 }
@@ -1836,8 +1830,7 @@
       throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
     }
 
-    if (!this || typeof this !== 'object' ||
-        this.__initializedIntlObject !== 'breakiterator') {
+    if (!%IsInitializedIntlObjectOfType(this, 'breakiterator')) {
       throw new $TypeError('resolvedOptions method called on a non-object or ' +
           'on a object that is not Intl.v8BreakIterator.');
     }
@@ -1884,7 +1877,8 @@
  * gets discarded.
  */
 function adoptText(iterator, text) {
-  %BreakIteratorAdoptText(iterator.iterator, $String(text));
+  %BreakIteratorAdoptText(%GetImplFromInitializedIntlObject(iterator),
+                          $String(text));
 }
 
 
@@ -1892,7 +1886,7 @@
  * Returns index of the first break in the string and moves current pointer.
  */
 function first(iterator) {
-  return %BreakIteratorFirst(iterator.iterator);
+  return %BreakIteratorFirst(%GetImplFromInitializedIntlObject(iterator));
 }
 
 
@@ -1900,7 +1894,7 @@
  * Returns the index of the next break and moves the pointer.
  */
 function next(iterator) {
-  return %BreakIteratorNext(iterator.iterator);
+  return %BreakIteratorNext(%GetImplFromInitializedIntlObject(iterator));
 }
 
 
@@ -1908,7 +1902,7 @@
  * Returns index of the current break.
  */
 function current(iterator) {
-  return %BreakIteratorCurrent(iterator.iterator);
+  return %BreakIteratorCurrent(%GetImplFromInitializedIntlObject(iterator));
 }
 
 
@@ -1916,7 +1910,7 @@
  * Returns type of the current break.
  */
 function breakType(iterator) {
-  return %BreakIteratorBreakType(iterator.iterator);
+  return %BreakIteratorBreakType(%GetImplFromInitializedIntlObject(iterator));
 }
 
 
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 4ffbe53..6c934b7 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1493,7 +1493,7 @@
   Register dividend = ToRegister(instr->dividend());
   int32_t divisor = instr->divisor();
   Register result = ToRegister(instr->result());
-  ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+  ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
   ASSERT(!result.is(dividend));
 
   // Check for (0 / -x) that will produce negative zero.
@@ -1556,15 +1556,15 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
 void LCodeGen::DoDivI(LDivI* instr) {
   HBinaryOperation* hdiv = instr->hydrogen();
-  Register dividend = ToRegister(instr->left());
-  Register divisor = ToRegister(instr->right());
+  Register dividend = ToRegister(instr->dividend());
+  Register divisor = ToRegister(instr->divisor());
   Register remainder = ToRegister(instr->temp());
-  Register result = ToRegister(instr->result());
   ASSERT(dividend.is(eax));
   ASSERT(remainder.is(edx));
-  ASSERT(result.is(eax));
+  ASSERT(ToRegister(instr->result()).is(eax));
   ASSERT(!divisor.is(eax));
   ASSERT(!divisor.is(edx));
 
@@ -1598,15 +1598,7 @@
   __ cdq();
   __ idiv(divisor);
 
-  if (hdiv->IsMathFloorOfDiv()) {
-    Label done;
-    __ test(remainder, remainder);
-    __ j(zero, &done, Label::kNear);
-    __ xor_(remainder, divisor);
-    __ sar(remainder, 31);
-    __ add(result, remainder);
-    __ bind(&done);
-  } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+  if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     // Deoptimize if remainder is not 0.
     __ test(remainder, remainder);
     DeoptimizeIf(not_zero, instr->environment());
@@ -1696,6 +1688,59 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
+  Register dividend = ToRegister(instr->dividend());
+  Register divisor = ToRegister(instr->divisor());
+  Register remainder = ToRegister(instr->temp());
+  Register result = ToRegister(instr->result());
+  ASSERT(dividend.is(eax));
+  ASSERT(remainder.is(edx));
+  ASSERT(result.is(eax));
+  ASSERT(!divisor.is(eax));
+  ASSERT(!divisor.is(edx));
+
+  // Check for x / 0.
+  if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+    __ test(divisor, divisor);
+    DeoptimizeIf(zero, instr->environment());
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    Label dividend_not_zero;
+    __ test(dividend, dividend);
+    __ j(not_zero, &dividend_not_zero, Label::kNear);
+    __ test(divisor, divisor);
+    DeoptimizeIf(sign, instr->environment());
+    __ bind(&dividend_not_zero);
+  }
+
+  // Check for (kMinInt / -1).
+  if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+    Label dividend_not_min_int;
+    __ cmp(dividend, kMinInt);
+    __ j(not_zero, &dividend_not_min_int, Label::kNear);
+    __ cmp(divisor, -1);
+    DeoptimizeIf(zero, instr->environment());
+    __ bind(&dividend_not_min_int);
+  }
+
+  // Sign extend to edx (= remainder).
+  __ cdq();
+  __ idiv(divisor);
+
+  Label done;
+  __ test(remainder, remainder);
+  __ j(zero, &done, Label::kNear);
+  __ xor_(remainder, divisor);
+  __ sar(remainder, 31);
+  __ add(result, remainder);
+  __ bind(&done);
+}
+
+
 void LCodeGen::DoMulI(LMulI* instr) {
   Register left = ToRegister(instr->left());
   LOperand* right = instr->right();
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 384a21c..c230deb 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1365,7 +1365,7 @@
 }
 
 
-LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
   ASSERT(instr->representation().IsSmiOrInteger32());
   ASSERT(instr->left()->representation().Equals(instr->representation()));
   ASSERT(instr->right()->representation().Equals(instr->representation()));
@@ -1377,8 +1377,7 @@
   if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
       instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
       instr->CheckFlag(HValue::kCanOverflow) ||
-      (!instr->IsMathFloorOfDiv() &&
-       !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+      !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     result = AssignEnvironment(result);
   }
   return result;
@@ -1442,13 +1441,31 @@
 }
 
 
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+  ASSERT(instr->representation().IsSmiOrInteger32());
+  ASSERT(instr->left()->representation().Equals(instr->representation()));
+  ASSERT(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseFixed(instr->left(), eax);
+  LOperand* divisor = UseRegister(instr->right());
+  LOperand* temp = FixedTemp(edx);
+  LInstruction* result = DefineFixed(new(zone()) LFlooringDivI(
+          dividend, divisor, temp), eax);
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      instr->CheckFlag(HValue::kCanOverflow)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
   if (instr->RightIsPowerOf2()) {
     return DoFlooringDivByPowerOf2I(instr);
   } else if (instr->right()->IsConstant()) {
     return DoFlooringDivByConstI(instr);
   } else {
-    return DoDivI(instr);
+    return DoFlooringDivI(instr);
   }
 }
 
@@ -1882,29 +1899,23 @@
 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
   Representation from = instr->from();
   Representation to = instr->to();
+  HValue* val = instr->value();
   if (from.IsSmi()) {
     if (to.IsTagged()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return DefineSameAsFirst(new(zone()) LDummyUse(value));
     }
     from = Representation::Tagged();
   }
-  // Only mark conversions that might need to allocate as calling rather than
-  // all changes. This makes simple, non-allocating conversion not have to force
-  // building a stack frame.
   if (from.IsTagged()) {
     if (to.IsDouble()) {
-      LOperand* value = UseRegister(instr->value());
-      // Temp register only necessary for minus zero check.
+      LOperand* value = UseRegister(val);
       LOperand* temp = TempRegister();
-      LInstruction* result = DefineAsRegister(
-          new(zone()) LNumberUntagD(value, temp));
-      if (!instr->value()->representation().IsSmi()) {
-        result = AssignEnvironment(result);
-      }
+      LInstruction* result =
+          DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
+      if (!val->representation().IsSmi()) result = AssignEnvironment(result);
       return result;
     } else if (to.IsSmi()) {
-      HValue* val = instr->value();
       LOperand* value = UseRegister(val);
       if (val->type().IsSmi()) {
         return DefineSameAsFirst(new(zone()) LDummyUse(value));
@@ -1912,18 +1923,18 @@
       return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      HValue* val = instr->value();
       if (val->type().IsSmi() || val->representation().IsSmi()) {
         LOperand* value = UseRegister(val);
         return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
       } else {
+        LOperand* value = UseRegister(val);
         bool truncating = instr->CanTruncateToInt32();
         LOperand* xmm_temp =
             (CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating)
                 ? FixedTemp(xmm1) : NULL;
-        LInstruction* result = DefineSameAsFirst(
-            new(zone()) LTaggedToI(UseRegister(val), xmm_temp));
-        if (!instr->value()->representation().IsSmi()) {
+        LInstruction* result =
+            DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
+        if (!val->representation().IsSmi()) {
           // Note: Only deopts in deferred code.
           result = AssignEnvironment(result);
         }
@@ -1933,23 +1944,20 @@
   } else if (from.IsDouble()) {
     if (to.IsTagged()) {
       info()->MarkAsDeferredCalling();
-      LOperand* value = UseRegisterAtStart(instr->value());
+      LOperand* value = UseRegisterAtStart(val);
       LOperand* temp = FLAG_inline_new ? TempRegister() : NULL;
-
-      // Make sure that temp and result_temp are different registers.
       LUnallocated* result_temp = TempRegister();
       LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
       return AssignPointerMap(Define(result, result_temp));
     } else if (to.IsSmi()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return AssignEnvironment(
           DefineAsRegister(new(zone()) LDoubleToSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
       bool truncating = instr->CanTruncateToInt32();
       bool needs_temp = CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating;
-      LOperand* value = needs_temp ?
-          UseTempRegister(instr->value()) : UseRegister(instr->value());
+      LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val);
       LOperand* temp = needs_temp ? TempRegister() : NULL;
       LInstruction* result =
           DefineAsRegister(new(zone()) LDoubleToI(value, temp));
@@ -1959,23 +1967,23 @@
   } else if (from.IsInteger32()) {
     info()->MarkAsDeferredCalling();
     if (to.IsTagged()) {
-      HValue* val = instr->value();
-      LOperand* value = UseRegister(val);
       if (!instr->CheckFlag(HValue::kCanOverflow)) {
+        LOperand* value = UseRegister(val);
         return DefineSameAsFirst(new(zone()) LSmiTag(value));
       } else if (val->CheckFlag(HInstruction::kUint32)) {
+        LOperand* value = UseRegister(val);
         LOperand* temp1 = TempRegister();
-        LOperand* temp2 = CpuFeatures::IsSupported(SSE2) ? FixedTemp(xmm1)
-                                                         : NULL;
+        LOperand* temp2 =
+            CpuFeatures::IsSupported(SSE2) ? FixedTemp(xmm1) : NULL;
         LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
         return AssignPointerMap(DefineSameAsFirst(result));
       } else {
+        LOperand* value = UseRegister(val);
         LOperand* temp = TempRegister();
         LNumberTagI* result = new(zone()) LNumberTagI(value, temp);
         return AssignPointerMap(DefineSameAsFirst(result));
       }
     } else if (to.IsSmi()) {
-      HValue* val = instr->value();
       LOperand* value = UseRegister(val);
       LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value));
       if (instr->CheckFlag(HValue::kCanOverflow)) {
@@ -1984,13 +1992,12 @@
       return result;
     } else {
       ASSERT(to.IsDouble());
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+      if (val->CheckFlag(HInstruction::kUint32)) {
         LOperand* temp = FixedTemp(xmm1);
         return DefineAsRegister(
-            new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
+            new(zone()) LUint32ToDouble(UseRegister(val), temp));
       } else {
-        return DefineAsRegister(
-            new(zone()) LInteger32ToDouble(Use(instr->value())));
+        return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
       }
     }
   }
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 7964b7f..c7b3bc7 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -99,6 +99,7 @@
   V(DummyUse)                                   \
   V(FlooringDivByConstI)                        \
   V(FlooringDivByPowerOf2I)                     \
+  V(FlooringDivI)                               \
   V(ForInCacheArray)                            \
   V(ForInPrepareMap)                            \
   V(FunctionLiteral)                            \
@@ -744,14 +745,14 @@
 
 class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
  public:
-  LDivI(LOperand* left, LOperand* right, LOperand* temp) {
-    inputs_[0] = left;
-    inputs_[1] = right;
+  LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
     temps_[0] = temp;
   }
 
-  LOperand* left() { return inputs_[0]; }
-  LOperand* right() { return inputs_[1]; }
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
@@ -806,6 +807,23 @@
 };
 
 
+class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+  LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
+    temps_[0] = temp;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
 class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
  public:
   LMulI(LOperand* left, LOperand* right, LOperand* temp) {
@@ -2750,12 +2768,13 @@
   LInstruction* DoMathClz32(HUnaryMathOperation* instr);
   LInstruction* DoDivByPowerOf2I(HDiv* instr);
   LInstruction* DoDivByConstI(HDiv* instr);
-  LInstruction* DoDivI(HBinaryOperation* instr);
+  LInstruction* DoDivI(HDiv* instr);
   LInstruction* DoModByPowerOf2I(HMod* instr);
   LInstruction* DoModByConstI(HMod* instr);
   LInstruction* DoModI(HMod* instr);
   LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
   LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+  LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
 
  private:
   enum Status {
diff --git a/src/ic.cc b/src/ic.cc
index f01c3d1..8b19a60 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -248,12 +248,7 @@
 
 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
                                                 Handle<String> name) {
-  if (target()->is_keyed_stub()) {
-    // Determine whether the failure is due to a name failure.
-    if (!name->IsName()) return false;
-    Name* stub_name = target()->FindFirstName();
-    if (*name != stub_name) return false;
-  }
+  if (!IsNameCompatibleWithMonomorphicPrototypeFailure(name)) return false;
 
   InlineCacheHolderFlag cache_holder =
       Code::ExtractCacheHolderFromFlags(target()->flags());
@@ -336,6 +331,18 @@
 }
 
 
+bool IC::IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name) {
+  if (target()->is_keyed_stub()) {
+    // Determine whether the failure is due to a name failure.
+    if (!name->IsName()) return false;
+    Name* stub_name = target()->FindFirstName();
+    if (*name != stub_name) return false;
+  }
+
+  return true;
+}
+
+
 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
   if (!name->IsString()) return;
   if (state() != MONOMORPHIC) {
@@ -352,8 +359,9 @@
   // because of changes in the prototype chain to avoid hitting it
   // again.
   if (TryRemoveInvalidPrototypeDependentStub(
-          receiver, Handle<String>::cast(name))) {
-    return MarkMonomorphicPrototypeFailure();
+          receiver, Handle<String>::cast(name)) &&
+      TryMarkMonomorphicPrototypeFailure(name)) {
+    return;
   }
 
   // The builtins object is special.  It only changes when JavaScript
@@ -634,7 +642,7 @@
     if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
       // Filter out deprecated maps to ensure their instances get migrated.
       ++deprecated_types;
-    } else if (type->IsCurrently(current_type)) {
+    } else if (type->NowIs(current_type)) {
       // If the receiver type is already in the polymorphic IC, this indicates
       // there was a prototoype chain failure. In that case, just overwrite the
       // handler.
@@ -658,7 +666,7 @@
   number_of_valid_types++;
   if (handler_to_overwrite >= 0) {
     handlers.Set(handler_to_overwrite, code);
-    if (!type->IsCurrently(types.at(handler_to_overwrite))) {
+    if (!type->NowIs(types.at(handler_to_overwrite))) {
       types.Set(handler_to_overwrite, type);
     }
   } else {
@@ -676,7 +684,7 @@
 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
   return object->IsJSGlobalObject()
       ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate)
-      : HeapType::OfCurrently(object, isolate);
+      : HeapType::NowOf(object, isolate);
 }
 
 
@@ -1184,8 +1192,9 @@
     // entirely by the migration above.
     receiver->map()->LookupTransition(*holder, *name, lookup);
     if (!lookup->IsTransition()) return false;
-    ic->MarkMonomorphicPrototypeFailure();
+    return ic->TryMarkMonomorphicPrototypeFailure(name);
   }
+
   return true;
 }
 
diff --git a/src/ic.h b/src/ic.h
index e70cb82..146b26b 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -96,8 +96,14 @@
 
   // Compute the current IC state based on the target stub, receiver and name.
   void UpdateState(Handle<Object> receiver, Handle<Object> name);
-  void MarkMonomorphicPrototypeFailure() {
-    state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
+
+  bool IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name);
+  bool TryMarkMonomorphicPrototypeFailure(Handle<Object> name) {
+    if (IsNameCompatibleWithMonomorphicPrototypeFailure(name)) {
+      state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
+      return true;
+    }
+    return false;
   }
 
   // Clear the inline cache to initial state.
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index f5b99eb..ebeaedf 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -1174,7 +1174,7 @@
   Register dividend = ToRegister(instr->dividend());
   int32_t divisor = instr->divisor();
   Register result = ToRegister(instr->result());
-  ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+  ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
   ASSERT(!result.is(dividend));
 
   // Check for (0 / -x) that will produce negative zero.
diff --git a/src/msan.h b/src/msan.h
index 484c9fa..b07d66d 100644
--- a/src/msan.h
+++ b/src/msan.h
@@ -30,6 +30,8 @@
 #ifndef V8_MSAN_H_
 #define V8_MSAN_H_
 
+#include "globals.h"
+
 #ifndef __has_feature
 # define __has_feature(x) 0
 #endif
@@ -38,12 +40,12 @@
 # define MEMORY_SANITIZER
 #endif
 
-#ifdef MEMORY_SANITIZER
-# include <sanitizer/msan_interface.h>
+#if defined(MEMORY_SANITIZER) && !defined(USE_SIMULATOR)
+# include <sanitizer/msan_interface.h>  // NOLINT
 // Marks a memory range as fully initialized.
-# define MSAN_MEMORY_IS_INITIALIZED(p, s) __msan_unpoison((p), (s))
+# define MSAN_MEMORY_IS_INITIALIZED_IN_JIT(p, s) __msan_unpoison((p), (s))
 #else
-# define MSAN_MEMORY_IS_INITIALIZED(p, s)
+# define MSAN_MEMORY_IS_INITIALIZED_IN_JIT(p, s)
 #endif
 
 #endif  // V8_MSAN_H_
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index ca025e6..ba9ff65 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -41,17 +41,22 @@
 void MaybeObject::Verify() {
   Object* this_as_object;
   if (ToObject(&this_as_object)) {
-    if (this_as_object->IsSmi()) {
-      Smi::cast(this_as_object)->SmiVerify();
-    } else {
-      HeapObject::cast(this_as_object)->HeapObjectVerify();
-    }
+    this_as_object->ObjectVerify();
   } else {
     Failure::cast(this)->FailureVerify();
   }
 }
 
 
+void Object::ObjectVerify() {
+  if (IsSmi()) {
+    Smi::cast(this)->SmiVerify();
+  } else {
+    HeapObject::cast(this)->HeapObjectVerify();
+  }
+}
+
+
 void Object::VerifyPointer(Object* p) {
   if (p->IsHeapObject()) {
     HeapObject::VerifyHeapPointer(p);
@@ -380,11 +385,7 @@
 void FixedArray::FixedArrayVerify() {
   for (int i = 0; i < length(); i++) {
     Object* e = get(i);
-    if (e->IsHeapObject()) {
-      VerifyHeapPointer(e);
-    } else {
-      e->Verify();
-    }
+    VerifyPointer(e);
   }
 }
 
@@ -626,7 +627,7 @@
 void Code::CodeVerify() {
   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
                   kCodeAlignment));
-  relocation_info()->Verify();
+  relocation_info()->ObjectVerify();
   Address last_gc_pc = NULL;
   for (RelocIterator it(this); !it.done(); it.next()) {
     it.rinfo()->Verify();
@@ -811,7 +812,7 @@
 
 void Box::BoxVerify() {
   CHECK(IsBox());
-  value()->Verify();
+  value()->ObjectVerify();
 }
 
 
@@ -947,7 +948,7 @@
 
 
 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
-  JSFunction::cast(get(kFactoryIndex))->Verify();
+  JSFunction::cast(get(kFactoryIndex))->ObjectVerify();
 
   int size = Smi::cast(get(kCacheSizeIndex))->value();
   CHECK(kEntriesIndex <= size);
@@ -962,18 +963,18 @@
   if (FLAG_enable_slow_asserts) {
     for (int i = kEntriesIndex; i < size; i++) {
       CHECK(!get(i)->IsTheHole());
-      get(i)->Verify();
+      get(i)->ObjectVerify();
     }
     for (int i = size; i < length(); i++) {
       CHECK(get(i)->IsTheHole());
-      get(i)->Verify();
+      get(i)->ObjectVerify();
     }
   }
 }
 
 
 void NormalizedMapCache::NormalizedMapCacheVerify() {
-  FixedArray::cast(this)->Verify();
+  FixedArray::cast(this)->FixedArrayVerify();
   if (FLAG_enable_slow_asserts) {
     for (int i = 0; i < length(); i++) {
       Object* e = get(i);
diff --git a/src/objects.cc b/src/objects.cc
index 92ec283..7057e9a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -13872,9 +13872,6 @@
   }
 
   MaybeObject* AsObject(Heap* heap) {
-    // Attempt to flatten the string, so that internalized strings will most
-    // often be flat strings.
-    string_ = string_->TryFlattenGetString();
     // Internalize the string if possible.
     Map* map = heap->InternalizedStringMapForString(string_);
     if (map != NULL) {
@@ -13914,7 +13911,7 @@
                                              int at_least_space_for,
                                              MinimumCapacity capacity_option,
                                              PretenureFlag pretenure) {
-  ASSERT(!capacity_option || IS_POWER_OF_TWO(at_least_space_for));
+  ASSERT(!capacity_option || IsPowerOf2(at_least_space_for));
   int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
                      ? at_least_space_for
                      : ComputeCapacity(at_least_space_for);
diff --git a/src/objects.h b/src/objects.h
index 98bf122..ce4dd50 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -355,8 +355,6 @@
                                                                                \
   V(INTERNALIZED_STRING_TYPE)                                                  \
   V(ASCII_INTERNALIZED_STRING_TYPE)                                            \
-  V(CONS_INTERNALIZED_STRING_TYPE)                                             \
-  V(CONS_ASCII_INTERNALIZED_STRING_TYPE)                                       \
   V(EXTERNAL_INTERNALIZED_STRING_TYPE)                                         \
   V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE)                                   \
   V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE)                      \
@@ -514,14 +512,6 @@
     kVariableSizeSentinel,                                                     \
     ascii_internalized_string,                                                 \
     AsciiInternalizedString)                                                   \
-  V(CONS_INTERNALIZED_STRING_TYPE,                                             \
-    ConsString::kSize,                                                         \
-    cons_internalized_string,                                                  \
-    ConsInternalizedString)                                                    \
-  V(CONS_ASCII_INTERNALIZED_STRING_TYPE,                                       \
-    ConsString::kSize,                                                         \
-    cons_ascii_internalized_string,                                            \
-    ConsAsciiInternalizedString)                                               \
   V(EXTERNAL_INTERNALIZED_STRING_TYPE,                                         \
     ExternalTwoByteString::kSize,                                              \
     external_internalized_string,                                              \
@@ -631,7 +621,7 @@
 // Use this mask to distinguish between cons and slice only after making
 // sure that the string is one of the two (an indirect string).
 const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
-STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
+STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
 
 // If bit 7 is clear, then bit 3 indicates whether this two-byte
 // string actually contains one byte data.
@@ -662,10 +652,6 @@
       | kInternalizedTag,
   ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kSeqStringTag
       | kInternalizedTag,
-  CONS_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kConsStringTag
-      | kInternalizedTag,
-  CONS_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kConsStringTag
-      | kInternalizedTag,
   EXTERNAL_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kExternalStringTag
       | kInternalizedTag,
   EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag
@@ -685,9 +671,9 @@
 
   STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
   ASCII_STRING_TYPE = ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
-  CONS_STRING_TYPE = CONS_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
+  CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
   CONS_ASCII_STRING_TYPE =
-      CONS_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
+      kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
 
   SLICED_STRING_TYPE =
       kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
@@ -1629,6 +1615,7 @@
   // < the length of the string.  Used to implement [] on strings.
   inline bool IsStringObjectWithCharacterAt(uint32_t index);
 
+  DECLARE_VERIFIER(Object)
 #ifdef VERIFY_HEAP
   // Verify a pointer is a valid object pointer.
   static void VerifyPointer(Object* p);
diff --git a/src/parser.cc b/src/parser.cc
index a00adb8..16a1028 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -304,20 +304,25 @@
 }
 
 
-Scanner::Location ScriptDataImpl::MessageLocation() {
+Scanner::Location ScriptDataImpl::MessageLocation() const {
   int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
   int end_pos = Read(PreparseDataConstants::kMessageEndPos);
   return Scanner::Location(beg_pos, end_pos);
 }
 
 
-const char* ScriptDataImpl::BuildMessage() {
+bool ScriptDataImpl::IsReferenceError() const {
+  return Read(PreparseDataConstants::kIsReferenceErrorPos);
+}
+
+
+const char* ScriptDataImpl::BuildMessage() const {
   unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
   return ReadString(start, NULL);
 }
 
 
-Vector<const char*> ScriptDataImpl::BuildArgs() {
+Vector<const char*> ScriptDataImpl::BuildArgs() const {
   int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
   const char** array = NewArray<const char*>(arg_count);
   // Position after text found by skipping past length field and
@@ -333,12 +338,12 @@
 }
 
 
-unsigned ScriptDataImpl::Read(int position) {
+unsigned ScriptDataImpl::Read(int position) const {
   return store_[PreparseDataConstants::kHeaderSize + position];
 }
 
 
-unsigned* ScriptDataImpl::ReadAddress(int position) {
+unsigned* ScriptDataImpl::ReadAddress(int position) const {
   return &store_[PreparseDataConstants::kHeaderSize + position];
 }
 
@@ -3385,8 +3390,7 @@
           }
           ParserTraits::ReportMessageAt(
               Scanner::Location(logger.start(), logger.end()),
-              logger.message(),
-              args);
+              logger.message(), args, logger.is_reference_error());
           *ok = false;
           return NULL;
         }
@@ -4688,7 +4692,8 @@
       Scanner::Location loc = cached_data->MessageLocation();
       const char* message = cached_data->BuildMessage();
       Vector<const char*> args = cached_data->BuildArgs();
-      ParserTraits::ReportMessageAt(loc, message, args);
+      ParserTraits::ReportMessageAt(loc, message, args,
+                                    cached_data->IsReferenceError());
       DeleteArray(message);
       for (int i = 0; i < args.length(); i++) {
         DeleteArray(args[i]);
diff --git a/src/parser.h b/src/parser.h
index 4bb9aad..287dfa4 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -104,9 +104,10 @@
   int GetSymbolIdentifier();
   bool SanityCheck();
 
-  Scanner::Location MessageLocation();
-  const char* BuildMessage();
-  Vector<const char*> BuildArgs();
+  Scanner::Location MessageLocation() const;
+  bool IsReferenceError() const;
+  const char* BuildMessage() const;
+  Vector<const char*> BuildArgs() const;
 
   int symbol_count() {
     return (store_.length() > PreparseDataConstants::kHeaderSize)
@@ -127,8 +128,8 @@
   int function_index_;
   bool owns_store_;
 
-  unsigned Read(int position);
-  unsigned* ReadAddress(int position);
+  unsigned Read(int position) const;
+  unsigned* ReadAddress(int position) const;
   // Reads a number from the current symbols
   int ReadNumber(byte** source);
 
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index 5ca1252..20c2533 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -214,6 +214,11 @@
   // See http://code.google.com/p/nativeclient/issues/3341
   return NULL;
 #endif
+#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
+    defined(THREAD_SANITIZER)
+  // Dynamic tools do not support custom mmap addresses.
+  return NULL;
+#endif
   Isolate* isolate = Isolate::UncheckedCurrent();
   // Note that the current isolate isn't set up in a call path via
   // CpuFeatures::Probe. We don't care about randomization in this case because
diff --git a/src/preparse-data-format.h b/src/preparse-data-format.h
index e2cf0a1..f5c3a5f 100644
--- a/src/preparse-data-format.h
+++ b/src/preparse-data-format.h
@@ -51,7 +51,8 @@
   static const int kMessageStartPos = 0;
   static const int kMessageEndPos = 1;
   static const int kMessageArgCountPos = 2;
-  static const int kMessageTextPos = 3;
+  static const int kIsReferenceErrorPos = 3;
+  static const int kMessageTextPos = 4;
 
   static const unsigned char kNumberTerminator = 0x80u;
 };
diff --git a/src/preparse-data.cc b/src/preparse-data.cc
index 9f585a9..5bc6173 100644
--- a/src/preparse-data.cc
+++ b/src/preparse-data.cc
@@ -88,9 +88,10 @@
 
 
 void CompleteParserRecorder::LogMessage(int start_pos,
-                                               int end_pos,
-                                               const char* message,
-                                               const char* arg_opt) {
+                                        int end_pos,
+                                        const char* message,
+                                        const char* arg_opt,
+                                        bool is_reference_error) {
   if (has_error()) return;
   preamble_[PreparseDataConstants::kHasErrorOffset] = true;
   function_store_.Reset();
@@ -100,7 +101,9 @@
   function_store_.Add(end_pos);
   STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2);
   function_store_.Add((arg_opt == NULL) ? 0 : 1);
-  STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 3);
+  STATIC_ASSERT(PreparseDataConstants::kIsReferenceErrorPos == 3);
+  function_store_.Add(is_reference_error ? 1 : 0);
+  STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 4);
   WriteString(CStrVector(message));
   if (arg_opt != NULL) WriteString(CStrVector(arg_opt));
   should_log_symbols_ = false;
diff --git a/src/preparse-data.h b/src/preparse-data.h
index 6a968e3..cfc33fe 100644
--- a/src/preparse-data.h
+++ b/src/preparse-data.h
@@ -55,7 +55,8 @@
   virtual void LogMessage(int start,
                           int end,
                           const char* message,
-                          const char* argument_opt) = 0;
+                          const char* argument_opt,
+                          bool is_reference_error) = 0;
 
   // Logs a symbol creation of a literal or identifier.
   bool ShouldLogSymbols() { return should_log_symbols_; }
@@ -80,8 +81,9 @@
 
 class SingletonLogger : public ParserRecorder {
  public:
-  SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
-  virtual ~SingletonLogger() { }
+  SingletonLogger()
+      : has_error_(false), start_(-1), end_(-1), is_reference_error_(false) {}
+  virtual ~SingletonLogger() {}
 
   void Reset() { has_error_ = false; }
 
@@ -104,36 +106,39 @@
   virtual void LogMessage(int start,
                           int end,
                           const char* message,
-                          const char* argument_opt) {
+                          const char* argument_opt,
+                          bool is_reference_error) {
     if (has_error_) return;
     has_error_ = true;
     start_ = start;
     end_ = end;
     message_ = message;
     argument_opt_ = argument_opt;
+    is_reference_error_ = is_reference_error;
   }
 
-  bool has_error() { return has_error_; }
+  bool has_error() const { return has_error_; }
 
-  int start() { return start_; }
-  int end() { return end_; }
-  int literals() {
+  int start() const { return start_; }
+  int end() const { return end_; }
+  int literals() const {
     ASSERT(!has_error_);
     return literals_;
   }
-  int properties() {
+  int properties() const {
     ASSERT(!has_error_);
     return properties_;
   }
-  StrictMode strict_mode() {
+  StrictMode strict_mode() const {
     ASSERT(!has_error_);
     return strict_mode_;
   }
+  int is_reference_error() const { return is_reference_error_; }
   const char* message() {
     ASSERT(has_error_);
     return message_;
   }
-  const char* argument_opt() {
+  const char* argument_opt() const {
     ASSERT(has_error_);
     return argument_opt_;
   }
@@ -149,6 +154,7 @@
   // For error messages.
   const char* message_;
   const char* argument_opt_;
+  bool is_reference_error_;
 };
 
 
@@ -180,7 +186,8 @@
   virtual void LogMessage(int start,
                           int end,
                           const char* message,
-                          const char* argument_opt);
+                          const char* argument_opt,
+                          bool is_reference_error_);
 
   virtual void PauseRecording() {
     ASSERT(should_log_symbols_);
diff --git a/src/preparser.cc b/src/preparser.cc
index 9bcc880..4995ed9 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -83,8 +83,8 @@
                                       const char* type,
                                       const char* name_opt,
                                       bool is_reference_error) {
-  pre_parser_->log_
-      ->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
+  pre_parser_->log_->LogMessage(location.beg_pos, location.end_pos, type,
+                                name_opt, is_reference_error);
 }
 
 
@@ -93,7 +93,8 @@
                                       const char* type,
                                       const char* name_opt,
                                       bool is_reference_error) {
-  pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt);
+  pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt,
+                                is_reference_error);
 }
 
 
diff --git a/src/property.cc b/src/property.cc
index 2f72eec..591ea0b 100644
--- a/src/property.cc
+++ b/src/property.cc
@@ -1,36 +1,14 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
-#include "v8.h"
+#include "property.h"
+
+#include "handles-inl.h"
 
 namespace v8 {
 namespace internal {
 
-
 void LookupResult::Iterate(ObjectVisitor* visitor) {
   LookupResult* current = this;  // Could be NULL.
   while (current != NULL) {
@@ -114,9 +92,6 @@
   PrintF(out, " @ ");
   GetValue()->ShortPrint(out);
 }
-
-
 #endif
 
-
 } }  // namespace v8::internal
diff --git a/src/property.h b/src/property.h
index baa5a0f..cfdf9c7 100644
--- a/src/property.h
+++ b/src/property.h
@@ -1,47 +1,20 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #ifndef V8_PROPERTY_H_
 #define V8_PROPERTY_H_
 
-#include "allocation.h"
-#include "transitions.h"
+#include "isolate.h"
 
 namespace v8 {
 namespace internal {
 
-
 // Abstraction for elements in instance-descriptor arrays.
 //
 // Each descriptor has a key, property attributes, property type,
 // property index (in the actual instance-descriptor array) and
 // optionally a piece of data.
-//
-
 class Descriptor BASE_EMBEDDED {
  public:
   MUST_USE_RESULT MaybeObject* KeyToUniqueName() {
@@ -96,7 +69,7 @@
 };
 
 
-class FieldDescriptor: public Descriptor {
+class FieldDescriptor V8_FINAL : public Descriptor {
  public:
   FieldDescriptor(Name* key,
                   int field_index,
@@ -107,7 +80,7 @@
 };
 
 
-class ConstantDescriptor: public Descriptor {
+class ConstantDescriptor V8_FINAL : public Descriptor {
  public:
   ConstantDescriptor(Name* key,
                      Object* value,
@@ -117,7 +90,7 @@
 };
 
 
-class CallbacksDescriptor:  public Descriptor {
+class CallbacksDescriptor V8_FINAL : public Descriptor {
  public:
   CallbacksDescriptor(Name* key,
                       Object* foreign,
@@ -129,7 +102,7 @@
 
 // Holds a property index value distinguishing if it is a field index or an
 // index inside the object header.
-class PropertyIndex {
+class PropertyIndex V8_FINAL {
  public:
   static PropertyIndex NewFieldIndex(int index) {
     return PropertyIndex(index, false);
@@ -177,7 +150,7 @@
 };
 
 
-class LookupResult BASE_EMBEDDED {
+class LookupResult V8_FINAL BASE_EMBEDDED {
  public:
   explicit LookupResult(Isolate* isolate)
       : isolate_(isolate),
@@ -488,7 +461,6 @@
   PropertyDetails details_;
 };
 
-
 } }  // namespace v8::internal
 
 #endif  // V8_PROPERTY_H_
diff --git a/src/runtime.cc b/src/runtime.cc
index 48e81e2..67810ef 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2048,37 +2048,39 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   ASSERT(args.length() == 1);
-  CONVERT_ARG_CHECKED(HeapObject, object, 0);
-  Map* old_map = object->map();
+  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+  Handle<Map> old_map(object->map());
   bool needs_access_checks = old_map->is_access_check_needed();
   if (needs_access_checks) {
     // Copy map so it won't interfere constructor's initial map.
-    Map* new_map;
-    MaybeObject* maybe_new_map = old_map->Copy();
-    if (!maybe_new_map->To(&new_map)) return maybe_new_map;
-
+    Handle<Map> new_map = Map::Copy(old_map);
     new_map->set_is_access_check_needed(false);
-    object->set_map(new_map);
+    if (object->IsJSObject()) {
+      JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
+    } else {
+      object->set_map(*new_map);
+    }
   }
   return isolate->heap()->ToBoolean(needs_access_checks);
 }
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   ASSERT(args.length() == 1);
-  CONVERT_ARG_CHECKED(HeapObject, object, 0);
-  Map* old_map = object->map();
+  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+  Handle<Map> old_map(object->map());
   if (!old_map->is_access_check_needed()) {
     // Copy map so it won't interfere constructor's initial map.
-    Map* new_map;
-    MaybeObject* maybe_new_map = old_map->Copy();
-    if (!maybe_new_map->To(&new_map)) return maybe_new_map;
-
+    Handle<Map> new_map = Map::Copy(old_map);
     new_map->set_is_access_check_needed(true);
-    object->set_map(new_map);
+    if (object->IsJSObject()) {
+      JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
+    } else {
+      object->set_map(*new_map);
+    }
   }
   return isolate->heap()->undefined_value();
 }
@@ -2945,9 +2947,9 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
-  SealHandleScope shs(isolate);
+  HandleScope shs(isolate);
   RUNTIME_ASSERT(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, function, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
 
   String* name = isolate->heap()->prototype_string();
 
@@ -2970,9 +2972,10 @@
             instance_desc, &new_desc, index, OMIT_TRANSITION);
     if (!maybe_map->To(&new_map)) return maybe_map;
 
-    function->set_map(new_map);
+    JSObject::MigrateToMap(function, handle(new_map));
   } else {  // Dictionary properties.
     // Directly manipulate the property details.
+    DisallowHeapAllocation no_gc;
     int entry = function->property_dictionary()->FindEntry(name);
     ASSERT(entry != NameDictionary::kNotFound);
     PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
@@ -2982,7 +2985,7 @@
         details.dictionary_index());
     function->property_dictionary()->DetailsAtPut(entry, new_details);
   }
-  return function;
+  return *function;
 }
 
 
@@ -3084,9 +3087,7 @@
   if (!func->shared()->live_objects_may_exist()) {
     func->shared()->set_expected_nof_properties(num);
     if (func->has_initial_map()) {
-      Handle<Map> new_initial_map =
-          func->GetIsolate()->factory()->CopyMap(
-              Handle<Map>(func->initial_map()));
+      Handle<Map> new_initial_map = Map::Copy(handle(func->initial_map()));
       new_initial_map->set_unused_property_fields(num);
       func->set_initial_map(*new_initial_map);
     }
@@ -7990,11 +7991,10 @@
       parameter_map->set_map(
           isolate->heap()->sloppy_arguments_elements_map());
 
-      Handle<Map> old_map(result->map());
-      Handle<Map> new_map = isolate->factory()->CopyMap(old_map);
-      new_map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
+      Handle<Map> map = Map::Copy(handle(result->map()));
+      map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
 
-      result->set_map(*new_map);
+      result->set_map(*map);
       result->set_elements(*parameter_map);
 
       // Store the context and the arguments array at the beginning of the
@@ -13899,6 +13899,87 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInitializedIntlObject) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+
+  if (!input->IsJSObject()) return isolate->heap()->ToBoolean(false);
+  Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
+  Handle<Object> tag(obj->GetHiddenProperty(*marker), isolate);
+  return isolate->heap()->ToBoolean(!tag->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInitializedIntlObjectOfType) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
+
+  if (!input->IsJSObject()) return isolate->heap()->ToBoolean(false);
+  Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
+  Handle<Object> tag(obj->GetHiddenProperty(*marker), isolate);
+  return isolate->heap()->ToBoolean(
+      tag->IsString() && String::cast(*tag)->Equals(*expected_type));
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MarkAsInitializedIntlObjectOfType) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
+
+  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
+  JSObject::SetHiddenProperty(input, marker, type);
+
+  marker = isolate->factory()->intl_impl_object_string();
+  JSObject::SetHiddenProperty(input, marker, impl);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetImplFromInitializedIntlObject) {
+  HandleScope scope(isolate);
+
+  ASSERT(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+
+  if (!input->IsJSObject()) {
+    Vector< Handle<Object> > arguments = HandleVector(&input, 1);
+    Handle<Object> type_error =
+        isolate->factory()->NewTypeError("not_intl_object", arguments);
+    return isolate->Throw(*type_error);
+  }
+
+  Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+  Handle<String> marker = isolate->factory()->intl_impl_object_string();
+  Handle<Object> impl(obj->GetHiddenProperty(*marker), isolate);
+  if (impl->IsTheHole()) {
+    Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
+    Handle<Object> type_error =
+        isolate->factory()->NewTypeError("not_intl_object", arguments);
+    return isolate->Throw(*type_error);
+  }
+  return *impl;
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
   HandleScope scope(isolate);
 
diff --git a/src/runtime.h b/src/runtime.h
index f84355b..50181b6 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -491,6 +491,10 @@
   F(AvailableLocalesOf, 1, 1) \
   F(GetDefaultICULocale, 0, 1) \
   F(GetLanguageTagVariants, 1, 1) \
+  F(IsInitializedIntlObject, 1, 1) \
+  F(IsInitializedIntlObjectOfType, 2, 1) \
+  F(MarkAsInitializedIntlObjectOfType, 3, 1) \
+  F(GetImplFromInitializedIntlObject, 1, 1) \
   \
   /* Date format and parse. */ \
   F(CreateDateTimeFormat, 3, 1) \
diff --git a/src/spaces.cc b/src/spaces.cc
index 2ca8c98..7831ef1 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -711,7 +711,7 @@
                                                 executable,
                                                 owner);
   result->set_reserved_memory(&reservation);
-  MSAN_MEMORY_IS_INITIALIZED(base, chunk_size);
+  MSAN_MEMORY_IS_INITIALIZED_IN_JIT(base, chunk_size);
   return result;
 }
 
@@ -1195,7 +1195,7 @@
       VerifyObject(object);
 
       // The object itself should look OK.
-      object->Verify();
+      object->ObjectVerify();
 
       // All the interior pointers should be contained in the heap.
       int size = object->Size();
@@ -1478,7 +1478,7 @@
       CHECK(!object->IsCode());
 
       // The object itself should look OK.
-      object->Verify();
+      object->ObjectVerify();
 
       // All the interior pointers should be contained in the heap.
       VerifyPointersVisitor visitor;
@@ -3119,7 +3119,7 @@
            object->IsFixedDoubleArray() || object->IsByteArray());
 
     // The object itself should look OK.
-    object->Verify();
+    object->ObjectVerify();
 
     // Byte arrays and strings don't have interior pointers.
     if (object->IsCode()) {
diff --git a/src/types-inl.h b/src/types-inl.h
new file mode 100644
index 0000000..941fda7
--- /dev/null
+++ b/src/types-inl.h
@@ -0,0 +1,372 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_TYPES_INL_H_
+#define V8_TYPES_INL_H_
+
+#include "types.h"
+
+#include "factory.h"
+#include "handles-inl.h"
+
+namespace v8 {
+namespace internal {
+
+// static
+ZoneTypeConfig::Tagged* ZoneTypeConfig::tagged_create(
+    Tag tag, int size, Zone* zone) {
+  Tagged* tagged = new(zone) Tagged(size + 1, zone);
+  tagged->Add(reinterpret_cast<void*>(tag), zone);
+  tagged->AddBlock(NULL, size, zone);
+  return tagged;
+}
+
+
+// static
+void ZoneTypeConfig::tagged_shrink(Tagged* tagged, int size) {
+  tagged->Rewind(size + 1);
+}
+
+
+// static
+ZoneTypeConfig::Tag ZoneTypeConfig::tagged_tag(Tagged* tagged) {
+  return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0)));
+}
+
+
+// static
+template<class T>
+T ZoneTypeConfig::tagged_get(Tagged* tagged, int i) {
+  return reinterpret_cast<T>(tagged->at(i + 1));
+}
+
+
+// static
+template<class T>
+void ZoneTypeConfig::tagged_set(Tagged* tagged, int i, T value) {
+  tagged->at(i + 1) = reinterpret_cast<void*>(value);
+}
+
+
+// static
+int ZoneTypeConfig::tagged_length(Tagged* tagged) {
+  return tagged->length() - 1;
+}
+
+
+// static
+Type* ZoneTypeConfig::handle(Type* type) {
+  return type;
+}
+
+
+// static
+bool ZoneTypeConfig::is(Type* type, Tag tag) {
+  return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
+}
+
+
+// static
+bool ZoneTypeConfig::is_bitset(Type* type) {
+  return reinterpret_cast<intptr_t>(type) & 1;
+}
+
+
+// static
+bool ZoneTypeConfig::is_tagged(Type* type) {
+  return !is_bitset(type);
+}
+
+
+// static
+bool ZoneTypeConfig::is_class(Type* type) {
+  return is(type, kClassTag);
+}
+
+
+// static
+bool ZoneTypeConfig::is_constant(Type* type) {
+  return is(type, kConstantTag);
+}
+
+
+// static
+bool ZoneTypeConfig::is_union(Type* type) {
+  return is(type, kUnionTag);
+}
+
+
+// static
+bool ZoneTypeConfig::tagged_is_union(Tagged* tagged) {
+  return is(from_tagged(tagged), kUnionTag);
+}
+
+
+// static
+int ZoneTypeConfig::as_bitset(Type* type) {
+  ASSERT(is_bitset(type));
+  return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1);
+}
+
+
+// static
+ZoneTypeConfig::Tagged* ZoneTypeConfig::as_tagged(Type* type) {
+  ASSERT(is_tagged(type));
+  return reinterpret_cast<Tagged*>(type);
+}
+
+
+// static
+i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
+  ASSERT(is_class(type));
+  return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 1));
+}
+
+
+// static
+i::Handle<i::Object> ZoneTypeConfig::as_constant(Type* type) {
+  ASSERT(is_constant(type));
+  return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1));
+}
+
+
+// static
+ZoneTypeConfig::Unioned* ZoneTypeConfig::as_union(Type* type) {
+  ASSERT(is_union(type));
+  return tagged_as_union(as_tagged(type));
+}
+
+
+// static
+ZoneTypeConfig::Unioned* ZoneTypeConfig::tagged_as_union(Tagged* tagged) {
+  ASSERT(tagged_is_union(tagged));
+  return reinterpret_cast<Unioned*>(tagged);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset) {
+  return reinterpret_cast<Type*>((bitset << 1) | 1);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset, Zone* Zone) {
+  return from_bitset(bitset);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_tagged(Tagged* tagged) {
+  return reinterpret_cast<Type*>(tagged);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
+    i::Handle<i::Map> map, int lub, Zone* zone) {
+  Tagged* tagged = tagged_create(kClassTag, 2, zone);
+  tagged_set(tagged, 0, lub);
+  tagged_set(tagged, 1, map.location());
+  return from_tagged(tagged);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_constant(
+    i::Handle<i::Object> value, int lub, Zone* zone) {
+  Tagged* tagged = tagged_create(kConstantTag, 2, zone);
+  tagged_set(tagged, 0, lub);
+  tagged_set(tagged, 1, value.location());
+  return from_tagged(tagged);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_union(Unioned* unioned) {
+  return from_tagged(tagged_from_union(unioned));
+}
+
+
+// static
+ZoneTypeConfig::Tagged* ZoneTypeConfig::tagged_from_union(Unioned* unioned) {
+  return reinterpret_cast<Tagged*>(unioned);
+}
+
+
+// static
+ZoneTypeConfig::Unioned* ZoneTypeConfig::union_create(int size, Zone* zone) {
+  return tagged_as_union(tagged_create(kUnionTag, size, zone));
+}
+
+
+// static
+void ZoneTypeConfig::union_shrink(Unioned* unioned, int size) {
+  tagged_shrink(tagged_from_union(unioned), size);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::union_get(Unioned* unioned, int i) {
+  Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
+  ASSERT(!is_union(type));
+  return type;
+}
+
+
+// static
+void ZoneTypeConfig::union_set(Unioned* unioned, int i, Type* type) {
+  ASSERT(!is_union(type));
+  tagged_set(tagged_from_union(unioned), i, type);
+}
+
+
+// static
+int ZoneTypeConfig::union_length(Unioned* unioned) {
+  return tagged_length(tagged_from_union(unioned));
+}
+
+
+// static
+int ZoneTypeConfig::lub_bitset(Type* type) {
+  ASSERT(is_class(type) || is_constant(type));
+  return static_cast<int>(tagged_get<intptr_t>(as_tagged(type), 0));
+}
+
+// -------------------------------------------------------------------------- //
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::handle(Type* type) {
+  return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
+}
+
+
+// static
+bool HeapTypeConfig::is_bitset(Type* type) {
+  return type->IsSmi();
+}
+
+
+// static
+bool HeapTypeConfig::is_class(Type* type) {
+  return type->IsMap();
+}
+
+
+// static
+bool HeapTypeConfig::is_constant(Type* type) {
+  return type->IsBox();
+}
+
+
+// static
+bool HeapTypeConfig::is_union(Type* type) {
+  return type->IsFixedArray();
+}
+
+
+// static
+int HeapTypeConfig::as_bitset(Type* type) {
+  return Smi::cast(type)->value();
+}
+
+
+// static
+i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
+  return i::handle(i::Map::cast(type));
+}
+
+
+// static
+i::Handle<i::Object> HeapTypeConfig::as_constant(Type* type) {
+  i::Box* box = i::Box::cast(type);
+  return i::handle(box->value(), box->GetIsolate());
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Unioned> HeapTypeConfig::as_union(Type* type) {
+  return i::handle(i::FixedArray::cast(type));
+}
+
+
+// static
+HeapTypeConfig::Type* HeapTypeConfig::from_bitset(int bitset) {
+  return Type::cast(i::Smi::FromInt(bitset));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
+    int bitset, Isolate* isolate) {
+  return i::handle(from_bitset(bitset), isolate);
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
+    i::Handle<i::Map> map, int lub, Isolate* isolate) {
+  return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_constant(
+    i::Handle<i::Object> value, int lub, Isolate* isolate) {
+  i::Handle<Box> box = isolate->factory()->NewBox(value);
+  return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_union(
+    i::Handle<Unioned> unioned) {
+  return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Unioned> HeapTypeConfig::union_create(
+    int size, Isolate* isolate) {
+  return isolate->factory()->NewFixedArray(size);
+}
+
+
+// static
+void HeapTypeConfig::union_shrink(i::Handle<Unioned> unioned, int size) {
+  unioned->Shrink(size);
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::union_get(
+    i::Handle<Unioned> unioned, int i) {
+  Type* type = static_cast<Type*>(unioned->get(i));
+  ASSERT(!is_union(type));
+  return i::handle(type, unioned->GetIsolate());
+}
+
+
+// static
+void HeapTypeConfig::union_set(
+    i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
+  ASSERT(!is_union(*type));
+  unioned->set(i, *type);
+}
+
+
+// static
+int HeapTypeConfig::union_length(i::Handle<Unioned> unioned) {
+  return unioned->length();
+}
+
+
+// static
+int HeapTypeConfig::lub_bitset(Type* type) {
+  return 0;  // kNone, which causes recomputation.
+}
+
+} }  // namespace v8::internal
+
+#endif  // V8_TYPES_INL_H_
diff --git a/src/types.cc b/src/types.cc
index 98bb280..5998fdc 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -1,32 +1,11 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #include "types.h"
+
 #include "string-stream.h"
+#include "types-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -190,8 +169,6 @@
     case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
     case INTERNALIZED_STRING_TYPE:
     case ASCII_INTERNALIZED_STRING_TYPE:
-    case CONS_INTERNALIZED_STRING_TYPE:
-    case CONS_ASCII_INTERNALIZED_STRING_TYPE:
     case EXTERNAL_INTERNALIZED_STRING_TYPE:
     case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
     case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
@@ -271,7 +248,7 @@
 
 // Most precise _current_ type of a value (usually its class).
 template<class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::OfCurrently(
+typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
     i::Handle<i::Object> value, Region* region) {
   if (value->IsSmi() ||
       i::HeapObject::cast(*value)->map()->instance_type() == HEAP_NUMBER_TYPE ||
@@ -326,7 +303,7 @@
 
 
 template<class Config>
-bool TypeImpl<Config>::IsCurrently(TypeImpl* that) {
+bool TypeImpl<Config>::NowIs(TypeImpl* that) {
   return this->Is(that) ||
       (this->IsConstant() && that->IsClass() &&
        this->AsConstant()->IsHeapObject() &&
@@ -378,6 +355,23 @@
 
 
 template<class Config>
+bool TypeImpl<Config>::Contains(i::Object* value) {
+  if (this->IsConstant()) {
+    return *this->AsConstant() == value;
+  }
+  return Config::from_bitset(LubBitset(value))->Is(this);
+}
+
+
+template<class Config>
+bool TypeImpl<Config>::NowContains(i::Object* value) {
+  return this->Contains(value) ||
+      (this->IsClass() && value->IsHeapObject() &&
+       *this->AsClass() == i::HeapObject::cast(value)->map());
+}
+
+
+template<class Config>
 bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
   ASSERT(!this->IsUnion());
   for (int i = 0; i < current_size; ++i) {
@@ -690,5 +684,4 @@
   TypeImpl<HeapTypeConfig>::Convert<Type>(
     TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
 
-
 } }  // namespace v8::internal
diff --git a/src/types.h b/src/types.h
index 4569d13..d5e3ca4 100644
--- a/src/types.h
+++ b/src/types.h
@@ -1,41 +1,15 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #ifndef V8_TYPES_H_
 #define V8_TYPES_H_
 
-#include "v8.h"
-
-#include "objects.h"
+#include "handles.h"
 
 namespace v8 {
 namespace internal {
 
-
 // A simple type system for compiler-internal use. It is based entirely on
 // union types, and all subtyping hence amounts to set inclusion. Besides the
 // obvious primitive types and some predefined unions, the type language also
@@ -246,16 +220,23 @@
   bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
   template<class TypeHandle>
   bool Is(TypeHandle that) { return this->Is(*that); }
+
   bool Maybe(TypeImpl* that);
   template<class TypeHandle>
   bool Maybe(TypeHandle that) { return this->Maybe(*that); }
 
+  // Equivalent to Constant(value)->Is(this), but avoiding allocation.
+  bool Contains(i::Object* val);
+  bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
+
   // State-dependent versions of Of and Is that consider subtyping between
   // a constant and its map class.
-  static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region);
-  bool IsCurrently(TypeImpl* that);
+  static TypeHandle NowOf(i::Handle<i::Object> value, Region* region);
+  bool NowIs(TypeImpl* that);
   template<class TypeHandle>
-  bool IsCurrently(TypeHandle that)  { return this->IsCurrently(*that); }
+  bool NowIs(TypeHandle that)  { return this->NowIs(*that); }
+  bool NowContains(i::Object* val);
+  bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
 
   bool IsClass() { return Config::is_class(this); }
   bool IsConstant() { return Config::is_constant(this); }
@@ -382,29 +363,12 @@
     kUnionTag
   };
 
-  static Tagged* tagged_create(Tag tag, int size, Zone* zone) {
-    Tagged* tagged = new(zone) Tagged(size + 1, zone);
-    tagged->Add(reinterpret_cast<void*>(tag), zone);
-    tagged->AddBlock(NULL, size, zone);
-    return tagged;
-  }
-  static void tagged_shrink(Tagged* tagged, int size) {
-    tagged->Rewind(size + 1);
-  }
-  static Tag tagged_tag(Tagged* tagged) {
-    return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0)));
-  }
-  template<class T>
-  static T tagged_get(Tagged* tagged, int i) {
-    return reinterpret_cast<T>(tagged->at(i + 1));
-  }
-  template<class T>
-  static void tagged_set(Tagged* tagged, int i, T value) {
-    tagged->at(i + 1) = reinterpret_cast<void*>(value);
-  }
-  static int tagged_length(Tagged* tagged) {
-    return tagged->length() - 1;
-  }
+  static inline Tagged* tagged_create(Tag tag, int size, Zone* zone);
+  static inline void tagged_shrink(Tagged* tagged, int size);
+  static inline Tag tagged_tag(Tagged* tagged);
+  template<class T> static inline T tagged_get(Tagged* tagged, int i);
+  template<class T> static inline void tagged_set(Tagged* tagged, int i, T val);
+  static inline int tagged_length(Tagged* tagged);
 
  public:
   typedef TypeImpl<ZoneTypeConfig> Type;
@@ -413,100 +377,38 @@
   typedef i::Zone Region;
   template<class T> struct Handle { typedef T* type; };
 
-  static Type* handle(Type* type) { return type; }
-
-  static bool is(Type* type, Tag tag) {
-    return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
-  }
-
-  static bool is_bitset(Type* type) {
-    return reinterpret_cast<intptr_t>(type) & 1;
-  }
-  static bool is_tagged(Type* type) { return !is_bitset(type); }
-  static bool is_class(Type* type) { return is(type, kClassTag); }
-  static bool is_constant(Type* type) { return is(type, kConstantTag); }
-  static bool is_union(Type* type) { return is(type, kUnionTag); }
-  static bool tagged_is_union(Tagged* tagged) {
-    return is(from_tagged(tagged), kUnionTag);
-  }
-
-  static int as_bitset(Type* type) {
-    ASSERT(is_bitset(type));
-    return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1);
-  }
-  static Tagged* as_tagged(Type* type) {
-    ASSERT(is_tagged(type));
-    return reinterpret_cast<Tagged*>(type);
-  }
-  static i::Handle<i::Map> as_class(Type* type) {
-    ASSERT(is_class(type));
-    return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 1));
-  }
-  static i::Handle<i::Object> as_constant(Type* type) {
-    ASSERT(is_constant(type));
-    return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1));
-  }
-  static Unioned* as_union(Type* type) {
-    ASSERT(is_union(type));
-    return tagged_as_union(as_tagged(type));
-  }
-  static Unioned* tagged_as_union(Tagged* tagged) {
-    ASSERT(tagged_is_union(tagged));
-    return reinterpret_cast<Unioned*>(tagged);
-  }
-
-  static Type* from_bitset(int bitset) {
-    return reinterpret_cast<Type*>((bitset << 1) | 1);
-  }
-  static Type* from_bitset(int bitset, Zone* Zone) {
-    return from_bitset(bitset);
-  }
-  static Type* from_tagged(Tagged* tagged) {
-    return reinterpret_cast<Type*>(tagged);
-  }
-  static Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone) {
-    Tagged* tagged = tagged_create(kClassTag, 2, zone);
-    tagged_set(tagged, 0, lub);
-    tagged_set(tagged, 1, map.location());
-    return from_tagged(tagged);
-  }
-  static Type* from_constant(i::Handle<i::Object> value, int lub, Zone* zone) {
-    Tagged* tagged = tagged_create(kConstantTag, 2, zone);
-    tagged_set(tagged, 0, lub);
-    tagged_set(tagged, 1, value.location());
-    return from_tagged(tagged);
-  }
-  static Type* from_union(Unioned* unioned) {
-    return from_tagged(tagged_from_union(unioned));
-  }
-  static Tagged* tagged_from_union(Unioned* unioned) {
-    return reinterpret_cast<Tagged*>(unioned);
-  }
-
-  static Unioned* union_create(int size, Zone* zone) {
-    return tagged_as_union(tagged_create(kUnionTag, size, zone));
-  }
-  static void union_shrink(Unioned* unioned, int size) {
-    tagged_shrink(tagged_from_union(unioned), size);
-  }
-  static Type* union_get(Unioned* unioned, int i) {
-    Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
-    ASSERT(!is_union(type));
-    return type;
-  }
-  static void union_set(Unioned* unioned, int i, Type* type) {
-    ASSERT(!is_union(type));
-    tagged_set(tagged_from_union(unioned), i, type);
-  }
-  static int union_length(Unioned* unioned) {
-    return tagged_length(tagged_from_union(unioned));
-  }
-  static int lub_bitset(Type* type) {
-    ASSERT(is_class(type) || is_constant(type));
-    return static_cast<int>(tagged_get<intptr_t>(as_tagged(type), 0));
-  }
+  static inline Type* handle(Type* type);
+  static inline bool is(Type* type, Tag tag);
+  static inline bool is_bitset(Type* type);
+  static inline bool is_tagged(Type* type);
+  static inline bool is_class(Type* type);
+  static inline bool is_constant(Type* type);
+  static inline bool is_union(Type* type);
+  static inline bool tagged_is_union(Tagged* tagged);
+  static inline int as_bitset(Type* type);
+  static inline Tagged* as_tagged(Type* type);
+  static inline i::Handle<i::Map> as_class(Type* type);
+  static inline i::Handle<i::Object> as_constant(Type* type);
+  static inline Unioned* as_union(Type* type);
+  static inline Unioned* tagged_as_union(Tagged* tagged);
+  static inline Type* from_bitset(int bitset);
+  static inline Type* from_bitset(int bitset, Zone* zone);
+  static inline Type* from_tagged(Tagged* tagged);
+  static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone);
+  static inline Type* from_constant(
+      i::Handle<i::Object> value, int lub, Zone* zone);
+  static inline Type* from_union(Unioned* unioned);
+  static inline Tagged* tagged_from_union(Unioned* unioned);
+  static inline Unioned* union_create(int size, Zone* zone);
+  static inline void union_shrink(Unioned* unioned, int size);
+  static inline Type* union_get(Unioned* unioned, int i);
+  static inline void union_set(Unioned* unioned, int i, Type* type);
+  static inline int union_length(Unioned* unioned);
+  static inline int lub_bitset(Type* type);
 };
 
+typedef TypeImpl<ZoneTypeConfig> Type;
+
 
 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for
 // constants, or fixed arrays for unions.
@@ -517,73 +419,31 @@
   typedef i::Isolate Region;
   template<class T> struct Handle { typedef i::Handle<T> type; };
 
-  static i::Handle<Type> handle(Type* type) {
-    return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
-  }
-
-  static bool is_bitset(Type* type) { return type->IsSmi(); }
-  static bool is_class(Type* type) { return type->IsMap(); }
-  static bool is_constant(Type* type) { return type->IsBox(); }
-  static bool is_union(Type* type) { return type->IsFixedArray(); }
-
-  static int as_bitset(Type* type) {
-    return Smi::cast(type)->value();
-  }
-  static i::Handle<i::Map> as_class(Type* type) {
-    return i::handle(i::Map::cast(type));
-  }
-  static i::Handle<i::Object> as_constant(Type* type) {
-    i::Box* box = i::Box::cast(type);
-    return i::handle(box->value(), box->GetIsolate());
-  }
-  static i::Handle<Unioned> as_union(Type* type) {
-    return i::handle(i::FixedArray::cast(type));
-  }
-
-  static Type* from_bitset(int bitset) {
-    return Type::cast(i::Smi::FromInt(bitset));
-  }
-  static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) {
-    return i::handle(from_bitset(bitset), isolate);
-  }
-  static i::Handle<Type> from_class(
-      i::Handle<i::Map> map, int lub, Isolate* isolate) {
-    return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
-  }
-  static i::Handle<Type> from_constant(
-      i::Handle<i::Object> value, int lub, Isolate* isolate) {
-    i::Handle<Box> box = isolate->factory()->NewBox(value);
-    return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
-  }
-  static i::Handle<Type> from_union(i::Handle<Unioned> unioned) {
-    return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
-  }
-
-  static i::Handle<Unioned> union_create(int size, Isolate* isolate) {
-    return isolate->factory()->NewFixedArray(size);
-  }
-  static void union_shrink(i::Handle<Unioned> unioned, int size) {
-    unioned->Shrink(size);
-  }
-  static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) {
-    Type* type = static_cast<Type*>(unioned->get(i));
-    ASSERT(!is_union(type));
-    return i::handle(type, unioned->GetIsolate());
-  }
-  static void union_set(
-      i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
-    ASSERT(!is_union(*type));
-    unioned->set(i, *type);
-  }
-  static int union_length(i::Handle<Unioned> unioned) {
-    return unioned->length();
-  }
-  static int lub_bitset(Type* type) {
-    return 0;  // kNone, which causes recomputation.
-  }
+  static inline i::Handle<Type> handle(Type* type);
+  static inline bool is_bitset(Type* type);
+  static inline bool is_class(Type* type);
+  static inline bool is_constant(Type* type);
+  static inline bool is_union(Type* type);
+  static inline int as_bitset(Type* type);
+  static inline i::Handle<i::Map> as_class(Type* type);
+  static inline i::Handle<i::Object> as_constant(Type* type);
+  static inline i::Handle<Unioned> as_union(Type* type);
+  static inline Type* from_bitset(int bitset);
+  static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate);
+  static inline i::Handle<Type> from_class(
+      i::Handle<i::Map> map, int lub, Isolate* isolate);
+  static inline i::Handle<Type> from_constant(
+      i::Handle<i::Object> value, int lub, Isolate* isolate);
+  static inline i::Handle<Type> from_union(i::Handle<Unioned> unioned);
+  static inline i::Handle<Unioned> union_create(int size, Isolate* isolate);
+  static inline void union_shrink(i::Handle<Unioned> unioned, int size);
+  static inline i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i);
+  static inline void union_set(
+      i::Handle<Unioned> unioned, int i, i::Handle<Type> type);
+  static inline int union_length(i::Handle<Unioned> unioned);
+  static inline int lub_bitset(Type* type);
 };
 
-typedef TypeImpl<ZoneTypeConfig> Type;
 typedef TypeImpl<HeapTypeConfig> HeapType;
 
 
@@ -643,7 +503,6 @@
 
 typedef BoundsImpl<ZoneTypeConfig> Bounds;
 
-
 } }  // namespace v8::internal
 
 #endif  // V8_TYPES_H_
diff --git a/src/typing.cc b/src/typing.cc
index 2a581e2..dd99d19 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -83,7 +83,7 @@
 
 
 Effect AstTyper::ObservedOnStack(Object* value) {
-  Type* lower = Type::OfCurrently(handle(value, isolate()), zone());
+  Type* lower = Type::NowOf(handle(value, isolate()), zone());
   return Effect(Bounds(lower, Type::Any(zone())));
 }
 
diff --git a/src/utils.h b/src/utils.h
index 7538226..845cb75 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -43,10 +43,10 @@
 // ----------------------------------------------------------------------------
 // General helper functions
 
-#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
+#define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
 
-// Returns true iff x is a power of 2 (or zero). Cannot be used with the
-// maximally negative value of the type T (the -1 overflows).
+// Returns true iff x is a power of 2. Cannot be used with the maximally
+// negative value of the type T (the -1 overflows).
 template <typename T>
 inline bool IsPowerOf2(T x) {
   return IS_POWER_OF_TWO(x);
@@ -56,7 +56,6 @@
 // X must be a power of 2.  Returns the number of trailing zeros.
 inline int WhichPowerOf2(uint32_t x) {
   ASSERT(IsPowerOf2(x));
-  ASSERT(x != 0);
   int bits = 0;
 #ifdef DEBUG
   int original_x = x;
diff --git a/src/v8.h b/src/v8.h
index d3f5a9c..26cb5a7 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -66,6 +66,7 @@
 #include "mark-compact-inl.h"
 #include "log-inl.h"
 #include "handles-inl.h"
+#include "types-inl.h"
 #include "zone-inl.h"
 
 namespace v8 {
@@ -135,6 +136,4 @@
 
 } }  // namespace v8::internal
 
-namespace i = v8::internal;
-
 #endif  // V8_V8_H_
diff --git a/src/v8globals.h b/src/v8globals.h
index e6cd94d..cb29614 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -565,4 +565,6 @@
 
 } }  // namespace v8::internal
 
+namespace i = v8::internal;
+
 #endif  // V8_V8GLOBALS_H_
diff --git a/src/v8utils.h b/src/v8utils.h
index 058b153..32c5c2e 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -215,6 +215,11 @@
 #undef STOS
 #endif
 
+#if defined(MEMORY_SANITIZER)
+  // MemorySanitizer does not understand inline assembly.
+#undef STOS
+#endif
+
 #if defined(__GNUC__) && defined(STOS)
   asm volatile(
       "cld;"
diff --git a/src/version.cc b/src/version.cc
index 6fc3a06..6f804d6 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     26
-#define BUILD_NUMBER      2
+#define BUILD_NUMBER      3
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index ac6d370..a64d3e2 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1205,11 +1205,64 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
+  Register dividend = ToRegister(instr->dividend());
+  Register divisor = ToRegister(instr->divisor());
+  Register remainder = ToRegister(instr->temp());
+  Register result = ToRegister(instr->result());
+  ASSERT(dividend.is(rax));
+  ASSERT(remainder.is(rdx));
+  ASSERT(result.is(rax));
+  ASSERT(!divisor.is(rax));
+  ASSERT(!divisor.is(rdx));
+
+  // Check for x / 0.
+  if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+    __ testl(divisor, divisor);
+    DeoptimizeIf(zero, instr->environment());
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    Label dividend_not_zero;
+    __ testl(dividend, dividend);
+    __ j(not_zero, &dividend_not_zero, Label::kNear);
+    __ testl(divisor, divisor);
+    DeoptimizeIf(sign, instr->environment());
+    __ bind(&dividend_not_zero);
+  }
+
+  // Check for (kMinInt / -1).
+  if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+    Label dividend_not_min_int;
+    __ cmpl(dividend, Immediate(kMinInt));
+    __ j(not_zero, &dividend_not_min_int, Label::kNear);
+    __ cmpl(divisor, Immediate(-1));
+    DeoptimizeIf(zero, instr->environment());
+    __ bind(&dividend_not_min_int);
+  }
+
+  // Sign extend to rdx (= remainder).
+  __ cdq();
+  __ idivl(divisor);
+
+  Label done;
+  __ testl(remainder, remainder);
+  __ j(zero, &done, Label::kNear);
+  __ xorl(remainder, divisor);
+  __ sarl(remainder, Immediate(31));
+  __ addl(result, remainder);
+  __ bind(&done);
+}
+
+
 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
   Register dividend = ToRegister(instr->dividend());
   int32_t divisor = instr->divisor();
   Register result = ToRegister(instr->result());
-  ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+  ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
   ASSERT(!result.is(dividend));
 
   // Check for (0 / -x) that will produce negative zero.
@@ -1272,15 +1325,15 @@
 }
 
 
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
 void LCodeGen::DoDivI(LDivI* instr) {
   HBinaryOperation* hdiv = instr->hydrogen();
-  Register dividend = ToRegister(instr->left());
-  Register divisor = ToRegister(instr->right());
+  Register dividend = ToRegister(instr->dividend());
+  Register divisor = ToRegister(instr->divisor());
   Register remainder = ToRegister(instr->temp());
-  Register result = ToRegister(instr->result());
   ASSERT(dividend.is(rax));
   ASSERT(remainder.is(rdx));
-  ASSERT(result.is(rax));
+  ASSERT(ToRegister(instr->result()).is(rax));
   ASSERT(!divisor.is(rax));
   ASSERT(!divisor.is(rdx));
 
@@ -1314,15 +1367,7 @@
   __ cdq();
   __ idivl(divisor);
 
-  if (hdiv->IsMathFloorOfDiv()) {
-    Label done;
-    __ testl(remainder, remainder);
-    __ j(zero, &done, Label::kNear);
-    __ xorl(remainder, divisor);
-    __ sarl(remainder, Immediate(31));
-    __ addl(result, remainder);
-    __ bind(&done);
-  } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+  if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     // Deoptimize if remainder is not 0.
     __ testl(remainder, remainder);
     DeoptimizeIf(not_zero, instr->environment());
@@ -1775,6 +1820,7 @@
 
   if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
     if (right->IsConstantOperand()) {
+      ASSERT(!target_rep.IsSmi());  // No support for smi-immediates.
       int32_t offset = ToInteger32(LConstantOperand::cast(right));
       if (is_p) {
         __ leap(ToRegister(instr->result()),
@@ -1793,6 +1839,7 @@
     }
   } else {
     if (right->IsConstantOperand()) {
+      ASSERT(!target_rep.IsSmi());  // No support for smi-immediates.
       if (is_p) {
         __ addp(ToRegister(left),
                 Immediate(ToInteger32(LConstantOperand::cast(right))));
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 9d99e91..d1c7731 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1310,7 +1310,7 @@
 }
 
 
-LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
   ASSERT(instr->representation().IsSmiOrInteger32());
   ASSERT(instr->left()->representation().Equals(instr->representation()));
   ASSERT(instr->right()->representation().Equals(instr->representation()));
@@ -1322,8 +1322,7 @@
   if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
       instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
       instr->CheckFlag(HValue::kCanOverflow) ||
-      (!instr->IsMathFloorOfDiv() &&
-       !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+      !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     result = AssignEnvironment(result);
   }
   return result;
@@ -1387,13 +1386,31 @@
 }
 
 
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+  ASSERT(instr->representation().IsSmiOrInteger32());
+  ASSERT(instr->left()->representation().Equals(instr->representation()));
+  ASSERT(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseFixed(instr->left(), rax);
+  LOperand* divisor = UseRegister(instr->right());
+  LOperand* temp = FixedTemp(rdx);
+  LInstruction* result = DefineFixed(new(zone()) LFlooringDivI(
+          dividend, divisor, temp), rax);
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      instr->CheckFlag(HValue::kCanOverflow)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
   if (instr->RightIsPowerOf2()) {
     return DoFlooringDivByPowerOf2I(instr);
   } else if (instr->right()->IsConstant()) {
     return DoFlooringDivByConstI(instr);
   } else {
-    return DoDivI(instr);
+    return DoFlooringDivI(instr);
   }
 }
 
@@ -1515,14 +1532,19 @@
     ASSERT(instr->right()->representation().Equals(instr->representation()));
     LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
     HValue* right_candidate = instr->BetterRightOperand();
-    LOperand* right = use_lea
-        ? UseRegisterOrConstantAtStart(right_candidate)
-        : UseOrConstantAtStart(right_candidate);
+    LOperand* right;
+    if (instr->representation().IsSmi()) {
+      // We cannot add a tagged immediate to a tagged value,
+      // so we request it in a register.
+      right = UseRegisterAtStart(right_candidate);
+    } else {
+      right = use_lea ? UseRegisterOrConstantAtStart(right_candidate)
+                      : UseOrConstantAtStart(right_candidate);
+    }
     LAddI* add = new(zone()) LAddI(left, right);
     bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
-    LInstruction* result = use_lea
-        ? DefineAsRegister(add)
-        : DefineSameAsFirst(add);
+    LInstruction* result = use_lea ? DefineAsRegister(add)
+                                   : DefineSameAsFirst(add);
     if (can_overflow) {
       result = AssignEnvironment(result);
     }
@@ -1804,26 +1826,21 @@
 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
   Representation from = instr->from();
   Representation to = instr->to();
+  HValue* val = instr->value();
   if (from.IsSmi()) {
     if (to.IsTagged()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return DefineSameAsFirst(new(zone()) LDummyUse(value));
     }
     from = Representation::Tagged();
   }
-  // Only mark conversions that might need to allocate as calling rather than
-  // all changes. This makes simple, non-allocating conversion not have to force
-  // building a stack frame.
   if (from.IsTagged()) {
     if (to.IsDouble()) {
-      LOperand* value = UseRegister(instr->value());
-      LInstruction* res = DefineAsRegister(new(zone()) LNumberUntagD(value));
-      if (!instr->value()->representation().IsSmi()) {
-        res = AssignEnvironment(res);
-      }
-      return res;
+      LOperand* value = UseRegister(val);
+      LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
+      if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+      return result;
     } else if (to.IsSmi()) {
-      HValue* val = instr->value();
       LOperand* value = UseRegister(val);
       if (val->type().IsSmi()) {
         return DefineSameAsFirst(new(zone()) LDummyUse(value));
@@ -1831,78 +1848,73 @@
       return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      HValue* val = instr->value();
-      LOperand* value = UseRegister(val);
       if (val->type().IsSmi() || val->representation().IsSmi()) {
+        LOperand* value = UseRegister(val);
         return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
       } else {
+        LOperand* value = UseRegister(val);
         bool truncating = instr->CanTruncateToInt32();
         LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
-        LInstruction* res =
+        LInstruction* result =
             DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
-        if (!instr->value()->representation().IsSmi()) {
+        if (!val->representation().IsSmi()) {
           // Note: Only deopts in deferred code.
-          res = AssignEnvironment(res);
+          result = AssignEnvironment(result);
         }
-        return res;
+        return result;
       }
     }
   } else if (from.IsDouble()) {
     if (to.IsTagged()) {
       info()->MarkAsDeferredCalling();
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       LOperand* temp = TempRegister();
-
-      // Make sure that temp and result_temp are different registers.
       LUnallocated* result_temp = TempRegister();
       LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
       return AssignPointerMap(Define(result, result_temp));
     } else if (to.IsSmi()) {
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       return AssignEnvironment(
           DefineAsRegister(new(zone()) LDoubleToSmi(value)));
     } else {
       ASSERT(to.IsInteger32());
-      LOperand* value = UseRegister(instr->value());
+      LOperand* value = UseRegister(val);
       LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
-      if (!instr->CanTruncateToInt32()) {
-        result = AssignEnvironment(result);
-      }
+      if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
       return result;
     }
   } else if (from.IsInteger32()) {
     info()->MarkAsDeferredCalling();
     if (to.IsTagged()) {
-      HValue* val = instr->value();
-      LOperand* value = UseRegister(val);
       if (!instr->CheckFlag(HValue::kCanOverflow)) {
+        LOperand* value = UseRegister(val);
         return DefineAsRegister(new(zone()) LSmiTag(value));
       } else if (val->CheckFlag(HInstruction::kUint32)) {
+        LOperand* value = UseRegister(val);
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = FixedTemp(xmm1);
         LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
         return AssignPointerMap(DefineSameAsFirst(result));
       } else {
+        LOperand* value = UseRegister(val);
         LNumberTagI* result = new(zone()) LNumberTagI(value);
         return AssignPointerMap(DefineSameAsFirst(result));
       }
     } else if (to.IsSmi()) {
-      HValue* val = instr->value();
       LOperand* value = UseRegister(val);
       LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
       if (instr->CheckFlag(HValue::kCanOverflow)) {
-        ASSERT(val->CheckFlag(HValue::kUint32));
         result = AssignEnvironment(result);
       }
       return result;
     } else {
-      if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+      ASSERT(to.IsDouble());
+      if (val->CheckFlag(HInstruction::kUint32)) {
         LOperand* temp = FixedTemp(xmm1);
         return DefineAsRegister(
-            new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
+            new(zone()) LUint32ToDouble(UseRegister(val), temp));
       } else {
-        ASSERT(to.IsDouble());
-        LOperand* value = Use(instr->value());
+        LOperand* value = Use(val);
         return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
       }
     }
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 9d9ac1e..1c8bb0d 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -97,6 +97,7 @@
   V(Dummy)                                      \
   V(FlooringDivByConstI)                        \
   V(FlooringDivByPowerOf2I)                     \
+  V(FlooringDivI)                               \
   V(ForInCacheArray)                            \
   V(ForInPrepareMap)                            \
   V(FunctionLiteral)                            \
@@ -732,14 +733,14 @@
 
 class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
  public:
-  LDivI(LOperand* left, LOperand* right, LOperand* temp) {
-    inputs_[0] = left;
-    inputs_[1] = right;
+  LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
     temps_[0] = temp;
   }
 
-  LOperand* left() { return inputs_[0]; }
-  LOperand* right() { return inputs_[1]; }
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
@@ -794,6 +795,23 @@
 };
 
 
+class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+  LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
+    temps_[0] = temp;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
 class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
  public:
   LMulI(LOperand* left, LOperand* right) {
@@ -2681,12 +2699,13 @@
   LInstruction* DoMathClz32(HUnaryMathOperation* instr);
   LInstruction* DoDivByPowerOf2I(HDiv* instr);
   LInstruction* DoDivByConstI(HDiv* instr);
-  LInstruction* DoDivI(HBinaryOperation* instr);
+  LInstruction* DoDivI(HDiv* instr);
   LInstruction* DoModByPowerOf2I(HMod* instr);
   LInstruction* DoModByConstI(HMod* instr);
   LInstruction* DoModI(HMod* instr);
   LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
   LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+  LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
 
  private:
   enum Status {