Version 3.25.8 (based on bleeding_edge revision r19840)

Fix HIsSmiAndBranch::KnownSuccessorBlock() by deleting it (Chromium issue 351320).

Fix handling of polymorphic array accesses with constant index (Chromium issue 351319).

Fix lazy deopt after tagged binary ops (Chromium issue 350434).

MIPS: Cleanup some of the range uses in ModI/DivI (issue 3204).

Fix issue with getOwnPropertySymbols and hidden properties (Chromium issue 350864).

Cleanup some of the range uses in ModI/DivI (issue 3204).

PromiseCoerce should ignore primitive values (Chromium issue 347095).

Use a per-isolate cache for the date object JS bits (Chromium issue 348856).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@19841 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/a64/assembler-a64.h b/src/a64/assembler-a64.h
index cb018a4..999b01a 100644
--- a/src/a64/assembler-a64.h
+++ b/src/a64/assembler-a64.h
@@ -264,36 +264,60 @@
   static const int kMaxNumRegisters = kNumberOfFPRegisters;
 
   // Crankshaft can use all the FP registers except:
-  //   - d29 which is used in crankshaft as a double scratch register
-  //   - d30 which is used to keep the 0 double value
+  //   - d15 which is used to keep the 0 double value
+  //   - d30 which is used in crankshaft as a double scratch register
   //   - d31 which is used in the MacroAssembler as a double scratch register
-  static const int kNumReservedRegisters = 3;
-  static const int kMaxNumAllocatableRegisters =
-      kNumberOfFPRegisters - kNumReservedRegisters;
-  static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
-  static const RegList kAllocatableFPRegisters =
-      (1 << kMaxNumAllocatableRegisters) - 1;
+  static const unsigned kAllocatableLowRangeBegin = 0;
+  static const unsigned kAllocatableLowRangeEnd = 14;
+  static const unsigned kAllocatableHighRangeBegin = 16;
+  static const unsigned kAllocatableHighRangeEnd = 29;
 
-  static FPRegister FromAllocationIndex(int index) {
-    ASSERT((index >= 0) && (index < NumAllocatableRegisters()));
-    return from_code(index);
+  static const RegList kAllocatableFPRegisters = 0x3fff7fff;
+
+  // Gap between low and high ranges.
+  static const int kAllocatableRangeGapSize =
+      (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1;
+
+  static const int kMaxNumAllocatableRegisters =
+      (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) +
+      (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1);
+  static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
+
+  // Return true if the register is one that crankshaft can allocate.
+  bool IsAllocatable() const {
+    return (Bit() & kAllocatableFPRegisters) != 0;
+  }
+
+  static FPRegister FromAllocationIndex(unsigned int index) {
+    ASSERT(index < static_cast<unsigned>(NumAllocatableRegisters()));
+
+    return (index <= kAllocatableLowRangeEnd)
+        ? from_code(index)
+        : from_code(index + kAllocatableRangeGapSize);
   }
 
   static const char* AllocationIndexToString(int index) {
     ASSERT((index >= 0) && (index < NumAllocatableRegisters()));
+    ASSERT((kAllocatableLowRangeBegin == 0) &&
+           (kAllocatableLowRangeEnd == 14) &&
+           (kAllocatableHighRangeBegin == 16) &&
+           (kAllocatableHighRangeEnd == 29));
     const char* const names[] = {
       "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
-      "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
+      "d8", "d9", "d10", "d11", "d12", "d13", "d14",
       "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
-      "d24", "d25", "d26", "d27", "d28",
+      "d24", "d25", "d26", "d27", "d28", "d29"
     };
     return names[index];
   }
 
   static int ToAllocationIndex(FPRegister reg) {
-    int code = reg.code();
-    ASSERT(code < NumAllocatableRegisters());
-    return code;
+    ASSERT(reg.IsAllocatable());
+    unsigned code = reg.code();
+
+    return (code <= kAllocatableLowRangeEnd)
+        ? code
+        : code - kAllocatableRangeGapSize;
   }
 
   static FPRegister from_code(int code) {
@@ -375,10 +399,10 @@
 ALIAS_REGISTER(Register, xzr, x31);
 ALIAS_REGISTER(Register, wzr, w31);
 
-// Crankshaft double scratch register.
-ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29);
 // Keeps the 0 double value.
-ALIAS_REGISTER(FPRegister, fp_zero, d30);
+ALIAS_REGISTER(FPRegister, fp_zero, d15);
+// Crankshaft double scratch register.
+ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d30);
 // MacroAssembler double scratch register.
 ALIAS_REGISTER(FPRegister, fp_scratch, d31);
 
@@ -822,9 +846,6 @@
     return SizeOfCodeGeneratedSince(label) / kInstructionSize;
   }
 
-  // TODO(all): Initialize these constants related with code patching.
-  // TODO(all): Set to -1 to hopefully crash if mistakenly used.
-
   // Number of instructions generated for the return sequence in
   // FullCodeGenerator::EmitReturnSequence.
   static const int kJSRetSequenceInstructions = 7;
diff --git a/src/a64/builtins-a64.cc b/src/a64/builtins-a64.cc
index 2c5fe89..c49133d 100644
--- a/src/a64/builtins-a64.cc
+++ b/src/a64/builtins-a64.cc
@@ -1042,7 +1042,7 @@
         (1 << SharedFunctionInfo::kNative),
         &shift_arguments);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     Register receiver = x2;
     __ Sub(scratch1, argc, 1);
     __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeInBytesLog2));
@@ -1244,7 +1244,7 @@
     // Do not transform the receiver for native functions.
     __ Tbnz(x10, SharedFunctionInfo::kNative, &push_receiver);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ JumpIfSmi(receiver, &convert_receiver_to_object);
     __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_receiver);
     __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex,
diff --git a/src/a64/code-stubs-a64.cc b/src/a64/code-stubs-a64.cc
index 3ed79a4..7e0d708 100644
--- a/src/a64/code-stubs-a64.cc
+++ b/src/a64/code-stubs-a64.cc
@@ -1182,7 +1182,6 @@
     if (exponent_type_ == ON_STACK) {
       FPRegister  half_double = d3;
       FPRegister  minus_half_double = d4;
-      FPRegister  zero_double = d5;
       // Detect square root case. Crankshaft detects constant +/-0.5 at compile
       // time and uses DoMathPowHalf instead. We then skip this check for
       // non-constant cases of +/-0.5 as these hardly occur.
@@ -1215,8 +1214,7 @@
       // where base is -INFINITY or -0.
 
       // Add +0 to base. This has no effect other than turning -0 into +0.
-      __ Fmov(zero_double, 0.0);
-      __ Fadd(base_double, base_double, zero_double);
+      __ Fadd(base_double, base_double, fp_zero);
       // The operation -0+0 results in +0 in all cases except where the
       // FPCR rounding mode is 'round towards minus infinity' (RM). The
       // A64 simulator does not currently simulate FPCR (where the rounding
@@ -1224,18 +1222,17 @@
       if (masm->emit_debug_code()) {
         UseScratchRegisterScope temps(masm);
         Register temp = temps.AcquireX();
-        //  d5  zero_double   The value +0.0 as a double.
-        __ Fneg(scratch0_double, zero_double);
+        __ Fneg(scratch0_double, fp_zero);
         // Verify that we correctly generated +0.0 and -0.0.
         //  bits(+0.0) = 0x0000000000000000
         //  bits(-0.0) = 0x8000000000000000
-        __ Fmov(temp, zero_double);
+        __ Fmov(temp, fp_zero);
         __ CheckRegisterIsClear(temp, kCouldNotGenerateZero);
         __ Fmov(temp, scratch0_double);
         __ Eor(temp, temp, kDSignMask);
         __ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero);
         // Check that -0.0 + 0.0 == +0.0.
-        __ Fadd(scratch0_double, scratch0_double, zero_double);
+        __ Fadd(scratch0_double, scratch0_double, fp_zero);
         __ Fmov(temp, scratch0_double);
         __ CheckRegisterIsClear(temp, kExpectedPositiveZero);
       }
@@ -1793,6 +1790,9 @@
 
   ProfileEntryHookStub::MaybeCallEntryHook(masm);
 
+  // Set up the reserved register for 0.0.
+  __ Fmov(fp_zero, 0.0);
+
   // Build an entry frame (see layout below).
   Isolate* isolate = masm->isolate();
 
@@ -2303,7 +2303,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // Stack layout on entry.
   //  jssp[0]:  number of parameters (tagged)
   //  jssp[8]:  address of receiver argument
@@ -2333,7 +2333,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   // Stack layout on entry.
   //  jssp[0]:  number of parameters (tagged)
   //  jssp[8]:  address of receiver argument
@@ -2419,7 +2419,8 @@
 
   // 2. Add the size of the backing store and arguments object.
   __ Add(size, size, Operand(arg_count, LSL, kPointerSizeLog2));
-  __ Add(size, size, FixedArray::kHeaderSize + Heap::kArgumentsObjectSize);
+  __ Add(size, size,
+         FixedArray::kHeaderSize + Heap::kSloppyArgumentsObjectSize);
 
   // Do the allocation of all three objects in one go. Assign this to x0, as it
   // will be returned to the caller.
@@ -2446,8 +2447,9 @@
   __ Ldr(global_ctx, FieldMemOperand(global_object,
                                      GlobalObject::kNativeContextOffset));
 
-  __ Ldr(args_offset, ContextMemOperand(global_ctx,
-                                        Context::ARGUMENTS_BOILERPLATE_INDEX));
+  __ Ldr(args_offset,
+         ContextMemOperand(global_ctx,
+                           Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX));
   __ Ldr(aliased_args_offset,
          ContextMemOperand(global_ctx,
                            Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX));
@@ -2486,7 +2488,7 @@
   //   x14  recv_arg      pointer to receiver arguments
 
   Register elements = x5;
-  __ Add(elements, alloc_obj, Heap::kArgumentsObjectSize);
+  __ Add(elements, alloc_obj, Heap::kSloppyArgumentsObjectSize);
   __ Str(elements, FieldMemOperand(alloc_obj, JSObject::kElementsOffset));
 
   // Initialize parameter map. If there are no mapped arguments, we're done.
@@ -2498,7 +2500,7 @@
   __ CmovX(backing_store, elements, eq);
   __ B(eq, &skip_parameter_map);
 
-  __ LoadRoot(x10, Heap::kNonStrictArgumentsElementsMapRootIndex);
+  __ LoadRoot(x10, Heap::kSloppyArgumentsElementsMapRootIndex);
   __ Str(x10, FieldMemOperand(elements, FixedArray::kMapOffset));
   __ Add(x10, mapped_params, 2);
   __ SmiTag(x10);
@@ -2651,7 +2653,7 @@
   __ Add(size, param_count, FixedArray::kHeaderSize / kPointerSize);
   __ Cmp(param_count, 0);
   __ CzeroX(size, eq);
-  __ Add(size, size, Heap::kArgumentsObjectSizeStrict / kPointerSize);
+  __ Add(size, size, Heap::kStrictArgumentsObjectSize / kPointerSize);
 
   // Do the allocation of both objects in one go. Assign this to x0, as it will
   // be returned to the caller.
@@ -2668,7 +2670,7 @@
                                      GlobalObject::kNativeContextOffset));
   __ Ldr(args_offset,
          ContextMemOperand(global_ctx,
-                           Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX));
+                           Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX));
 
   //   x0   alloc_obj         pointer to allocated objects: parameter array and
   //                          arguments object
@@ -2695,7 +2697,7 @@
   // Set up the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
   Register elements = x5;
-  __ Add(elements, alloc_obj, Heap::kArgumentsObjectSizeStrict);
+  __ Add(elements, alloc_obj, Heap::kStrictArgumentsObjectSize);
   __ Str(elements, FieldMemOperand(alloc_obj, JSObject::kElementsOffset));
   __ LoadRoot(x10, Heap::kFixedArrayMapRootIndex);
   __ Str(x10, FieldMemOperand(elements, FixedArray::kMapOffset));
@@ -3405,7 +3407,7 @@
       __ Tbnz(w4, SharedFunctionInfo::kNative, &cont);
     }
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ Peek(x3, argc_ * kPointerSize);
 
     if (NeedsChecks()) {
@@ -4939,8 +4941,7 @@
 
 
 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
-  // TODO(jbramley): The ARM code leaves the (shifted) offset in r1. Why?
-  CEntryStub ces(1, kSaveFPRegs);
+  CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
   __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
   int parameter_count_offset =
       StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
diff --git a/src/a64/codegen-a64.cc b/src/a64/codegen-a64.cc
index f008494..6a2fa5b 100644
--- a/src/a64/codegen-a64.cc
+++ b/src/a64/codegen-a64.cc
@@ -546,13 +546,11 @@
   // Continue the common case first. 'mi' tests N == 1.
   __ B(&result_is_finite_non_zero, mi);
 
-  // TODO(jbramley): Add (and use) a zero D register for A64.
   // TODO(jbramley): Consider adding a +infinity register for A64.
   __ Ldr(double_temp2, ExpConstant(constants, 2));    // Synthesize +infinity.
-  __ Fsub(double_temp1, double_temp1, double_temp1);  // Synthesize +0.0.
 
   // Select between +0.0 and +infinity. 'lo' tests C == 0.
-  __ Fcsel(result, double_temp1, double_temp2, lo);
+  __ Fcsel(result, fp_zero, double_temp2, lo);
   // Select between {+0.0 or +infinity} and input. 'vc' tests V == 0.
   __ Fcsel(result, result, input, vc);
   __ B(&done);
diff --git a/src/a64/deoptimizer-a64.cc b/src/a64/deoptimizer-a64.cc
index af1a48c..58bd2d9 100644
--- a/src/a64/deoptimizer-a64.cc
+++ b/src/a64/deoptimizer-a64.cc
@@ -149,7 +149,7 @@
 
   // Save all allocatable floating point registers.
   CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSize,
-                                0, FPRegister::NumAllocatableRegisters() - 1);
+                                FPRegister::kAllocatableFPRegisters);
   __ PushCPURegList(saved_fp_registers);
 
   // We save all the registers expcept jssp, sp and lr.
diff --git a/src/a64/full-codegen-a64.cc b/src/a64/full-codegen-a64.cc
index 7760530..369d8ac 100644
--- a/src/a64/full-codegen-a64.cc
+++ b/src/a64/full-codegen-a64.cc
@@ -143,10 +143,10 @@
   }
 #endif
 
-  // Classic mode functions and builtins need to replace the receiver with the
+  // Sloppy mode functions and builtins need to replace the receiver with the
   // global proxy when called as functions (without an explicit receiver
   // object).
-  if (info->is_classic_mode() && !info->is_native()) {
+  if (info->strict_mode() == SLOPPY && !info->is_native()) {
     Label ok;
     int receiver_offset = info->scope()->num_parameters() * kXRegSizeInBytes;
     __ Peek(x10, receiver_offset);
@@ -249,12 +249,12 @@
     // The stub will rewrite receiver and parameter count if the previous
     // stack frame was an arguments adapter frame.
     ArgumentsAccessStub::Type type;
-    if (!is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       type = ArgumentsAccessStub::NEW_STRICT;
     } else if (function()->has_duplicate_parameters()) {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+      type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
     } else {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+      type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
     ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
@@ -279,7 +279,7 @@
       if (scope()->is_function_scope() && scope()->function() != NULL) {
         VariableDeclaration* function = scope()->function();
         ASSERT(function->proxy()->var()->mode() == CONST ||
-               function->proxy()->var()->mode() == CONST_HARMONY);
+               function->proxy()->var()->mode() == CONST_LEGACY);
         ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
         VisitVariableDeclaration(function);
       }
@@ -790,7 +790,7 @@
   VariableProxy* proxy = declaration->proxy();
   VariableMode mode = declaration->mode();
   Variable* variable = proxy->var();
-  bool hole_init = (mode == CONST) || (mode == CONST_HARMONY) || (mode == LET);
+  bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
 
   switch (variable->location()) {
     case Variable::UNALLOCATED:
@@ -1320,7 +1320,7 @@
       !pretenure &&
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
-    FastNewClosureStub stub(info->language_mode(), info->is_generator());
+    FastNewClosureStub stub(info->strict_mode(), info->is_generator());
     __ Mov(x2, Operand(info));
     __ CallStub(&stub);
   } else {
@@ -1350,7 +1350,7 @@
   Scope* s = scope();
   while (s != NULL) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ Ldr(temp, ContextMemOperand(current, Context::EXTENSION_INDEX));
         __ Cbnz(temp, slow);
@@ -1362,7 +1362,7 @@
     }
     // If no outer scope calls eval, we do not need to check more
     // context extensions.
-    if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break;
+    if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
     s = s->outer_scope();
   }
 
@@ -1400,7 +1400,7 @@
 
   for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ Ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
         __ Cbnz(temp, slow);
@@ -1436,13 +1436,12 @@
   } else if (var->mode() == DYNAMIC_LOCAL) {
     Variable* local = var->local_if_not_shadowed();
     __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow));
-    if (local->mode() == LET ||
-        local->mode() == CONST ||
-        local->mode() == CONST_HARMONY) {
+    if (local->mode() == LET || local->mode() == CONST ||
+        local->mode() == CONST_LEGACY) {
       __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done);
-      if (local->mode() == CONST) {
+      if (local->mode() == CONST_LEGACY) {
         __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
-      } else {  // LET || CONST_HARMONY
+      } else {  // LET || CONST
         __ Mov(x0, Operand(var->name()));
         __ Push(x0);
         __ CallRuntime(Runtime::kThrowReferenceError, 1);
@@ -1509,7 +1508,7 @@
           // Check that we always have valid source position.
           ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
           ASSERT(proxy->position() != RelocInfo::kNoPosition);
-          skip_init_check = var->mode() != CONST &&
+          skip_init_check = var->mode() != CONST_LEGACY &&
               var->initializer_position() < proxy->position();
         }
 
@@ -1518,7 +1517,7 @@
           GetVar(x0, var);
           Label done;
           __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done);
-          if (var->mode() == LET || var->mode() == CONST_HARMONY) {
+          if (var->mode() == LET || var->mode() == CONST) {
             // Throw a reference error when using an uninitialized let/const
             // binding in harmony mode.
             __ Mov(x0, Operand(var->name()));
@@ -1527,7 +1526,7 @@
             __ Bind(&done);
           } else {
             // Uninitalized const bindings outside of harmony mode are unholed.
-            ASSERT(var->mode() == CONST);
+            ASSERT(var->mode() == CONST_LEGACY);
             __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
             __ Bind(&done);
           }
@@ -2136,7 +2135,7 @@
       VisitForAccumulatorValue(prop->key());
       __ Mov(x1, x0);
       __ Pop(x2, x0);
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic);
@@ -2161,9 +2160,9 @@
 
 
 void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, LanguageMode mode) {
+    Handle<String> name, StrictMode strict_mode) {
   __ Mov(x11, Operand(name));
-  __ Mov(x10, Operand(Smi::FromInt(mode)));
+  __ Mov(x10, Operand(Smi::FromInt(strict_mode)));
   // jssp[0]  : mode.
   // jssp[8]  : name.
   // jssp[16] : context.
@@ -2182,7 +2181,7 @@
     __ Ldr(x1, GlobalObjectMemOperand());
     CallStoreIC();
 
-  } else if (op == Token::INIT_CONST) {
+  } else if (op == Token::INIT_CONST_LEGACY) {
     // Const initializers need a write barrier.
     ASSERT(!var->IsParameter());  // No const parameters.
     if (var->IsLookupSlot()) {
@@ -2203,7 +2202,7 @@
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       Label assign;
@@ -2218,11 +2217,11 @@
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
 
-  } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
+  } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     // Assignment to var or initializing assignment to let/const
     // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       MemOperand location = VarOperand(var, x1);
@@ -2266,7 +2265,7 @@
   // TODO(all): Could we pass this in registers rather than on the stack?
   __ Pop(x1, x2);  // Key and object holding the property.
 
-  Handle<Code> ic = is_classic_mode()
+  Handle<Code> ic = strict_mode() == SLOPPY
       ? isolate()->builtins()->KeyedStoreIC_Initialize()
       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
   CallIC(ic, expr->AssignmentFeedbackId());
@@ -2320,7 +2319,7 @@
       PrepareForBailout(callee, NO_REGISTERS);
     }
     // Push undefined as receiver. This is patched in the method prologue if it
-    // is a classic mode method.
+    // is a sloppy mode method.
     __ Push(isolate()->factory()->undefined_value());
     flags = NO_CALL_FUNCTION_FLAGS;
   } else {
@@ -2441,7 +2440,7 @@
   __ Push(x10, x11);
 
   // Prepare to push the language mode.
-  __ Mov(x10, Operand(Smi::FromInt(language_mode())));
+  __ Mov(x10, Operand(Smi::FromInt(strict_mode())));
   // Prepare to push the start position of the scope the calls resides in.
   __ Mov(x11, Operand(Smi::FromInt(scope()->start_position())));
 
@@ -3878,9 +3877,7 @@
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
-            ? kNonStrictMode : kStrictMode;
-        __ Mov(x10, Operand(Smi::FromInt(strict_mode_flag)));
+        __ Mov(x10, Operand(Smi::FromInt(strict_mode())));
         __ Push(x10);
         __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
         context()->Plug(x0);
@@ -3888,11 +3885,11 @@
         Variable* var = proxy->var();
         // Delete of an unqualified identifier is disallowed in strict mode
         // but "delete this" is allowed.
-        ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
+        ASSERT(strict_mode() == SLOPPY || var->is_this());
         if (var->IsUnallocated()) {
           __ Ldr(x12, GlobalObjectMemOperand());
           __ Mov(x11, Operand(var->name()));
-          __ Mov(x10, Operand(Smi::FromInt(kNonStrictMode)));
+          __ Mov(x10, Operand(Smi::FromInt(SLOPPY)));
           __ Push(x12, x11, x10);
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
           context()->Plug(x0);
@@ -4149,7 +4146,7 @@
     case KEYED_PROPERTY: {
       __ Pop(x1);  // Key.
       __ Pop(x2);  // Receiver.
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic, expr->CountStoreFeedbackId());
diff --git a/src/a64/ic-a64.cc b/src/a64/ic-a64.cc
index 73d4013..18677f7 100644
--- a/src/a64/ic-a64.cc
+++ b/src/a64/ic-a64.cc
@@ -369,7 +369,7 @@
   __ Tbnz(key, kXSignBit, slow_case);
 
   // Load the elements object and check its map.
-  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
   __ Ldr(map, FieldMemOperand(object, JSObject::kElementsOffset));
   __ CheckMap(map, scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK);
 
@@ -474,12 +474,8 @@
 
   __ IncrementCounter(isolate->counters()->load_miss(), 1, x3, x4);
 
-  // TODO(jbramley): Does the target actually expect an argument in x3, or is
-  // this inherited from ARM's push semantics?
-  __ Mov(x3, x0);
-  __ Push(x3, x2);
-
   // Perform tail call to the entry.
+  __ Push(x0, x2);
   ExternalReference ref =
       ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
   __ TailCallExternalReference(ref, 2, 1);
@@ -493,16 +489,12 @@
   //  -- x0    : receiver
   // -----------------------------------
 
-  // TODO(jbramley): Does the target actually expect an argument in x3, or is
-  // this inherited from ARM's push semantics?
-  __ Mov(x3, x0);
-  __ Push(x3, x2);
-
+  __ Push(x0, x2);
   __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
 }
 
 
-void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
   //  -- x0     : key
@@ -534,8 +526,8 @@
 }
 
 
-void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
-  ASM_LOCATION("KeyedStoreIC::GenerateNonStrictArguments");
+void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
+  ASM_LOCATION("KeyedStoreIC::GenerateSloppyArguments");
   // ---------- S t a t e --------------
   //  -- lr     : return address
   //  -- x0     : value
@@ -930,7 +922,7 @@
 
 
 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictModeFlag strict_mode) {
+                                              StrictMode strict_mode) {
   ASM_LOCATION("KeyedStoreIC::GenerateRuntimeSetProperty");
   // ---------- S t a t e --------------
   //  -- x0     : value
@@ -985,8 +977,6 @@
   // We have to go to the runtime if the current value is the hole because there
   // may be a callback on the element.
   Label holecheck_passed;
-  // TODO(all): This address calculation is repeated later (for the store
-  // itself). We should keep the result to avoid doing the work twice.
   __ Add(x10, elements, FixedArray::kHeaderSize - kHeapObjectTag);
   __ Add(x10, x10, Operand::UntagSmiAndScale(key, kPointerSizeLog2));
   __ Ldr(x11, MemOperand(x10));
@@ -1039,8 +1029,6 @@
   // HOLECHECK: guards "A[i] double hole?"
   // We have to see if the double version of the hole is present. If so go to
   // the runtime.
-  // TODO(all): This address calculation was done earlier. We should keep the
-  // result to avoid doing the work twice.
   __ Add(x10, elements, FixedDoubleArray::kHeaderSize - kHeapObjectTag);
   __ Add(x10, x10, Operand::UntagSmiAndScale(key, kPointerSizeLog2));
   __ Ldr(x11, MemOperand(x10));
@@ -1117,7 +1105,7 @@
 
 
 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictModeFlag strict_mode) {
+                                   StrictMode strict_mode) {
   ASM_LOCATION("KeyedStoreIC::GenerateGeneric");
   // ---------- S t a t e --------------
   //  -- x0     : value
@@ -1283,7 +1271,7 @@
 
 
 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                  StrictModeFlag strict_mode) {
+                                         StrictMode strict_mode) {
   ASM_LOCATION("StoreIC::GenerateRuntimeSetProperty");
   // ----------- S t a t e -------------
   //  -- x0    : value
diff --git a/src/a64/lithium-a64.cc b/src/a64/lithium-a64.cc
index dff7003..2f2061f 100644
--- a/src/a64/lithium-a64.cc
+++ b/src/a64/lithium-a64.cc
@@ -506,15 +506,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);
 
-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -736,6 +727,26 @@
       instr = AssignEnvironment(instr);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+      LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+            SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -1374,16 +1385,15 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      (instr->CheckFlag(HValue::kCanOverflow) &&
-       instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+  LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+          dividend, divisor));
+  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
       (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
-       divisor != 1 && divisor != -1);
-  return can_deopt ? AssignEnvironment(result) : result;
+       divisor != 1 && divisor != -1)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1393,16 +1403,16 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  bool truncating = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
-  LOperand* temp = truncating ? NULL : TempRegister();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LDivByConstI(dividend, divisor, temp));
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      !truncating;
-  return can_deopt ? AssignEnvironment(result) : result;
+  LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
+      ? NULL : TempRegister();
+  LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI(
+          dividend, divisor, temp));
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1760,8 +1770,7 @@
       DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
   bool can_deopt =
       divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0);
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
   return can_deopt ? AssignEnvironment(result) : result;
 }
 
@@ -1812,12 +1821,12 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegisterAtStart(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      instr->left()->CanBeNegative();
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+          dividend, divisor));
+  if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1828,13 +1837,12 @@
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
   LOperand* temp = TempRegister();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LModByConstI(dividend, divisor, temp));
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->CanBeNegative());
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineAsRegister(new(zone()) LModByConstI(
+          dividend, divisor, temp));
+  if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1844,12 +1852,12 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   LOperand* divisor = UseRegister(instr->right());
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LModI(dividend, divisor));
-  bool can_deopt = (instr->right()->CanBeZero() ||
-                    (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-                     instr->left()->CanBeNegative() && instr->CanBeZero()));
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineAsRegister(new(zone()) LModI(dividend, divisor));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1909,8 +1917,7 @@
     // allocated for the second operand.
     LInstruction* result;
     if (instr->representation().IsSmi()) {
-      // TODO(jbramley/rmcilroy): Fix LMulS so we can UseRegisterAtStart here.
-      LOperand* right = UseRegister(most_const);
+      LOperand* right = UseRegisterAtStart(most_const);
       result = DefineAsRegister(new(zone()) LMulS(left, right));
     } else {
       LOperand* right = UseRegisterAtStart(most_const);
@@ -2110,21 +2117,6 @@
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (pending_deoptimization_ast_id_ == instr->ast_id()) {
-    LInstruction* result = new(zone()) LLazyBailout;
-    result = AssignEnvironment(result);
-    // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }
 
@@ -2239,17 +2231,29 @@
 
 
 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
-  // TODO(jbramley): Optimize register usage in this instruction. For now, it
-  // allocates everything that it might need because it keeps changing in the
-  // merge and keeping it valid is time-consuming.
-
   // TODO(jbramley): It might be beneficial to allow value to be a constant in
   // some cases. x64 makes use of this with FLAG_track_fields, for example.
 
   LOperand* object = UseRegister(instr->object());
-  LOperand* value = UseRegisterAndClobber(instr->value());
-  LOperand* temp0 = TempRegister();
-  LOperand* temp1 = TempRegister();
+  LOperand* value;
+  LOperand* temp0 = NULL;
+  LOperand* temp1 = NULL;
+
+  if (instr->access().IsExternalMemory() ||
+      instr->field_representation().IsDouble()) {
+    value = UseRegister(instr->value());
+  } else if (instr->NeedsWriteBarrier()) {
+    value = UseRegisterAndClobber(instr->value());
+    temp0 = TempRegister();
+    temp1 = TempRegister();
+  } else if (instr->NeedsWriteBarrierForMap()) {
+    value = UseRegister(instr->value());
+    temp0 = TempRegister();
+    temp1 = TempRegister();
+  } else {
+    value = UseRegister(instr->value());
+    temp0 = TempRegister();
+  }
 
   LStoreNamedField* result =
       new(zone()) LStoreNamedField(object, value, temp0, temp1);
diff --git a/src/a64/lithium-a64.h b/src/a64/lithium-a64.h
index 6f718e5..cb222bf 100644
--- a/src/a64/lithium-a64.h
+++ b/src/a64/lithium-a64.h
@@ -1335,8 +1335,6 @@
   LOperand* right() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
-  bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
   DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
 };
@@ -2490,7 +2488,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2539,7 +2537,7 @@
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2978,9 +2976,7 @@
         status_(UNUSED),
         current_instruction_(NULL),
         current_block_(NULL),
-        allocator_(allocator),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        allocator_(allocator) { }
 
   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -3117,8 +3113,6 @@
   HInstruction* current_instruction_;
   HBasicBlock* current_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;
 
   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index ea826d6..96e5cd3 100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -668,11 +668,11 @@
 
     // TODO(all): Add support for stop_t FLAG in DEBUG mode.
 
-    // Classic mode functions and builtins need to replace the receiver with the
+    // Sloppy mode functions and builtins need to replace the receiver with the
     // global proxy when called as functions (without an explicit receiver
     // object).
     if (info_->this_has_uses() &&
-        info_->is_classic_mode() &&
+        info_->strict_mode() == SLOPPY &&
         !info_->is_native()) {
       Label ok;
       int receiver_offset = info_->scope()->num_parameters() * kXRegSizeInBytes;
@@ -771,6 +771,13 @@
 }
 
 
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}
+
+
 bool LCodeGen::GenerateDeferredCode() {
   ASSERT(is_generating());
   if (deferred_.length() > 0) {
@@ -2607,14 +2614,12 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ Cmp(dividend, 0);
     DeoptimizeIf(eq, instr->environment());
   }
   // Check for (kMinInt / -1).
-  if (hdiv->CheckFlag(HValue::kCanOverflow) &&
-      hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+  if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
     __ Cmp(dividend, kMinInt);
     DeoptimizeIf(eq, instr->environment());
   }
@@ -2657,8 +2662,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     DeoptimizeIfZero(dividend, instr->environment());
   }
 
@@ -2678,16 +2682,16 @@
 
 
 void LCodeGen::DoDivI(LDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
   Register dividend = ToRegister32(instr->left());
   Register divisor = ToRegister32(instr->right());
   Register result = ToRegister32(instr->result());
-  HValue* hdiv = instr->hydrogen_value();
 
   // Issue the division first, and then check for any deopt cases whilst the
   // result is computed.
   __ Sdiv(result, dividend, divisor);
 
-  if (hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+  if (hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     ASSERT_EQ(NULL, instr->temp());
     return;
   }
@@ -2779,7 +2783,7 @@
   // space for nested functions that don't need literals cloning.
   bool pretenure = instr->hydrogen()->pretenure();
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
-    FastNewClosureStub stub(instr->hydrogen()->language_mode(),
+    FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
                             instr->hydrogen()->is_generator());
     __ Mov(x2, Operand(instr->hydrogen()->shared_info()));
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
@@ -3472,7 +3476,7 @@
       case FAST_ELEMENTS:
       case FAST_SMI_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -3735,8 +3739,7 @@
     Register input = ToRegister(instr->value());
     __ JumpIfSmi(result, &result_ok);
     __ Cmp(input, result);
-    // TODO(all): Shouldn't we assert here?
-    DeoptimizeIf(ne, instr->environment());
+    __ Assert(eq, kUnexpectedValue);
     __ Bind(&result_ok);
   }
 
@@ -3895,8 +3898,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ Cmp(dividend, 0);
     DeoptimizeIf(eq, instr->environment());
   }
@@ -3983,9 +3985,7 @@
   __ B(&done, eq);
 
   // Add +0.0 to convert -0.0 to +0.0.
-  // TODO(jbramley): A constant zero register would be helpful here.
-  __ Fmov(double_scratch(), 0.0);
-  __ Fadd(double_scratch(), input, double_scratch());
+  __ Fadd(double_scratch(), input, fp_zero);
   __ Fsqrt(result, double_scratch());
 
   __ Bind(&done);
@@ -4184,8 +4184,7 @@
 
   // Check for negative zero.
   HMod* hmod = instr->hydrogen();
-  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hmod->left()->CanBeNegative()) {
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label remainder_not_zero;
     __ Cbnz(result, &remainder_not_zero);
     DeoptimizeIfNegative(dividend, instr->environment());
@@ -4202,7 +4201,7 @@
   Label deopt, done;
   // modulo = dividend - quotient * divisor
   __ Sdiv(result, dividend, divisor);
-  if (instr->hydrogen()->right()->CanBeZero()) {
+  if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
     // Combine the deoptimization sites.
     Label ok;
     __ Cbnz(divisor, &ok);
@@ -4211,9 +4210,7 @@
     __ Bind(&ok);
   }
   __ Msub(result, result, divisor, dividend);
-  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      instr->hydrogen()->left()->CanBeNegative() &&
-      instr->hydrogen()->CanBeZero()) {
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     __ Cbnz(result, &done);
     if (deopt.is_bound()) {  // TODO(all) This is a hack, remove this...
       __ Tbnz(dividend, kWSignBit, &deopt);
@@ -4328,7 +4325,7 @@
   bool bailout_on_minus_zero =
     instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
 
-  if (bailout_on_minus_zero) {
+  if (bailout_on_minus_zero && !left.Is(right)) {
     // If one operand is zero and the other is negative, the result is -0.
     //  - Set Z (eq) if either left or right, or both, are 0.
     __ Cmp(left, 0);
@@ -4358,7 +4355,7 @@
   bool bailout_on_minus_zero =
     instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
 
-  if (bailout_on_minus_zero) {
+  if (bailout_on_minus_zero && !left.Is(right)) {
     // If one operand is zero and the other is negative, the result is -0.
     //  - Set Z (eq) if either left or right, or both, are 0.
     __ Cmp(left, 0);
@@ -4376,10 +4373,25 @@
     __ SmiTag(result);
     DeoptimizeIf(ne, instr->environment());
   } else {
-    // TODO(jbramley): This could be rewritten to support UseRegisterAtStart.
-    ASSERT(!AreAliased(result, right));
-    __ SmiUntag(result, left);
-    __ Mul(result, result, right);
+    if (AreAliased(result, left, right)) {
+      // All three registers are the same: half untag the input and then
+      // multiply, giving a tagged result.
+      STATIC_ASSERT((kSmiShift % 2) == 0);
+      __ Asr(result, left, kSmiShift / 2);
+      __ Mul(result, result, result);
+    } else if (result.Is(left) && !left.Is(right)) {
+      // Registers result and left alias, right is distinct: untag left into
+      // result, and then multiply by right, giving a tagged result.
+      __ SmiUntag(result, left);
+      __ Mul(result, result, right);
+    } else {
+      ASSERT(!left.Is(result));
+      // Registers result and right alias, left is distinct, or all registers
+      // are distinct: untag right into result, and then multiply by left,
+      // giving a tagged result.
+      __ SmiUntag(result, right);
+      __ Mul(result, left, result);
+    }
   }
 }
 
@@ -5074,7 +5086,7 @@
       case FAST_HOLEY_ELEMENTS:
       case FAST_HOLEY_SMI_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -5175,43 +5187,27 @@
   ASSERT(ToRegister(instr->key()).Is(x1));
   ASSERT(ToRegister(instr->value()).Is(x0));
 
-  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
+  Handle<Code> ic = instr->strict_mode() == STRICT
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
 
-// TODO(jbramley): Once the merge is done and we're tracking bleeding_edge, try
-// to tidy up this function.
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Representation representation = instr->representation();
 
   Register object = ToRegister(instr->object());
-  Register temp0 = ToRegister(instr->temp0());
-  Register temp1 = ToRegister(instr->temp1());
   HObjectAccess access = instr->hydrogen()->access();
+  Handle<Map> transition = instr->transition();
   int offset = access.offset();
 
   if (access.IsExternalMemory()) {
+    ASSERT(transition.is_null());
+    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     Register value = ToRegister(instr->value());
     __ Store(value, MemOperand(object, offset), representation);
     return;
-  }
-
-  Handle<Map> transition = instr->transition();
-  SmiCheck check_needed =
-      instr->hydrogen()->value()->IsHeapObject()
-          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
-
-  if (representation.IsHeapObject()) {
-    Register value = ToRegister(instr->value());
-    if (!instr->hydrogen()->value()->type().IsHeapObject()) {
-      DeoptimizeIfSmi(value, instr->environment());
-
-      // We know that value is a smi now, so we can omit the check below.
-      check_needed = OMIT_SMI_CHECK;
-    }
   } else if (representation.IsDouble()) {
     ASSERT(transition.is_null());
     ASSERT(access.IsInobject());
@@ -5221,9 +5217,22 @@
     return;
   }
 
+  Register value = ToRegister(instr->value());
+
+  SmiCheck check_needed = instr->hydrogen()->value()->IsHeapObject()
+      ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+
+  if (representation.IsHeapObject() &&
+      !instr->hydrogen()->value()->type().IsHeapObject()) {
+    DeoptimizeIfSmi(value, instr->environment());
+
+    // We know that value is a smi now, so we can omit the check below.
+    check_needed = OMIT_SMI_CHECK;
+  }
+
   if (!transition.is_null()) {
     // Store the new map value.
-    Register new_map_value = temp0;
+    Register new_map_value = ToRegister(instr->temp0());
     __ Mov(new_map_value, Operand(transition));
     __ Str(new_map_value, FieldMemOperand(object, HeapObject::kMapOffset));
     if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
@@ -5231,7 +5240,7 @@
       __ RecordWriteField(object,
                           HeapObject::kMapOffset,
                           new_map_value,
-                          temp1,
+                          ToRegister(instr->temp1()),
                           GetLinkRegisterState(),
                           kSaveFPRegs,
                           OMIT_REMEMBERED_SET,
@@ -5240,21 +5249,28 @@
   }
 
   // Do the store.
-  Register value = ToRegister(instr->value());
   Register destination;
   if (access.IsInobject()) {
     destination = object;
   } else {
+    Register temp0 = ToRegister(instr->temp0());
     __ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset));
     destination = temp0;
   }
 
   if (representation.IsSmi() &&
-      instr->hydrogen()->value()->representation().IsInteger32()) {
+     instr->hydrogen()->value()->representation().IsInteger32()) {
     ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
 #ifdef DEBUG
-    __ Ldr(temp1, FieldMemOperand(destination, offset));
-    __ AssertSmi(temp1);
+    Register temp0 = ToRegister(instr->temp0());
+    __ Ldr(temp0, FieldMemOperand(destination, offset));
+    __ AssertSmi(temp0);
+    // If destination aliased temp0, restore it to the address calculated
+    // earlier.
+    if (destination.Is(temp0)) {
+      ASSERT(!access.IsInobject());
+      __ Ldr(destination, FieldMemOperand(object, JSObject::kPropertiesOffset));
+    }
 #endif
     STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0);
     __ Store(value, UntagSmiFieldMemOperand(destination, offset),
@@ -5265,8 +5281,8 @@
   if (instr->hydrogen()->NeedsWriteBarrier()) {
     __ RecordWriteField(destination,
                         offset,
-                        value,      // Clobbered.
-                        temp1,      // Clobbered.
+                        value,                        // Clobbered.
+                        ToRegister(instr->temp1()),   // Clobbered.
                         GetLinkRegisterState(),
                         kSaveFPRegs,
                         EMIT_REMEMBERED_SET,
@@ -5282,8 +5298,7 @@
 
   // Name must be in x2.
   __ Mov(x2, Operand(instr->name()));
-  Handle<Code> ic = StoreIC::initialize_stub(isolate(),
-                                             instr->strict_mode_flag());
+  Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
diff --git a/src/a64/lithium-codegen-a64.h b/src/a64/lithium-codegen-a64.h
index 140b1ae..fb1ca94 100644
--- a/src/a64/lithium-codegen-a64.h
+++ b/src/a64/lithium-codegen-a64.h
@@ -276,6 +276,7 @@
   void RestoreCallerDoubles();
 
   // Code generation steps.  Returns true if code generation should continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateDeoptJumpTable();
diff --git a/src/a64/macro-assembler-a64.cc b/src/a64/macro-assembler-a64.cc
index 2bc2128..4b6b8eb 100644
--- a/src/a64/macro-assembler-a64.cc
+++ b/src/a64/macro-assembler-a64.cc
@@ -1516,12 +1516,7 @@
 
 void MacroAssembler::AssertName(Register object) {
   if (emit_debug_code()) {
-    STATIC_ASSERT(kSmiTag == 0);
-    // TODO(jbramley): Add AbortIfSmi and related functions.
-    Label not_smi;
-    JumpIfNotSmi(object, &not_smi);
-    Abort(kOperandIsASmiAndNotAName);
-    Bind(&not_smi);
+    AssertNotSmi(object, kOperandIsASmiAndNotAName);
 
     UseScratchRegisterScope temps(this);
     Register temp = temps.AcquireX();
@@ -1763,11 +1758,13 @@
 }
 
 
-void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
-  ASSERT(!target.is(x1));
-  GetBuiltinFunction(x1, id);
+void MacroAssembler::GetBuiltinEntry(Register target,
+                                     Register function,
+                                     Builtins::JavaScript id) {
+  ASSERT(!AreAliased(target, function));
+  GetBuiltinFunction(function, id);
   // Load the code entry point from the builtins object.
-  Ldr(target, FieldMemOperand(x1, JSFunction::kCodeEntryOffset));
+  Ldr(target, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
 }
 
 
@@ -1778,7 +1775,8 @@
   // You can't call a builtin without a valid frame.
   ASSERT(flag == JUMP_FUNCTION || has_frame());
 
-  GetBuiltinEntry(x2, id);
+  // Get the builtin entry in x2 and setup the function object in x1.
+  GetBuiltinEntry(x2, x1, id);
   if (flag == CALL_FUNCTION) {
     call_wrapper.BeforeCall(CallSize(x2));
     Call(x2);
@@ -2847,8 +2845,6 @@
     ASSERT(StackPointer().Is(jssp));
     UseScratchRegisterScope temps(this);
     Register temp = temps.AcquireX();
-    // TODO(jbramley): Does x1 contain a JSFunction here, or does it already
-    // have the special STUB smi?
     __ Mov(temp, Operand(Smi::FromInt(StackFrame::STUB)));
     // Compiled stubs don't age, and so they don't need the predictable code
     // ageing sequence.
diff --git a/src/a64/macro-assembler-a64.h b/src/a64/macro-assembler-a64.h
index f5fa14f..a9cf189 100644
--- a/src/a64/macro-assembler-a64.h
+++ b/src/a64/macro-assembler-a64.h
@@ -1047,7 +1047,6 @@
     CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
   }
 
-  // TODO(all): Why does this variant save FP regs unconditionally?
   void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
     const Runtime::Function* function = Runtime::FunctionForId(id);
     CallRuntime(function, function->nargs, kSaveFPRegs);
@@ -1110,9 +1109,10 @@
                      const CallWrapper& call_wrapper = NullCallWrapper());
 
   // Store the code object for the given builtin in the target register and
-  // setup the function in x1.
-  // TODO(all): Can we use another register than x1?
-  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
+  // setup the function in the function register.
+  void GetBuiltinEntry(Register target,
+                       Register function,
+                       Builtins::JavaScript id);
 
   // Store the function for the given builtin in the target register.
   void GetBuiltinFunction(Register target, Builtins::JavaScript id);
diff --git a/src/accessors.cc b/src/accessors.cc
index 9bc728d..ac64683 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -891,10 +891,10 @@
   if (caller->shared()->bound()) {
     return isolate->heap()->null_value();
   }
-  // Censor if the caller is not a classic mode function.
+  // Censor if the caller is not a sloppy mode function.
   // Change from ES5, which used to throw, see:
   // https://bugs.ecmascript.org/show_bug.cgi?id=310
-  if (!caller->shared()->is_classic_mode()) {
+  if (caller->shared()->strict_mode() == STRICT) {
     return isolate->heap()->null_value();
   }
 
diff --git a/src/api.cc b/src/api.cc
index f2b4cb3..a6ff52c 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2651,6 +2651,13 @@
 }
 
 
+void v8::Promise::CheckCast(Value* that) {
+  Utils::ApiCheck(that->IsPromise(),
+                  "v8::Promise::Cast()",
+                  "Could not convert to promise");
+}
+
+
 void v8::ArrayBuffer::CheckCast(Value* that) {
   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   Utils::ApiCheck(obj->IsJSArrayBuffer(),
@@ -2988,7 +2995,7 @@
       key_obj,
       value_obj,
       static_cast<PropertyAttributes>(attribs),
-      i::kNonStrictMode);
+      i::SLOPPY);
   has_pending_exception = obj.is_null();
   EXCEPTION_BAILOUT_CHECK(isolate, false);
   return true;
@@ -3008,7 +3015,7 @@
       index,
       value_obj,
       NONE,
-      i::kNonStrictMode);
+      i::SLOPPY);
   has_pending_exception = obj.is_null();
   EXCEPTION_BAILOUT_CHECK(isolate, false);
   return true;
@@ -5618,30 +5625,18 @@
 
   i_isolate->date_cache()->ResetDateCache();
 
-  i::HandleScope scope(i_isolate);
-  // Get the function ResetDateCache (defined in date.js).
-  i::Handle<i::String> func_name_str =
-      i_isolate->factory()->InternalizeOneByteString(
-          STATIC_ASCII_VECTOR("ResetDateCache"));
-  i::MaybeObject* result =
-      i_isolate->js_builtins_object()->GetProperty(*func_name_str);
-  i::Object* object_func;
-  if (!result->ToObject(&object_func)) {
+  if (!i_isolate->eternal_handles()->Exists(
+          i::EternalHandles::DATE_CACHE_VERSION)) {
     return;
   }
-
-  if (object_func->IsJSFunction()) {
-    i::Handle<i::JSFunction> func =
-        i::Handle<i::JSFunction>(i::JSFunction::cast(object_func));
-
-    // Call ResetDateCache(0 but expect no exceptions:
-    bool caught_exception = false;
-    i::Execution::TryCall(func,
-                          i_isolate->js_builtins_object(),
-                          0,
-                          NULL,
-                          &caught_exception);
-  }
+  i::Handle<i::FixedArray> date_cache_version =
+      i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
+          i::EternalHandles::DATE_CACHE_VERSION));
+  ASSERT_EQ(1, date_cache_version->length());
+  CHECK(date_cache_version->get(0)->IsSmi());
+  date_cache_version->set(
+      0,
+      i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1));
 }
 
 
@@ -5743,6 +5738,124 @@
 }
 
 
+bool Value::IsPromise() const {
+  i::Handle<i::Object> val = Utils::OpenHandle(this);
+  if (!i::FLAG_harmony_promises || !val->IsJSObject()) return false;
+  i::Handle<i::JSObject> obj = i::Handle<i::JSObject>::cast(val);
+  i::Isolate* isolate = obj->GetIsolate();
+  LOG_API(isolate, "IsPromise");
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
+  i::Handle<i::Object> argv[] = { obj };
+  i::Handle<i::Object> b = i::Execution::Call(
+      isolate,
+      handle(
+          isolate->context()->global_object()->native_context()->is_promise()),
+      isolate->factory()->undefined_value(),
+      ARRAY_SIZE(argv), argv,
+      &has_pending_exception,
+      false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
+  return b->BooleanValue();
+}
+
+
+Local<Promise> Promise::New(Isolate* v8_isolate) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+  LOG_API(isolate, "Promise::New");
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
+  i::Handle<i::Object> result = i::Execution::Call(
+      isolate,
+      handle(isolate->context()->global_object()->native_context()->
+             promise_create()),
+      isolate->factory()->undefined_value(),
+      0, NULL,
+      &has_pending_exception,
+      false);
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
+  return Local<Promise>::Cast(Utils::ToLocal(result));
+}
+
+
+void Promise::Resolve(Handle<Value> value) {
+  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+  i::Isolate* isolate = promise->GetIsolate();
+  LOG_API(isolate, "Promise::Resolve");
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
+  i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
+  i::Execution::Call(
+      isolate,
+      handle(isolate->context()->global_object()->native_context()->
+             promise_resolve()),
+      isolate->factory()->undefined_value(),
+      ARRAY_SIZE(argv), argv,
+      &has_pending_exception,
+      false);
+  EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
+}
+
+
+void Promise::Reject(Handle<Value> value) {
+  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+  i::Isolate* isolate = promise->GetIsolate();
+  LOG_API(isolate, "Promise::Reject");
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
+  i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
+  i::Execution::Call(
+      isolate,
+      handle(isolate->context()->global_object()->native_context()->
+             promise_reject()),
+      isolate->factory()->undefined_value(),
+      ARRAY_SIZE(argv), argv,
+      &has_pending_exception,
+      false);
+  EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
+}
+
+
+Local<Promise> Promise::Chain(Handle<Function> handler) {
+  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+  i::Isolate* isolate = promise->GetIsolate();
+  LOG_API(isolate, "Promise::Chain");
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
+  i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
+  i::Handle<i::Object> result = i::Execution::Call(
+      isolate,
+      handle(isolate->context()->global_object()->native_context()->
+             promise_chain()),
+      promise,
+      ARRAY_SIZE(argv), argv,
+      &has_pending_exception,
+      false);
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
+  return Local<Promise>::Cast(Utils::ToLocal(result));
+}
+
+
+Local<Promise> Promise::Catch(Handle<Function> handler) {
+  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+  i::Isolate* isolate = promise->GetIsolate();
+  LOG_API(isolate, "Promise::Catch");
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
+  i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
+  i::Handle<i::Object> result = i::Execution::Call(
+      isolate,
+      handle(isolate->context()->global_object()->native_context()->
+             promise_catch()),
+      promise,
+      ARRAY_SIZE(argv), argv,
+      &has_pending_exception,
+      false);
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
+  return Local<Promise>::Cast(Utils::ToLocal(result));
+}
+
+
 bool v8::ArrayBuffer::IsExternal() const {
   return Utils::OpenHandle(this)->is_external();
 }
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index cf14172..610f153 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -1059,14 +1059,19 @@
 }
 
 
-static bool use_movw_movt(const Operand& x, const Assembler* assembler) {
-  if (Assembler::use_immediate_embedded_pointer_loads(assembler)) {
+static bool use_mov_immediate_load(const Operand& x,
+                                   const Assembler* assembler) {
+  if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
+             (assembler == NULL || !assembler->predictable_code_size())) {
+    // Prefer movw / movt to constant pool if it is more efficient on the CPU.
     return true;
-  }
-  if (x.must_output_reloc_info(assembler)) {
+  } else if (x.must_output_reloc_info(assembler)) {
+    // Prefer constant pool if data is likely to be patched.
     return false;
+  } else {
+    // Otherwise, use immediate load if movw / movt is available.
+    return CpuFeatures::IsSupported(ARMv7);
   }
-  return CpuFeatures::IsSupported(ARMv7);
 }
 
 
@@ -1080,7 +1085,7 @@
     // constant pool is required. For a mov instruction not setting the
     // condition code additional instruction conventions can be used.
     if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
-      return !use_movw_movt(*this, assembler);
+      return !use_mov_immediate_load(*this, assembler);
     } else {
       // If this is not a mov or mvn instruction there will always an additional
       // instructions - either mov or ldr. The mov might actually be two
@@ -1096,12 +1101,11 @@
 }
 
 
-void Assembler::move_32_bit_immediate(Condition cond,
-                                      Register rd,
-                                      SBit s,
-                                      const Operand& x) {
-  if (rd.code() != pc.code() && s == LeaveCC) {
-    if (use_movw_movt(x, this)) {
+void Assembler::move_32_bit_immediate(Register rd,
+                                      const Operand& x,
+                                      Condition cond) {
+  if (rd.code() != pc.code()) {
+    if (use_mov_immediate_load(x, this)) {
       if (x.must_output_reloc_info(this)) {
         RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL);
         // Make sure the movw/movt doesn't get separated.
@@ -1138,20 +1142,9 @@
       CHECK(!rn.is(ip));  // rn should never be ip, or will be trashed
       Condition cond = Instruction::ConditionField(instr);
       if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
-        move_32_bit_immediate(cond, rd, LeaveCC, x);
+        move_32_bit_immediate(rd, x, cond);
       } else {
-        if ((instr & kMovMvnMask) == kMovMvnPattern) {
-          // Moves need to use a constant pool entry.
-          RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
-          ldr(ip, MemOperand(pc, 0), cond);
-        } else if (x.must_output_reloc_info(this)) {
-          // Otherwise, use most efficient form of fetching from constant pool.
-          move_32_bit_immediate(cond, ip, LeaveCC, x);
-        } else {
-          // If this is not a mov or mvn instruction we may still be able to
-          // avoid a constant pool entry by using mvn or movw.
-          mov(ip, x, LeaveCC, cond);
-        }
+        mov(ip, x, LeaveCC, cond);
         addrmod1(instr, rn, rd, Operand(ip));
       }
       return;
@@ -1819,8 +1812,7 @@
     if (src.must_output_reloc_info(this) ||
         !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
       // Immediate operand cannot be encoded, load it first to register ip.
-      RecordRelocInfo(src.rmode_, src.imm32_);
-      ldr(ip, MemOperand(pc, 0), cond);
+      move_32_bit_immediate(ip, src);
       msr(fields, Operand(ip), cond);
       return;
     }
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index ccb5104..c35c80b 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -1292,12 +1292,6 @@
   // Jump unconditionally to given label.
   void jmp(Label* L) { b(L, al); }
 
-  static bool use_immediate_embedded_pointer_loads(
-      const Assembler* assembler) {
-    return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
-        (assembler == NULL || !assembler->predictable_code_size());
-  }
-
   // Check the code size generated from label to here.
   int SizeOfCodeGeneratedSince(Label* label) {
     return pc_offset() - label->pos();
@@ -1565,10 +1559,9 @@
   inline void emit(Instr x);
 
   // 32-bit immediate values
-  void move_32_bit_immediate(Condition cond,
-                             Register rd,
-                             SBit s,
-                             const Operand& x);
+  void move_32_bit_immediate(Register rd,
+                             const Operand& x,
+                             Condition cond = al);
 
   // Instruction generation
   void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index e9aec8e..80512a8 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -1038,7 +1038,7 @@
     __ tst(r3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
     __ b(ne, &shift_arguments);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
     __ ldr(r2, MemOperand(r2, -kPointerSize));
     // r0: actual number of arguments
@@ -1246,7 +1246,7 @@
     __ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
     __ b(ne, &push_receiver);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ JumpIfSmi(r0, &call_to_object);
     __ LoadRoot(r1, Heap::kNullValueRootIndex);
     __ cmp(r0, r1);
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index f661ad8..558f5e1 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -2258,7 +2258,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // sp[0] : number of parameters
   // sp[4] : receiver displacement
   // sp[8] : function
@@ -2282,7 +2282,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   // Stack layout:
   //  sp[0] : number of parameters (tagged)
   //  sp[4] : address of receiver argument
@@ -2336,7 +2336,7 @@
   __ add(r9, r9, Operand(FixedArray::kHeaderSize));
 
   // 3. Arguments object.
-  __ add(r9, r9, Operand(Heap::kArgumentsObjectSize));
+  __ add(r9, r9, Operand(Heap::kSloppyArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
   __ Allocate(r9, r0, r3, r4, &runtime, TAG_OBJECT);
@@ -2345,7 +2345,7 @@
   // r2 = argument count (tagged)
   // Get the arguments boilerplate from the current native context into r4.
   const int kNormalOffset =
-      Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
+      Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX);
   const int kAliasedOffset =
       Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
 
@@ -2381,7 +2381,7 @@
   // Set up the elements pointer in the allocated arguments object.
   // If we allocated a parameter map, r4 will point there, otherwise
   // it will point to the backing store.
-  __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
+  __ add(r4, r0, Operand(Heap::kSloppyArgumentsObjectSize));
   __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
 
   // r0 = address of new object (tagged)
@@ -2396,7 +2396,7 @@
   __ mov(r3, r4, LeaveCC, eq);
   __ b(eq, &skip_parameter_map);
 
-  __ LoadRoot(r6, Heap::kNonStrictArgumentsElementsMapRootIndex);
+  __ LoadRoot(r6, Heap::kSloppyArgumentsElementsMapRootIndex);
   __ str(r6, FieldMemOperand(r4, FixedArray::kMapOffset));
   __ add(r6, r1, Operand(Smi::FromInt(2)));
   __ str(r6, FieldMemOperand(r4, FixedArray::kLengthOffset));
@@ -2426,7 +2426,7 @@
   // r1 = mapping index (tagged)
   // r3 = address of backing store (tagged)
   // r4 = address of parameter map (tagged), which is also the address of new
-  //      object + Heap::kArgumentsObjectSize (tagged)
+  //      object + Heap::kSloppyArgumentsObjectSize (tagged)
   // r0 = temporary scratch (a.o., for address calculation)
   // r5 = the hole value
   __ jmp(&parameters_test);
@@ -2444,7 +2444,7 @@
   __ b(ne, &parameters_loop);
 
   // Restore r0 = new object (tagged)
-  __ sub(r0, r4, Operand(Heap::kArgumentsObjectSize));
+  __ sub(r0, r4, Operand(Heap::kSloppyArgumentsObjectSize));
 
   __ bind(&skip_parameter_map);
   // r0 = address of new object (tagged)
@@ -2517,7 +2517,7 @@
   __ b(eq, &add_arguments_object);
   __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
   __ bind(&add_arguments_object);
-  __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
+  __ add(r1, r1, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize));
 
   // Do the allocation of both objects in one go.
   __ Allocate(r1, r0, r2, r3, &runtime,
@@ -2527,7 +2527,7 @@
   __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
   __ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset));
   __ ldr(r4, MemOperand(r4, Context::SlotOffset(
-      Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
+      Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX)));
 
   // Copy the JS object part.
   __ CopyFields(r0, r4, d0, JSObject::kHeaderSize / kPointerSize);
@@ -2548,7 +2548,7 @@
 
   // Set up the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict));
+  __ add(r4, r0, Operand(Heap::kStrictArgumentsObjectSize));
   __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
   __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
   __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
@@ -3134,7 +3134,7 @@
       __ b(ne, &cont);
     }
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ ldr(r3, MemOperand(sp, argc_ * kPointerSize));
 
     if (NeedsChecks()) {
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 760afba..5d06701 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -145,10 +145,10 @@
   }
 #endif
 
-  // Classic mode functions and builtins need to replace the receiver with the
+  // Sloppy mode functions and builtins need to replace the receiver with the
   // global proxy when called as functions (without an explicit receiver
   // object).
-  if (info->is_classic_mode() && !info->is_native()) {
+  if (info->strict_mode() == SLOPPY && !info->is_native()) {
     Label ok;
     int receiver_offset = info->scope()->num_parameters() * kPointerSize;
     __ ldr(r2, MemOperand(sp, receiver_offset));
@@ -262,12 +262,12 @@
     // The stub will rewrite receiever and parameter count if the previous
     // stack frame was an arguments adapter frame.
     ArgumentsAccessStub::Type type;
-    if (!is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       type = ArgumentsAccessStub::NEW_STRICT;
     } else if (function()->has_duplicate_parameters()) {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+      type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
     } else {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+      type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
     ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
@@ -293,7 +293,7 @@
       if (scope()->is_function_scope() && scope()->function() != NULL) {
         VariableDeclaration* function = scope()->function();
         ASSERT(function->proxy()->var()->mode() == CONST ||
-               function->proxy()->var()->mode() == CONST_HARMONY);
+               function->proxy()->var()->mode() == CONST_LEGACY);
         ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
         VisitVariableDeclaration(function);
       }
@@ -790,7 +790,7 @@
   VariableProxy* proxy = declaration->proxy();
   VariableMode mode = declaration->mode();
   Variable* variable = proxy->var();
-  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
+  bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
       globals_->Add(variable->name(), zone());
@@ -1325,7 +1325,7 @@
       !pretenure &&
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
-    FastNewClosureStub stub(info->language_mode(), info->is_generator());
+    FastNewClosureStub stub(info->strict_mode(), info->is_generator());
     __ mov(r2, Operand(info));
     __ CallStub(&stub);
   } else {
@@ -1355,7 +1355,7 @@
   Scope* s = scope();
   while (s != NULL) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX));
         __ tst(temp, temp);
@@ -1368,7 +1368,7 @@
     }
     // If no outer scope calls eval, we do not need to check more
     // context extensions.
-    if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break;
+    if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
     s = s->outer_scope();
   }
 
@@ -1411,7 +1411,7 @@
 
   for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ ldr(temp, ContextOperand(context, Context::EXTENSION_INDEX));
         __ tst(temp, temp);
@@ -1449,13 +1449,12 @@
   } else if (var->mode() == DYNAMIC_LOCAL) {
     Variable* local = var->local_if_not_shadowed();
     __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow));
-    if (local->mode() == LET ||
-        local->mode() == CONST ||
-        local->mode() == CONST_HARMONY) {
+    if (local->mode() == LET || local->mode() == CONST ||
+        local->mode() == CONST_LEGACY) {
       __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
-      if (local->mode() == CONST) {
+      if (local->mode() == CONST_LEGACY) {
         __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
-      } else {  // LET || CONST_HARMONY
+      } else {  // LET || CONST
         __ b(ne, done);
         __ mov(r0, Operand(var->name()));
         __ push(r0);
@@ -1522,7 +1521,7 @@
           // Check that we always have valid source position.
           ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
           ASSERT(proxy->position() != RelocInfo::kNoPosition);
-          skip_init_check = var->mode() != CONST &&
+          skip_init_check = var->mode() != CONST_LEGACY &&
               var->initializer_position() < proxy->position();
         }
 
@@ -1530,7 +1529,7 @@
           // Let and const need a read barrier.
           GetVar(r0, var);
           __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
-          if (var->mode() == LET || var->mode() == CONST_HARMONY) {
+          if (var->mode() == LET || var->mode() == CONST) {
             // Throw a reference error when using an uninitialized let/const
             // binding in harmony mode.
             Label done;
@@ -1541,7 +1540,7 @@
             __ bind(&done);
           } else {
             // Uninitalized const bindings outside of harmony mode are unholed.
-            ASSERT(var->mode() == CONST);
+            ASSERT(var->mode() == CONST_LEGACY);
             __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
           }
           context()->Plug(r0);
@@ -2438,7 +2437,7 @@
       VisitForAccumulatorValue(prop->key());
       __ mov(r1, r0);
       __ Pop(r0, r2);  // r0 = restored value.
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic);
@@ -2463,24 +2462,23 @@
 
 
 void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, LanguageMode mode) {
+    Handle<String> name, StrictMode strict_mode) {
   __ push(r0);  // Value.
   __ mov(r1, Operand(name));
-  __ mov(r0, Operand(Smi::FromInt(mode)));
+  __ mov(r0, Operand(Smi::FromInt(strict_mode)));
   __ Push(cp, r1, r0);  // Context, name, strict mode.
   __ CallRuntime(Runtime::kStoreContextSlot, 4);
 }
 
 
-void FullCodeGenerator::EmitVariableAssignment(Variable* var,
-                                               Token::Value op) {
+void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
   if (var->IsUnallocated()) {
     // Global var, const, or let.
     __ mov(r2, Operand(var->name()));
     __ ldr(r1, GlobalObjectOperand());
     CallStoreIC();
 
-  } else if (op == Token::INIT_CONST) {
+  } else if (op == Token::INIT_CONST_LEGACY) {
     // Const initializers need a write barrier.
     ASSERT(!var->IsParameter());  // No const parameters.
     if (var->IsLookupSlot()) {
@@ -2502,7 +2500,7 @@
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       Label assign;
@@ -2518,11 +2516,11 @@
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
 
-  } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
+  } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     // Assignment to var or initializing assignment to let/const
     // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
       MemOperand location = VarOperand(var, r1);
@@ -2564,7 +2562,7 @@
   SetSourcePosition(expr->position());
   __ Pop(r2, r1);  // r1 = key.
 
-  Handle<Code> ic = is_classic_mode()
+  Handle<Code> ic = strict_mode() == SLOPPY
       ? isolate()->builtins()->KeyedStoreIC_Initialize()
       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
   CallIC(ic, expr->AssignmentFeedbackId());
@@ -2617,7 +2615,7 @@
       PrepareForBailout(callee, NO_REGISTERS);
     }
     // Push undefined as receiver. This is patched in the method prologue if it
-    // is a classic mode method.
+    // is a sloppy mode method.
     __ Push(isolate()->factory()->undefined_value());
     flags = NO_CALL_FUNCTION_FLAGS;
   } else {
@@ -2734,8 +2732,8 @@
   int receiver_offset = 2 + info_->scope()->num_parameters();
   __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize));
 
-  // r2: the language mode.
-  __ mov(r2, Operand(Smi::FromInt(language_mode())));
+  // r2: strict mode.
+  __ mov(r2, Operand(Smi::FromInt(strict_mode())));
 
   // r1: the start position of the scope the calls resides in.
   __ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
@@ -4172,9 +4170,7 @@
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
-            ? kNonStrictMode : kStrictMode;
-        __ mov(r1, Operand(Smi::FromInt(strict_mode_flag)));
+        __ mov(r1, Operand(Smi::FromInt(strict_mode())));
         __ push(r1);
         __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
         context()->Plug(r0);
@@ -4182,11 +4178,11 @@
         Variable* var = proxy->var();
         // Delete of an unqualified identifier is disallowed in strict mode
         // but "delete this" is allowed.
-        ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
+        ASSERT(strict_mode() == SLOPPY || var->is_this());
         if (var->IsUnallocated()) {
           __ ldr(r2, GlobalObjectOperand());
           __ mov(r1, Operand(var->name()));
-          __ mov(r0, Operand(Smi::FromInt(kNonStrictMode)));
+          __ mov(r0, Operand(Smi::FromInt(SLOPPY)));
           __ Push(r2, r1, r0);
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
           context()->Plug(r0);
@@ -4440,7 +4436,7 @@
     }
     case KEYED_PROPERTY: {
       __ Pop(r2, r1);  // r1 = key. r2 = receiver.
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic, expr->CountStoreFeedbackId());
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 1af6cf8..3d57105 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -427,7 +427,7 @@
   __ b(ne, slow_case);
 
   // Load the elements into scratch1 and check its map.
-  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
   __ ldr(scratch1, FieldMemOperand(object, JSObject::kElementsOffset));
   __ CheckMap(scratch1, scratch2, arguments_map, slow_case, DONT_DO_SMI_CHECK);
 
@@ -489,7 +489,7 @@
 }
 
 
-void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
   //  -- r0     : key
@@ -515,7 +515,7 @@
 }
 
 
-void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ---------- S t a t e --------------
   //  -- r0     : value
   //  -- r1     : key
@@ -876,7 +876,7 @@
 
 
 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictModeFlag strict_mode) {
+                                              StrictMode strict_mode) {
   // ---------- S t a t e --------------
   //  -- r0     : value
   //  -- r1     : key
@@ -1060,7 +1060,7 @@
 
 
 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictModeFlag strict_mode) {
+                                   StrictMode strict_mode) {
   // ---------- S t a t e --------------
   //  -- r0     : value
   //  -- r1     : key
@@ -1219,7 +1219,7 @@
 
 
 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictModeFlag strict_mode) {
+                                         StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- r0    : value
   //  -- r1    : receiver
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index f12b6ea..d6a4c83 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -614,15 +614,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);
 
-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -905,6 +896,26 @@
       instr = AssignEnvironment(instr);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+      LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+            SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -1244,16 +1255,15 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      (instr->CheckFlag(HValue::kCanOverflow) &&
-       instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+  LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+          dividend, divisor));
+  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
       (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
-       divisor != 1 && divisor != -1);
-  return can_deopt ? AssignEnvironment(result) : result;
+       divisor != 1 && divisor != -1)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1263,14 +1273,14 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LDivByConstI(dividend, divisor));
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI(
+          dividend, divisor));
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1326,8 +1336,7 @@
       DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
   bool can_deopt =
       divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0);
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
   return can_deopt ? AssignEnvironment(result) : result;
 }
 
@@ -1349,12 +1358,12 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegisterAtStart(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      instr->left()->CanBeNegative();
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+          dividend, divisor));
+  if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1364,13 +1373,12 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LModByConstI(dividend, divisor));
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->CanBeNegative());
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineAsRegister(new(zone()) LModByConstI(
+          dividend, divisor));
+  if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1378,32 +1386,17 @@
   ASSERT(instr->representation().IsSmiOrInteger32());
   ASSERT(instr->left()->representation().Equals(instr->representation()));
   ASSERT(instr->right()->representation().Equals(instr->representation()));
-  if (CpuFeatures::IsSupported(SUDIV)) {
-    LOperand* dividend = UseRegister(instr->left());
-    LOperand* divisor = UseRegister(instr->right());
-    LInstruction* result =
-        DefineAsRegister(new(zone()) LModI(dividend, divisor, NULL, NULL));
-    bool can_deopt = (instr->right()->CanBeZero() ||
-                      (instr->left()->RangeCanInclude(kMinInt) &&
-                       instr->right()->RangeCanInclude(-1) &&
-                       instr->CheckFlag(HValue::kBailoutOnMinusZero)) ||
-                      (instr->left()->CanBeNegative() &&
-                       instr->CanBeZero() &&
-                       instr->CheckFlag(HValue::kBailoutOnMinusZero)));
-    return can_deopt ? AssignEnvironment(result) : result;
-  } else {
-    LOperand* dividend = UseRegister(instr->left());
-    LOperand* divisor = UseRegister(instr->right());
-    LOperand* temp = FixedTemp(d10);
-    LOperand* temp2 = FixedTemp(d11);
-    LInstruction* result =
-        DefineAsRegister(new(zone()) LModI(dividend, divisor, temp, temp2));
-    bool can_deopt = (instr->right()->CanBeZero() ||
-                      (instr->left()->CanBeNegative() &&
-                       instr->CanBeZero() &&
-                       instr->CheckFlag(HValue::kBailoutOnMinusZero)));
-    return can_deopt ? AssignEnvironment(result) : result;
+  LOperand* dividend = UseRegister(instr->left());
+  LOperand* divisor = UseRegister(instr->right());
+  LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d10);
+  LOperand* temp2 = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d11);
+  LInstruction* result = DefineAsRegister(new(zone()) LModI(
+          dividend, divisor, temp, temp2));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
   }
+  return result;
 }
 
 
@@ -2463,21 +2456,6 @@
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (pending_deoptimization_ast_id_ == instr->ast_id()) {
-    LInstruction* result = new(zone()) LLazyBailout;
-    result = AssignEnvironment(result);
-    // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }
 
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 86cf2f2..953bd34 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -725,8 +725,6 @@
   LOperand* right() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
-  bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
   DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
 };
@@ -2217,7 +2215,7 @@
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2280,7 +2278,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2722,9 +2720,7 @@
         current_instruction_(NULL),
         current_block_(NULL),
         next_block_(NULL),
-        allocator_(allocator),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        allocator_(allocator) { }
 
   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -2868,8 +2864,6 @@
   HBasicBlock* current_block_;
   HBasicBlock* next_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;
 
   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index b10ed59..d725c7c 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -147,11 +147,11 @@
     // fp: Caller's frame pointer.
     // lr: Caller's pc.
 
-    // Classic mode functions and builtins need to replace the receiver with the
+    // Sloppy mode functions and builtins need to replace the receiver with the
     // global proxy when called as functions (without an explicit receiver
     // object).
     if (info_->this_has_uses() &&
-        info_->is_classic_mode() &&
+        info_->strict_mode() == SLOPPY &&
         !info_->is_native()) {
       Label ok;
       int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
@@ -269,6 +269,13 @@
 }
 
 
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}
+
+
 bool LCodeGen::GenerateDeferredCode() {
   ASSERT(is_generating());
   if (deferred_.length() > 0) {
@@ -1163,8 +1170,7 @@
 
   // Check for negative zero.
   HMod* hmod = instr->hydrogen();
-  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hmod->left()->CanBeNegative()) {
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label remainder_not_zero;
     __ b(ne, &remainder_not_zero);
     __ cmp(dividend, Operand::Zero());
@@ -1176,8 +1182,6 @@
 
 void LCodeGen::DoModI(LModI* instr) {
   HMod* hmod = instr->hydrogen();
-  HValue* left = hmod->left();
-  HValue* right = hmod->right();
   if (CpuFeatures::IsSupported(SUDIV)) {
     CpuFeatureScope scope(masm(), SUDIV);
 
@@ -1188,14 +1192,14 @@
     Label done;
     // Check for x % 0, sdiv might signal an exception. We have to deopt in this
     // case because we can't return a NaN.
-    if (right->CanBeZero()) {
+    if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
       __ cmp(right_reg, Operand::Zero());
       DeoptimizeIf(eq, instr->environment());
     }
 
     // Check for kMinInt % -1, sdiv will return kMinInt, which is not what we
     // want. We have to deopt if we care about -0, because we can't return that.
-    if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
+    if (hmod->CheckFlag(HValue::kCanOverflow)) {
       Label no_overflow_possible;
       __ cmp(left_reg, Operand(kMinInt));
       __ b(ne, &no_overflow_possible);
@@ -1218,9 +1222,7 @@
     __ mls(result_reg, result_reg, right_reg, left_reg);
 
     // If we care about -0, test if the dividend is <0 and the result is 0.
-    if (left->CanBeNegative() &&
-        hmod->CanBeZero() &&
-        hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
       __ cmp(result_reg, Operand::Zero());
       __ b(ne, &done);
       __ cmp(left_reg, Operand::Zero());
@@ -1247,7 +1249,7 @@
     Label done;
     // Check for x % 0, we have to deopt in this case because we can't return a
     // NaN.
-    if (right->CanBeZero()) {
+    if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
       __ cmp(right_reg, Operand::Zero());
       DeoptimizeIf(eq, instr->environment());
     }
@@ -1276,9 +1278,7 @@
     __ sub(result_reg, left_reg, scratch, SetCC);
 
     // If we care about -0, test if the dividend is <0 and the result is 0.
-    if (left->CanBeNegative() &&
-        hmod->CanBeZero() &&
-        hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
       __ b(ne, &done);
       __ cmp(left_reg, Operand::Zero());
       DeoptimizeIf(mi, instr->environment());
@@ -1297,14 +1297,12 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ cmp(dividend, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
   }
   // Check for (kMinInt / -1).
-  if (hdiv->CheckFlag(HValue::kCanOverflow) &&
-      hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+  if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
     __ cmp(dividend, Operand(kMinInt));
     DeoptimizeIf(eq, instr->environment());
   }
@@ -1347,8 +1345,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ cmp(dividend, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
   }
@@ -1367,18 +1364,19 @@
 
 
 void LCodeGen::DoDivI(LDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
   const Register left = ToRegister(instr->left());
   const Register right = ToRegister(instr->right());
   const Register result = ToRegister(instr->result());
 
   // Check for x / 0.
-  if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
+  if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
     __ cmp(right, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
   }
 
   // Check for (0 / -x) that will produce negative zero.
-  if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+  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.
@@ -1391,10 +1389,9 @@
   }
 
   // Check for (kMinInt / -1).
-  if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow) &&
+  if (hdiv->CheckFlag(HValue::kCanOverflow) &&
       (!CpuFeatures::IsSupported(SUDIV) ||
-       !instr->hydrogen_value()->CheckFlag(
-           HValue::kAllUsesTruncatingToInt32))) {
+       !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));
@@ -1406,8 +1403,7 @@
     CpuFeatureScope scope(masm(), SUDIV);
     __ sdiv(result, left, right);
 
-    if (!instr->hydrogen_value()->CheckFlag(
-        HInstruction::kAllUsesTruncatingToInt32)) {
+    if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
       // Compute remainder and deopt if it's not zero.
       const Register remainder = scratch0();
       __ mls(remainder, result, right, left);
@@ -1425,8 +1421,7 @@
     __ vcvt_s32_f64(double_scratch0().low(), vleft);
     __ vmov(result, double_scratch0().low());
 
-    if (!instr->hydrogen_value()->CheckFlag(
-        HInstruction::kAllUsesTruncatingToInt32)) {
+    if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
       // Deopt if exact conversion to integer was not possible.
       // Use vright as scratch register.
       __ vcvt_f64_s32(double_scratch0(), double_scratch0().low());
@@ -1511,8 +1506,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ cmp(dividend, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
   }
@@ -2079,7 +2073,6 @@
   // is in the correct position.
   Assembler::BlockConstPoolScope block_const_pool(masm());
   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-  __ nop();  // Signals no inlined code.
 }
 
 
@@ -3175,7 +3168,7 @@
       case FAST_ELEMENTS:
       case FAST_SMI_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4097,8 +4090,7 @@
 
   // Name is always in r2.
   __ mov(r2, Operand(instr->name()));
-  Handle<Code> ic = StoreIC::initialize_stub(isolate(),
-                                             instr->strict_mode_flag());
+  Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
   CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
 }
 
@@ -4219,7 +4211,7 @@
       case FAST_HOLEY_ELEMENTS:
       case FAST_HOLEY_SMI_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4335,7 +4327,7 @@
   ASSERT(ToRegister(instr->key()).is(r1));
   ASSERT(ToRegister(instr->value()).is(r0));
 
-  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
+  Handle<Code> ic = instr->strict_mode() == STRICT
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
@@ -5373,7 +5365,7 @@
   // space for nested functions that don't need literals cloning.
   bool pretenure = instr->hydrogen()->pretenure();
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
-    FastNewClosureStub stub(instr->hydrogen()->language_mode(),
+    FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
                             instr->hydrogen()->is_generator());
     __ mov(r2, Operand(instr->hydrogen()->shared_info()));
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index e0f5009..21da500 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -164,9 +164,7 @@
 #undef DECLARE_DO
 
  private:
-  StrictModeFlag strict_mode_flag() const {
-    return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
-  }
+  StrictMode strict_mode() const { return info()->strict_mode(); }
 
   Scope* scope() const { return scope_; }
 
@@ -193,6 +191,7 @@
 
   // Code generation passes.  Returns true if code generation should
   // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateDeoptJumpTable();
diff --git a/src/array.js b/src/array.js
index 372b7ec..9b71283 100644
--- a/src/array.js
+++ b/src/array.js
@@ -1153,7 +1153,7 @@
   }
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsClassicModeFunction(f)) {
+  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
     receiver = ToObject(receiver);
   }
 
@@ -1201,7 +1201,7 @@
   }
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsClassicModeFunction(f)) {
+  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
     receiver = ToObject(receiver);
   }
 
@@ -1242,7 +1242,7 @@
   }
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsClassicModeFunction(f)) {
+  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
     receiver = ToObject(receiver);
   }
 
@@ -1282,7 +1282,7 @@
   }
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsClassicModeFunction(f)) {
+  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
     receiver = ToObject(receiver);
   }
 
@@ -1321,7 +1321,7 @@
   }
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsClassicModeFunction(f)) {
+  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
     receiver = ToObject(receiver);
   }
 
diff --git a/src/ast.cc b/src/ast.cc
index 6b2f48f..997d3e0 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -180,8 +180,8 @@
 }
 
 
-LanguageMode FunctionLiteral::language_mode() const {
-  return scope()->language_mode();
+StrictMode FunctionLiteral::strict_mode() const {
+  return scope()->strict_mode();
 }
 
 
@@ -379,9 +379,9 @@
     } else if (boilerplate_value->IsUninitialized()) {
       is_simple = false;
       JSObject::SetOwnElement(
-          array, i, handle(Smi::FromInt(0), isolate), kNonStrictMode);
+          array, i, handle(Smi::FromInt(0), isolate), SLOPPY);
     } else {
-      JSObject::SetOwnElement(array, i, boilerplate_value, kNonStrictMode);
+      JSObject::SetOwnElement(array, i, boilerplate_value, SLOPPY);
     }
   }
 
diff --git a/src/ast.h b/src/ast.h
index aacc5e4..262b41a 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -2315,8 +2315,7 @@
   int SourceSize() const { return end_position() - start_position(); }
   bool is_expression() const { return IsExpression::decode(bitfield_); }
   bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
-  bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
-  LanguageMode language_mode() const;
+  StrictMode strict_mode() const;
 
   int materialized_literal_count() { return materialized_literal_count_; }
   int expected_property_count() { return expected_property_count_; }
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 61361f8..dd2ddad 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -300,7 +300,7 @@
                                      PrototypePropertyMode prototypeMode);
   void MakeFunctionInstancePrototypeWritable();
 
-  Handle<Map> CreateStrictModeFunctionMap(
+  Handle<Map> CreateStrictFunctionMap(
       PrototypePropertyMode prototype_mode,
       Handle<JSFunction> empty_function);
 
@@ -328,8 +328,8 @@
   // prototype for the processing of JS builtins. Later the function maps are
   // replaced in order to make prototype writable. These are the final, writable
   // prototype, maps.
-  Handle<Map> function_map_writable_prototype_;
-  Handle<Map> strict_mode_function_map_writable_prototype_;
+  Handle<Map> sloppy_function_map_writable_prototype_;
+  Handle<Map> strict_function_map_writable_prototype_;
   Handle<JSFunction> throw_type_error_function;
 
   BootstrapperActive active_;
@@ -474,18 +474,19 @@
   // can not be used as constructors.
   Handle<Map> function_without_prototype_map =
       CreateFunctionMap(DONT_ADD_PROTOTYPE);
-  native_context()->set_function_without_prototype_map(
+  native_context()->set_sloppy_function_without_prototype_map(
       *function_without_prototype_map);
 
   // Allocate the function map. This map is temporary, used only for processing
   // of builtins.
   // Later the map is replaced with writable prototype map, allocated below.
   Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
-  native_context()->set_function_map(*function_map);
+  native_context()->set_sloppy_function_map(*function_map);
 
   // The final map for functions. Writeable prototype.
   // This map is installed in MakeFunctionInstancePrototypeWritable.
-  function_map_writable_prototype_ = CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
+  sloppy_function_map_writable_prototype_ =
+      CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
 
   Factory* factory = isolate->factory();
 
@@ -519,7 +520,7 @@
   Handle<String> empty_string =
       factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty"));
   Handle<JSFunction> empty_function =
-      factory->NewFunctionWithoutPrototype(empty_string, CLASSIC_MODE);
+      factory->NewFunctionWithoutPrototype(empty_string, SLOPPY);
 
   // --- E m p t y ---
   Handle<Code> code =
@@ -537,10 +538,10 @@
   empty_function->shared()->DontAdaptArguments();
 
   // Set prototypes for the function maps.
-  native_context()->function_map()->set_prototype(*empty_function);
-  native_context()->function_without_prototype_map()->
+  native_context()->sloppy_function_map()->set_prototype(*empty_function);
+  native_context()->sloppy_function_without_prototype_map()->
       set_prototype(*empty_function);
-  function_map_writable_prototype_->set_prototype(*empty_function);
+  sloppy_function_map_writable_prototype_->set_prototype(*empty_function);
 
   // Allocate the function map first and then patch the prototype later
   Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE);
@@ -604,11 +605,10 @@
     Handle<String> name = factory()->InternalizeOneByteString(
         STATIC_ASCII_VECTOR("ThrowTypeError"));
     throw_type_error_function =
-      factory()->NewFunctionWithoutPrototype(name, CLASSIC_MODE);
+      factory()->NewFunctionWithoutPrototype(name, SLOPPY);
     Handle<Code> code(isolate()->builtins()->builtin(
         Builtins::kStrictModePoisonPill));
-    throw_type_error_function->set_map(
-        native_context()->function_map());
+    throw_type_error_function->set_map(native_context()->sloppy_function_map());
     throw_type_error_function->set_code(*code);
     throw_type_error_function->shared()->set_code(*code);
     throw_type_error_function->shared()->DontAdaptArguments();
@@ -619,7 +619,7 @@
 }
 
 
-Handle<Map> Genesis::CreateStrictModeFunctionMap(
+Handle<Map> Genesis::CreateStrictFunctionMap(
     PrototypePropertyMode prototype_mode,
     Handle<JSFunction> empty_function) {
   Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
@@ -632,28 +632,27 @@
 
 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
   // Allocate map for the prototype-less strict mode instances.
-  Handle<Map> strict_mode_function_without_prototype_map =
-      CreateStrictModeFunctionMap(DONT_ADD_PROTOTYPE, empty);
-  native_context()->set_strict_mode_function_without_prototype_map(
-      *strict_mode_function_without_prototype_map);
+  Handle<Map> strict_function_without_prototype_map =
+      CreateStrictFunctionMap(DONT_ADD_PROTOTYPE, empty);
+  native_context()->set_strict_function_without_prototype_map(
+      *strict_function_without_prototype_map);
 
   // Allocate map for the strict mode functions. This map is temporary, used
   // only for processing of builtins.
   // Later the map is replaced with writable prototype map, allocated below.
-  Handle<Map> strict_mode_function_map =
-      CreateStrictModeFunctionMap(ADD_READONLY_PROTOTYPE, empty);
-  native_context()->set_strict_mode_function_map(
-      *strict_mode_function_map);
+  Handle<Map> strict_function_map =
+      CreateStrictFunctionMap(ADD_READONLY_PROTOTYPE, empty);
+  native_context()->set_strict_function_map(*strict_function_map);
 
   // The final map for the strict mode functions. Writeable prototype.
   // This map is installed in MakeFunctionInstancePrototypeWritable.
-  strict_mode_function_map_writable_prototype_ =
-      CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
+  strict_function_map_writable_prototype_ =
+      CreateStrictFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
 
   // Complete the callbacks.
-  PoisonArgumentsAndCaller(strict_mode_function_without_prototype_map);
-  PoisonArgumentsAndCaller(strict_mode_function_map);
-  PoisonArgumentsAndCaller(strict_mode_function_map_writable_prototype_);
+  PoisonArgumentsAndCaller(strict_function_without_prototype_map);
+  PoisonArgumentsAndCaller(strict_function_map);
+  PoisonArgumentsAndCaller(strict_function_map_writable_prototype_);
 }
 
 
@@ -1137,7 +1136,7 @@
     function->shared()->set_expected_nof_properties(2);
     Handle<JSObject> result = factory->NewJSObject(function);
 
-    native_context()->set_arguments_boilerplate(*result);
+    native_context()->set_sloppy_arguments_boilerplate(*result);
     // Note: length must be added as the first property and
     //       callee must be added as the second property.
     CHECK_NOT_EMPTY_HANDLE(isolate,
@@ -1173,22 +1172,23 @@
   {  // --- aliased_arguments_boilerplate_
     // Set up a well-formed parameter map to make assertions happy.
     Handle<FixedArray> elements = factory->NewFixedArray(2);
-    elements->set_map(heap->non_strict_arguments_elements_map());
+    elements->set_map(heap->sloppy_arguments_elements_map());
     Handle<FixedArray> array;
     array = factory->NewFixedArray(0);
     elements->set(0, *array);
     array = factory->NewFixedArray(0);
     elements->set(1, *array);
 
-    Handle<Map> old_map(native_context()->arguments_boilerplate()->map());
+    Handle<Map> old_map(
+        native_context()->sloppy_arguments_boilerplate()->map());
     Handle<Map> new_map = factory->CopyMap(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
     // NewJSObjectFromMap assumes a fast elements map.
-    new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
+    new_map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
     result->set_elements(*elements);
-    ASSERT(result->HasNonStrictArgumentsElements());
+    ASSERT(result->HasSloppyArgumentsElements());
     native_context()->set_aliased_arguments_boilerplate(*result);
   }
 
@@ -1211,7 +1211,7 @@
 
     // Create the map. Allocate one in-object field for length.
     Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
-                                      Heap::kArgumentsObjectSizeStrict);
+                                      Heap::kStrictArgumentsObjectSize);
     // Create the descriptor array for the arguments object.
     Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 3);
     DescriptorArray::WhitenessWitness witness(*descriptors);
@@ -1240,13 +1240,13 @@
     map->set_pre_allocated_property_fields(1);
     map->set_inobject_properties(1);
 
-    // Copy constructor from the non-strict arguments boilerplate.
+    // Copy constructor from the sloppy arguments boilerplate.
     map->set_constructor(
-      native_context()->arguments_boilerplate()->map()->constructor());
+      native_context()->sloppy_arguments_boilerplate()->map()->constructor());
 
     // Allocate the arguments boilerplate object.
     Handle<JSObject> result = factory->NewJSObjectFromMap(map);
-    native_context()->set_strict_mode_arguments_boilerplate(*result);
+    native_context()->set_strict_arguments_boilerplate(*result);
 
     // Add length property only for strict mode boilerplate.
     CHECK_NOT_EMPTY_HANDLE(isolate,
@@ -1389,18 +1389,19 @@
 
     // Create maps for generator functions and their prototypes.  Store those
     // maps in the native context.
-    Handle<Map> function_map(native_context()->function_map());
+    Handle<Map> function_map(native_context()->sloppy_function_map());
     Handle<Map> generator_function_map = factory()->CopyMap(function_map);
     generator_function_map->set_prototype(*generator_function_prototype);
-    native_context()->set_generator_function_map(*generator_function_map);
+    native_context()->set_sloppy_generator_function_map(
+        *generator_function_map);
 
     Handle<Map> strict_mode_function_map(
-        native_context()->strict_mode_function_map());
+        native_context()->strict_function_map());
     Handle<Map> strict_mode_generator_function_map = factory()->CopyMap(
         strict_mode_function_map);
     strict_mode_generator_function_map->set_prototype(
         *generator_function_prototype);
-    native_context()->set_strict_mode_generator_function_map(
+    native_context()->set_strict_generator_function_map(
         *strict_mode_generator_function_map);
 
     Handle<Map> object_map(native_context()->object_function()->initial_map());
@@ -1585,6 +1586,15 @@
   INSTALL_NATIVE(JSFunction, "EnqueueExternalMicrotask",
                  enqueue_external_microtask);
 
+  if (FLAG_harmony_promises) {
+    INSTALL_NATIVE(JSFunction, "IsPromise", is_promise);
+    INSTALL_NATIVE(JSFunction, "PromiseCreate", promise_create);
+    INSTALL_NATIVE(JSFunction, "PromiseResolve", promise_resolve);
+    INSTALL_NATIVE(JSFunction, "PromiseReject", promise_reject);
+    INSTALL_NATIVE(JSFunction, "PromiseChain", promise_chain);
+    INSTALL_NATIVE(JSFunction, "PromiseCatch", promise_catch);
+  }
+
   if (FLAG_harmony_proxies) {
     INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
     INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
@@ -2550,13 +2560,14 @@
   // The maps with writable prototype are created in CreateEmptyFunction
   // and CreateStrictModeFunctionMaps respectively. Initially the maps are
   // created with read-only prototype for JS builtins processing.
-  ASSERT(!function_map_writable_prototype_.is_null());
-  ASSERT(!strict_mode_function_map_writable_prototype_.is_null());
+  ASSERT(!sloppy_function_map_writable_prototype_.is_null());
+  ASSERT(!strict_function_map_writable_prototype_.is_null());
 
   // Replace function instance maps to make prototype writable.
-  native_context()->set_function_map(*function_map_writable_prototype_);
-  native_context()->set_strict_mode_function_map(
-      *strict_mode_function_map_writable_prototype_);
+  native_context()->set_sloppy_function_map(
+      *sloppy_function_map_writable_prototype_);
+  native_context()->set_strict_function_map(
+      *strict_function_map_writable_prototype_);
 }
 
 
diff --git a/src/builtins.cc b/src/builtins.cc
index f6b21f2..4e5fbd3 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -677,8 +677,8 @@
   } else {
     // Array.slice(arguments, ...) is quite a common idiom (notably more
     // than 50% of invocations in Web apps).  Treat it in C++ as well.
-    Map* arguments_map =
-        isolate->context()->native_context()->arguments_boilerplate()->map();
+    Map* arguments_map = isolate->context()->native_context()->
+        sloppy_arguments_boilerplate()->map();
 
     bool is_arguments_object_with_fast_elements =
         receiver->IsJSObject() &&
@@ -1174,7 +1174,7 @@
   }
 
   SharedFunctionInfo* shared = function->shared();
-  if (shared->is_classic_mode() && !shared->native()) {
+  if (shared->strict_mode() == SLOPPY && !shared->native()) {
     Object* recv = args[0];
     ASSERT(!recv->IsNull());
     if (recv->IsUndefined()) {
@@ -1364,8 +1364,8 @@
 }
 
 
-static void Generate_KeyedLoadIC_NonStrictArguments(MacroAssembler* masm) {
-  KeyedLoadIC::GenerateNonStrictArguments(masm);
+static void Generate_KeyedLoadIC_SloppyArguments(MacroAssembler* masm) {
+  KeyedLoadIC::GenerateSloppyArguments(masm);
 }
 
 
@@ -1390,12 +1390,12 @@
 
 
 static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode);
+  KeyedStoreIC::GenerateGeneric(masm, SLOPPY);
 }
 
 
 static void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateGeneric(masm, kStrictMode);
+  KeyedStoreIC::GenerateGeneric(masm, STRICT);
 }
 
 
@@ -1429,8 +1429,8 @@
 }
 
 
-static void Generate_KeyedStoreIC_NonStrictArguments(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateNonStrictArguments(masm);
+static void Generate_KeyedStoreIC_SloppyArguments(MacroAssembler* masm) {
+  KeyedStoreIC::GenerateSloppyArguments(masm);
 }
 
 
diff --git a/src/builtins.h b/src/builtins.h
index d977a48..88cfd53 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -137,7 +137,7 @@
                                     kNoExtraICState)                    \
   V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MONOMORPHIC,         \
                                     kNoExtraICState)                    \
-  V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, MONOMORPHIC,         \
+  V(KeyedLoadIC_SloppyArguments,    KEYED_LOAD_IC, MONOMORPHIC,         \
                                     kNoExtraICState)                    \
                                                                         \
   V(StoreIC_Setter_ForDeopt,        STORE_IC, MONOMORPHIC,              \
@@ -156,8 +156,8 @@
                                     StoreIC::kStrictModeState)          \
   V(KeyedStoreIC_Generic_Strict,    KEYED_STORE_IC, GENERIC,            \
                                     StoreIC::kStrictModeState)          \
-  V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, MONOMORPHIC,       \
-                                     kNoExtraICState)                   \
+  V(KeyedStoreIC_SloppyArguments,   KEYED_STORE_IC, MONOMORPHIC,        \
+                                    kNoExtraICState)                    \
                                                                         \
   /* Uses KeyedLoadIC_Initialize; must be after in list. */             \
   V(FunctionCall,                   BUILTIN, UNINITIALIZED,             \
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 7bd5d8b..23095f7 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -1293,7 +1293,7 @@
   HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(),
                                              NOT_TENURED, JS_FUNCTION_TYPE);
 
-  int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
+  int map_index = Context::FunctionMapIndex(casted_stub()->strict_mode(),
                                             casted_stub()->is_generator());
 
   // Compute the function map in the current native context and set that
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index fe7d77e..6bf0479 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -561,7 +561,7 @@
     case DICTIONARY_ELEMENTS:
       KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm);
       break;
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
+    case SLOPPY_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
       break;
   }
@@ -572,8 +572,8 @@
   stream->Add("ArgumentsAccessStub_");
   switch (type_) {
     case READ_ELEMENT: stream->Add("ReadElement"); break;
-    case NEW_NON_STRICT_FAST: stream->Add("NewNonStrictFast"); break;
-    case NEW_NON_STRICT_SLOW: stream->Add("NewNonStrictSlow"); break;
+    case NEW_SLOPPY_FAST: stream->Add("NewSloppyFast"); break;
+    case NEW_SLOPPY_SLOW: stream->Add("NewSloppySlow"); break;
     case NEW_STRICT: stream->Add("NewStrict"); break;
   }
 }
@@ -736,7 +736,7 @@
 
 
 void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
-  FastNewClosureStub stub(STRICT_MODE, false);
+  FastNewClosureStub stub(STRICT, false);
   InstallDescriptor(isolate, &stub);
 }
 
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 62026a8..c86b3a4 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -522,8 +522,8 @@
 
 class FastNewClosureStub : public HydrogenCodeStub {
  public:
-  explicit FastNewClosureStub(LanguageMode language_mode, bool is_generator)
-    : language_mode_(language_mode),
+  explicit FastNewClosureStub(StrictMode strict_mode, bool is_generator)
+    : strict_mode_(strict_mode),
       is_generator_(is_generator) { }
 
   virtual Handle<Code> GenerateCode(Isolate* isolate);
@@ -534,7 +534,7 @@
 
   static void InstallDescriptors(Isolate* isolate);
 
-  LanguageMode language_mode() const { return language_mode_; }
+  StrictMode strict_mode() const { return strict_mode_; }
   bool is_generator() const { return is_generator_; }
 
  private:
@@ -543,11 +543,11 @@
 
   Major MajorKey() { return FastNewClosure; }
   int NotMissMinorKey() {
-    return StrictModeBits::encode(language_mode_ != CLASSIC_MODE) |
+    return StrictModeBits::encode(strict_mode_ == STRICT) |
       IsGeneratorBits::encode(is_generator_);
   }
 
-  LanguageMode language_mode_;
+  StrictMode strict_mode_;
   bool is_generator_;
 };
 
@@ -659,8 +659,7 @@
   // Maximum number of properties in copied object.
   static const int kMaximumClonedProperties = 6;
 
-  explicit FastCloneShallowObjectStub(int length)
-      : length_(length) {
+  explicit FastCloneShallowObjectStub(int length) : length_(length) {
     ASSERT_GE(length_, 0);
     ASSERT_LE(length_, kMaximumClonedProperties);
   }
@@ -847,7 +846,7 @@
 
 class StoreICStub: public ICStub {
  public:
-  StoreICStub(Code::Kind kind, StrictModeFlag strict_mode)
+  StoreICStub(Code::Kind kind, StrictMode strict_mode)
       : ICStub(kind), strict_mode_(strict_mode) { }
 
  protected:
@@ -862,13 +861,13 @@
     return KindBits::encode(kind()) | StrictModeBits::encode(strict_mode_);
   }
 
-  StrictModeFlag strict_mode_;
+  StrictMode strict_mode_;
 };
 
 
 class StoreArrayLengthStub: public StoreICStub {
  public:
-  explicit StoreArrayLengthStub(Code::Kind kind, StrictModeFlag strict_mode)
+  explicit StoreArrayLengthStub(Code::Kind kind, StrictMode strict_mode)
       : StoreICStub(kind, strict_mode) { }
   virtual void Generate(MacroAssembler* masm);
 
@@ -1535,8 +1534,8 @@
  public:
   enum Type {
     READ_ELEMENT,
-    NEW_NON_STRICT_FAST,
-    NEW_NON_STRICT_SLOW,
+    NEW_SLOPPY_FAST,
+    NEW_SLOPPY_SLOW,
     NEW_STRICT
   };
 
@@ -1551,8 +1550,8 @@
   void Generate(MacroAssembler* masm);
   void GenerateReadElement(MacroAssembler* masm);
   void GenerateNewStrict(MacroAssembler* masm);
-  void GenerateNewNonStrictFast(MacroAssembler* masm);
-  void GenerateNewNonStrictSlow(MacroAssembler* masm);
+  void GenerateNewSloppyFast(MacroAssembler* masm);
+  void GenerateNewSloppySlow(MacroAssembler* masm);
 
   virtual void PrintName(StringStream* stream);
 };
diff --git a/src/codegen.cc b/src/codegen.cc
index f6c3668..ea0ead3 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -222,11 +222,11 @@
     case READ_ELEMENT:
       GenerateReadElement(masm);
       break;
-    case NEW_NON_STRICT_FAST:
-      GenerateNewNonStrictFast(masm);
+    case NEW_SLOPPY_FAST:
+      GenerateNewSloppyFast(masm);
       break;
-    case NEW_NON_STRICT_SLOW:
-      GenerateNewNonStrictSlow(masm);
+    case NEW_SLOPPY_SLOW:
+      GenerateNewSloppySlow(masm);
       break;
     case NEW_STRICT:
       GenerateNewStrict(masm);
diff --git a/src/compilation-cache.cc b/src/compilation-cache.cc
index a69ef4c..54d4565 100644
--- a/src/compilation-cache.cc
+++ b/src/compilation-cache.cc
@@ -269,7 +269,7 @@
 Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
     Handle<String> source,
     Handle<Context> context,
-    LanguageMode language_mode,
+    StrictMode strict_mode,
     int scope_position) {
   // Make sure not to leak the table into the surrounding handle
   // scope. Otherwise, we risk keeping old tables around even after
@@ -280,7 +280,7 @@
     for (generation = 0; generation < generations(); generation++) {
       Handle<CompilationCacheTable> table = GetTable(generation);
       result = table->LookupEval(
-          *source, *context, language_mode, scope_position);
+          *source, *context, strict_mode, scope_position);
       if (result->IsSharedFunctionInfo()) {
         break;
       }
@@ -421,7 +421,7 @@
 Handle<SharedFunctionInfo> CompilationCache::LookupEval(
     Handle<String> source,
     Handle<Context> context,
-    LanguageMode language_mode,
+    StrictMode strict_mode,
     int scope_position) {
   if (!IsEnabled()) {
     return Handle<SharedFunctionInfo>::null();
@@ -430,11 +430,11 @@
   Handle<SharedFunctionInfo> result;
   if (context->IsNativeContext()) {
     result = eval_global_.Lookup(
-        source, context, language_mode, scope_position);
+        source, context, strict_mode, scope_position);
   } else {
     ASSERT(scope_position != RelocInfo::kNoPosition);
     result = eval_contextual_.Lookup(
-        source, context, language_mode, scope_position);
+        source, context, strict_mode, scope_position);
   }
   return result;
 }
diff --git a/src/compilation-cache.h b/src/compilation-cache.h
index ead52b5..b31de31 100644
--- a/src/compilation-cache.h
+++ b/src/compilation-cache.h
@@ -136,10 +136,9 @@
 // entries:
 // 1. The source string.
 // 2. The shared function info of the calling function.
-// 3. Whether the source should be compiled as strict code or as non-strict
-//    code.
+// 3. Whether the source should be compiled as strict code or as sloppy code.
 //    Note: Currently there are clients of CompileEval that always compile
-//    non-strict code even if the calling function is a strict mode function.
+//    sloppy code even if the calling function is a strict mode function.
 //    More specifically these are the CompileString, DebugEvaluate and
 //    DebugEvaluateGlobal runtime functions.
 // 4. The start position of the calling scope.
@@ -150,7 +149,7 @@
 
   Handle<SharedFunctionInfo> Lookup(Handle<String> source,
                                     Handle<Context> context,
-                                    LanguageMode language_mode,
+                                    StrictMode strict_mode,
                                     int scope_position);
 
   void Put(Handle<String> source,
@@ -222,7 +221,7 @@
   // contain a script for the given source string.
   Handle<SharedFunctionInfo> LookupEval(Handle<String> source,
                                         Handle<Context> context,
-                                        LanguageMode language_mode,
+                                        StrictMode strict_mode,
                                         int scope_position);
 
   // Returns the regexp data associated with the given regexp if it
diff --git a/src/compiler.cc b/src/compiler.cc
index 89864e0..21f107a 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -56,7 +56,7 @@
 
 CompilationInfo::CompilationInfo(Handle<Script> script,
                                  Zone* zone)
-    : flags_(LanguageModeField::encode(CLASSIC_MODE)),
+    : flags_(StrictModeField::encode(SLOPPY)),
       script_(script),
       osr_ast_id_(BailoutId::None()),
       parameter_count_(0),
@@ -68,7 +68,7 @@
 
 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
                                  Zone* zone)
-    : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
+    : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)),
       shared_info_(shared_info),
       script_(Handle<Script>(Script::cast(shared_info->script()))),
       osr_ast_id_(BailoutId::None()),
@@ -81,7 +81,7 @@
 
 CompilationInfo::CompilationInfo(Handle<JSFunction> closure,
                                  Zone* zone)
-    : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
+    : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)),
       closure_(closure),
       shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
       script_(Handle<Script>(Script::cast(shared_info_->script()))),
@@ -97,8 +97,7 @@
 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub,
                                  Isolate* isolate,
                                  Zone* zone)
-    : flags_(LanguageModeField::encode(CLASSIC_MODE) |
-             IsLazy::encode(true)),
+    : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)),
       osr_ast_id_(BailoutId::None()),
       parameter_count_(0),
       this_has_uses_(true),
@@ -137,8 +136,8 @@
     MarkAsNative();
   }
   if (!shared_info_.is_null()) {
-    ASSERT(language_mode() == CLASSIC_MODE);
-    SetLanguageMode(shared_info_->language_mode());
+    ASSERT(strict_mode() == SLOPPY);
+    SetStrictMode(shared_info_->strict_mode());
   }
   set_bailout_reason(kUnknown);
 
@@ -237,7 +236,7 @@
     FLAG_optimize_closures &&
     closure_.is_null() &&
     !scope_->HasTrivialOuterContext() &&
-    !scope_->outer_scope_calls_non_strict_eval() &&
+    !scope_->outer_scope_calls_sloppy_eval() &&
     !scope_->inside_with();
   SetMode(is_optimizable_closure ? BASE : NONOPT);
 }
@@ -606,7 +605,7 @@
   shared->set_dont_optimize_reason(lit->dont_optimize_reason());
   shared->set_dont_inline(lit->flags()->Contains(kDontInline));
   shared->set_ast_node_count(lit->ast_node_count());
-  shared->set_language_mode(lit->language_mode());
+  shared->set_strict_mode(lit->strict_mode());
 }
 
 
@@ -631,7 +630,7 @@
   function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   function_info->set_allows_lazy_compilation_without_context(
       lit->AllowsLazyCompilationWithoutContext());
-  function_info->set_language_mode(lit->language_mode());
+  function_info->set_strict_mode(lit->strict_mode());
   function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
   function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
   function_info->set_ast_node_count(lit->ast_node_count());
@@ -662,8 +661,7 @@
   VMState<COMPILER> state(info->isolate());
   PostponeInterruptsScope postpone(info->isolate());
   if (!Parser::Parse(info)) return Handle<Code>::null();
-  LanguageMode language_mode = info->function()->language_mode();
-  info->SetLanguageMode(language_mode);
+  info->SetStrictMode(info->function()->strict_mode());
 
   if (!CompileUnoptimizedCode(info)) return Handle<Code>::null();
   Compiler::RecordFunctionCompilation(
@@ -771,8 +769,7 @@
 
   info.MarkAsGlobal();
   if (!Parser::Parse(&info)) return;
-  LanguageMode language_mode = info.function()->language_mode();
-  info.SetLanguageMode(language_mode);
+  info.SetStrictMode(info.function()->strict_mode());
 
   LiveEditFunctionTracker tracker(info.isolate(), info.function());
   if (!CompileUnoptimizedCode(&info)) return;
@@ -889,7 +886,7 @@
 
 Handle<JSFunction> Compiler::GetFunctionFromEval(Handle<String> source,
                                                  Handle<Context> context,
-                                                 LanguageMode language_mode,
+                                                 StrictMode strict_mode,
                                                  ParseRestriction restriction,
                                                  int scope_position) {
   Isolate* isolate = source->GetIsolate();
@@ -899,14 +896,14 @@
 
   CompilationCache* compilation_cache = isolate->compilation_cache();
   Handle<SharedFunctionInfo> shared_info = compilation_cache->LookupEval(
-      source, context, language_mode, scope_position);
+      source, context, strict_mode, scope_position);
 
   if (shared_info.is_null()) {
     Handle<Script> script = isolate->factory()->NewScript(source);
     CompilationInfoWithZone info(script);
     info.MarkAsEval();
     if (context->IsNativeContext()) info.MarkAsGlobal();
-    info.SetLanguageMode(language_mode);
+    info.SetStrictMode(strict_mode);
     info.SetParseRestriction(restriction);
     info.SetContext(context);
 
@@ -923,14 +920,8 @@
       // to handle eval-code in the optimizing compiler.
       shared_info->DisableOptimization(kEval);
 
-      // If caller is strict mode, the result must be in strict mode or
-      // extended mode as well, but not the other way around. Consider:
-      // eval("'use strict'; ...");
-      ASSERT(language_mode != STRICT_MODE || !shared_info->is_classic_mode());
-      // If caller is in extended mode, the result must also be in
-      // extended mode.
-      ASSERT(language_mode != EXTENDED_MODE ||
-             shared_info->is_extended_mode());
+      // If caller is strict mode, the result must be in strict mode as well.
+      ASSERT(strict_mode == SLOPPY || shared_info->strict_mode() == STRICT);
       if (!shared_info->dont_cache()) {
         compilation_cache->PutEval(
             source, context, shared_info, scope_position);
@@ -1000,9 +991,7 @@
     info.SetExtension(extension);
     info.SetPreParseData(pre_data);
     info.SetContext(context);
-    if (FLAG_use_strict) {
-      info.SetLanguageMode(FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE);
-    }
+    if (FLAG_use_strict) info.SetStrictMode(STRICT);
     result = CompileToplevel(&info);
     if (extension == NULL && !result.is_null() && !result->dont_cache()) {
       compilation_cache->PutScript(source, context, result);
@@ -1022,7 +1011,7 @@
   CompilationInfoWithZone info(script);
   info.SetFunction(literal);
   info.PrepareForCompilation(literal->scope());
-  info.SetLanguageMode(literal->scope()->language_mode());
+  info.SetStrictMode(literal->scope()->strict_mode());
 
   Isolate* isolate = info.isolate();
   Factory* factory = isolate->factory();
@@ -1118,8 +1107,7 @@
 
 static bool CompileOptimizedPrologue(CompilationInfo* info) {
   if (!Parser::Parse(info)) return false;
-  LanguageMode language_mode = info->function()->language_mode();
-  info->SetLanguageMode(language_mode);
+  info->SetStrictMode(info->function()->strict_mode());
 
   if (!Rewriter::Rewrite(info)) return false;
   if (!Scope::Analyze(info)) return false;
diff --git a/src/compiler.h b/src/compiler.h
index 2f83043..e4ade7b 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -66,11 +66,7 @@
   bool is_lazy() const { return IsLazy::decode(flags_); }
   bool is_eval() const { return IsEval::decode(flags_); }
   bool is_global() const { return IsGlobal::decode(flags_); }
-  bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
-  bool is_extended_mode() const { return language_mode() == EXTENDED_MODE; }
-  LanguageMode language_mode() const {
-    return LanguageModeField::decode(flags_);
-  }
+  StrictMode strict_mode() const { return StrictModeField::decode(flags_); }
   bool is_in_loop() const { return IsInLoop::decode(flags_); }
   FunctionLiteral* function() const { return function_; }
   Scope* scope() const { return scope_; }
@@ -109,11 +105,9 @@
   bool this_has_uses() {
     return this_has_uses_;
   }
-  void SetLanguageMode(LanguageMode language_mode) {
-    ASSERT(this->language_mode() == CLASSIC_MODE ||
-           this->language_mode() == language_mode ||
-           language_mode == EXTENDED_MODE);
-    flags_ = LanguageModeField::update(flags_, language_mode);
+  void SetStrictMode(StrictMode strict_mode) {
+    ASSERT(this->strict_mode() == SLOPPY || this->strict_mode() == strict_mode);
+    flags_ = StrictModeField::update(flags_, strict_mode);
   }
   void MarkAsInLoop() {
     ASSERT(is_lazy());
@@ -363,26 +357,26 @@
   // Flags that can be set for lazy compilation.
   class IsInLoop: public BitField<bool, 3, 1> {};
   // Strict mode - used in eager compilation.
-  class LanguageModeField: public BitField<LanguageMode, 4, 2> {};
+  class StrictModeField: public BitField<StrictMode, 4, 1> {};
   // Is this a function from our natives.
-  class IsNative: public BitField<bool, 6, 1> {};
+  class IsNative: public BitField<bool, 5, 1> {};
   // Is this code being compiled with support for deoptimization..
-  class SupportsDeoptimization: public BitField<bool, 7, 1> {};
+  class SupportsDeoptimization: public BitField<bool, 6, 1> {};
   // If compiling for debugging produce just full code matching the
   // initial mode setting.
-  class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
+  class IsCompilingForDebugging: public BitField<bool, 7, 1> {};
   // If the compiled code contains calls that require building a frame
-  class IsCalling: public BitField<bool, 9, 1> {};
+  class IsCalling: public BitField<bool, 8, 1> {};
   // If the compiled code contains calls that require building a frame
-  class IsDeferredCalling: public BitField<bool, 10, 1> {};
+  class IsDeferredCalling: public BitField<bool, 9, 1> {};
   // If the compiled code contains calls that require building a frame
-  class IsNonDeferredCalling: public BitField<bool, 11, 1> {};
+  class IsNonDeferredCalling: public BitField<bool, 10, 1> {};
   // If the compiled code saves double caller registers that it clobbers.
-  class SavesCallerDoubles: public BitField<bool, 12, 1> {};
+  class SavesCallerDoubles: public BitField<bool, 11, 1> {};
   // If the set of valid statements is restricted.
-  class ParseRestricitonField: public BitField<ParseRestriction, 13, 1> {};
+  class ParseRestricitonField: public BitField<ParseRestriction, 12, 1> {};
   // If the function requires a frame (for unspecified reasons)
-  class RequiresFrame: public BitField<bool, 14, 1> {};
+  class RequiresFrame: public BitField<bool, 13, 1> {};
 
   unsigned flags_;
 
@@ -624,7 +618,7 @@
   // Compile a String source within a context for eval.
   static Handle<JSFunction> GetFunctionFromEval(Handle<String> source,
                                                 Handle<Context> context,
-                                                LanguageMode language_mode,
+                                                StrictMode strict_mode,
                                                 ParseRestriction restriction,
                                                 int scope_position);
 
diff --git a/src/contexts.cc b/src/contexts.cc
index 710d30a..964347f 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -185,12 +185,12 @@
             *binding_flags = (init_flag == kNeedsInitialization)
                 ? MUTABLE_CHECK_INITIALIZED : MUTABLE_IS_INITIALIZED;
             break;
-          case CONST:
+          case CONST_LEGACY:
             *attributes = READ_ONLY;
             *binding_flags = (init_flag == kNeedsInitialization)
                 ? IMMUTABLE_CHECK_INITIALIZED : IMMUTABLE_IS_INITIALIZED;
             break;
-          case CONST_HARMONY:
+          case CONST:
             *attributes = READ_ONLY;
             *binding_flags = (init_flag == kNeedsInitialization)
                 ? IMMUTABLE_CHECK_INITIALIZED_HARMONY :
@@ -222,8 +222,8 @@
           }
           *index = function_index;
           *attributes = READ_ONLY;
-          ASSERT(mode == CONST || mode == CONST_HARMONY);
-          *binding_flags = (mode == CONST)
+          ASSERT(mode == CONST_LEGACY || mode == CONST);
+          *binding_flags = (mode == CONST_LEGACY)
               ? IMMUTABLE_IS_INITIALIZED : IMMUTABLE_IS_INITIALIZED_HARMONY;
           return context;
         }
diff --git a/src/contexts.h b/src/contexts.h
index d15ef86..479a692 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -135,17 +135,19 @@
   V(FLOAT64_ARRAY_FUN_INDEX, JSFunction, float64_array_fun) \
   V(UINT8_CLAMPED_ARRAY_FUN_INDEX, JSFunction, uint8_clamped_array_fun) \
   V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun) \
-  V(FUNCTION_MAP_INDEX, Map, function_map) \
-  V(STRICT_MODE_FUNCTION_MAP_INDEX, Map, strict_mode_function_map) \
-  V(FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, function_without_prototype_map) \
-  V(STRICT_MODE_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
-    strict_mode_function_without_prototype_map) \
+  V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map) \
+  V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \
+  V(SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
+    sloppy_function_without_prototype_map) \
+  V(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
+    strict_function_without_prototype_map) \
   V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)\
-  V(ARGUMENTS_BOILERPLATE_INDEX, JSObject, arguments_boilerplate) \
+  V(SLOPPY_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
+    sloppy_arguments_boilerplate) \
   V(ALIASED_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
     aliased_arguments_boilerplate) \
-  V(STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
-    strict_mode_arguments_boilerplate) \
+  V(STRICT_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
+    strict_arguments_boilerplate) \
   V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
   V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
   V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun) \
@@ -168,6 +170,12 @@
     error_message_for_code_gen_from_strings) \
   V(RUN_MICROTASKS_INDEX, JSFunction, run_microtasks) \
   V(ENQUEUE_EXTERNAL_MICROTASK_INDEX, JSFunction, enqueue_external_microtask) \
+  V(IS_PROMISE_INDEX, JSFunction, is_promise) \
+  V(PROMISE_CREATE_INDEX, JSFunction, promise_create) \
+  V(PROMISE_RESOLVE_INDEX, JSFunction, promise_resolve) \
+  V(PROMISE_REJECT_INDEX, JSFunction, promise_reject) \
+  V(PROMISE_CHAIN_INDEX, JSFunction, promise_chain) \
+  V(PROMISE_CATCH_INDEX, JSFunction, promise_catch) \
   V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
     to_complete_property_descriptor) \
   V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
@@ -180,9 +188,8 @@
     observers_begin_perform_splice) \
   V(OBSERVERS_END_SPLICE_INDEX, JSFunction, \
     observers_end_perform_splice) \
-  V(GENERATOR_FUNCTION_MAP_INDEX, Map, generator_function_map) \
-  V(STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX, Map, \
-    strict_mode_generator_function_map) \
+  V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \
+  V(STRICT_GENERATOR_FUNCTION_MAP_INDEX, Map, strict_generator_function_map) \
   V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, \
     generator_object_prototype_map) \
   V(GENERATOR_RESULT_MAP_INDEX, Map, generator_result_map)
@@ -259,14 +266,14 @@
     // These slots are only in native contexts.
     GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
     SECURITY_TOKEN_INDEX,
-    ARGUMENTS_BOILERPLATE_INDEX,
+    SLOPPY_ARGUMENTS_BOILERPLATE_INDEX,
     ALIASED_ARGUMENTS_BOILERPLATE_INDEX,
-    STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX,
+    STRICT_ARGUMENTS_BOILERPLATE_INDEX,
     REGEXP_RESULT_MAP_INDEX,
-    FUNCTION_MAP_INDEX,
-    STRICT_MODE_FUNCTION_MAP_INDEX,
-    FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
-    STRICT_MODE_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
+    SLOPPY_FUNCTION_MAP_INDEX,
+    STRICT_FUNCTION_MAP_INDEX,
+    SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
+    STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
     INITIAL_OBJECT_PROTOTYPE_INDEX,
     INITIAL_ARRAY_PROTOTYPE_INDEX,
     BOOLEAN_FUNCTION_INDEX,
@@ -323,6 +330,12 @@
     ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
     RUN_MICROTASKS_INDEX,
     ENQUEUE_EXTERNAL_MICROTASK_INDEX,
+    IS_PROMISE_INDEX,
+    PROMISE_CREATE_INDEX,
+    PROMISE_RESOLVE_INDEX,
+    PROMISE_REJECT_INDEX,
+    PROMISE_CHAIN_INDEX,
+    PROMISE_CATCH_INDEX,
     TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
     DERIVED_HAS_TRAP_INDEX,
     DERIVED_GET_TRAP_INDEX,
@@ -332,8 +345,8 @@
     OBSERVERS_ENQUEUE_SPLICE_INDEX,
     OBSERVERS_BEGIN_SPLICE_INDEX,
     OBSERVERS_END_SPLICE_INDEX,
-    GENERATOR_FUNCTION_MAP_INDEX,
-    STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX,
+    SLOPPY_GENERATOR_FUNCTION_MAP_INDEX,
+    STRICT_GENERATOR_FUNCTION_MAP_INDEX,
     GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX,
     GENERATOR_RESULT_MAP_INDEX,
 
@@ -493,14 +506,14 @@
     return kHeaderSize + index * kPointerSize - kHeapObjectTag;
   }
 
-  static int FunctionMapIndex(LanguageMode language_mode, bool is_generator) {
+  static int FunctionMapIndex(StrictMode strict_mode, bool is_generator) {
     return is_generator
-      ? (language_mode == CLASSIC_MODE
-         ? GENERATOR_FUNCTION_MAP_INDEX
-         : STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX)
-      : (language_mode == CLASSIC_MODE
-         ? FUNCTION_MAP_INDEX
-         : STRICT_MODE_FUNCTION_MAP_INDEX);
+      ? (strict_mode == SLOPPY
+         ? SLOPPY_GENERATOR_FUNCTION_MAP_INDEX
+         : STRICT_GENERATOR_FUNCTION_MAP_INDEX)
+      : (strict_mode == SLOPPY
+         ? SLOPPY_FUNCTION_MAP_INDEX
+         : STRICT_FUNCTION_MAP_INDEX);
   }
 
   static const int kSize = kHeaderSize + NATIVE_CONTEXT_SLOTS * kPointerSize;
diff --git a/src/date.cc b/src/date.cc
index 4afd8dc..4d9cf22 100644
--- a/src/date.cc
+++ b/src/date.cc
@@ -62,6 +62,7 @@
   after_ = &dst_[1];
   local_offset_ms_ = kInvalidLocalOffsetInMs;
   ymd_valid_ = false;
+  OS::TimeZoneChanged();
 }
 
 
diff --git a/src/date.js b/src/date.js
index f3d4af2..5eece68 100644
--- a/src/date.js
+++ b/src/date.js
@@ -46,6 +46,7 @@
 
 function LocalTimezone(t) {
   if (NUMBER_IS_NAN(t)) return "";
+  CheckDateCacheCurrent();
   if (t == timezone_cache_time) {
     return timezone_cache_timezone;
   }
@@ -156,6 +157,7 @@
     } else if (IS_STRING(year)) {
       // Probe the Date cache. If we already have a time value for the
       // given time, we re-use that instead of parsing the string again.
+      CheckDateCacheCurrent();
       var cache = Date_cache;
       if (cache.string === year) {
         value = cache.time;
@@ -743,10 +745,22 @@
 }
 
 
-function ResetDateCache() {
+var date_cache_version_holder;
+var date_cache_version = NAN;
+
+
+function CheckDateCacheCurrent() {
+  if (!date_cache_version_holder) {
+    date_cache_version_holder = %DateCacheVersion();
+  }
+  if (date_cache_version_holder[0] == date_cache_version) {
+    return;
+  }
+  date_cache_version = date_cache_version_holder[0];
+
   // Reset the timezone cache:
   timezone_cache_time = NAN;
-  timezone_cache_timezone = undefined;
+  timezone_cache_timezone = UNDEFINED;
 
   // Reset the date cache:
   cache = Date_cache;
diff --git a/src/debug.cc b/src/debug.cc
index 5e740bc..7014129 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -852,7 +852,7 @@
                               key,
                               Handle<Object>(global->builtins(), isolate_),
                               NONE,
-                              kNonStrictMode),
+                              SLOPPY),
       false);
 
   // Compile the JavaScript for the debugger in the debugger context.
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 1f645e4..cf3c03d 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -392,9 +392,33 @@
     element = next;
   }
 
+#ifdef DEBUG
+  // Make sure all activations of optimized code can deopt at their current PC.
+  for (StackFrameIterator it(isolate, isolate->thread_local_top());
+       !it.done(); it.Advance()) {
+    StackFrame::Type type = it.frame()->type();
+    if (type == StackFrame::OPTIMIZED) {
+      Code* code = it.frame()->LookupCode();
+      if (FLAG_trace_deopt) {
+        JSFunction* function =
+            static_cast<OptimizedFrame*>(it.frame())->function();
+        CodeTracer::Scope scope(isolate->GetCodeTracer());
+        PrintF(scope.file(), "[deoptimizer patches for lazy deopt: ");
+        function->PrintName(scope.file());
+        PrintF(scope.file(),
+               " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
+      }
+      SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
+      int deopt_index = safepoint.deoptimization_index();
+      CHECK(deopt_index != Safepoint::kNoDeoptimizationIndex);
+    }
+  }
+#endif
+
   // TODO(titzer): we need a handle scope only because of the macro assembler,
   // which is only used in EnsureCodeForDeoptimizationEntry.
   HandleScope scope(isolate);
+
   // Now patch all the codes for deoptimization.
   for (int i = 0; i < codes.length(); i++) {
     // It is finally time to die, code object.
diff --git a/src/elements-kind.cc b/src/elements-kind.cc
index d2abb04..c9480d6 100644
--- a/src/elements-kind.cc
+++ b/src/elements-kind.cc
@@ -66,7 +66,7 @@
     case FAST_HOLEY_SMI_ELEMENTS:
     case FAST_HOLEY_ELEMENTS:
     case DICTIONARY_ELEMENTS:
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
+    case SLOPPY_ARGUMENTS_ELEMENTS:
       return kPointerSizeLog2;
   }
   UNREACHABLE();
diff --git a/src/elements-kind.h b/src/elements-kind.h
index 5a3f00d..32108f5 100644
--- a/src/elements-kind.h
+++ b/src/elements-kind.h
@@ -51,7 +51,7 @@
 
   // The "slow" kind.
   DICTIONARY_ELEMENTS,
-  NON_STRICT_ARGUMENTS_ELEMENTS,
+  SLOPPY_ARGUMENTS_ELEMENTS,
   // The "fast" kind for external arrays
   EXTERNAL_INT8_ELEMENTS,
   EXTERNAL_UINT8_ELEMENTS,
diff --git a/src/elements.cc b/src/elements.cc
index 2e4667d..7123bca 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -68,7 +68,7 @@
 //     - FixedFloat64ElementsAccessor
 //     - FixedUint8ClampedElementsAccessor
 //   - DictionaryElementsAccessor
-//   - NonStrictArgumentsElementsAccessor
+//   - SloppyArgumentsElementsAccessor
 
 
 namespace v8 {
@@ -95,7 +95,7 @@
     FixedDoubleArray)                                                   \
   V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS,                    \
     SeededNumberDictionary)                                             \
-  V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS,  \
+  V(SloppyArgumentsElementsAccessor, SLOPPY_ARGUMENTS_ELEMENTS,         \
     FixedArray)                                                         \
   V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS,               \
     ExternalInt8Array)                                                  \
@@ -920,7 +920,7 @@
                              KindTraits>(name) {}
  protected:
   friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
-  friend class NonStrictArgumentsElementsAccessor;
+  friend class SloppyArgumentsElementsAccessor;
 
   typedef typename KindTraits::BackingStore BackingStore;
 
@@ -998,9 +998,9 @@
     }
     typename KindTraits::BackingStore* backing_store =
         KindTraits::BackingStore::cast(elements);
-    bool is_non_strict_arguments_elements_map =
-        backing_store->map() == heap->non_strict_arguments_elements_map();
-    if (is_non_strict_arguments_elements_map) {
+    bool is_sloppy_arguments_elements_map =
+        backing_store->map() == heap->sloppy_arguments_elements_map();
+    if (is_sloppy_arguments_elements_map) {
       backing_store = KindTraits::BackingStore::cast(
           FixedArray::cast(backing_store)->get(1));
     }
@@ -1009,7 +1009,7 @@
         ? Smi::cast(JSArray::cast(obj)->length())->value()
         : backing_store->length());
     if (key < length) {
-      if (!is_non_strict_arguments_elements_map) {
+      if (!is_sloppy_arguments_elements_map) {
         ElementsKind kind = KindTraits::Kind;
         if (IsFastPackedElementsKind(kind)) {
           MaybeObject* transitioned =
@@ -1152,9 +1152,9 @@
         CopyDictionaryToObjectElements(
             from, from_start, to, to_kind, to_start, copy_size);
         return to->GetHeap()->undefined_value();
-      case NON_STRICT_ARGUMENTS_ELEMENTS: {
+      case SLOPPY_ARGUMENTS_ELEMENTS: {
         // TODO(verwaest): This is a temporary hack to support extending
-        // NON_STRICT_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength.
+        // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength.
         // This case should be UNREACHABLE().
         FixedArray* parameter_map = FixedArray::cast(from);
         FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
@@ -1282,7 +1282,7 @@
         CopyDictionaryToDoubleElements(
             from, from_start, to, to_start, copy_size);
         break;
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
 
 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                       \
@@ -1492,7 +1492,7 @@
     Heap* heap = isolate->heap();
     FixedArray* backing_store = FixedArray::cast(obj->elements());
     bool is_arguments =
-        (obj->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS);
+        (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
     if (is_arguments) {
       backing_store = FixedArray::cast(backing_store->get(1));
     }
@@ -1632,18 +1632,18 @@
 };
 
 
-class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
-    NonStrictArgumentsElementsAccessor,
-    ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > {
+class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
+    SloppyArgumentsElementsAccessor,
+    ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > {
  public:
-  explicit NonStrictArgumentsElementsAccessor(const char* name)
+  explicit SloppyArgumentsElementsAccessor(const char* name)
       : ElementsAccessorBase<
-          NonStrictArgumentsElementsAccessor,
-          ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {}
+          SloppyArgumentsElementsAccessor,
+          ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
  protected:
   friend class ElementsAccessorBase<
-      NonStrictArgumentsElementsAccessor,
-      ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >;
+      SloppyArgumentsElementsAccessor,
+      ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
 
   MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
                                               JSObject* obj,
@@ -1859,10 +1859,18 @@
       MaybeObject* result = ElementsAccessorSubclass::
           SetLengthWithoutNormalize(backing_store, array, smi_length, value);
       if (!result->ToObject(&new_length)) return result;
-      ASSERT(new_length->IsSmi() || new_length->IsUndefined());
+      // even though the proposed length was a smi, new_length could
+      // still be a heap number because SetLengthWithoutNormalize doesn't
+      // allow the array length property to drop below the index of
+      // non-deletable elements.
+      ASSERT(new_length->IsSmi() || new_length->IsHeapNumber() ||
+             new_length->IsUndefined());
       if (new_length->IsSmi()) {
         array->set_length(Smi::cast(new_length));
         return array;
+      } else if (new_length->IsHeapNumber()) {
+        array->set_length(new_length);
+        return array;
       }
     } else {
       return ThrowArrayLengthRangeError(array->GetHeap());
diff --git a/src/elements.h b/src/elements.h
index 6353aae..9351598 100644
--- a/src/elements.h
+++ b/src/elements.h
@@ -175,7 +175,7 @@
   static void TearDown();
 
  protected:
-  friend class NonStrictArgumentsElementsAccessor;
+  friend class SloppyArgumentsElementsAccessor;
 
   virtual uint32_t GetCapacity(FixedArrayBase* backing_store) = 0;
 
diff --git a/src/execution.cc b/src/execution.cc
index 690a4e3..ac848e1 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -163,9 +163,10 @@
   }
   Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
 
-  // In non-strict mode, convert receiver.
+  // In sloppy mode, convert receiver.
   if (convert_receiver && !receiver->IsJSReceiver() &&
-      !func->shared()->native() && func->shared()->is_classic_mode()) {
+      !func->shared()->native() &&
+      func->shared()->strict_mode() == SLOPPY) {
     if (receiver->IsUndefined() || receiver->IsNull()) {
       Object* global = func->context()->global_object()->global_receiver();
       // Under some circumstances, 'global' can be the JSBuiltinsObject
diff --git a/src/factory.cc b/src/factory.cc
index 1141229..6f86647 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -927,7 +927,7 @@
 static Handle<Map> MapForNewFunction(Isolate *isolate,
                                      Handle<SharedFunctionInfo> function_info) {
   Context *context = isolate->context()->native_context();
-  int map_index = Context::FunctionMapIndex(function_info->language_mode(),
+  int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
                                             function_info->is_generator());
   return Handle<Map>(Map::cast(context->get(map_index)));
 }
@@ -1250,8 +1250,7 @@
 
 Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
                                                         Handle<Code> code) {
-  Handle<JSFunction> function = NewFunctionWithoutPrototype(name,
-                                                            CLASSIC_MODE);
+  Handle<JSFunction> function = NewFunctionWithoutPrototype(name, SLOPPY);
   function->shared()->set_code(*code);
   function->set_code(*code);
   ASSERT(!function->has_initial_map());
@@ -1627,7 +1626,7 @@
   Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
   CALL_HEAP_FUNCTION(
       isolate(),
-      isolate()->heap()->AllocateFunction(*isolate()->function_map(),
+      isolate()->heap()->AllocateFunction(*isolate()->sloppy_function_map(),
                                           *function_share,
                                           *prototype),
       JSFunction);
@@ -1644,11 +1643,11 @@
 
 Handle<JSFunction> Factory::NewFunctionWithoutPrototypeHelper(
     Handle<String> name,
-    LanguageMode language_mode) {
+    StrictMode strict_mode) {
   Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
-  Handle<Map> map = (language_mode == CLASSIC_MODE)
-      ? isolate()->function_without_prototype_map()
-      : isolate()->strict_mode_function_without_prototype_map();
+  Handle<Map> map = strict_mode == SLOPPY
+      ? isolate()->sloppy_function_without_prototype_map()
+      : isolate()->strict_function_without_prototype_map();
   CALL_HEAP_FUNCTION(isolate(),
                      isolate()->heap()->AllocateFunction(
                          *map,
@@ -1660,9 +1659,8 @@
 
 Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
     Handle<String> name,
-    LanguageMode language_mode) {
-  Handle<JSFunction> fun =
-      NewFunctionWithoutPrototypeHelper(name, language_mode);
+    StrictMode strict_mode) {
+  Handle<JSFunction> fun = NewFunctionWithoutPrototypeHelper(name, strict_mode);
   fun->set_context(isolate()->context()->native_context());
   return fun;
 }
diff --git a/src/factory.h b/src/factory.h
index 7d1a17a..558ff85 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -377,7 +377,7 @@
 
   Handle<JSFunction> NewFunctionWithoutPrototype(
       Handle<String> name,
-      LanguageMode language_mode);
+      StrictMode strict_mode);
 
   Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global);
 
@@ -580,7 +580,7 @@
 
   Handle<JSFunction> NewFunctionWithoutPrototypeHelper(
       Handle<String> name,
-      LanguageMode language_mode);
+      StrictMode strict_mode);
 
   // Create a new map cache.
   Handle<MapCache> NewMapCache(int at_least_space_for);
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 8c3f39d..5441a1d 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -893,7 +893,7 @@
 #define FLAG FLAG_READONLY
 
 // assembler-arm.h
-DEFINE_bool(enable_ool_constant_pool, false,
+DEFINE_bool(enable_ool_constant_pool, V8_OOL_CONSTANT_POOL,
             "enable use of out-of-line constant pools (ARM only)")
 
 // Cleanup...
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index d116bae..165d007 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -802,10 +802,10 @@
 
 
 int FullCodeGenerator::DeclareGlobalsFlags() {
-  ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode()));
+  ASSERT(DeclareGlobalsStrictMode::is_valid(strict_mode()));
   return DeclareGlobalsEvalFlag::encode(is_eval()) |
       DeclareGlobalsNativeFlag::encode(is_native()) |
-      DeclareGlobalsLanguageMode::encode(language_mode());
+      DeclareGlobalsStrictMode::encode(strict_mode());
 }
 
 
diff --git a/src/full-codegen.h b/src/full-codegen.h
index bc85d57..f2e39de 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -556,7 +556,7 @@
   // Helper functions to EmitVariableAssignment
   void EmitStoreToStackLocalOrContextSlot(Variable* var,
                                           MemOperand location);
-  void EmitCallStoreContextSlot(Handle<String> name, LanguageMode mode);
+  void EmitCallStoreContextSlot(Handle<String> name, StrictMode strict_mode);
 
   // Complete a named property assignment.  The receiver is expected on top
   // of the stack and the right-hand-side value in the accumulator.
@@ -602,11 +602,7 @@
   Handle<Script> script() { return info_->script(); }
   bool is_eval() { return info_->is_eval(); }
   bool is_native() { return info_->is_native(); }
-  bool is_classic_mode() { return language_mode() == CLASSIC_MODE; }
-  StrictModeFlag strict_mode() {
-    return is_classic_mode() ? kNonStrictMode : kStrictMode;
-  }
-  LanguageMode language_mode() { return function()->language_mode(); }
+  StrictMode strict_mode() { return function()->strict_mode(); }
   FunctionLiteral* function() { return info_->function(); }
   Scope* scope() { return scope_; }
 
diff --git a/src/func-name-inferrer.h b/src/func-name-inferrer.h
index f57e778..41953ff 100644
--- a/src/func-name-inferrer.h
+++ b/src/func-name-inferrer.h
@@ -28,9 +28,13 @@
 #ifndef V8_FUNC_NAME_INFERRER_H_
 #define V8_FUNC_NAME_INFERRER_H_
 
+#include "handles.h"
+#include "zone.h"
+
 namespace v8 {
 namespace internal {
 
+class FunctionLiteral;
 class Isolate;
 
 // FuncNameInferrer is a stateful class that is used to perform name
diff --git a/src/global-handles.h b/src/global-handles.h
index a406451..f46a22a 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -340,6 +340,7 @@
   enum SingletonHandle {
     I18N_TEMPLATE_ONE,
     I18N_TEMPLATE_TWO,
+    DATE_CACHE_VERSION,
 
     NUMBER_OF_SINGLETON_HANDLES
   };
diff --git a/src/globals.h b/src/globals.h
index ac5b710..85b5e6b 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -162,6 +162,9 @@
 #error Unknown target architecture endiannes
 #endif
 
+// Determine whether the architecture uses an out-of-line constant pool.
+#define V8_OOL_CONSTANT_POOL 0
+
 // Support for alternative bool type. This is only enabled if the code is
 // compiled with USE_MYBOOL defined. This catches some nasty type bugs.
 // For instance, 'bool b = "false";' results in b == true! This is a hidden
@@ -407,34 +410,9 @@
 // -----------------------------------------------------------------------------
 // Declarations for use in both the preparser and the rest of V8.
 
-// The different language modes that V8 implements. ES5 defines two language
-// modes: an unrestricted mode respectively a strict mode which are indicated by
-// CLASSIC_MODE respectively STRICT_MODE in the enum. The harmony spec drafts
-// for the next ES standard specify a new third mode which is called 'extended
-// mode'. The extended mode is only available if the harmony flag is set. It is
-// based on the 'strict mode' and adds new functionality to it. This means that
-// most of the semantics of these two modes coincide.
-//
-// In the current draft the term 'base code' is used to refer to code that is
-// neither in strict nor extended mode. However, the more distinguishing term
-// 'classic mode' is used in V8 instead to avoid mix-ups.
-
-enum LanguageMode {
-  CLASSIC_MODE,
-  STRICT_MODE,
-  EXTENDED_MODE
-};
-
-
 // The Strict Mode (ECMA-262 5th edition, 4.2.2).
-//
-// This flag is used in the backend to represent the language mode. So far
-// there is no semantic difference between the strict and the extended mode in
-// the backend, so both modes are represented by the kStrictMode value.
-enum StrictModeFlag {
-  kNonStrictMode,
-  kStrictMode
-};
+
+enum StrictMode { SLOPPY, STRICT };
 
 
 } }  // namespace v8::internal
diff --git a/src/handles.cc b/src/handles.cc
index 47bab25..899f9bf 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -509,7 +509,7 @@
   Isolate* isolate = object->GetIsolate();
   Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
   Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
-      isolate->context()->native_context()->arguments_boilerplate(),
+      isolate->context()->native_context()->sloppy_arguments_boilerplate(),
       isolate);
   Handle<JSFunction> arguments_function = Handle<JSFunction>(
       JSFunction::cast(arguments_boilerplate->map()->constructor()),
diff --git a/src/harmony-array.js b/src/harmony-array.js
index 2cedeba..d37d875 100644
--- a/src/harmony-array.js
+++ b/src/harmony-array.js
@@ -51,7 +51,7 @@
 
   if (IS_NULL_OR_UNDEFINED(thisArg)) {
     thisArg = %GetDefaultReceiver(predicate) || thisArg;
-  } else if (!IS_SPEC_OBJECT(thisArg) && %IsClassicModeFunction(predicate)) {
+  } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
     thisArg = ToObject(thisArg);
   }
 
@@ -86,7 +86,7 @@
 
   if (IS_NULL_OR_UNDEFINED(thisArg)) {
     thisArg = %GetDefaultReceiver(predicate) || thisArg;
-  } else if (!IS_SPEC_OBJECT(thisArg) && %IsClassicModeFunction(predicate)) {
+  } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
     thisArg = ToObject(thisArg);
   }
 
diff --git a/src/heap.cc b/src/heap.cc
index d54a2d6..25f7121 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -614,6 +614,9 @@
   if (FLAG_code_stats) ReportCodeStatistics("After GC");
 #endif
   if (FLAG_deopt_every_n_garbage_collections > 0) {
+    // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that
+    // the topmost optimized frame can be deoptimized safely, because it
+    // might not have a lazy bailout point right after its current PC.
     if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) {
       Deoptimizer::DeoptimizeAll(isolate());
       gcs_since_last_deopt_ = 0;
@@ -2866,7 +2869,7 @@
      TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP)
 #undef ALLOCATE_FIXED_TYPED_ARRAY_MAP
 
-    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, non_strict_arguments_elements)
+    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
 
     ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
 
@@ -4277,16 +4280,15 @@
   JSObject* boilerplate;
   int arguments_object_size;
   bool strict_mode_callee = callee->IsJSFunction() &&
-      !JSFunction::cast(callee)->shared()->is_classic_mode();
+      JSFunction::cast(callee)->shared()->strict_mode() == STRICT;
   if (strict_mode_callee) {
     boilerplate =
-        isolate()->context()->native_context()->
-            strict_mode_arguments_boilerplate();
-    arguments_object_size = kArgumentsObjectSizeStrict;
+        isolate()->context()->native_context()->strict_arguments_boilerplate();
+    arguments_object_size = kStrictArgumentsObjectSize;
   } else {
     boilerplate =
-        isolate()->context()->native_context()->arguments_boilerplate();
-    arguments_object_size = kArgumentsObjectSize;
+        isolate()->context()->native_context()->sloppy_arguments_boilerplate();
+    arguments_object_size = kSloppyArgumentsObjectSize;
   }
 
   // Check that the size of the boilerplate matches our
@@ -4312,7 +4314,7 @@
   JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsLengthIndex,
                                                 Smi::FromInt(length),
                                                 SKIP_WRITE_BARRIER);
-  // Set the callee property for non-strict mode arguments object only.
+  // Set the callee property for sloppy mode arguments object only.
   if (!strict_mode_callee) {
     JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex,
                                                   callee);
diff --git a/src/heap.h b/src/heap.h
index 2292464..304e1f8 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -164,7 +164,7 @@
   V(Map, fixed_float32_array_map, FixedFloat32ArrayMap)                        \
   V(Map, fixed_float64_array_map, FixedFloat64ArrayMap)                        \
   V(Map, fixed_uint8_clamped_array_map, FixedUint8ClampedArrayMap)             \
-  V(Map, non_strict_arguments_elements_map, NonStrictArgumentsElementsMap)     \
+  V(Map, sloppy_arguments_elements_map, SloppyArgumentsElementsMap)            \
   V(Map, function_context_map, FunctionContextMap)                             \
   V(Map, catch_context_map, CatchContextMap)                                   \
   V(Map, with_context_map, WithContextMap)                                     \
@@ -250,7 +250,7 @@
   V(empty_constant_pool_array)            \
   V(arguments_marker)                     \
   V(symbol_map)                           \
-  V(non_strict_arguments_elements_map)    \
+  V(sloppy_arguments_elements_map)        \
   V(function_context_map)                 \
   V(catch_context_map)                    \
   V(with_context_map)                     \
@@ -1078,15 +1078,15 @@
       Object* prototype,
       PretenureFlag pretenure = TENURED);
 
-  // Arguments object size.
-  static const int kArgumentsObjectSize =
+  // Sloppy mode arguments object size.
+  static const int kSloppyArgumentsObjectSize =
       JSObject::kHeaderSize + 2 * kPointerSize;
   // Strict mode arguments has no callee so it is smaller.
-  static const int kArgumentsObjectSizeStrict =
+  static const int kStrictArgumentsObjectSize =
       JSObject::kHeaderSize + 1 * kPointerSize;
   // Indicies for direct access into argument objects.
   static const int kArgumentsLengthIndex = 0;
-  // callee is only valid in non-strict mode.
+  // callee is only valid in sloppy mode.
   static const int kArgumentsCalleeIndex = 1;
 
   // Allocates an arguments object - optionally with an elements array.
diff --git a/src/hydrogen-gvn.cc b/src/hydrogen-gvn.cc
index 4c98015..827ad27 100644
--- a/src/hydrogen-gvn.cc
+++ b/src/hydrogen-gvn.cc
@@ -592,7 +592,9 @@
               graph()->use_optimistic_licm() ? "yes" : "no");
   for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
     HBasicBlock* block = graph()->blocks()->at(i);
-    if (block->IsLoopHeader()) {
+    if (block->IsLoopHeader() &&
+        block->IsReachable() &&
+        !block->IsDeoptimizing()) {
       SideEffects side_effects = loop_side_effects_[block->block_id()];
       if (FLAG_trace_gvn) {
         HeapStringAllocator allocator;
@@ -616,6 +618,7 @@
     HBasicBlock* block,
     HBasicBlock* loop_header,
     SideEffects loop_kills) {
+  if (!block->IsReachable() || block->IsDeoptimizing()) return;
   HBasicBlock* pre_header = loop_header->predecessors()->at(0);
   if (FLAG_trace_gvn) {
     HeapStringAllocator allocator;
@@ -680,10 +683,8 @@
 
 bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr,
                                             HBasicBlock* loop_header) {
-  // If we've disabled code motion or we're in a block that unconditionally
-  // deoptimizes, don't move any instructions.
-  return AllowCodeMotion() && !instr->block()->IsDeoptimizing() &&
-      instr->block()->IsReachable();
+  // If we've disabled code motion, don't move any instructions.
+  return AllowCodeMotion();
 }
 
 
@@ -776,20 +777,18 @@
   }
 
   GvnBasicBlockState* next_dominated(Zone* zone) {
-    dominated_index_++;
-    if (dominated_index_ == length_ - 1) {
-      // No need to copy the map for the last child in the dominator tree.
-      Initialize(block_->dominated_blocks()->at(dominated_index_),
-                 map(),
-                 dominators(),
-                 false,
-                 zone);
-      return this;
-    } else if (dominated_index_ < length_) {
-      return push(zone, block_->dominated_blocks()->at(dominated_index_));
-    } else {
-      return NULL;
+    while (++dominated_index_ < length_) {
+      HBasicBlock* block = block_->dominated_blocks()->at(dominated_index_);
+      if (block->IsReachable()) {
+        if (dominated_index_ == length_ - 1) {
+          // No need to copy the map for the last child in the dominator tree.
+          Initialize(block, map(), dominators(), false, zone);
+          return this;
+        }
+        return push(zone, block);
+      }
     }
+    return NULL;
   }
 
   GvnBasicBlockState* push(Zone* zone, HBasicBlock* block) {
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 79c7964..59fa3b1 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -30,6 +30,7 @@
 #include "double.h"
 #include "factory.h"
 #include "hydrogen-infer-representation.h"
+#include "property-details-inl.h"
 
 #if V8_TARGET_ARCH_IA32
 #include "ia32/lithium-ia32.h"
@@ -1433,19 +1434,19 @@
 
 
 HInstruction* HForceRepresentation::New(Zone* zone, HValue* context,
-       HValue* value, Representation required_representation) {
+       HValue* value, Representation representation) {
   if (FLAG_fold_constants && value->IsConstant()) {
     HConstant* c = HConstant::cast(value);
     if (c->HasNumberValue()) {
       double double_res = c->DoubleValue();
-      if (IsInt32Double(double_res)) {
+      if (representation.CanContainDouble(double_res)) {
         return HConstant::New(zone, context,
                               static_cast<int32_t>(double_res),
-                              required_representation);
+                              representation);
       }
     }
   }
-  return new(zone) HForceRepresentation(value, required_representation);
+  return new(zone) HForceRepresentation(value, representation);
 }
 
 
@@ -1788,7 +1789,7 @@
 }
 
 
-Range* HDiv::InferRange(Zone* zone) {
+Range* HBinaryOperation::InferRangeForDiv(Zone* zone) {
   if (representation().IsInteger32()) {
     Range* a = left()->range();
     Range* b = right()->range();
@@ -1797,11 +1798,11 @@
                                   (a->CanBeMinusZero() ||
                                    (a->CanBeZero() && b->CanBeNegative())));
     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
-      ClearFlag(HValue::kCanOverflow);
+      ClearFlag(kCanOverflow);
     }
 
     if (!b->CanBeZero()) {
-      ClearFlag(HValue::kCanBeDivByZero);
+      ClearFlag(kCanBeDivByZero);
     }
     return result;
   } else {
@@ -1810,6 +1811,16 @@
 }
 
 
+Range* HDiv::InferRange(Zone* zone) {
+  return InferRangeForDiv(zone);
+}
+
+
+Range* HMathFloorOfDiv::InferRange(Zone* zone) {
+  return InferRangeForDiv(zone);
+}
+
+
 Range* HMod::InferRange(Zone* zone) {
   if (representation().IsInteger32()) {
     Range* a = left()->range();
@@ -2460,6 +2471,7 @@
 
 
 void HSimulate::ReplayEnvironment(HEnvironment* env) {
+  if (done_with_replay_) return;
   ASSERT(env != NULL);
   env->set_ast_id(ast_id());
   env->Drop(pop_count());
@@ -2471,6 +2483,7 @@
       env->Push(value);
     }
   }
+  done_with_replay_ = true;
 }
 
 
@@ -3056,7 +3069,7 @@
 
 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
   if (FLAG_fold_constants && left()->IsConstant() && right()->IsConstant()) {
-    *block = HConstant::cast(left())->Equals(HConstant::cast(right()))
+    *block = HConstant::cast(left())->DataEquals(HConstant::cast(right()))
         ? FirstSuccessor() : SecondSuccessor();
     return true;
   }
@@ -3099,17 +3112,6 @@
 }
 
 
-bool HIsSmiAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
-  if (FLAG_fold_constants && value()->IsConstant()) {
-    *block = HConstant::cast(value())->HasSmiValue()
-        ? FirstSuccessor() : SecondSuccessor();
-    return true;
-  }
-  *block = NULL;
-  return false;
-}
-
-
 bool HIsUndetectableAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
   if (FLAG_fold_constants && value()->IsConstant()) {
     *block = HConstant::cast(value())->IsUndetectable()
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index e8ae22d..8d5d271 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -855,7 +855,6 @@
   // TODO(svenpanne) We should really use the null object pattern here.
   bool HasRange() const { return range_ != NULL; }
   bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); }
-  bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); }
   bool RangeCanInclude(int value) const {
     return !HasRange() || range()->Includes(value);
   }
@@ -1878,7 +1877,8 @@
         values_(2, zone),
         assigned_indexes_(2, zone),
         zone_(zone),
-        removable_(removable) {}
+        removable_(removable),
+        done_with_replay_(false) {}
   ~HSimulate() {}
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
@@ -1961,7 +1961,8 @@
   ZoneList<HValue*> values_;
   ZoneList<int> assigned_indexes_;
   Zone* zone_;
-  RemovableSimulate removable_;
+  RemovableSimulate removable_ : 2;
+  bool done_with_replay_ : 1;
 
 #ifdef DEBUG
   Handle<JSFunction> closure_;
@@ -3585,15 +3586,6 @@
     return object_.IsInitialized() && object_ == other;
   }
 
-#ifdef DEBUG
-  virtual void Verify() V8_OVERRIDE { }
-#endif
-
-  DECLARE_CONCRETE_INSTRUCTION(Constant)
-
- protected:
-  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
-
   virtual bool DataEquals(HValue* other) V8_OVERRIDE {
     HConstant* other_constant = HConstant::cast(other);
     if (has_int32_value_) {
@@ -3618,6 +3610,15 @@
     }
   }
 
+#ifdef DEBUG
+  virtual void Verify() V8_OVERRIDE { }
+#endif
+
+  DECLARE_CONCRETE_INSTRUCTION(Constant)
+
+ protected:
+  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
+
  private:
   friend class HGraph;
   HConstant(Handle<Object> handle, Representation r = Representation::None());
@@ -3763,6 +3764,9 @@
 
   DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
 
+ protected:
+  Range* InferRangeForDiv(Zone* zone);
+
  private:
   bool IgnoreObservedOutputRepresentation(Representation current_rep);
 
@@ -4049,7 +4053,6 @@
   }
 
   virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
-    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
       SetAllSideEffects();
@@ -4058,6 +4061,7 @@
       ClearAllSideEffects();
       SetFlag(kUseGVN);
     }
+    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
   }
 
   virtual void UpdateRepresentation(Representation new_rep,
@@ -4103,12 +4107,12 @@
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
     SetFlag(kCanOverflow);
-    if (!right->IsConstant()) {
-      SetFlag(kCanBeDivByZero);
-    }
+    SetFlag(kCanBeDivByZero);
     SetFlag(kAllowUndefinedAsNaN);
   }
 
+  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
+
   virtual bool IsDeletable() const V8_OVERRIDE { return true; }
 };
 
@@ -4123,7 +4127,6 @@
   }
 
   virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
-    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
       SetAllSideEffects();
@@ -4132,6 +4135,7 @@
       ClearAllSideEffects();
       SetFlag(kUseGVN);
     }
+    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
   }
 
   DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
@@ -4281,24 +4285,6 @@
 
 class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> {
  public:
-  HCompareObjectEqAndBranch(HValue* left,
-                            HValue* right,
-                            HBasicBlock* true_target = NULL,
-                            HBasicBlock* false_target = NULL) {
-    // TODO(danno): make this private when the IfBuilder properly constructs
-    // control flow instructions.
-    ASSERT(!left->IsConstant() ||
-           (!HConstant::cast(left)->HasInteger32Value() ||
-            HConstant::cast(left)->HasSmiValue()));
-    ASSERT(!right->IsConstant() ||
-           (!HConstant::cast(right)->HasInteger32Value() ||
-            HConstant::cast(right)->HasSmiValue()));
-    SetOperandAt(0, left);
-    SetOperandAt(1, right);
-    SetSuccessorAt(0, true_target);
-    SetSuccessorAt(1, false_target);
-  }
-
   DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*);
   DECLARE_INSTRUCTION_FACTORY_P4(HCompareObjectEqAndBranch, HValue*, HValue*,
                                  HBasicBlock*, HBasicBlock*);
@@ -4319,6 +4305,23 @@
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
+
+ private:
+  HCompareObjectEqAndBranch(HValue* left,
+                            HValue* right,
+                            HBasicBlock* true_target = NULL,
+                            HBasicBlock* false_target = NULL) {
+    ASSERT(!left->IsConstant() ||
+           (!HConstant::cast(left)->HasInteger32Value() ||
+            HConstant::cast(left)->HasSmiValue()));
+    ASSERT(!right->IsConstant() ||
+           (!HConstant::cast(right)->HasInteger32Value() ||
+            HConstant::cast(right)->HasSmiValue()));
+    SetOperandAt(0, left);
+    SetOperandAt(1, right);
+    SetSuccessorAt(0, true_target);
+    SetSuccessorAt(1, false_target);
+  }
 };
 
 
@@ -4381,8 +4384,6 @@
     return Representation::Tagged();
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
-
  protected:
   virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
   virtual int RedefinedOperandIndex() { return 0; }
@@ -4716,10 +4717,6 @@
   }
 
   virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
-    if (to.IsTagged()) {
-      SetChangesFlag(kNewSpacePromotion);
-      ClearFlag(kAllowUndefinedAsNaN);
-    }
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() ||
          left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) {
@@ -4729,6 +4726,10 @@
       ClearAllSideEffects();
       SetFlag(kUseGVN);
     }
+    if (to.IsTagged()) {
+      SetChangesFlag(kNewSpacePromotion);
+      ClearFlag(kAllowUndefinedAsNaN);
+    }
   }
 
   virtual Representation RepresentationFromInputs() V8_OVERRIDE;
@@ -5684,10 +5685,10 @@
     ASSERT(var->IsContextSlot());
     switch (var->mode()) {
       case LET:
-      case CONST_HARMONY:
+      case CONST:
         mode_ = kCheckDeoptimize;
         break;
-      case CONST:
+      case CONST_LEGACY:
         mode_ = kCheckReturnUndefined;
         break;
       default:
@@ -6638,12 +6639,12 @@
  public:
   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*,
                                               Handle<String>, HValue*,
-                                              StrictModeFlag);
+                                              StrictMode);
   HValue* object() { return OperandAt(0); }
   HValue* value() { return OperandAt(1); }
   HValue* context() { return OperandAt(2); }
   Handle<String> name() { return name_; }
-  StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
+  StrictMode strict_mode() { return strict_mode_; }
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
@@ -6658,9 +6659,9 @@
                      HValue* object,
                      Handle<String> name,
                      HValue* value,
-                     StrictModeFlag strict_mode_flag)
+                     StrictMode strict_mode)
       : name_(name),
-        strict_mode_flag_(strict_mode_flag) {
+        strict_mode_(strict_mode) {
     SetOperandAt(0, object);
     SetOperandAt(1, value);
     SetOperandAt(2, context);
@@ -6668,7 +6669,7 @@
   }
 
   Handle<String> name_;
-  StrictModeFlag strict_mode_flag_;
+  StrictMode strict_mode_;
 };
 
 
@@ -6850,13 +6851,13 @@
 class HStoreKeyedGeneric V8_FINAL : public HTemplateInstruction<4> {
  public:
   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreKeyedGeneric, HValue*,
-                                              HValue*, HValue*, StrictModeFlag);
+                                              HValue*, HValue*, StrictMode);
 
   HValue* object() { return OperandAt(0); }
   HValue* key() { return OperandAt(1); }
   HValue* value() { return OperandAt(2); }
   HValue* context() { return OperandAt(3); }
-  StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
+  StrictMode strict_mode() { return strict_mode_; }
 
   virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     // tagged[tagged] = tagged
@@ -6872,8 +6873,8 @@
                      HValue* object,
                      HValue* key,
                      HValue* value,
-                     StrictModeFlag strict_mode_flag)
-      : strict_mode_flag_(strict_mode_flag) {
+                     StrictMode strict_mode)
+      : strict_mode_(strict_mode) {
     SetOperandAt(0, object);
     SetOperandAt(1, key);
     SetOperandAt(2, value);
@@ -6881,7 +6882,7 @@
     SetAllSideEffects();
   }
 
-  StrictModeFlag strict_mode_flag_;
+  StrictMode strict_mode_;
 };
 
 
@@ -7169,7 +7170,7 @@
   bool pretenure() const { return pretenure_; }
   bool has_no_literals() const { return has_no_literals_; }
   bool is_generator() const { return is_generator_; }
-  LanguageMode language_mode() const { return language_mode_; }
+  StrictMode strict_mode() const { return strict_mode_; }
 
  private:
   HFunctionLiteral(HValue* context,
@@ -7180,7 +7181,7 @@
         pretenure_(pretenure),
         has_no_literals_(shared->num_literals() == 0),
         is_generator_(shared->is_generator()),
-        language_mode_(shared->language_mode()) {
+        strict_mode_(shared->strict_mode()) {
     SetOperandAt(0, context);
     set_representation(Representation::Tagged());
     SetChangesFlag(kNewSpacePromotion);
@@ -7192,7 +7193,7 @@
   bool pretenure_ : 1;
   bool has_no_literals_ : 1;
   bool is_generator_ : 1;
-  LanguageMode language_mode_;
+  StrictMode strict_mode_;
 };
 
 
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 4dd9955..ce5ad80 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1282,7 +1282,7 @@
     Handle<JSFunction> f = Handle<JSFunction>::cast(
         HConstant::cast(function)->handle(isolate()));
     SharedFunctionInfo* shared = f->shared();
-    if (!shared->is_classic_mode() || shared->native()) return object;
+    if (shared->strict_mode() == STRICT || shared->native()) return object;
   }
   return Add<HWrapReceiver>(object, function);
 }
@@ -5584,7 +5584,7 @@
 
 static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
   return type->Is(Type::NumberOrString()) &&
-      target->shared()->is_classic_mode() &&
+      target->shared()->strict_mode() == SLOPPY &&
       !target->shared()->native();
 }
 
@@ -5925,7 +5925,7 @@
         HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
     HStoreNamedGeneric* instr =
         Add<HStoreNamedGeneric>(global_object, var->name(),
-                                 value, function_strict_mode_flag());
+                                 value, function_strict_mode());
     USE(instr);
     ASSERT(instr->HasObservableSideEffects());
     Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
@@ -5960,7 +5960,7 @@
 
       case Variable::PARAMETER:
       case Variable::LOCAL:
-        if (var->mode() == CONST)  {
+        if (var->mode() == CONST_LEGACY)  {
           return Bailout(kUnsupportedConstCompoundAssignment);
         }
         BindIfLive(var, Top());
@@ -5989,11 +5989,11 @@
             mode = HStoreContextSlot::kCheckDeoptimize;
             break;
           case CONST:
-            return ast_context()->ReturnValue(Pop());
-          case CONST_HARMONY:
             // This case is checked statically so no need to
             // perform checks here
             UNREACHABLE();
+          case CONST_LEGACY:
+            return ast_context()->ReturnValue(Pop());
           default:
             mode = HStoreContextSlot::kNoCheck;
         }
@@ -6058,6 +6058,10 @@
 
     if (var->mode() == CONST) {
       if (expr->op() != Token::INIT_CONST) {
+        return Bailout(kNonInitializerAssignmentToConst);
+      }
+    } else if (var->mode() == CONST_LEGACY) {
+      if (expr->op() != Token::INIT_CONST_LEGACY) {
         CHECK_ALIVE(VisitForValue(expr->value()));
         return ast_context()->ReturnValue(Pop());
       }
@@ -6068,10 +6072,6 @@
         HValue* old_value = environment()->Lookup(var);
         Add<HUseConst>(old_value);
       }
-    } else if (var->mode() == CONST_HARMONY) {
-      if (expr->op() != Token::INIT_CONST_HARMONY) {
-        return Bailout(kNonInitializerAssignmentToConst);
-      }
     }
 
     if (proxy->IsArguments()) return Bailout(kAssignmentToArguments);
@@ -6127,20 +6127,20 @@
               mode = HStoreContextSlot::kCheckDeoptimize;
               break;
             case CONST:
-              return ast_context()->ReturnValue(Pop());
-            case CONST_HARMONY:
               // This case is checked statically so no need to
               // perform checks here
               UNREACHABLE();
+            case CONST_LEGACY:
+              return ast_context()->ReturnValue(Pop());
             default:
               mode = HStoreContextSlot::kNoCheck;
           }
         } else if (expr->op() == Token::INIT_VAR ||
                    expr->op() == Token::INIT_LET ||
-                   expr->op() == Token::INIT_CONST_HARMONY) {
+                   expr->op() == Token::INIT_CONST) {
           mode = HStoreContextSlot::kNoCheck;
         } else {
-          ASSERT(expr->op() == Token::INIT_CONST);
+          ASSERT(expr->op() == Token::INIT_CONST_LEGACY);
 
           mode = HStoreContextSlot::kCheckIgnoreAssignment;
         }
@@ -6234,8 +6234,7 @@
   if (access_type == LOAD) {
     return New<HLoadNamedGeneric>(object, name);
   } else {
-    return New<HStoreNamedGeneric>(
-        object, name, value, function_strict_mode_flag());
+    return New<HStoreNamedGeneric>(object, name, value, function_strict_mode());
   }
 }
 
@@ -6249,8 +6248,7 @@
   if (access_type == LOAD) {
     return New<HLoadKeyedGeneric>(object, key);
   } else {
-    return New<HStoreKeyedGeneric>(
-        object, key, value, function_strict_mode_flag());
+    return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode());
   }
 }
 
@@ -7937,7 +7935,7 @@
 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
                                                     Handle<JSFunction> target) {
   SharedFunctionInfo* shared = target->shared();
-  if (shared->is_classic_mode() && !shared->native()) {
+  if (shared->strict_mode() == SLOPPY && !shared->native()) {
     // Cannot embed a direct reference to the global proxy
     // as is it dropped on deserialization.
     CHECK(!Serializer::enabled());
@@ -8646,7 +8644,7 @@
     HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
     Add<HPushArgument>(obj);
     Add<HPushArgument>(key);
-    Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag()));
+    Add<HPushArgument>(Add<HConstant>(function_strict_mode()));
     // TODO(olivf) InvokeFunction produces a check for the parameter count,
     // even though we are certain to pass the correct number of arguments here.
     HInstruction* instr = New<HInvokeFunction>(function, 3);
@@ -8810,7 +8808,7 @@
 
   if (proxy != NULL) {
     Variable* var = proxy->var();
-    if (var->mode() == CONST)  {
+    if (var->mode() == CONST_LEGACY)  {
       return Bailout(kUnsupportedCountOperationWithConst);
     }
     // Argument of the count operation is a variable, not a property.
@@ -10020,7 +10018,7 @@
     for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
     int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
         DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
-        DeclareGlobalsLanguageMode::encode(current_info()->language_mode());
+        DeclareGlobalsStrictMode::encode(current_info()->strict_mode());
     Add<HDeclareGlobals>(array, flags);
     globals_.Clear();
   }
@@ -10032,7 +10030,7 @@
   VariableProxy* proxy = declaration->proxy();
   VariableMode mode = declaration->mode();
   Variable* variable = proxy->var();
-  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
+  bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
       globals_.Add(variable->name(), zone());
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 9c6192b..4d538f4 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -2109,9 +2109,8 @@
   void ClearInlinedTestContext() {
     function_state()->ClearInlinedTestContext();
   }
-  StrictModeFlag function_strict_mode_flag() {
-    return function_state()->compilation_info()->is_classic_mode()
-        ? kNonStrictMode : kStrictMode;
+  StrictMode function_strict_mode() {
+    return function_state()->compilation_info()->strict_mode();
   }
 
   // Generators for inline runtime functions.
diff --git a/src/i18n.cc b/src/i18n.cc
index 5c97c6b..d5ea77d 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -163,7 +163,7 @@
             reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
             pattern.length())),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   // Set time zone and calendar.
   const icu::Calendar* calendar = date_format->getCalendar();
@@ -173,7 +173,7 @@
       isolate->factory()->NewStringFromAscii(CStrVector("calendar")),
       isolate->factory()->NewStringFromAscii(CStrVector(calendar_name)),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   const icu::TimeZone& tz = calendar->getTimeZone();
   icu::UnicodeString time_zone;
@@ -188,7 +188,7 @@
           isolate->factory()->NewStringFromAscii(CStrVector("timeZone")),
           isolate->factory()->NewStringFromAscii(CStrVector("UTC")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
     } else {
       JSObject::SetProperty(
           resolved,
@@ -199,7 +199,7 @@
                     canonical_time_zone.getBuffer()),
                 canonical_time_zone.length())),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
     }
   }
 
@@ -216,14 +216,14 @@
         isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
         isolate->factory()->NewStringFromAscii(CStrVector(ns)),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   } else {
     JSObject::SetProperty(
         resolved,
         isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
         isolate->factory()->undefined_value(),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
   delete numbering_system;
 
@@ -238,7 +238,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector(result)),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   } else {
     // This would never happen, since we got the locale from ICU.
     JSObject::SetProperty(
@@ -246,7 +246,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector("und")),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
 }
 
@@ -389,7 +389,7 @@
             reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
             pattern.length())),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   // Set resolved currency code in options.currency if not empty.
   icu::UnicodeString currency(number_format->getCurrency());
@@ -402,7 +402,7 @@
               reinterpret_cast<const uint16_t*>(currency.getBuffer()),
               currency.length())),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
 
   // Ugly hack. ICU doesn't expose numbering system in any way, so we have
@@ -418,14 +418,14 @@
         isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
         isolate->factory()->NewStringFromAscii(CStrVector(ns)),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   } else {
     JSObject::SetProperty(
         resolved,
         isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
         isolate->factory()->undefined_value(),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
   delete numbering_system;
 
@@ -434,7 +434,7 @@
       isolate->factory()->NewStringFromAscii(CStrVector("useGrouping")),
       isolate->factory()->ToBoolean(number_format->isGroupingUsed()),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   JSObject::SetProperty(
       resolved,
@@ -443,7 +443,7 @@
       isolate->factory()->NewNumberFromInt(
           number_format->getMinimumIntegerDigits()),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   JSObject::SetProperty(
       resolved,
@@ -452,7 +452,7 @@
       isolate->factory()->NewNumberFromInt(
           number_format->getMinimumFractionDigits()),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   JSObject::SetProperty(
       resolved,
@@ -461,7 +461,7 @@
       isolate->factory()->NewNumberFromInt(
           number_format->getMaximumFractionDigits()),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   Handle<String> key = isolate->factory()->NewStringFromAscii(
       CStrVector("minimumSignificantDigits"));
@@ -473,7 +473,7 @@
         isolate->factory()->NewNumberFromInt(
             number_format->getMinimumSignificantDigits()),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
 
   key = isolate->factory()->NewStringFromAscii(
@@ -486,7 +486,7 @@
         isolate->factory()->NewNumberFromInt(
             number_format->getMaximumSignificantDigits()),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
 
   // Set the locale
@@ -500,7 +500,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector(result)),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   } else {
     // This would never happen, since we got the locale from ICU.
     JSObject::SetProperty(
@@ -508,7 +508,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector("und")),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
 }
 
@@ -589,7 +589,7 @@
       isolate->factory()->ToBoolean(
           collator->getAttribute(UCOL_NUMERIC_COLLATION, status) == UCOL_ON),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   switch (collator->getAttribute(UCOL_CASE_FIRST, status)) {
     case UCOL_LOWER_FIRST:
@@ -598,7 +598,7 @@
           isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
           isolate->factory()->NewStringFromAscii(CStrVector("lower")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       break;
     case UCOL_UPPER_FIRST:
       JSObject::SetProperty(
@@ -606,7 +606,7 @@
           isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
           isolate->factory()->NewStringFromAscii(CStrVector("upper")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       break;
     default:
       JSObject::SetProperty(
@@ -614,7 +614,7 @@
           isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
           isolate->factory()->NewStringFromAscii(CStrVector("false")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
   }
 
   switch (collator->getAttribute(UCOL_STRENGTH, status)) {
@@ -624,7 +624,7 @@
           isolate->factory()->NewStringFromAscii(CStrVector("strength")),
           isolate->factory()->NewStringFromAscii(CStrVector("primary")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
 
       // case level: true + s1 -> case, s1 -> base.
       if (UCOL_ON == collator->getAttribute(UCOL_CASE_LEVEL, status)) {
@@ -633,14 +633,14 @@
             isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
             isolate->factory()->NewStringFromAscii(CStrVector("case")),
             NONE,
-            kNonStrictMode);
+            SLOPPY);
       } else {
         JSObject::SetProperty(
             resolved,
             isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
             isolate->factory()->NewStringFromAscii(CStrVector("base")),
             NONE,
-            kNonStrictMode);
+            SLOPPY);
       }
       break;
     }
@@ -650,13 +650,13 @@
           isolate->factory()->NewStringFromAscii(CStrVector("strength")),
           isolate->factory()->NewStringFromAscii(CStrVector("secondary")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       JSObject::SetProperty(
           resolved,
           isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
           isolate->factory()->NewStringFromAscii(CStrVector("accent")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       break;
     case UCOL_TERTIARY:
       JSObject::SetProperty(
@@ -664,13 +664,13 @@
           isolate->factory()->NewStringFromAscii(CStrVector("strength")),
           isolate->factory()->NewStringFromAscii(CStrVector("tertiary")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       JSObject::SetProperty(
           resolved,
           isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
           isolate->factory()->NewStringFromAscii(CStrVector("variant")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       break;
     case UCOL_QUATERNARY:
       // We shouldn't get quaternary and identical from ICU, but if we do
@@ -680,13 +680,13 @@
           isolate->factory()->NewStringFromAscii(CStrVector("strength")),
           isolate->factory()->NewStringFromAscii(CStrVector("quaternary")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       JSObject::SetProperty(
           resolved,
           isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
           isolate->factory()->NewStringFromAscii(CStrVector("variant")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       break;
     default:
       JSObject::SetProperty(
@@ -694,13 +694,13 @@
           isolate->factory()->NewStringFromAscii(CStrVector("strength")),
           isolate->factory()->NewStringFromAscii(CStrVector("identical")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
       JSObject::SetProperty(
           resolved,
           isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
           isolate->factory()->NewStringFromAscii(CStrVector("variant")),
           NONE,
-          kNonStrictMode);
+          SLOPPY);
   }
 
   JSObject::SetProperty(
@@ -709,7 +709,7 @@
       isolate->factory()->ToBoolean(collator->getAttribute(
           UCOL_ALTERNATE_HANDLING, status) == UCOL_SHIFTED),
       NONE,
-      kNonStrictMode);
+      SLOPPY);
 
   // Set the locale
   char result[ULOC_FULLNAME_CAPACITY];
@@ -722,7 +722,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector(result)),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   } else {
     // This would never happen, since we got the locale from ICU.
     JSObject::SetProperty(
@@ -730,7 +730,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector("und")),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
 }
 
@@ -785,7 +785,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector(result)),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   } else {
     // This would never happen, since we got the locale from ICU.
     JSObject::SetProperty(
@@ -793,7 +793,7 @@
         isolate->factory()->NewStringFromAscii(CStrVector("locale")),
         isolate->factory()->NewStringFromAscii(CStrVector("und")),
         NONE,
-        kNonStrictMode);
+        SLOPPY);
   }
 }
 
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 38c99e4..48be1d4 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -737,7 +737,7 @@
               1 << SharedFunctionInfo::kNativeBitWithinByte);
     __ j(not_equal, &shift_arguments);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ mov(ebx, Operand(esp, eax, times_4, 0));  // First argument.
 
     // Call ToObject on the receiver if it is not an object, or use the
@@ -923,7 +923,7 @@
               1 << SharedFunctionInfo::kNativeBitWithinByte);
     __ j(not_equal, &push_receiver);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     // Call ToObject on the receiver if it is not an object, or use the
     // global object if it is null or undefined.
     __ JumpIfSmi(ebx, &call_to_object);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index d1725bb..c383ca0 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -1190,7 +1190,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // esp[0] : return address
   // esp[4] : number of parameters
   // esp[8] : receiver displacement
@@ -1215,7 +1215,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   Isolate* isolate = masm->isolate();
 
   // esp[0] : return address
@@ -1275,7 +1275,7 @@
   __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
 
   // 3. Arguments object.
-  __ add(ebx, Immediate(Heap::kArgumentsObjectSize));
+  __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
   __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
@@ -1293,7 +1293,7 @@
   __ test(ebx, ebx);
   __ j(not_zero, &has_mapped_parameters, Label::kNear);
   __ mov(edi, Operand(edi,
-         Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX)));
+         Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX)));
   __ jmp(&copy, Label::kNear);
 
   __ bind(&has_mapped_parameters);
@@ -1330,7 +1330,7 @@
   // Set up the elements pointer in the allocated arguments object.
   // If we allocated a parameter map, edi will point there, otherwise to the
   // backing store.
-  __ lea(edi, Operand(eax, Heap::kArgumentsObjectSize));
+  __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize));
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
 
   // eax = address of new object (tagged)
@@ -1349,7 +1349,7 @@
   __ j(zero, &skip_parameter_map);
 
   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
-         Immediate(isolate->factory()->non_strict_arguments_elements_map()));
+         Immediate(isolate->factory()->sloppy_arguments_elements_map()));
   __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
   __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
   __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
@@ -1475,7 +1475,7 @@
   __ j(zero, &add_arguments_object, Label::kNear);
   __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize));
   __ bind(&add_arguments_object);
-  __ add(ecx, Immediate(Heap::kArgumentsObjectSizeStrict));
+  __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize));
 
   // Do the allocation of both objects in one go.
   __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
@@ -1484,7 +1484,7 @@
   __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
   __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
   const int offset =
-      Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
+      Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX);
   __ mov(edi, Operand(edi, offset));
 
   // Copy the JS object part.
@@ -1510,7 +1510,7 @@
 
   // Set up the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ lea(edi, Operand(eax, Heap::kArgumentsObjectSizeStrict));
+  __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
          Immediate(isolate->factory()->fixed_array_map()));
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 380b15e..54c96fd 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -133,10 +133,10 @@
   }
 #endif
 
-  // Classic mode functions and builtins need to replace the receiver with the
+  // Sloppy mode functions and builtins need to replace the receiver with the
   // global proxy when called as functions (without an explicit receiver
   // object).
-  if (info->is_classic_mode() && !info->is_native()) {
+  if (info->strict_mode() == SLOPPY && !info->is_native()) {
     Label ok;
     // +1 for return address.
     int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize;
@@ -243,12 +243,12 @@
     // The stub will rewrite receiver and parameter count if the previous
     // stack frame was an arguments adapter frame.
     ArgumentsAccessStub::Type type;
-    if (!is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       type = ArgumentsAccessStub::NEW_STRICT;
     } else if (function()->has_duplicate_parameters()) {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+      type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
     } else {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+      type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
     ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
@@ -274,7 +274,7 @@
       if (scope()->is_function_scope() && scope()->function() != NULL) {
         VariableDeclaration* function = scope()->function();
         ASSERT(function->proxy()->var()->mode() == CONST ||
-               function->proxy()->var()->mode() == CONST_HARMONY);
+               function->proxy()->var()->mode() == CONST_LEGACY);
         ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
         VisitVariableDeclaration(function);
       }
@@ -744,7 +744,7 @@
   VariableProxy* proxy = declaration->proxy();
   VariableMode mode = declaration->mode();
   Variable* variable = proxy->var();
-  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
+  bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
       globals_->Add(variable->name(), zone());
@@ -1260,7 +1260,7 @@
       !pretenure &&
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
-    FastNewClosureStub stub(info->language_mode(), info->is_generator());
+    FastNewClosureStub stub(info->strict_mode(), info->is_generator());
     __ mov(ebx, Immediate(info));
     __ CallStub(&stub);
   } else {
@@ -1290,7 +1290,7 @@
   Scope* s = scope();
   while (s != NULL) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
                Immediate(0));
@@ -1304,7 +1304,7 @@
     // If no outer scope calls eval, we do not need to check more
     // context extensions.  If we have reached an eval scope, we check
     // all extensions from this point.
-    if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break;
+    if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
     s = s->outer_scope();
   }
 
@@ -1349,7 +1349,7 @@
 
   for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
                Immediate(0));
@@ -1386,14 +1386,13 @@
   } else if (var->mode() == DYNAMIC_LOCAL) {
     Variable* local = var->local_if_not_shadowed();
     __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
-    if (local->mode() == LET ||
-        local->mode() == CONST ||
-        local->mode() == CONST_HARMONY) {
+    if (local->mode() == LET || local->mode() == CONST ||
+        local->mode() == CONST_LEGACY) {
       __ cmp(eax, isolate()->factory()->the_hole_value());
       __ j(not_equal, done);
-      if (local->mode() == CONST) {
+      if (local->mode() == CONST_LEGACY) {
         __ mov(eax, isolate()->factory()->undefined_value());
-      } else {  // LET || CONST_HARMONY
+      } else {  // LET || CONST
         __ push(Immediate(var->name()));
         __ CallRuntime(Runtime::kThrowReferenceError, 1);
       }
@@ -1458,7 +1457,7 @@
           // Check that we always have valid source position.
           ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
           ASSERT(proxy->position() != RelocInfo::kNoPosition);
-          skip_init_check = var->mode() != CONST &&
+          skip_init_check = var->mode() != CONST_LEGACY &&
               var->initializer_position() < proxy->position();
         }
 
@@ -1468,14 +1467,14 @@
           GetVar(eax, var);
           __ cmp(eax, isolate()->factory()->the_hole_value());
           __ j(not_equal, &done, Label::kNear);
-          if (var->mode() == LET || var->mode() == CONST_HARMONY) {
+          if (var->mode() == LET || var->mode() == CONST) {
             // Throw a reference error when using an uninitialized let/const
             // binding in harmony mode.
             __ push(Immediate(var->name()));
             __ CallRuntime(Runtime::kThrowReferenceError, 1);
           } else {
             // Uninitalized const bindings outside of harmony mode are unholed.
-            ASSERT(var->mode() == CONST);
+            ASSERT(var->mode() == CONST_LEGACY);
             __ mov(eax, isolate()->factory()->undefined_value());
           }
           __ bind(&done);
@@ -2388,7 +2387,7 @@
       __ mov(ecx, eax);
       __ pop(edx);  // Receiver.
       __ pop(eax);  // Restore value.
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic);
@@ -2411,11 +2410,11 @@
 
 
 void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, LanguageMode mode) {
+    Handle<String> name, StrictMode strict_mode) {
   __ push(eax);  // Value.
   __ push(esi);  // Context.
   __ push(Immediate(name));
-  __ push(Immediate(Smi::FromInt(mode)));
+  __ push(Immediate(Smi::FromInt(strict_mode)));
   __ CallRuntime(Runtime::kStoreContextSlot, 4);
 }
 
@@ -2428,7 +2427,7 @@
     __ mov(edx, GlobalObjectOperand());
     CallStoreIC();
 
-  } else if (op == Token::INIT_CONST) {
+  } else if (op == Token::INIT_CONST_LEGACY) {
     // Const initializers need a write barrier.
     ASSERT(!var->IsParameter());  // No const parameters.
     if (var->IsLookupSlot()) {
@@ -2450,7 +2449,7 @@
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       Label assign;
@@ -2464,11 +2463,11 @@
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
 
-  } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
+  } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     // Assignment to var or initializing assignment to let/const
     // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       MemOperand location = VarOperand(var, ecx);
@@ -2514,7 +2513,7 @@
   __ pop(edx);
   // Record source code position before IC call.
   SetSourcePosition(expr->position());
-  Handle<Code> ic = is_classic_mode()
+  Handle<Code> ic = strict_mode() == SLOPPY
       ? isolate()->builtins()->KeyedStoreIC_Initialize()
       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
   CallIC(ic, expr->AssignmentFeedbackId());
@@ -2568,7 +2567,7 @@
       PrepareForBailout(callee, NO_REGISTERS);
     }
     // Push undefined as receiver. This is patched in the method prologue if it
-    // is a classic mode method.
+    // is a sloppy mode method.
     __ push(Immediate(isolate()->factory()->undefined_value()));
     flags = NO_CALL_FUNCTION_FLAGS;
   } else {
@@ -2685,7 +2684,7 @@
   // Push the receiver of the enclosing function.
   __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize));
   // Push the language mode.
-  __ push(Immediate(Smi::FromInt(language_mode())));
+  __ push(Immediate(Smi::FromInt(strict_mode())));
 
   // Push the start position of the scope the calls resides in.
   __ push(Immediate(Smi::FromInt(scope()->start_position())));
@@ -4167,20 +4166,18 @@
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
-            ? kNonStrictMode : kStrictMode;
-        __ push(Immediate(Smi::FromInt(strict_mode_flag)));
+        __ push(Immediate(Smi::FromInt(strict_mode())));
         __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
         context()->Plug(eax);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
         // Delete of an unqualified identifier is disallowed in strict mode
         // but "delete this" is allowed.
-        ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
+        ASSERT(strict_mode() == SLOPPY || var->is_this());
         if (var->IsUnallocated()) {
           __ push(GlobalObjectOperand());
           __ push(Immediate(var->name()));
-          __ push(Immediate(Smi::FromInt(kNonStrictMode)));
+          __ push(Immediate(Smi::FromInt(SLOPPY)));
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
           context()->Plug(eax);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
@@ -4447,7 +4444,7 @@
     case KEYED_PROPERTY: {
       __ pop(ecx);
       __ pop(edx);
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic, expr->CountStoreFeedbackId());
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 69f6e3a..c2be7da 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -351,7 +351,7 @@
   __ j(not_zero, slow_case);
 
   // Load the elements into scratch1 and check its map.
-  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
   __ mov(scratch1, FieldOperand(object, JSObject::kElementsOffset));
   __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK);
 
@@ -657,7 +657,7 @@
 }
 
 
-void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- ecx    : key
   //  -- edx    : receiver
@@ -682,7 +682,7 @@
 }
 
 
-void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : key
@@ -859,7 +859,7 @@
 
 
 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictModeFlag strict_mode) {
+                                   StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : key
@@ -1130,7 +1130,7 @@
 
 
 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictModeFlag strict_mode) {
+                                         StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : name
@@ -1151,7 +1151,7 @@
 
 
 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictModeFlag strict_mode) {
+                                              StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : key
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 56d850b..024c7ff 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -175,11 +175,11 @@
     }
 #endif
 
-    // Classic mode functions and builtins need to replace the receiver with the
+    // Sloppy mode functions and builtins need to replace the receiver with the
     // global proxy when called as functions (without an explicit receiver
     // object).
     if (info_->this_has_uses() &&
-        info_->is_classic_mode() &&
+        info_->strict_mode() == SLOPPY &&
         !info_->is_native()) {
       Label ok;
       // +1 for return address.
@@ -390,6 +390,9 @@
 
 
 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
   if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
 }
 
@@ -1421,8 +1424,7 @@
 
   // Check for negative zero.
   HMod* hmod = instr->hydrogen();
-  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hmod->left()->CanBeNegative()) {
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label remainder_not_zero;
     __ j(not_zero, &remainder_not_zero, Label::kNear);
     __ cmp(dividend, Immediate(0));
@@ -1434,8 +1436,6 @@
 
 void LCodeGen::DoModI(LModI* instr) {
   HMod* hmod = instr->hydrogen();
-  HValue* left = hmod->left();
-  HValue* right = hmod->right();
 
   Register left_reg = ToRegister(instr->left());
   ASSERT(left_reg.is(eax));
@@ -1448,14 +1448,14 @@
   Label done;
   // Check for x % 0, idiv would signal a divide error. We have to
   // deopt in this case because we can't return a NaN.
-  if (right->CanBeZero()) {
+  if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
     __ test(right_reg, Operand(right_reg));
     DeoptimizeIf(zero, instr->environment());
   }
 
   // Check for kMinInt % -1, idiv would signal a divide error. We
   // have to deopt if we care about -0, because we can't return that.
-  if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
+  if (hmod->CheckFlag(HValue::kCanOverflow)) {
     Label no_overflow_possible;
     __ cmp(left_reg, kMinInt);
     __ j(not_equal, &no_overflow_possible, Label::kNear);
@@ -1474,9 +1474,7 @@
   __ cdq();
 
   // If we care about -0, test if the dividend is <0 and the result is 0.
-  if (left->CanBeNegative() &&
-      hmod->CanBeZero() &&
-      hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label positive_left;
     __ test(left_reg, Operand(left_reg));
     __ j(not_sign, &positive_left, Label::kNear);
@@ -1500,14 +1498,12 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ test(dividend, dividend);
     DeoptimizeIf(zero, instr->environment());
   }
   // Check for (kMinInt / -1).
-  if (hdiv->CheckFlag(HValue::kCanOverflow) &&
-      hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+  if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
     __ cmp(dividend, kMinInt);
     DeoptimizeIf(zero, instr->environment());
   }
@@ -1543,8 +1539,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ test(dividend, dividend);
     DeoptimizeIf(zero, instr->environment());
   }
@@ -1565,6 +1560,7 @@
 
 
 void LCodeGen::DoDivI(LDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
   Register dividend = ToRegister(instr->left());
   Register divisor = ToRegister(instr->right());
   Register remainder = ToRegister(instr->temp());
@@ -1576,7 +1572,6 @@
   ASSERT(!divisor.is(edx));
 
   // Check for x / 0.
-  HBinaryOperation* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
     __ test(divisor, divisor);
     DeoptimizeIf(zero, instr->environment());
@@ -1606,7 +1601,7 @@
   __ cdq();
   __ idiv(divisor);
 
-  if (instr->is_flooring()) {
+  if (hdiv->IsMathFloorOfDiv()) {
     Label done;
     __ test(remainder, remainder);
     __ j(zero, &done, Label::kNear);
@@ -1614,8 +1609,7 @@
     __ sar(remainder, 31);
     __ add(result, remainder);
     __ bind(&done);
-  } else if (!instr->hydrogen()->CheckFlag(
-      HInstruction::kAllUsesTruncatingToInt32)) {
+  } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     // Deoptimize if remainder is not 0.
     __ test(remainder, remainder);
     DeoptimizeIf(not_zero, instr->environment());
@@ -1672,8 +1666,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ test(dividend, dividend);
     DeoptimizeIf(zero, instr->environment());
   }
@@ -2295,7 +2288,6 @@
 
   BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-  __ nop();  // Signals no inlined code.
 }
 
 
@@ -3428,7 +3420,7 @@
       case FAST_HOLEY_ELEMENTS:
       case FAST_HOLEY_DOUBLE_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4435,8 +4427,7 @@
   ASSERT(ToRegister(instr->value()).is(eax));
 
   __ mov(ecx, instr->name());
-  Handle<Code> ic = StoreIC::initialize_stub(isolate(),
-                                             instr->strict_mode_flag());
+  Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -4541,7 +4532,7 @@
       case FAST_HOLEY_ELEMENTS:
       case FAST_HOLEY_DOUBLE_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4687,7 +4678,7 @@
   ASSERT(ToRegister(instr->key()).is(ecx));
   ASSERT(ToRegister(instr->value()).is(eax));
 
-  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
+  Handle<Code> ic = instr->strict_mode() == STRICT
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -5998,7 +5989,7 @@
   // space for nested functions that don't need literals cloning.
   bool pretenure = instr->hydrogen()->pretenure();
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
-    FastNewClosureStub stub(instr->hydrogen()->language_mode(),
+    FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
                             instr->hydrogen()->is_generator());
     __ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index c5e253b..079595c 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -179,9 +179,7 @@
 #undef DECLARE_DO
 
  private:
-  StrictModeFlag strict_mode_flag() const {
-    return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
-  }
+  StrictMode strict_mode() const { return info()->strict_mode(); }
 
   Scope* scope() const { return scope_; }
 
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index c4ad7e8..896b499 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -679,15 +679,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);
 
-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -980,6 +971,26 @@
       chunk_->AddInstruction(clobber, current_block_);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+      LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+            SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -1327,16 +1338,15 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      (instr->CheckFlag(HValue::kCanOverflow) &&
-       instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+  LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+          dividend, divisor));
+  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
       (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
-       divisor != 1 && divisor != -1);
-  return can_deopt ? AssignEnvironment(result) : result;
+       divisor != 1 && divisor != -1)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1348,15 +1358,14 @@
   int32_t divisor = instr->right()->GetInteger32Constant();
   LOperand* temp1 = FixedTemp(eax);
   LOperand* temp2 = FixedTemp(edx);
-  LInstruction* result =
-      DefineFixed(
-          new(zone()) LDivByConstI(dividend, divisor, temp1, temp2), edx);
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineFixed(new(zone()) LDivByConstI(
+          dividend, divisor, temp1, temp2), edx);
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1367,9 +1376,16 @@
   LOperand* dividend = UseFixed(instr->left(), eax);
   LOperand* divisor = UseRegister(instr->right());
   LOperand* temp = FixedTemp(edx);
-  LInstruction* result =
-      DefineFixed(new(zone()) LDivI(dividend, divisor, temp), eax);
-  return AssignEnvironment(result);
+  LInstruction* result = DefineFixed(new(zone()) LDivI(
+          dividend, divisor, temp), eax);
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      instr->CheckFlag(HValue::kCanOverflow) ||
+      (!instr->IsMathFloorOfDiv() &&
+       !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1418,8 +1434,7 @@
                   edx);
   bool can_deopt =
       divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0);
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
   return can_deopt ? AssignEnvironment(result) : result;
 }
 
@@ -1441,12 +1456,12 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegisterAtStart(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      instr->left()->CanBeNegative();
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+          dividend, divisor));
+  if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1458,14 +1473,12 @@
   int32_t divisor = instr->right()->GetInteger32Constant();
   LOperand* temp1 = FixedTemp(eax);
   LOperand* temp2 = FixedTemp(edx);
-  LInstruction* result =
-      DefineFixed(
-          new(zone()) LModByConstI(dividend, divisor, temp1, temp2), eax);
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->CanBeNegative());
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineFixed(new(zone()) LModByConstI(
+          dividend, divisor, temp1, temp2), eax);
+  if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1476,16 +1489,13 @@
   LOperand* dividend = UseFixed(instr->left(), eax);
   LOperand* divisor = UseRegister(instr->right());
   LOperand* temp = FixedTemp(edx);
-  LInstruction* result =
-      DefineFixed(new(zone()) LModI(dividend, divisor, temp), edx);
-  bool can_deopt = (instr->right()->CanBeZero() ||
-                    (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-                     instr->left()->RangeCanInclude(kMinInt) &&
-                     instr->right()->RangeCanInclude(-1)) ||
-                    (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-                     instr->left()->CanBeNegative() &&
-                     instr->CanBeZero()));
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineFixed(new(zone()) LModI(
+          dividend, divisor, temp), edx);
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2586,22 +2596,6 @@
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (!pending_deoptimization_ast_id_.IsNone()) {
-    ASSERT(pending_deoptimization_ast_id_ == instr->ast_id());
-    LLazyBailout* lazy_bailout = new(zone()) LLazyBailout;
-    LInstruction* result = AssignEnvironment(lazy_bailout);
-    // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }
 
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index ac9cffa..5770ff6 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -756,8 +756,6 @@
   LOperand* right() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
-  bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
   DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
 };
@@ -2241,7 +2239,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
   Handle<Object> name() const { return hydrogen()->name(); }
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2298,7 +2296,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2754,9 +2752,7 @@
         current_instruction_(NULL),
         current_block_(NULL),
         next_block_(NULL),
-        allocator_(allocator),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        allocator_(allocator) { }
 
   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -2908,8 +2904,6 @@
   HBasicBlock* current_block_;
   HBasicBlock* next_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;
 
   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 2e5b835..eef2edd 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -2833,6 +2833,15 @@
 }
 
 
+void MacroAssembler::Move(Register dst, Immediate imm) {
+  if (imm.is_zero()) {
+    xor_(dst, dst);
+  } else {
+    mov(dst, imm);
+  }
+}
+
+
 void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
   if (FLAG_native_code_counters && counter->Enabled()) {
     mov(Operand::StaticVariable(ExternalReference(counter)), Immediate(value));
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index dafa65d..7f393c9 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -843,6 +843,9 @@
   // Move if the registers are not identical.
   void Move(Register target, Register source);
 
+  // Move a constant into a register using the most efficient encoding.
+  void Move(Register dst, Immediate imm);
+
   // Push a handle value.
   void Push(Handle<Object> handle) { push(Immediate(handle)); }
   void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
diff --git a/src/ic.cc b/src/ic.cc
index 3b54b9c..a70ac1c 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -943,8 +943,8 @@
         Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
         if (!object->IsJSObject() &&
             !function->IsBuiltin() &&
-            function->shared()->is_classic_mode()) {
-          // Calling non-strict non-builtins with a value as the receiver
+            function->shared()->strict_mode() == SLOPPY) {
+          // Calling sloppy non-builtins with a value as the receiver
           // requires boxing.
           break;
         }
@@ -1078,12 +1078,12 @@
     } else if (object->IsJSObject()) {
       Handle<JSObject> receiver = Handle<JSObject>::cast(object);
       if (receiver->elements()->map() ==
-          isolate()->heap()->non_strict_arguments_elements_map()) {
-        stub = non_strict_arguments_stub();
+          isolate()->heap()->sloppy_arguments_elements_map()) {
+        stub = sloppy_arguments_stub();
       } else if (receiver->HasIndexedInterceptor()) {
         stub = indexed_interceptor_stub();
       } else if (!key->ToSmi()->IsFailure() &&
-                 (!target().is_identical_to(non_strict_arguments_stub()))) {
+                 (!target().is_identical_to(sloppy_arguments_stub()))) {
         stub = LoadElementStub(receiver);
       }
     }
@@ -1182,7 +1182,7 @@
   }
 
   // The length property of string values is read-only. Throw in strict mode.
-  if (strict_mode() == kStrictMode && object->IsString() &&
+  if (strict_mode() == STRICT && object->IsString() &&
       name->Equals(isolate()->heap()->length_string())) {
     return TypeError("strict_read_only_property", object, name);
   }
@@ -1233,7 +1233,7 @@
   LookupResult lookup(isolate());
   bool can_store = LookupForWrite(receiver, name, value, &lookup, this);
   if (!can_store &&
-      strict_mode() == kStrictMode &&
+      strict_mode() == STRICT &&
       !(lookup.IsProperty() && lookup.IsReadOnly()) &&
       object->IsGlobalObject()) {
     // Strict mode doesn't allow setting non-existent global property.
@@ -1263,7 +1263,7 @@
 
 
 Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
-                                      StrictModeFlag strict_mode) {
+                                      StrictMode strict_mode) {
   ExtraICState extra_state = ComputeExtraICState(strict_mode);
   Handle<Code> ic = isolate->stub_cache()->ComputeStore(
       UNINITIALIZED, extra_state);
@@ -1282,7 +1282,7 @@
 
 
 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate,
-                                           StrictModeFlag strict_mode) {
+                                           StrictMode strict_mode) {
   ExtraICState state = ComputeExtraICState(strict_mode);
   return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state);
 }
@@ -1316,7 +1316,7 @@
 
   Handle<JSObject> holder(lookup->holder());
   // Handlers do not use strict mode.
-  StoreStubCompiler compiler(isolate(), kNonStrictMode, kind());
+  StoreStubCompiler compiler(isolate(), SLOPPY, kind());
   switch (lookup->type()) {
     case FIELD:
       return compiler.CompileStoreField(receiver, lookup, name);
@@ -1687,12 +1687,12 @@
         Handle<JSObject> receiver = Handle<JSObject>::cast(object);
         bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure();
         if (receiver->elements()->map() ==
-            isolate()->heap()->non_strict_arguments_elements_map()) {
-          if (strict_mode() == kNonStrictMode) {
-            stub = non_strict_arguments_stub();
+            isolate()->heap()->sloppy_arguments_elements_map()) {
+          if (strict_mode() == SLOPPY) {
+            stub = sloppy_arguments_stub();
           }
         } else if (key_is_smi_like &&
-                   !(target().is_identical_to(non_strict_arguments_stub()))) {
+                   !(target().is_identical_to(sloppy_arguments_stub()))) {
           // We should go generic if receiver isn't a dictionary, but our
           // prototype chain does have dictionary elements. This ensures that
           // other non-dictionary receivers in the polymorphic case benefit
@@ -1899,7 +1899,7 @@
   Handle<Object> object = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
   Handle<Object> value = args.at<Object>(2);
-  StrictModeFlag strict_mode = ic.strict_mode();
+  StrictMode strict_mode = ic.strict_mode();
   Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
                                                      value,
                                                      NONE,
@@ -1916,7 +1916,7 @@
   Handle<Object> object = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
   Handle<Object> value = args.at<Object>(2);
-  StrictModeFlag strict_mode = ic.strict_mode();
+  StrictMode strict_mode = ic.strict_mode();
   Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
                                                      value,
                                                      NONE,
@@ -1934,7 +1934,7 @@
   Handle<Map> map = args.at<Map>(1);
   Handle<Object> key = args.at<Object>(2);
   Handle<Object> object = args.at<Object>(3);
-  StrictModeFlag strict_mode = ic.strict_mode();
+  StrictMode strict_mode = ic.strict_mode();
   if (object->IsJSObject()) {
     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
                                      map->elements_kind());
diff --git a/src/ic.h b/src/ic.h
index 213a481..ec9fe8b 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -399,7 +399,7 @@
   static void GenerateGeneric(MacroAssembler* masm);
   static void GenerateString(MacroAssembler* masm);
   static void GenerateIndexedInterceptor(MacroAssembler* masm);
-  static void GenerateNonStrictArguments(MacroAssembler* masm);
+  static void GenerateSloppyArguments(MacroAssembler* masm);
 
   // Bit mask to be tested against bit field for the cases when
   // generic stub should go into slow case.
@@ -436,8 +436,8 @@
   Handle<Code> indexed_interceptor_stub() {
     return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
   }
-  Handle<Code> non_strict_arguments_stub() {
-    return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
+  Handle<Code> sloppy_arguments_stub() {
+    return isolate()->builtins()->KeyedLoadIC_SloppyArguments();
   }
   Handle<Code> string_stub() {
     return isolate()->builtins()->KeyedLoadIC_String();
@@ -451,12 +451,11 @@
 
 class StoreIC: public IC {
  public:
-  class StrictModeState: public BitField<StrictModeFlag, 1, 1> {};
-  static ExtraICState ComputeExtraICState(StrictModeFlag flag) {
+  class StrictModeState: public BitField<StrictMode, 1, 1> {};
+  static ExtraICState ComputeExtraICState(StrictMode flag) {
     return StrictModeState::encode(flag);
   }
-
-  static StrictModeFlag GetStrictMode(ExtraICState state) {
+  static StrictMode GetStrictMode(ExtraICState state) {
     return StrictModeState::decode(state);
   }
 
@@ -470,7 +469,7 @@
     ASSERT(IsStoreStub());
   }
 
-  StrictModeFlag strict_mode() const {
+  StrictMode strict_mode() const {
     return StrictModeState::decode(extra_ic_state());
   }
 
@@ -484,10 +483,10 @@
   static void GenerateMegamorphic(MacroAssembler* masm);
   static void GenerateNormal(MacroAssembler* masm);
   static void GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictModeFlag strict_mode);
+                                         StrictMode strict_mode);
 
   static Handle<Code> initialize_stub(Isolate* isolate,
-                                      StrictModeFlag strict_mode);
+                                      StrictMode strict_mode);
 
   MUST_USE_RESULT MaybeObject* Store(
       Handle<Object> object,
@@ -512,7 +511,7 @@
   }
 
   static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
-                                           StrictModeFlag strict_mode);
+                                           StrictMode strict_mode);
 
   // Update the inline cache and the global stub cache based on the
   // lookup result.
@@ -559,7 +558,7 @@
   class ExtraICStateKeyedAccessStoreMode:
       public BitField<KeyedAccessStoreMode, 2, 4> {};  // NOLINT
 
-  static ExtraICState ComputeExtraICState(StrictModeFlag flag,
+  static ExtraICState ComputeExtraICState(StrictMode flag,
                                           KeyedAccessStoreMode mode) {
     return StrictModeState::encode(flag) |
         ExtraICStateKeyedAccessStoreMode::encode(mode);
@@ -587,9 +586,9 @@
   static void GenerateMiss(MacroAssembler* masm);
   static void GenerateSlow(MacroAssembler* masm);
   static void GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictModeFlag strict_mode);
-  static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
-  static void GenerateNonStrictArguments(MacroAssembler* masm);
+                                         StrictMode strict_mode);
+  static void GenerateGeneric(MacroAssembler* masm, StrictMode strict_mode);
+  static void GenerateSloppyArguments(MacroAssembler* masm);
 
  protected:
   virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
@@ -600,8 +599,8 @@
     return pre_monomorphic_stub(isolate(), strict_mode());
   }
   static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
-                                           StrictModeFlag strict_mode) {
-    if (strict_mode == kStrictMode) {
+                                           StrictMode strict_mode) {
+    if (strict_mode == STRICT) {
       return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
     } else {
       return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
@@ -611,7 +610,7 @@
     return isolate()->builtins()->KeyedStoreIC_Slow();
   }
   virtual Handle<Code> megamorphic_stub() {
-    if (strict_mode() == kStrictMode) {
+    if (strict_mode() == STRICT) {
       return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
     } else {
       return isolate()->builtins()->KeyedStoreIC_Generic();
@@ -630,15 +629,15 @@
 
   // Stub accessors.
   virtual Handle<Code> generic_stub() const {
-    if (strict_mode() == kStrictMode) {
+    if (strict_mode() == STRICT) {
       return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
     } else {
       return isolate()->builtins()->KeyedStoreIC_Generic();
     }
   }
 
-  Handle<Code> non_strict_arguments_stub() {
-    return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
+  Handle<Code> sloppy_arguments_stub() {
+    return isolate()->builtins()->KeyedStoreIC_SloppyArguments();
   }
 
   static void Clear(Isolate* isolate, Address address, Code* target);
diff --git a/src/isolate.cc b/src/isolate.cc
index 8c1c2c1..bb97c93 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -453,10 +453,10 @@
   // If the caller parameter is a function we skip frames until we're
   // under it before starting to collect.
   bool seen_caller = !caller->IsJSFunction();
-  // First element is reserved to store the number of non-strict frames.
+  // First element is reserved to store the number of sloppy frames.
   int cursor = 1;
   int frames_seen = 0;
-  int non_strict_frames = 0;
+  int sloppy_frames = 0;
   bool encountered_strict_function = false;
   for (StackFrameIterator iter(this);
        !iter.done() && frames_seen < limit;
@@ -487,13 +487,13 @@
         Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this);
         // The stack trace API should not expose receivers and function
         // objects on frames deeper than the top-most one with a strict
-        // mode function.  The number of non-strict frames is stored as
+        // mode function.  The number of sloppy frames is stored as
         // first element in the result array.
         if (!encountered_strict_function) {
-          if (!fun->shared()->is_classic_mode()) {
+          if (fun->shared()->strict_mode() == STRICT) {
             encountered_strict_function = true;
           } else {
-            non_strict_frames++;
+            sloppy_frames++;
           }
         }
         elements->set(cursor++, *recv);
@@ -503,7 +503,7 @@
       }
     }
   }
-  elements->set(0, Smi::FromInt(non_strict_frames));
+  elements->set(0, Smi::FromInt(sloppy_frames));
   Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
   result->set_length(Smi::FromInt(cursor));
   return result;
diff --git a/src/json-parser.h b/src/json-parser.h
index c164ebf..0973589 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -361,7 +361,7 @@
           Handle<Object> value = ParseJsonValue();
           if (value.is_null()) return ReportUnexpectedCharacter();
 
-          JSObject::SetOwnElement(json_object, index, value, kNonStrictMode);
+          JSObject::SetOwnElement(json_object, index, value, SLOPPY);
           continue;
         }
         // Not an index, fallback to the slow path.
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 5da91ad..91f8150 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -49,14 +49,14 @@
 #ifdef ENABLE_DEBUGGER_SUPPORT
 
 
-void SetElementNonStrict(Handle<JSObject> object,
-                         uint32_t index,
-                         Handle<Object> value) {
+void SetElementSloppy(Handle<JSObject> object,
+                      uint32_t index,
+                      Handle<Object> value) {
   // Ignore return value from SetElement. It can only be a failure if there
   // are element setters causing exceptions and the debugger context has none
   // of these.
   Handle<Object> no_failure =
-      JSObject::SetElement(object, index, value, NONE, kNonStrictMode);
+      JSObject::SetElement(object, index, value, NONE, SLOPPY);
   ASSERT(!no_failure.is_null());
   USE(no_failure);
 }
@@ -359,17 +359,17 @@
 
   void WriteChunk(int char_pos1, int char_pos2, int char_len1, int char_len2) {
     Isolate* isolate = array_->GetIsolate();
-    SetElementNonStrict(array_,
-                        current_size_,
-                        Handle<Object>(Smi::FromInt(char_pos1), isolate));
-    SetElementNonStrict(array_,
-                        current_size_ + 1,
-                        Handle<Object>(Smi::FromInt(char_pos1 + char_len1),
-                                       isolate));
-    SetElementNonStrict(array_,
-                        current_size_ + 2,
-                        Handle<Object>(Smi::FromInt(char_pos2 + char_len2),
-                                       isolate));
+    SetElementSloppy(array_,
+                     current_size_,
+                     Handle<Object>(Smi::FromInt(char_pos1), isolate));
+    SetElementSloppy(array_,
+                     current_size_ + 1,
+                     Handle<Object>(Smi::FromInt(char_pos1 + char_len1),
+                                    isolate));
+    SetElementSloppy(array_,
+                     current_size_ + 2,
+                     Handle<Object>(Smi::FromInt(char_pos2 + char_len2),
+                                    isolate));
     current_size_ += 3;
   }
 
@@ -662,12 +662,12 @@
 
  protected:
   void SetField(int field_position, Handle<Object> value) {
-    SetElementNonStrict(array_, field_position, value);
+    SetElementSloppy(array_, field_position, value);
   }
   void SetSmiValueField(int field_position, int value) {
-    SetElementNonStrict(array_,
-                        field_position,
-                        Handle<Smi>(Smi::FromInt(value), isolate()));
+    SetElementSloppy(array_,
+                     field_position,
+                     Handle<Smi>(Smi::FromInt(value), isolate()));
   }
   Object* GetField(int field_position) {
     return array_->GetElementNoExceptionThrown(isolate(), field_position);
@@ -818,7 +818,7 @@
                               fun->materialized_literal_count(),
                               current_parent_index_);
     current_parent_index_ = len_;
-    SetElementNonStrict(result_, len_, info.GetJSArray());
+    SetElementSloppy(result_, len_, info.GetJSArray());
     len_++;
   }
 
@@ -885,20 +885,20 @@
       context_list.Sort(&Variable::CompareIndex);
 
       for (int i = 0; i < context_list.length(); i++) {
-        SetElementNonStrict(scope_info_list,
-                            scope_info_length,
-                            context_list[i]->name());
+        SetElementSloppy(scope_info_list,
+                         scope_info_length,
+                         context_list[i]->name());
         scope_info_length++;
-        SetElementNonStrict(
+        SetElementSloppy(
             scope_info_list,
             scope_info_length,
             Handle<Smi>(Smi::FromInt(context_list[i]->index()), isolate()));
         scope_info_length++;
       }
-      SetElementNonStrict(scope_info_list,
-                          scope_info_length,
-                          Handle<Object>(isolate()->heap()->null_value(),
-                                         isolate()));
+      SetElementSloppy(scope_info_list,
+                       scope_info_length,
+                       Handle<Object>(isolate()->heap()->null_value(),
+                                      isolate()));
       scope_info_length++;
 
       current_scope = current_scope->outer_scope();
@@ -959,11 +959,11 @@
       Handle<Smi> end_pos(Smi::FromInt(message_location.end_pos()), isolate);
       Handle<JSValue> script_obj = GetScriptWrapper(message_location.script());
       JSReceiver::SetProperty(
-          rethrow_exception, start_pos_key, start_pos, NONE, kNonStrictMode);
+          rethrow_exception, start_pos_key, start_pos, NONE, SLOPPY);
       JSReceiver::SetProperty(
-          rethrow_exception, end_pos_key, end_pos, NONE, kNonStrictMode);
+          rethrow_exception, end_pos_key, end_pos, NONE, SLOPPY);
       JSReceiver::SetProperty(
-          rethrow_exception, script_obj_key, script_obj, NONE, kNonStrictMode);
+          rethrow_exception, script_obj_key, script_obj, NONE, SLOPPY);
     }
   }
 
@@ -992,7 +992,7 @@
     Handle<String> name_handle(String::cast(info->name()));
     info_wrapper.SetProperties(name_handle, info->start_position(),
                                info->end_position(), info);
-    SetElementNonStrict(array, i, info_wrapper.GetJSArray());
+    SetElementSloppy(array, i, info_wrapper.GetJSArray());
   }
 }
 
@@ -1639,8 +1639,7 @@
         UnwrapSharedFunctionInfoFromJSValue(jsvalue);
 
     if (function->shared() == *shared || IsInlined(*function, *shared)) {
-      SetElementNonStrict(result, i, Handle<Smi>(Smi::FromInt(status),
-                                                 isolate));
+      SetElementSloppy(result, i, Handle<Smi>(Smi::FromInt(status), isolate));
       return true;
     }
   }
@@ -1954,7 +1953,7 @@
         Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
       Handle<Object> replaced(
           Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate);
-      SetElementNonStrict(result, i, replaced);
+      SetElementSloppy(result, i, replaced);
     }
   }
   return NULL;
@@ -1995,7 +1994,7 @@
 
   // Fill the default values.
   for (int i = 0; i < len; i++) {
-    SetElementNonStrict(
+    SetElementSloppy(
         result,
         i,
         Handle<Smi>(Smi::FromInt(FUNCTION_AVAILABLE_FOR_PATCH), isolate));
@@ -2018,7 +2017,7 @@
     // Add error message as an array extra element.
     Vector<const char> vector_message(error_message, StrLength(error_message));
     Handle<String> str = isolate->factory()->NewStringFromAscii(vector_message);
-    SetElementNonStrict(result, len, str);
+    SetElementSloppy(result, len, str);
   }
   return result;
 }
diff --git a/src/messages.js b/src/messages.js
index ca2da30..fbe9151 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -155,8 +155,8 @@
   invalid_preparser_data:        ["Invalid preparser data for function ", "%0"],
   strict_mode_with:              ["Strict mode code may not include a with statement"],
   strict_eval_arguments:         ["Unexpected eval or arguments in strict mode"],
-  too_many_arguments:            ["Too many arguments in function call (only 32766 allowed)"],
-  too_many_parameters:           ["Too many parameters in function definition (only 32766 allowed)"],
+  too_many_arguments:            ["Too many arguments in function call (only 65535 allowed)"],
+  too_many_parameters:           ["Too many parameters in function definition (only 65535 allowed)"],
   too_many_variables:            ["Too many variables declared (only 131071 allowed)"],
   strict_param_dupe:             ["Strict mode function may not have duplicate parameter names"],
   strict_octal_literal:          ["Octal literals are not allowed in strict mode."],
@@ -1074,15 +1074,15 @@
 
 function GetStackFrames(raw_stack) {
   var frames = new InternalArray();
-  var non_strict_frames = raw_stack[0];
+  var sloppy_frames = raw_stack[0];
   for (var i = 1; i < raw_stack.length; i += 4) {
     var recv = raw_stack[i];
     var fun = raw_stack[i + 1];
     var code = raw_stack[i + 2];
     var pc = raw_stack[i + 3];
     var pos = %FunctionGetPositionForOffset(code, pc);
-    non_strict_frames--;
-    frames.push(new CallSite(recv, fun, pos, (non_strict_frames < 0)));
+    sloppy_frames--;
+    frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
   }
   return frames;
 }
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 9f18f4e..b0a70a2 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -1066,7 +1066,7 @@
     __ And(t3, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
     __ Branch(&shift_arguments, ne, t3, Operand(zero_reg));
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     // Load first argument in a2. a2 = -kPointerSize(sp + n_args << 2).
     __ sll(at, a0, kPointerSizeLog2);
     __ addu(a2, sp, at);
@@ -1269,7 +1269,7 @@
     __ And(t3, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
     __ Branch(&push_receiver, ne, t3, Operand(zero_reg));
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ JumpIfSmi(a0, &call_to_object);
     __ LoadRoot(a1, Heap::kNullValueRootIndex);
     __ Branch(&use_global_receiver, eq, a0, Operand(a1));
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 8941519..dc8ff6e 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -2365,7 +2365,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // sp[0] : number of parameters
   // sp[4] : receiver displacement
   // sp[8] : function
@@ -2391,7 +2391,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   // Stack layout:
   //  sp[0] : number of parameters (tagged)
   //  sp[4] : address of receiver argument
@@ -2455,7 +2455,7 @@
   __ Addu(t5, t5, Operand(FixedArray::kHeaderSize));
 
   // 3. Arguments object.
-  __ Addu(t5, t5, Operand(Heap::kArgumentsObjectSize));
+  __ Addu(t5, t5, Operand(Heap::kSloppyArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
   __ Allocate(t5, v0, a3, t0, &runtime, TAG_OBJECT);
@@ -2464,7 +2464,7 @@
   // a2 = argument count (tagged)
   // Get the arguments boilerplate from the current native context into t0.
   const int kNormalOffset =
-      Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
+      Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX);
   const int kAliasedOffset =
       Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
 
@@ -2505,7 +2505,7 @@
   // Set up the elements pointer in the allocated arguments object.
   // If we allocated a parameter map, t0 will point there, otherwise
   // it will point to the backing store.
-  __ Addu(t0, v0, Operand(Heap::kArgumentsObjectSize));
+  __ Addu(t0, v0, Operand(Heap::kSloppyArgumentsObjectSize));
   __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
 
   // v0 = address of new object (tagged)
@@ -2523,7 +2523,7 @@
 
   __ Branch(&skip_parameter_map, eq, a1, Operand(Smi::FromInt(0)));
 
-  __ LoadRoot(t2, Heap::kNonStrictArgumentsElementsMapRootIndex);
+  __ LoadRoot(t2, Heap::kSloppyArgumentsElementsMapRootIndex);
   __ sw(t2, FieldMemOperand(t0, FixedArray::kMapOffset));
   __ Addu(t2, a1, Operand(Smi::FromInt(2)));
   __ sw(t2, FieldMemOperand(t0, FixedArray::kLengthOffset));
@@ -2646,7 +2646,7 @@
 
   __ Addu(a1, a1, Operand(FixedArray::kHeaderSize / kPointerSize));
   __ bind(&add_arguments_object);
-  __ Addu(a1, a1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
+  __ Addu(a1, a1, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize));
 
   // Do the allocation of both objects in one go.
   __ Allocate(a1, v0, a2, a3, &runtime,
@@ -2656,7 +2656,7 @@
   __ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
   __ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset));
   __ lw(t0, MemOperand(t0, Context::SlotOffset(
-      Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
+      Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX)));
 
   // Copy the JS object part.
   __ CopyFields(v0, t0, a3.bit(), JSObject::kHeaderSize / kPointerSize);
@@ -2675,7 +2675,7 @@
 
   // Set up the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ Addu(t0, v0, Operand(Heap::kArgumentsObjectSizeStrict));
+  __ Addu(t0, v0, Operand(Heap::kStrictArgumentsObjectSize));
   __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
   __ LoadRoot(a3, Heap::kFixedArrayMapRootIndex);
   __ sw(a3, FieldMemOperand(t0, FixedArray::kMapOffset));
@@ -3285,7 +3285,7 @@
       __ Branch(&cont, ne, at, Operand(zero_reg));
     }
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ lw(a3, MemOperand(sp, argc_ * kPointerSize));
 
     if (NeedsChecks()) {
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 9eec0a3..8250ce0 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -153,10 +153,10 @@
   }
 #endif
 
-  // Classic mode functions and builtins need to replace the receiver with the
+  // Sloppy mode functions and builtins need to replace the receiver with the
   // global proxy when called as functions (without an explicit receiver
   // object).
-  if (info->is_classic_mode() && !info->is_native()) {
+  if (info->strict_mode() == SLOPPY && !info->is_native()) {
     Label ok;
     int receiver_offset = info->scope()->num_parameters() * kPointerSize;
     __ lw(at, MemOperand(sp, receiver_offset));
@@ -271,12 +271,12 @@
     // The stub will rewrite receiever and parameter count if the previous
     // stack frame was an arguments adapter frame.
     ArgumentsAccessStub::Type type;
-    if (!is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       type = ArgumentsAccessStub::NEW_STRICT;
     } else if (function()->has_duplicate_parameters()) {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+      type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
     } else {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+      type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
     ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
@@ -302,7 +302,7 @@
       if (scope()->is_function_scope() && scope()->function() != NULL) {
         VariableDeclaration* function = scope()->function();
         ASSERT(function->proxy()->var()->mode() == CONST ||
-               function->proxy()->var()->mode() == CONST_HARMONY);
+               function->proxy()->var()->mode() == CONST_LEGACY);
         ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
         VisitVariableDeclaration(function);
       }
@@ -803,7 +803,7 @@
   VariableProxy* proxy = declaration->proxy();
   VariableMode mode = declaration->mode();
   Variable* variable = proxy->var();
-  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
+  bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
       globals_->Add(variable->name(), zone());
@@ -1336,7 +1336,7 @@
       !pretenure &&
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
-    FastNewClosureStub stub(info->language_mode(), info->is_generator());
+    FastNewClosureStub stub(info->strict_mode(), info->is_generator());
     __ li(a2, Operand(info));
     __ CallStub(&stub);
   } else {
@@ -1366,7 +1366,7 @@
   Scope* s = scope();
   while (s != NULL) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ lw(temp, ContextOperand(current, Context::EXTENSION_INDEX));
         __ Branch(slow, ne, temp, Operand(zero_reg));
@@ -1378,7 +1378,7 @@
     }
     // If no outer scope calls eval, we do not need to check more
     // context extensions.
-    if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break;
+    if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
     s = s->outer_scope();
   }
 
@@ -1419,7 +1419,7 @@
 
   for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX));
         __ Branch(slow, ne, temp, Operand(zero_reg));
@@ -1455,15 +1455,14 @@
   } else if (var->mode() == DYNAMIC_LOCAL) {
     Variable* local = var->local_if_not_shadowed();
     __ lw(v0, ContextSlotOperandCheckExtensions(local, slow));
-    if (local->mode() == LET ||
-        local->mode() == CONST ||
-        local->mode() == CONST_HARMONY) {
+    if (local->mode() == LET || local->mode() == CONST ||
+        local->mode() == CONST_LEGACY) {
       __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
       __ subu(at, v0, at);  // Sub as compare: at == 0 on eq.
-      if (local->mode() == CONST) {
+      if (local->mode() == CONST_LEGACY) {
         __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
         __ Movz(v0, a0, at);  // Conditional move: return Undefined if TheHole.
-      } else {  // LET || CONST_HARMONY
+      } else {  // LET || CONST
         __ Branch(done, ne, at, Operand(zero_reg));
         __ li(a0, Operand(var->name()));
         __ push(a0);
@@ -1530,7 +1529,7 @@
           // Check that we always have valid source position.
           ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
           ASSERT(proxy->position() != RelocInfo::kNoPosition);
-          skip_init_check = var->mode() != CONST &&
+          skip_init_check = var->mode() != CONST_LEGACY &&
               var->initializer_position() < proxy->position();
         }
 
@@ -1539,7 +1538,7 @@
           GetVar(v0, var);
           __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
           __ subu(at, v0, at);  // Sub as compare: at == 0 on eq.
-          if (var->mode() == LET || var->mode() == CONST_HARMONY) {
+          if (var->mode() == LET || var->mode() == CONST) {
             // Throw a reference error when using an uninitialized let/const
             // binding in harmony mode.
             Label done;
@@ -1550,7 +1549,7 @@
             __ bind(&done);
           } else {
             // Uninitalized const bindings outside of harmony mode are unholed.
-            ASSERT(var->mode() == CONST);
+            ASSERT(var->mode() == CONST_LEGACY);
             __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
             __ Movz(v0, a0, at);  // Conditional move: Undefined if TheHole.
           }
@@ -2459,7 +2458,7 @@
       VisitForAccumulatorValue(prop->key());
       __ mov(a1, result_register());
       __ Pop(a0, a2);  // a0 = restored value.
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
         ? isolate()->builtins()->KeyedStoreIC_Initialize()
         : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic);
@@ -2484,16 +2483,15 @@
 
 
 void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, LanguageMode mode) {
+    Handle<String> name, StrictMode strict_mode) {
   __ li(a1, Operand(name));
-  __ li(a0, Operand(Smi::FromInt(mode)));
+  __ li(a0, Operand(Smi::FromInt(strict_mode)));
   __ Push(v0, cp, a1, a0);  // Value, context, name, strict mode.
   __ CallRuntime(Runtime::kStoreContextSlot, 4);
 }
 
 
-void FullCodeGenerator::EmitVariableAssignment(Variable* var,
-                                               Token::Value op) {
+void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
   if (var->IsUnallocated()) {
     // Global var, const, or let.
     __ mov(a0, result_register());
@@ -2501,7 +2499,7 @@
     __ lw(a1, GlobalObjectOperand());
     CallStoreIC();
 
-  } else if (op == Token::INIT_CONST) {
+  } else if (op == Token::INIT_CONST_LEGACY) {
     // Const initializers need a write barrier.
     ASSERT(!var->IsParameter());  // No const parameters.
     if (var->IsLookupSlot()) {
@@ -2522,7 +2520,7 @@
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       Label assign;
@@ -2538,11 +2536,11 @@
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
 
-  } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
+  } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     // Assignment to var or initializing assignment to let/const
     // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
       MemOperand location = VarOperand(var, a1);
@@ -2591,7 +2589,7 @@
   __ mov(a0, result_register());
   __ Pop(a2, a1);  // a1 = key.
 
-  Handle<Code> ic = is_classic_mode()
+  Handle<Code> ic = strict_mode() == SLOPPY
       ? isolate()->builtins()->KeyedStoreIC_Initialize()
       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
   CallIC(ic, expr->AssignmentFeedbackId());
@@ -2641,7 +2639,7 @@
       PrepareForBailout(callee, NO_REGISTERS);
     }
     // Push undefined as receiver. This is patched in the method prologue if it
-    // is a classic mode method.
+    // is a sloppy mode method.
     __ Push(isolate()->factory()->undefined_value());
     flags = NO_CALL_FUNCTION_FLAGS;
   } else {
@@ -2757,8 +2755,8 @@
   int receiver_offset = 2 + info_->scope()->num_parameters();
   __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize));
 
-  // t0: the language mode.
-  __ li(t0, Operand(Smi::FromInt(language_mode())));
+  // t0: the strict mode.
+  __ li(t0, Operand(Smi::FromInt(strict_mode())));
 
   // a1: the start position of the scope the calls resides in.
   __ li(a1, Operand(Smi::FromInt(scope()->start_position())));
@@ -4227,9 +4225,7 @@
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
-            ? kNonStrictMode : kStrictMode;
-        __ li(a1, Operand(Smi::FromInt(strict_mode_flag)));
+        __ li(a1, Operand(Smi::FromInt(strict_mode())));
         __ push(a1);
         __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
         context()->Plug(v0);
@@ -4237,11 +4233,11 @@
         Variable* var = proxy->var();
         // Delete of an unqualified identifier is disallowed in strict mode
         // but "delete this" is allowed.
-        ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
+        ASSERT(strict_mode() == SLOPPY || var->is_this());
         if (var->IsUnallocated()) {
           __ lw(a2, GlobalObjectOperand());
           __ li(a1, Operand(var->name()));
-          __ li(a0, Operand(Smi::FromInt(kNonStrictMode)));
+          __ li(a0, Operand(Smi::FromInt(SLOPPY)));
           __ Push(a2, a1, a0);
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
           context()->Plug(v0);
@@ -4500,7 +4496,7 @@
     case KEYED_PROPERTY: {
       __ mov(a0, result_register());  // Value.
       __ Pop(a2, a1);  // a1 = key, a2 = receiver.
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic, expr->CountStoreFeedbackId());
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index 4088ea4..09ffe95 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -417,6 +417,8 @@
                                                 Register scratch3,
                                                 Label* unmapped_case,
                                                 Label* slow_case) {
+  Heap* heap = masm->isolate()->heap();
+
   // Check that the receiver is a JSObject. Because of the map check
   // later, we do not need to check for interceptors or whether it
   // requires access checks.
@@ -430,10 +432,11 @@
   __ Branch(slow_case, ne, scratch1, Operand(zero_reg));
 
   // Load the elements into scratch1 and check its map.
+  Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
   __ lw(scratch1, FieldMemOperand(object, JSObject::kElementsOffset));
   __ CheckMap(scratch1,
               scratch2,
-              Heap::kNonStrictArgumentsElementsMapRootIndex,
+              arguments_map,
               slow_case,
               DONT_DO_SMI_CHECK);
   // Check if element is in the range of mapped arguments. If not, jump
@@ -496,7 +499,7 @@
 }
 
 
-void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
   //  -- a0     : key
@@ -521,7 +524,7 @@
 }
 
 
-void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ---------- S t a t e --------------
   //  -- a0     : value
   //  -- a1     : key
@@ -800,7 +803,7 @@
 
 
 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictModeFlag strict_mode) {
+                                              StrictMode strict_mode) {
   // ---------- S t a t e --------------
   //  -- a0     : value
   //  -- a1     : key
@@ -992,7 +995,7 @@
 
 
 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictModeFlag strict_mode) {
+                                   StrictMode strict_mode) {
   // ---------- S t a t e --------------
   //  -- a0     : value
   //  -- a1     : key
@@ -1235,7 +1238,7 @@
 
 
 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictModeFlag strict_mode) {
+                                         StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- a0    : value
   //  -- a1    : receiver
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index b5102a4..292ce13 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -146,11 +146,11 @@
     // fp: Caller's frame pointer.
     // lr: Caller's pc.
 
-    // Classic mode functions and builtins need to replace the receiver with the
+    // Sloppy mode functions and builtins need to replace the receiver with the
     // global proxy when called as functions (without an explicit receiver
     // object).
     if (info_->this_has_uses() &&
-        info_->is_classic_mode() &&
+        info_->strict_mode() == SLOPPY &&
         !info_->is_native()) {
       Label ok;
       int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
@@ -259,6 +259,13 @@
 }
 
 
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}
+
+
 bool LCodeGen::GenerateDeferredCode() {
   ASSERT(is_generating());
   if (deferred_.length() > 0) {
@@ -1095,8 +1102,6 @@
 
 void LCodeGen::DoModI(LModI* instr) {
   HMod* hmod = instr->hydrogen();
-  HValue* left = hmod->left();
-  HValue* right = hmod->right();
   const Register left_reg = ToRegister(instr->left());
   const Register right_reg = ToRegister(instr->right());
   const Register result_reg = ToRegister(instr->result());
@@ -1107,24 +1112,28 @@
   Label done;
   // Check for x % 0, we have to deopt in this case because we can't return a
   // NaN.
-  if (right->CanBeZero()) {
+  if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
     DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg));
   }
 
-  // Check for kMinInt % -1, we have to deopt if we care about -0, because we
-  // can't return that.
-  if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
-    Label left_not_min_int;
-    __ Branch(&left_not_min_int, ne, left_reg, Operand(kMinInt));
-    // TODO(svenpanne) Don't deopt when we don't care about -0.
-    DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1));
-    __ bind(&left_not_min_int);
+  // Check for kMinInt % -1, div will return kMinInt, which is not what we
+  // want. We have to deopt if we care about -0, because we can't return that.
+  if (hmod->CheckFlag(HValue::kCanOverflow)) {
+    Label no_overflow_possible;
+    __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt));
+    if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+      DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1));
+    } else {
+      __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1));
+      __ Branch(USE_DELAY_SLOT, &done);
+      __ mov(result_reg, zero_reg);
+    }
+    __ bind(&no_overflow_possible);
   }
 
-  // TODO(svenpanne) Only emit the test/deopt if we have to.
+  // If we care about -0, test if the dividend is <0 and the result is 0.
   __ Branch(USE_DELAY_SLOT, &done, ge, left_reg, Operand(zero_reg));
   __ mfhi(result_reg);
-
   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
   }
@@ -1133,6 +1142,7 @@
 
 
 void LCodeGen::DoDivI(LDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
   const Register left = ToRegister(instr->left());
   const Register right = ToRegister(instr->right());
   const Register result = ToRegister(instr->result());
@@ -1142,12 +1152,12 @@
   __ div(left, right);
 
   // Check for x / 0.
-  if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
+  if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
     DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
   }
 
   // Check for (0 / -x) that will produce negative zero.
-  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label left_not_zero;
     __ Branch(&left_not_zero, ne, left, Operand(zero_reg));
     DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg));
@@ -1155,14 +1165,15 @@
   }
 
   // Check for (kMinInt / -1).
-  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+  if (hdiv->CheckFlag(HValue::kCanOverflow) &&
+      !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     Label left_not_min_int;
     __ Branch(&left_not_min_int, ne, left, Operand(kMinInt));
     DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
     __ bind(&left_not_min_int);
   }
 
-  if (!instr->hydrogen()->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+  if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     __ mfhi(result);
     DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg));
   }
@@ -1233,8 +1244,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg));
   }
 
@@ -3028,7 +3038,7 @@
       case FAST_HOLEY_ELEMENTS:
       case FAST_HOLEY_SMI_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4004,8 +4014,7 @@
 
   // Name is always in a2.
   __ li(a2, Operand(instr->name()));
-  Handle<Code> ic = StoreIC::initialize_stub(isolate(),
-                                             instr->strict_mode_flag());
+  Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -4136,7 +4145,7 @@
       case FAST_HOLEY_ELEMENTS:
       case FAST_HOLEY_SMI_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4261,7 +4270,7 @@
   ASSERT(ToRegister(instr->key()).is(a1));
   ASSERT(ToRegister(instr->value()).is(a0));
 
-  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
+  Handle<Code> ic = (instr->strict_mode() == STRICT)
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -5322,7 +5331,7 @@
   // space for nested functions that don't need literals cloning.
   bool pretenure = instr->hydrogen()->pretenure();
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
-    FastNewClosureStub stub(instr->hydrogen()->language_mode(),
+    FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
                             instr->hydrogen()->is_generator());
     __ li(a2, Operand(instr->hydrogen()->shared_info()));
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index 28782cc..63f0661 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -163,9 +163,7 @@
 #undef DECLARE_DO
 
  private:
-  StrictModeFlag strict_mode_flag() const {
-    return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
-  }
+  StrictMode strict_mode() const { return info()->strict_mode(); }
 
   Scope* scope() const { return scope_; }
 
@@ -193,6 +191,7 @@
 
   // Code generation passes.  Returns true if code generation should
   // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateDeoptJumpTable();
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index d2cc39b..93acbab 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -619,15 +619,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);
 
-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -913,6 +904,26 @@
       instr = AssignEnvironment(instr);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+      LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+            SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -1289,8 +1300,7 @@
       DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
   bool can_deopt =
       divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0);
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
   return can_deopt ? AssignEnvironment(result) : result;
 }
 
@@ -1317,12 +1327,12 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegisterAtStart(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      instr->left()->CanBeNegative();
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+          dividend, divisor));
+  if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1332,17 +1342,13 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   LOperand* divisor = UseRegister(instr->right());
-  LModI* mod = new(zone()) LModI(dividend,
-                                 divisor);
-  LInstruction* result = DefineAsRegister(mod);
-  bool can_deopt = (instr->right()->CanBeZero() ||
-                    (instr->left()->RangeCanInclude(kMinInt) &&
-                     instr->right()->RangeCanInclude(-1) &&
-                     instr->CheckFlag(HValue::kBailoutOnMinusZero)) ||
-                    (instr->left()->CanBeNegative() &&
-                     instr->CanBeZero() &&
-                     instr->CheckFlag(HValue::kBailoutOnMinusZero)));
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineAsRegister(new(zone()) LModI(
+      dividend, divisor));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2352,21 +2358,6 @@
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (pending_deoptimization_ast_id_ == instr->ast_id()) {
-    LInstruction* result = new(zone()) LLazyBailout;
-    result = AssignEnvironment(result);
-    // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }
 
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 45b6cb5..b778517 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -2141,7 +2141,7 @@
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2198,7 +2198,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2642,9 +2642,7 @@
         current_instruction_(NULL),
         current_block_(NULL),
         next_block_(NULL),
-        allocator_(allocator),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        allocator_(allocator) { }
 
   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -2784,8 +2782,6 @@
   HBasicBlock* current_block_;
   HBasicBlock* next_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;
 
   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 0988d9d..4fafc15 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -275,7 +275,7 @@
   VerifyHeapPointer(properties());
   VerifyHeapPointer(elements());
 
-  if (GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) {
+  if (GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS) {
     CHECK(this->elements()->IsFixedArray());
     CHECK_GE(this->elements()->length(), 2);
   }
@@ -1060,7 +1060,7 @@
           dict->Capacity() - dict->NumberOfElements();
       break;
     }
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
+    case SLOPPY_ARGUMENTS_ELEMENTS:
       break;
   }
 }
diff --git a/src/objects-inl.h b/src/objects-inl.h
index ec2ffdb..6c5b4bf 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1739,7 +1739,7 @@
     SeededNumberDictionary* dictionary;
     MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0);
     if (!maybe->To(&dictionary)) return maybe;
-    if (map() == GetHeap()->non_strict_arguments_elements_map()) {
+    if (map() == GetHeap()->sloppy_arguments_elements_map()) {
       FixedArray::cast(elements())->set(1, dictionary);
     } else {
       set_elements(dictionary);
@@ -5146,39 +5146,21 @@
 }
 
 
-LanguageMode SharedFunctionInfo::language_mode() {
-  int hints = compiler_hints();
-  if (BooleanBit::get(hints, kExtendedModeFunction)) {
-    ASSERT(BooleanBit::get(hints, kStrictModeFunction));
-    return EXTENDED_MODE;
-  }
-  return BooleanBit::get(hints, kStrictModeFunction)
-      ? STRICT_MODE : CLASSIC_MODE;
+StrictMode SharedFunctionInfo::strict_mode() {
+  return BooleanBit::get(compiler_hints(), kStrictModeFunction)
+      ? STRICT : SLOPPY;
 }
 
 
-void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
-  // We only allow language mode transitions that go set the same language mode
-  // again or go up in the chain:
-  //   CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
-  ASSERT(this->language_mode() == CLASSIC_MODE ||
-         this->language_mode() == language_mode ||
-         language_mode == EXTENDED_MODE);
+void SharedFunctionInfo::set_strict_mode(StrictMode strict_mode) {
+  // We only allow mode transitions from sloppy to strict.
+  ASSERT(this->strict_mode() == SLOPPY || this->strict_mode() == strict_mode);
   int hints = compiler_hints();
-  hints = BooleanBit::set(
-      hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
-  hints = BooleanBit::set(
-      hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
+  hints = BooleanBit::set(hints, kStrictModeFunction, strict_mode == STRICT);
   set_compiler_hints(hints);
 }
 
 
-bool SharedFunctionInfo::is_classic_mode() {
-  return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
-}
-
-BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
-            kExtendedModeFunction)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, inline_builtin,
                kInlineBuiltin)
@@ -5448,6 +5430,11 @@
   bool was_optimized = IsOptimized();
   bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
 
+  if (was_optimized && is_optimized) {
+    shared()->EvictFromOptimizedCodeMap(this->code(),
+        "Replacing with another optimized code");
+  }
+
   set_code(code);
 
   // Add/remove the function from the list of optimized functions for this
@@ -5704,6 +5691,7 @@
   WRITE_FIELD(this, kRelocationInfoOffset, NULL);
   WRITE_FIELD(this, kHandlerTableOffset, NULL);
   WRITE_FIELD(this, kDeoptimizationDataOffset, NULL);
+  WRITE_FIELD(this, kConstantPoolOffset, NULL);
   // Do not wipe out e.g. a minor key.
   if (!READ_FIELD(this, kTypeFeedbackInfoOffset)->IsSmi()) {
     WRITE_FIELD(this, kTypeFeedbackInfoOffset, NULL);
@@ -5925,7 +5913,7 @@
             fixed_array->IsFixedArray() &&
             fixed_array->IsDictionary()) ||
            (kind > DICTIONARY_ELEMENTS));
-    ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
+    ASSERT((kind != SLOPPY_ARGUMENTS_ELEMENTS) ||
            (elements()->IsFixedArray() && elements()->length() >= 2));
   }
 #endif
@@ -5973,8 +5961,8 @@
 }
 
 
-bool JSObject::HasNonStrictArgumentsElements() {
-  return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
+bool JSObject::HasSloppyArgumentsElements() {
+  return GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS;
 }
 
 
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 15ea33a..e287691 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -378,7 +378,7 @@
     case DICTIONARY_ELEMENTS:
       elements()->Print(out);
       break;
-    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+    case SLOPPY_ARGUMENTS_ELEMENTS: {
       FixedArray* p = FixedArray::cast(elements());
       PrintF(out, "   parameter map:");
       for (int i = 2; i < p->length(); i++) {
diff --git a/src/objects.cc b/src/objects.cc
index aebcc01..ec8493a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -519,7 +519,7 @@
                                               Handle<JSReceiver> receiver,
                                               uint32_t index,
                                               Handle<Object> value,
-                                              StrictModeFlag strict_mode) {
+                                              StrictMode strict_mode) {
   Isolate* isolate = proxy->GetIsolate();
   Handle<String> name = isolate->factory()->Uint32ToString(index);
   return SetPropertyWithHandler(
@@ -2147,7 +2147,7 @@
                                      Handle<Name> name,
                                      Handle<Object> value,
                                      PropertyAttributes attributes,
-                                     StrictModeFlag strict_mode,
+                                     StrictMode strict_mode,
                                      JSReceiver::StoreFromKeyed store_mode,
                                      ExtensibilityCheck extensibility_check,
                                      ValueType value_type,
@@ -2163,7 +2163,7 @@
 
   if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
       !object->map()->is_extensible()) {
-    if (strict_mode == kNonStrictMode) {
+    if (strict_mode == SLOPPY) {
       return value;
     } else {
       Handle<Object> args[1] = { name };
@@ -2236,7 +2236,7 @@
     Handle<Name> name,
     Handle<Object> value,
     PropertyAttributes attributes,
-    StrictModeFlag strict_mode) {
+    StrictMode strict_mode) {
   // Check local property, ignore interceptor.
   LookupResult result(object->GetIsolate());
   object->LocalLookupRealNamedProperty(*name, &result);
@@ -2846,7 +2846,7 @@
     Handle<Name> name,
     Handle<Object> value,
     PropertyAttributes attributes,
-    StrictModeFlag strict_mode) {
+    StrictMode strict_mode) {
   // TODO(rossberg): Support symbols in the API.
   if (name->IsSymbol()) return value;
   Isolate* isolate = object->GetIsolate();
@@ -2878,7 +2878,7 @@
                                        Handle<Name> name,
                                        Handle<Object> value,
                                        PropertyAttributes attributes,
-                                       StrictModeFlag strict_mode,
+                                       StrictMode strict_mode,
                                        StoreFromKeyed store_mode) {
   LookupResult result(object->GetIsolate());
   object->LocalLookup(*name, &result, true);
@@ -2895,7 +2895,7 @@
                                                  Handle<Name> name,
                                                  Handle<Object> value,
                                                  Handle<JSObject> holder,
-                                                 StrictModeFlag strict_mode) {
+                                                 StrictMode strict_mode) {
   Isolate* isolate = object->GetIsolate();
 
   // We should never get here to initialize a const with the hole
@@ -2954,9 +2954,7 @@
       return SetPropertyWithDefinedSetter(
           object, Handle<JSReceiver>::cast(setter), value);
     } else {
-      if (strict_mode == kNonStrictMode) {
-        return value;
-      }
+      if (strict_mode == SLOPPY) return value;
       Handle<Object> args[2] = { name, holder };
       Handle<Object> error =
           isolate->factory()->NewTypeError("no_setter_in_callback",
@@ -3007,7 +3005,7 @@
     uint32_t index,
     Handle<Object> value,
     bool* found,
-    StrictModeFlag strict_mode) {
+    StrictMode strict_mode) {
   Isolate *isolate = object->GetIsolate();
   for (Handle<Object> proto = handle(object->GetPrototype(), isolate);
        !proto->IsNull();
@@ -3047,7 +3045,7 @@
                                                   Handle<Name> name,
                                                   Handle<Object> value,
                                                   PropertyAttributes attributes,
-                                                  StrictModeFlag strict_mode,
+                                                  StrictMode strict_mode,
                                                   bool* done) {
   Isolate* isolate = object->GetIsolate();
 
@@ -3091,7 +3089,7 @@
 
   // If we get here with *done true, we have encountered a read-only property.
   if (*done) {
-    if (strict_mode == kNonStrictMode) return value;
+    if (strict_mode == SLOPPY) return value;
     Handle<Object> args[] = { name, object };
     Handle<Object> error = isolate->factory()->NewTypeError(
         "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
@@ -3460,7 +3458,7 @@
     Handle<Name> name,
     Handle<Object> value,
     bool check_prototype,
-    StrictModeFlag strict_mode) {
+    StrictMode strict_mode) {
   if (check_prototype && !result->IsProperty()) {
     object->LookupRealNamedPropertyInPrototypes(*name, result);
   }
@@ -3527,7 +3525,7 @@
                                        Handle<Name> key,
                                        Handle<Object> value,
                                        PropertyAttributes attributes,
-                                       StrictModeFlag strict_mode,
+                                       StrictMode strict_mode,
                                        StoreFromKeyed store_mode) {
   if (result->IsHandler()) {
     return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
@@ -3559,7 +3557,7 @@
                                                Handle<Name> name,
                                                Handle<Object> value,
                                                PropertyAttributes attributes,
-                                               StrictModeFlag strict_mode) {
+                                               StrictMode strict_mode) {
   Isolate* isolate = proxy->GetIsolate();
 
   // TODO(rossberg): adjust once there is a story for symbols vs proxies.
@@ -3579,7 +3577,7 @@
     Handle<Name> name,
     Handle<Object> value,
     PropertyAttributes attributes,
-    StrictModeFlag strict_mode,
+    StrictMode strict_mode,
     bool* done) {
   Isolate* isolate = proxy->GetIsolate();
   Handle<Object> handler(proxy->handler(), isolate);  // Trap might morph proxy.
@@ -3647,7 +3645,7 @@
     ASSERT(writable->IsTrue() || writable->IsFalse());
     *done = writable->IsFalse();
     if (!*done) return isolate->factory()->the_hole_value();
-    if (strict_mode == kNonStrictMode) return value;
+    if (strict_mode == SLOPPY) return value;
     Handle<Object> args[] = { name, receiver };
     Handle<Object> error = isolate->factory()->NewTypeError(
         "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
@@ -3666,7 +3664,7 @@
         receiver, Handle<JSReceiver>::cast(setter), value);
   }
 
-  if (strict_mode == kNonStrictMode) return value;
+  if (strict_mode == SLOPPY) return value;
   Handle<Object> args2[] = { name, proxy };
   Handle<Object> error = isolate->factory()->NewTypeError(
       "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2)));
@@ -3916,7 +3914,7 @@
     // of the map. If we get a fast copy of the map, all field representations
     // will be tagged since the transition is omitted.
     return JSObject::AddProperty(
-        object, name, value, attributes, kNonStrictMode,
+        object, name, value, attributes, SLOPPY,
         JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
         JSReceiver::OMIT_EXTENSIBILITY_CHECK,
         JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
@@ -4028,7 +4026,7 @@
                                               Handle<Name> name,
                                               Handle<Object> value,
                                               PropertyAttributes attributes,
-                                              StrictModeFlag strict_mode,
+                                              StrictMode strict_mode,
                                               StoreFromKeyed store_mode) {
   Isolate* isolate = object->GetIsolate();
 
@@ -4077,7 +4075,7 @@
   }
 
   if (lookup->IsProperty() && lookup->IsReadOnly()) {
-    if (strict_mode == kStrictMode) {
+    if (strict_mode == STRICT) {
       Handle<Object> args[] = { name, object };
       Handle<Object> error = isolate->factory()->NewTypeError(
           "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
@@ -4183,7 +4181,7 @@
   if (object->IsAccessCheckNeeded()) {
     if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
       return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
-                                              false, kNonStrictMode);
+                                              false, SLOPPY);
     }
   }
 
@@ -4206,7 +4204,7 @@
     TransitionFlag flag = lookup.IsFound()
         ? OMIT_TRANSITION : INSERT_TRANSITION;
     // Neither properties nor transitions found.
-    return AddProperty(object, name, value, attributes, kNonStrictMode,
+    return AddProperty(object, name, value, attributes, SLOPPY,
         MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag);
   }
 
@@ -4736,7 +4734,7 @@
   FixedArrayBase* array = FixedArrayBase::cast(elements());
   Map* old_map = array->map();
   bool is_arguments =
-      (old_map == old_map->GetHeap()->non_strict_arguments_elements_map());
+      (old_map == old_map->GetHeap()->sloppy_arguments_elements_map());
   if (is_arguments) {
     array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
   }
@@ -5389,7 +5387,7 @@
       if (ReferencesObjectFromElements(elements, kind, obj)) return true;
       break;
     }
-    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+    case SLOPPY_ARGUMENTS_ELEMENTS: {
       FixedArray* parameter_map = FixedArray::cast(elements());
       // Check the mapped parameters.
       int length = parameter_map->length();
@@ -5411,7 +5409,7 @@
     // Get the constructor function for arguments array.
     JSObject* arguments_boilerplate =
         heap->isolate()->context()->native_context()->
-            arguments_boilerplate();
+            sloppy_arguments_boilerplate();
     JSFunction* arguments_function =
         JSFunction::cast(arguments_boilerplate->map()->constructor());
 
@@ -5533,8 +5531,8 @@
 
 
 Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
-  // Freezing non-strict arguments should be handled elsewhere.
-  ASSERT(!object->HasNonStrictArgumentsElements());
+  // Freezing sloppy arguments should be handled elsewhere.
+  ASSERT(!object->HasSloppyArgumentsElements());
   ASSERT(!object->map()->is_observed());
 
   if (object->map()->is_frozen()) return object;
@@ -5801,7 +5799,7 @@
           if (copying) {
             // Creating object copy for literals. No strict mode needed.
             CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
-                copy, key_string, result, NONE, kNonStrictMode));
+                copy, key_string, result, NONE, SLOPPY));
           }
         }
       }
@@ -5860,7 +5858,7 @@
         }
         break;
       }
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNIMPLEMENTED();
         break;
 
@@ -5918,9 +5916,9 @@
     JSObject* curr = JSObject::cast(o);
     int enum_length = curr->map()->EnumLength();
     if (enum_length == kInvalidEnumCacheSentinel) return false;
+    if (curr->IsAccessCheckNeeded()) return false;
     ASSERT(!curr->HasNamedInterceptor());
     ASSERT(!curr->HasIndexedInterceptor());
-    ASSERT(!curr->IsAccessCheckNeeded());
     if (curr->NumberOfEnumElements() > 0) return false;
     if (curr != this && enum_length != 0) return false;
   }
@@ -6121,7 +6119,7 @@
         return;
       }
       break;
-    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+    case SLOPPY_ARGUMENTS_ELEMENTS: {
       // Ascertain whether we have read-only properties or an existing
       // getter/setter pair in an arguments elements dictionary backing
       // store.
@@ -6273,7 +6271,7 @@
   dictionary->set_requires_slow_elements();
 
   // Update the dictionary backing store on the object.
-  if (object->elements()->map() == heap->non_strict_arguments_elements_map()) {
+  if (object->elements()->map() == heap->sloppy_arguments_elements_map()) {
     // Also delete any parameter alias.
     //
     // TODO(kmillikin): when deleting the last parameter alias we could
@@ -6575,7 +6573,7 @@
 
       case DICTIONARY_ELEMENTS:
         break;
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNIMPLEMENTED();
         break;
     }
@@ -9811,15 +9809,15 @@
 
 void JSFunction::RemovePrototype() {
   Context* native_context = context()->native_context();
-  Map* no_prototype_map = shared()->is_classic_mode()
-      ? native_context->function_without_prototype_map()
-      : native_context->strict_mode_function_without_prototype_map();
+  Map* no_prototype_map = shared()->strict_mode() == SLOPPY
+      ? native_context->sloppy_function_without_prototype_map()
+      : native_context->strict_function_without_prototype_map();
 
   if (map() == no_prototype_map) return;
 
-  ASSERT(map() == (shared()->is_classic_mode()
-                   ? native_context->function_map()
-                   : native_context->strict_mode_function_map()));
+  ASSERT(map() == (shared()->strict_mode() == SLOPPY
+                   ? native_context->sloppy_function_map()
+                   : native_context->strict_function_map()));
 
   set_map(no_prototype_map);
   set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
@@ -11078,9 +11076,7 @@
   switch (kind) {
     case STORE_IC:
     case KEYED_STORE_IC:
-      if (extra == kStrictMode) {
-        name = "STRICT";
-      }
+      if (extra == STRICT) name = "STRICT";
       break;
     default:
       break;
@@ -11247,7 +11243,7 @@
       accessor->CopyElements(this, new_elements, elements_kind);
   if (maybe_obj->IsFailure()) return maybe_obj;
 
-  if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
+  if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
     Map* new_map = map();
     if (new_elements_kind != elements_kind) {
       MaybeObject* maybe =
@@ -11319,7 +11315,7 @@
         accessor->CopyElements(this, elems, elements_kind);
     if (maybe_obj->IsFailure()) return maybe_obj;
   }
-  if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
+  if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
     ValidateElements();
     set_map_and_elements(new_map, elems);
   } else {
@@ -11490,12 +11486,12 @@
   if (delete_count > 0) {
     for (int i = indices.length() - 1; i >= 0; i--) {
       JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE,
-                           kNonStrictMode);
+                           SLOPPY);
     }
 
     SetProperty(deleted, isolate->factory()->length_string(),
                 isolate->factory()->NewNumberFromUint(delete_count),
-                NONE, kNonStrictMode);
+                NONE, SLOPPY);
   }
 
   EnqueueSpliceRecord(self, index, deleted, add_count);
@@ -11934,7 +11930,7 @@
     uint32_t index,
     Handle<Object> value,
     PropertyAttributes attributes,
-    StrictModeFlag strict_mode,
+    StrictMode strict_mode,
     bool check_prototype,
     SetPropertyMode set_mode) {
   Isolate* isolate = object->GetIsolate();
@@ -12022,7 +12018,7 @@
                                                 uint32_t index,
                                                 Handle<Object> value,
                                                 Handle<JSObject> holder,
-                                                StrictModeFlag strict_mode) {
+                                                StrictMode strict_mode) {
   Isolate* isolate = object->GetIsolate();
 
   // We should never get here to initialize a const with the hole
@@ -12061,9 +12057,7 @@
       return SetPropertyWithDefinedSetter(
           object, Handle<JSReceiver>::cast(setter), value);
     } else {
-      if (strict_mode == kNonStrictMode) {
-        return value;
-      }
+      if (strict_mode == SLOPPY) return value;
       Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
       Handle<Object> args[2] = { key, holder };
       Handle<Object> error = isolate->factory()->NewTypeError(
@@ -12085,7 +12079,7 @@
   Heap* heap = GetHeap();
   if (!elements()->IsFixedArray()) return false;
   FixedArray* elements = FixedArray::cast(this->elements());
-  if (elements->map() != heap->non_strict_arguments_elements_map()) {
+  if (elements->map() != heap->sloppy_arguments_elements_map()) {
     return false;
   }
   FixedArray* arguments = FixedArray::cast(elements->get(1));
@@ -12097,7 +12091,7 @@
   Heap* heap = GetHeap();
   if (!elements()->IsFixedArray()) return false;
   FixedArray* elements = FixedArray::cast(this->elements());
-  if (elements->map() != heap->non_strict_arguments_elements_map()) {
+  if (elements->map() != heap->sloppy_arguments_elements_map()) {
     return false;
   }
   FixedArray* arguments = FixedArray::cast(elements->get(1));
@@ -12111,7 +12105,7 @@
 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
                                         uint32_t index,
                                         Handle<Object> value,
-                                        StrictModeFlag strict_mode,
+                                        StrictMode strict_mode,
                                         bool check_prototype) {
   ASSERT(object->HasFastSmiOrObjectElements() ||
          object->HasFastArgumentsElements());
@@ -12129,7 +12123,7 @@
 
   Handle<FixedArray> backing_store(FixedArray::cast(object->elements()));
   if (backing_store->map() ==
-      isolate->heap()->non_strict_arguments_elements_map()) {
+      isolate->heap()->sloppy_arguments_elements_map()) {
     backing_store = handle(FixedArray::cast(backing_store->get(1)));
   } else {
     backing_store = EnsureWritableFastElements(object);
@@ -12240,7 +12234,7 @@
                                               uint32_t index,
                                               Handle<Object> value,
                                               PropertyAttributes attributes,
-                                              StrictModeFlag strict_mode,
+                                              StrictMode strict_mode,
                                               bool check_prototype,
                                               SetPropertyMode set_mode) {
   ASSERT(object->HasDictionaryElements() ||
@@ -12250,7 +12244,7 @@
   // Insert element in the dictionary.
   Handle<FixedArray> elements(FixedArray::cast(object->elements()));
   bool is_arguments =
-      (elements->map() == isolate->heap()->non_strict_arguments_elements_map());
+      (elements->map() == isolate->heap()->sloppy_arguments_elements_map());
   Handle<SeededNumberDictionary> dictionary(is_arguments
     ? SeededNumberDictionary::cast(elements->get(1))
     : SeededNumberDictionary::cast(*elements));
@@ -12272,7 +12266,7 @@
             attributes, NORMAL, details.dictionary_index());
         dictionary->DetailsAtPut(entry, details);
       } else if (details.IsReadOnly() && !element->IsTheHole()) {
-        if (strict_mode == kNonStrictMode) {
+        if (strict_mode == SLOPPY) {
           return isolate->factory()->undefined_value();
         } else {
           Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
@@ -12310,7 +12304,7 @@
     // When we set the is_extensible flag to false we always force the
     // element into dictionary mode (and force them to stay there).
     if (!object->map()->is_extensible()) {
-      if (strict_mode == kNonStrictMode) {
+      if (strict_mode == SLOPPY) {
         return isolate->factory()->undefined_value();
       } else {
         Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
@@ -12383,7 +12377,7 @@
     Handle<JSObject> object,
     uint32_t index,
     Handle<Object> value,
-    StrictModeFlag strict_mode,
+    StrictMode strict_mode,
     bool check_prototype) {
   ASSERT(object->HasFastDoubleElements());
 
@@ -12481,7 +12475,7 @@
                                       uint32_t index,
                                       Handle<Object> value,
                                       PropertyAttributes attributes,
-                                      StrictModeFlag strict_mode) {
+                                      StrictMode strict_mode) {
   if (object->IsJSProxy()) {
     return JSProxy::SetElementWithHandler(
         Handle<JSProxy>::cast(object), object, index, value, strict_mode);
@@ -12494,7 +12488,7 @@
 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
                                        uint32_t index,
                                        Handle<Object> value,
-                                       StrictModeFlag strict_mode) {
+                                       StrictMode strict_mode) {
   ASSERT(!object->HasExternalArrayElements());
   return JSObject::SetElement(object, index, value, NONE, strict_mode, false);
 }
@@ -12504,7 +12498,7 @@
                                     uint32_t index,
                                     Handle<Object> value,
                                     PropertyAttributes attributes,
-                                    StrictModeFlag strict_mode,
+                                    StrictMode strict_mode,
                                     bool check_prototype,
                                     SetPropertyMode set_mode) {
   Isolate* isolate = object->GetIsolate();
@@ -12637,7 +12631,7 @@
     uint32_t index,
     Handle<Object> value,
     PropertyAttributes attributes,
-    StrictModeFlag strict_mode,
+    StrictMode strict_mode,
     bool check_prototype,
     SetPropertyMode set_mode) {
   ASSERT(object->HasDictionaryElements() ||
@@ -12685,7 +12679,7 @@
       return SetDictionaryElement(object, index, value, attributes, strict_mode,
                                   check_prototype,
                                   set_mode);
-    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+    case SLOPPY_ARGUMENTS_ELEMENTS: {
       Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
       uint32_t length = parameter_map->length();
       Handle<Object> probe = index < length - 2 ?
@@ -13044,7 +13038,7 @@
   FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
   FixedArray* backing_store = NULL;
   switch (GetElementsKind()) {
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
+    case SLOPPY_ARGUMENTS_ELEMENTS:
       backing_store_base =
           FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
       backing_store = FixedArray::cast(backing_store_base);
@@ -13160,7 +13154,7 @@
 
   FixedArray* elements = FixedArray::cast(this->elements());
   SeededNumberDictionary* dictionary = NULL;
-  if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
+  if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) {
     dictionary = SeededNumberDictionary::cast(elements->get(1));
   } else {
     dictionary = SeededNumberDictionary::cast(elements);
@@ -13640,7 +13634,7 @@
       counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
       break;
     }
-    case NON_STRICT_ARGUMENTS_ELEMENTS: {
+    case SLOPPY_ARGUMENTS_ELEMENTS: {
       FixedArray* parameter_map = FixedArray::cast(elements());
       int mapped_length = parameter_map->length() - 2;
       FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
@@ -13738,11 +13732,11 @@
  public:
   StringSharedKey(String* source,
                   SharedFunctionInfo* shared,
-                  LanguageMode language_mode,
+                  StrictMode strict_mode,
                   int scope_position)
       : source_(source),
         shared_(shared),
-        language_mode_(language_mode),
+        strict_mode_(strict_mode),
         scope_position_(scope_position) { }
 
   bool IsMatch(Object* other) {
@@ -13750,12 +13744,10 @@
     FixedArray* other_array = FixedArray::cast(other);
     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
     if (shared != shared_) return false;
-    int language_unchecked = Smi::cast(other_array->get(2))->value();
-    ASSERT(language_unchecked == CLASSIC_MODE ||
-           language_unchecked == STRICT_MODE ||
-           language_unchecked == EXTENDED_MODE);
-    LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
-    if (language_mode != language_mode_) return false;
+    int strict_unchecked = Smi::cast(other_array->get(2))->value();
+    ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
+    StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
+    if (strict_mode != strict_mode_) return false;
     int scope_position = Smi::cast(other_array->get(3))->value();
     if (scope_position != scope_position_) return false;
     String* source = String::cast(other_array->get(1));
@@ -13764,7 +13756,7 @@
 
   static uint32_t StringSharedHashHelper(String* source,
                                          SharedFunctionInfo* shared,
-                                         LanguageMode language_mode,
+                                         StrictMode strict_mode,
                                          int scope_position) {
     uint32_t hash = source->Hash();
     if (shared->HasSourceCode()) {
@@ -13775,8 +13767,7 @@
       // collection.
       Script* script = Script::cast(shared->script());
       hash ^= String::cast(script->source())->Hash();
-      if (language_mode == STRICT_MODE) hash ^= 0x8000;
-      if (language_mode == EXTENDED_MODE) hash ^= 0x0080;
+      if (strict_mode == STRICT) hash ^= 0x8000;
       hash += scope_position;
     }
     return hash;
@@ -13784,21 +13775,19 @@
 
   uint32_t Hash() {
     return StringSharedHashHelper(
-        source_, shared_, language_mode_, scope_position_);
+        source_, shared_, strict_mode_, scope_position_);
   }
 
   uint32_t HashForObject(Object* obj) {
     FixedArray* other_array = FixedArray::cast(obj);
     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
     String* source = String::cast(other_array->get(1));
-    int language_unchecked = Smi::cast(other_array->get(2))->value();
-    ASSERT(language_unchecked == CLASSIC_MODE ||
-           language_unchecked == STRICT_MODE ||
-           language_unchecked == EXTENDED_MODE);
-    LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
+    int strict_unchecked = Smi::cast(other_array->get(2))->value();
+    ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
+    StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
     int scope_position = Smi::cast(other_array->get(3))->value();
     return StringSharedHashHelper(
-        source, shared, language_mode, scope_position);
+        source, shared, strict_mode, scope_position);
   }
 
   MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) {
@@ -13809,7 +13798,7 @@
     FixedArray* other_array = FixedArray::cast(obj);
     other_array->set(0, shared_);
     other_array->set(1, source_);
-    other_array->set(2, Smi::FromInt(language_mode_));
+    other_array->set(2, Smi::FromInt(strict_mode_));
     other_array->set(3, Smi::FromInt(scope_position_));
     return other_array;
   }
@@ -13817,7 +13806,7 @@
  private:
   String* source_;
   SharedFunctionInfo* shared_;
-  LanguageMode language_mode_;
+  StrictMode strict_mode_;
   int scope_position_;
 };
 
@@ -15010,22 +14999,11 @@
 }
 
 
-// The key for the script compilation cache is dependent on the mode flags,
-// because they change the global language mode and thus binding behaviour.
-// If flags change at some point, we must ensure that we do not hit the cache
-// for code compiled with different settings.
-static LanguageMode CurrentGlobalLanguageMode() {
-  return FLAG_use_strict
-      ? (FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE)
-      : CLASSIC_MODE;
-}
-
-
 Object* CompilationCacheTable::Lookup(String* src, Context* context) {
   SharedFunctionInfo* shared = context->closure()->shared();
   StringSharedKey key(src,
                       shared,
-                      CurrentGlobalLanguageMode(),
+                      FLAG_use_strict ? STRICT : SLOPPY,
                       RelocInfo::kNoPosition);
   int entry = FindEntry(&key);
   if (entry == kNotFound) return GetHeap()->undefined_value();
@@ -15035,11 +15013,11 @@
 
 Object* CompilationCacheTable::LookupEval(String* src,
                                           Context* context,
-                                          LanguageMode language_mode,
+                                          StrictMode strict_mode,
                                           int scope_position) {
   StringSharedKey key(src,
                       context->closure()->shared(),
-                      language_mode,
+                      strict_mode,
                       scope_position);
   int entry = FindEntry(&key);
   if (entry == kNotFound) return GetHeap()->undefined_value();
@@ -15062,7 +15040,7 @@
   SharedFunctionInfo* shared = context->closure()->shared();
   StringSharedKey key(src,
                       shared,
-                      CurrentGlobalLanguageMode(),
+                      FLAG_use_strict ? STRICT : SLOPPY,
                       RelocInfo::kNoPosition);
   CompilationCacheTable* cache;
   MaybeObject* maybe_cache = EnsureCapacity(1, &key);
@@ -15086,7 +15064,7 @@
                                             int scope_position) {
   StringSharedKey key(src,
                       context->closure()->shared(),
-                      value->language_mode(),
+                      value->strict_mode(),
                       scope_position);
   Object* obj;
   { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
diff --git a/src/objects.h b/src/objects.h
index cd8999c..dcb2721 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2043,14 +2043,14 @@
                                     Handle<Name> key,
                                     Handle<Object> value,
                                     PropertyAttributes attributes,
-                                    StrictModeFlag strict_mode,
+                                    StrictMode strict_mode,
                                     StoreFromKeyed store_mode =
                                         MAY_BE_STORE_FROM_KEYED);
   static Handle<Object> SetElement(Handle<JSReceiver> object,
                                    uint32_t index,
                                    Handle<Object> value,
                                    PropertyAttributes attributes,
-                                   StrictModeFlag strict_mode);
+                                   StrictMode strict_mode);
 
   // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
   static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
@@ -2123,7 +2123,7 @@
                                     Handle<Name> key,
                                     Handle<Object> value,
                                     PropertyAttributes attributes,
-                                    StrictModeFlag strict_mode,
+                                    StrictMode strict_mode,
                                     StoreFromKeyed store_from_keyed);
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
@@ -2155,14 +2155,14 @@
   // In the fast mode elements is a FixedArray and so each element can
   // be quickly accessed. This fact is used in the generated code. The
   // elements array can have one of three maps in this mode:
-  // fixed_array_map, non_strict_arguments_elements_map or
+  // fixed_array_map, sloppy_arguments_elements_map or
   // fixed_cow_array_map (for copy-on-write arrays). In the latter case
   // the elements array may be shared by a few objects and so before
   // writing to any element the array must be copied. Use
   // EnsureWritableFastElements in this case.
   //
   // In the slow mode the elements is either a NumberDictionary, an
-  // ExternalArray, or a FixedArray parameter map for a (non-strict)
+  // ExternalArray, or a FixedArray parameter map for a (sloppy)
   // arguments object.
   DECL_ACCESSORS(elements, FixedArrayBase)
   inline void initialize_elements();
@@ -2184,7 +2184,7 @@
   // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
   // ElementsKind.
   inline bool HasFastHoleyElements();
-  inline bool HasNonStrictArgumentsElements();
+  inline bool HasSloppyArgumentsElements();
   inline bool HasDictionaryElements();
 
   inline bool HasExternalUint8ClampedElements();
@@ -2236,14 +2236,14 @@
       Handle<Name> name,
       Handle<Object> value,
       Handle<JSObject> holder,
-      StrictModeFlag strict_mode);
+      StrictMode strict_mode);
 
   static Handle<Object> SetPropertyWithInterceptor(
       Handle<JSObject> object,
       Handle<Name> name,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode);
+      StrictMode strict_mode);
 
   static Handle<Object> SetPropertyForResult(
       Handle<JSObject> object,
@@ -2251,7 +2251,7 @@
       Handle<Name> name,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
 
   static Handle<Object> SetLocalPropertyIgnoreAttributes(
@@ -2436,13 +2436,13 @@
 
   static Handle<Object> SetFastElement(Handle<JSObject> object, uint32_t index,
                                        Handle<Object> value,
-                                       StrictModeFlag strict_mode,
+                                       StrictMode strict_mode,
                                        bool check_prototype);
 
   static Handle<Object> SetOwnElement(Handle<JSObject> object,
                                       uint32_t index,
                                       Handle<Object> value,
-                                      StrictModeFlag strict_mode);
+                                      StrictMode strict_mode);
 
   // Empty handle is returned if the element cannot be set to the given value.
   static Handle<Object> SetElement(
@@ -2450,7 +2450,7 @@
       uint32_t index,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       bool check_prototype = true,
       SetPropertyMode set_mode = SET_PROPERTY);
 
@@ -2771,13 +2771,13 @@
       uint32_t index,
       Handle<Object> value,
       Handle<JSObject> holder,
-      StrictModeFlag strict_mode);
+      StrictMode strict_mode);
   static Handle<Object> SetElementWithInterceptor(
       Handle<JSObject> object,
       uint32_t index,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       bool check_prototype,
       SetPropertyMode set_mode);
   static Handle<Object> SetElementWithoutInterceptor(
@@ -2785,7 +2785,7 @@
       uint32_t index,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       bool check_prototype,
       SetPropertyMode set_mode);
   static Handle<Object> SetElementWithCallbackSetterInPrototypes(
@@ -2793,20 +2793,20 @@
       uint32_t index,
       Handle<Object> value,
       bool* found,
-      StrictModeFlag strict_mode);
+      StrictMode strict_mode);
   static Handle<Object> SetDictionaryElement(
       Handle<JSObject> object,
       uint32_t index,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       bool check_prototype,
       SetPropertyMode set_mode = SET_PROPERTY);
   static Handle<Object> SetFastDoubleElement(
       Handle<JSObject> object,
       uint32_t index,
       Handle<Object> value,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       bool check_prototype = true);
 
   // Searches the prototype chain for property 'name'. If it is found and
@@ -2818,14 +2818,14 @@
       Handle<Name> name,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       bool* done);
   static Handle<Object> SetPropertyPostInterceptor(
       Handle<JSObject> object,
       Handle<Name> name,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode);
+      StrictMode strict_mode);
   static Handle<Object> SetPropertyUsingTransition(
       Handle<JSObject> object,
       LookupResult* lookup,
@@ -2838,7 +2838,7 @@
       Handle<Name> name,
       Handle<Object> value,
       bool check_prototype,
-      StrictModeFlag strict_mode);
+      StrictMode strict_mode);
 
   // Add a property to an object.
   static Handle<Object> AddProperty(
@@ -2846,7 +2846,7 @@
       Handle<Name> name,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
       ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
       ValueType value_type = OPTIMAL_REPRESENTATION,
@@ -4339,13 +4339,11 @@
   // Does this scope call eval?
   bool CallsEval();
 
-  // Return the language mode of this scope.
-  LanguageMode language_mode();
+  // Return the strict mode of this scope.
+  StrictMode strict_mode();
 
-  // Does this scope make a non-strict eval call?
-  bool CallsNonStrictEval() {
-    return CallsEval() && (language_mode() == CLASSIC_MODE);
-  }
+  // Does this scope make a sloppy eval call?
+  bool CallsSloppyEval() { return CallsEval() && strict_mode() == SLOPPY; }
 
   // Return the total number of locals allocated on the stack and in the
   // context. This includes the parameters that are allocated in the context.
@@ -4519,9 +4517,9 @@
   // Properties of scopes.
   class ScopeTypeField:        public BitField<ScopeType,            0, 3> {};
   class CallsEvalField:        public BitField<bool,                 3, 1> {};
-  class LanguageModeField:     public BitField<LanguageMode,         4, 2> {};
-  class FunctionVariableField: public BitField<FunctionVariableInfo, 6, 2> {};
-  class FunctionVariableMode:  public BitField<VariableMode,         8, 3> {};
+  class StrictModeField:       public BitField<StrictMode,           4, 1> {};
+  class FunctionVariableField: public BitField<FunctionVariableInfo, 5, 2> {};
+  class FunctionVariableMode:  public BitField<VariableMode,         7, 3> {};
 
   // BitFields representing the encoded information for context locals in the
   // ContextLocalInfoEntries part.
@@ -5932,8 +5930,8 @@
     return IsFastElementsKind(elements_kind());
   }
 
-  inline bool has_non_strict_arguments_elements() {
-    return elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
+  inline bool has_sloppy_arguments_elements() {
+    return elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
   }
 
   inline bool has_external_array_elements() {
@@ -5950,7 +5948,7 @@
 
   inline bool has_slow_elements_kind() {
     return elements_kind() == DICTIONARY_ELEMENTS
-        || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
+        || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
   }
 
   static bool IsValidElementsTransition(ElementsKind from_kind,
@@ -6938,20 +6936,9 @@
   // spending time attempting to optimize it again.
   DECL_BOOLEAN_ACCESSORS(optimization_disabled)
 
-  // Indicates the language mode of the function's code as defined by the
-  // current harmony drafts for the next ES language standard. Possible
-  // values are:
-  // 1. CLASSIC_MODE - Unrestricted syntax and semantics, same as in ES5.
-  // 2. STRICT_MODE - Restricted syntax and semantics, same as in ES5.
-  // 3. EXTENDED_MODE - Only available under the harmony flag, not part of ES5.
-  inline LanguageMode language_mode();
-  inline void set_language_mode(LanguageMode language_mode);
-
-  // Indicates whether the language mode of this function is CLASSIC_MODE.
-  inline bool is_classic_mode();
-
-  // Indicates whether the language mode of this function is EXTENDED_MODE.
-  inline bool is_extended_mode();
+  // Indicates the language mode.
+  inline StrictMode strict_mode();
+  inline void set_strict_mode(StrictMode strict_mode);
 
   // False if the function definitely does not allocate an arguments object.
   DECL_BOOLEAN_ACCESSORS(uses_arguments)
@@ -7202,7 +7189,6 @@
     kLiveObjectsMayExist,
     kOptimizationDisabled,
     kStrictModeFunction,
-    kExtendedModeFunction,
     kUsesArguments,
     kHasDuplicateParameters,
     kNative,
@@ -7247,26 +7233,18 @@
   static const int kStrictModeBitWithinByte =
       (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
 
-  static const int kExtendedModeBitWithinByte =
-      (kExtendedModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
-
   static const int kNativeBitWithinByte =
       (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
   static const int kStrictModeByteOffset = kCompilerHintsOffset +
       (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
-  static const int kExtendedModeByteOffset = kCompilerHintsOffset +
-      (kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
   static const int kNativeByteOffset = kCompilerHintsOffset +
       (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
 #elif __BYTE_ORDER == __BIG_ENDIAN
   static const int kStrictModeByteOffset = kCompilerHintsOffset +
       (kCompilerHintsSize - 1) -
       ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
-  static const int kExtendedModeByteOffset = kCompilerHintsOffset +
-      (kCompilerHintsSize - 1) -
-      ((kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
   static const int kNativeByteOffset = kCompilerHintsOffset +
       (kCompilerHintsSize - 1) -
       ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
@@ -8017,7 +7995,7 @@
   Object* Lookup(String* src, Context* context);
   Object* LookupEval(String* src,
                      Context* context,
-                     LanguageMode language_mode,
+                     StrictMode strict_mode,
                      int scope_position);
   Object* LookupRegExp(String* source, JSRegExp::Flags flags);
   MUST_USE_RESULT MaybeObject* Put(String* src,
@@ -8454,8 +8432,8 @@
 };
 
 
-// Representation of a slow alias as part of a non-strict arguments objects.
-// For fast aliases (if HasNonStrictArgumentsElements()):
+// Representation of a slow alias as part of a sloppy arguments objects.
+// For fast aliases (if HasSloppyArgumentsElements()):
 // - the parameter map contains an index into the context
 // - all attributes of the element have default values
 // For slow aliases (if HasDictionaryArgumentsElements()):
@@ -9633,7 +9611,7 @@
       Handle<Name> name,
       Handle<Object> value,
       PropertyAttributes attributes,
-      StrictModeFlag strict_mode,
+      StrictMode strict_mode,
       bool* done);
 
   MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
@@ -9684,12 +9662,12 @@
                                                Handle<Name> name,
                                                Handle<Object> value,
                                                PropertyAttributes attributes,
-                                               StrictModeFlag strict_mode);
+                                               StrictMode strict_mode);
   static Handle<Object> SetElementWithHandler(Handle<JSProxy> proxy,
                                               Handle<JSReceiver> receiver,
                                               uint32_t index,
                                               Handle<Object> value,
-                                              StrictModeFlag strict_mode);
+                                              StrictMode strict_mode);
 
   static bool HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name);
   static bool HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index);
diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
index d215070..fb3eac5 100644
--- a/src/optimizing-compiler-thread.cc
+++ b/src/optimizing-compiler-thread.cc
@@ -258,9 +258,13 @@
       uint32_t offset = code->TranslateAstIdToPcOffset(info->osr_ast_id());
       BackEdgeTable::RemoveStackCheck(code, offset);
     } else {
-      Handle<Code> code = Compiler::GetConcurrentlyOptimizedCode(job);
-      function->ReplaceCode(
-          code.is_null() ? function->shared()->code() : *code);
+      if (function->IsOptimized()) {
+        DisposeOptimizedCompileJob(job, false);
+      } else {
+        Handle<Code> code = Compiler::GetConcurrentlyOptimizedCode(job);
+        function->ReplaceCode(
+            code.is_null() ? function->shared()->code() : *code);
+      }
     }
   }
 }
diff --git a/src/parser.cc b/src/parser.cc
index 9e456f0..c6c72fe 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -33,7 +33,6 @@
 #include "char-predicates-inl.h"
 #include "codegen.h"
 #include "compiler.h"
-#include "func-name-inferrer.h"
 #include "messages.h"
 #include "parser.h"
 #include "platform.h"
@@ -520,7 +519,7 @@
 }
 
 
-Expression* ParserTraits::ExpressionFromLiteral(
+Literal* ParserTraits::ExpressionFromLiteral(
     Token::Value token, int pos,
     Scanner* scanner,
     AstNodeFactory<AstConstructionVisitor>* factory) {
@@ -577,11 +576,6 @@
 }
 
 
-Expression* ParserTraits::ParseObjectLiteral(bool* ok) {
-  return parser_->ParseObjectLiteral(ok);
-}
-
-
 Expression* ParserTraits::ParseAssignmentExpression(bool accept_IN, bool* ok) {
   return parser_->ParseAssignmentExpression(accept_IN, ok);
 }
@@ -592,6 +586,20 @@
 }
 
 
+FunctionLiteral* ParserTraits::ParseFunctionLiteral(
+    Handle<String> name,
+    Scanner::Location function_name_location,
+    bool name_is_strict_reserved,
+    bool is_generator,
+    int function_token_position,
+    FunctionLiteral::FunctionType type,
+    bool* ok) {
+  return parser_->ParseFunctionLiteral(name, function_name_location,
+                                       name_is_strict_reserved, is_generator,
+                                       function_token_position, type, ok);
+}
+
+
 Parser::Parser(CompilationInfo* info)
     : ParserBase<ParserTraits>(&scanner_,
                                info->isolate()->stack_guard()->real_climit(),
@@ -606,7 +614,6 @@
       original_scope_(NULL),
       target_stack_(NULL),
       pre_parse_data_(NULL),
-      fni_(NULL),
       info_(info) {
   ASSERT(!script_.is_null());
   isolate_->set_ast_node_id(0);
@@ -682,7 +689,7 @@
     }
     original_scope_ = scope;
     if (info->is_eval()) {
-      if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) {
+      if (!scope->is_global_scope() || info->strict_mode() == STRICT) {
         scope = NewScope(scope, EVAL_SCOPE);
       }
     } else if (info->is_global()) {
@@ -703,16 +710,16 @@
     // Enters 'scope'.
     FunctionState function_state(&function_state_, &scope_, scope, zone());
 
-    scope_->SetLanguageMode(info->language_mode());
+    scope_->SetStrictMode(info->strict_mode());
     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
     bool ok = true;
     int beg_pos = scanner()->location().beg_pos;
     ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
-    if (ok && !scope_->is_classic_mode()) {
+    if (ok && strict_mode() == STRICT) {
       CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
     }
 
-    if (ok && is_extended_mode()) {
+    if (ok && FLAG_harmony_scoping && strict_mode() == STRICT) {
       CheckConflictingVarDeclarations(scope_, &ok);
     }
 
@@ -817,11 +824,9 @@
     }
     original_scope_ = scope;
     FunctionState function_state(&function_state_, &scope_, scope, zone());
-    ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
-    ASSERT(scope->language_mode() != EXTENDED_MODE ||
-           info()->is_extended_mode());
-    ASSERT(info()->language_mode() == shared_info->language_mode());
-    scope->SetLanguageMode(shared_info->language_mode());
+    ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
+    ASSERT(info()->strict_mode() == shared_info->strict_mode());
+    scope->SetStrictMode(shared_info->strict_mode());
     FunctionLiteral::FunctionType function_type = shared_info->is_expression()
         ? (shared_info->is_anonymous()
               ? FunctionLiteral::ANONYMOUS_EXPRESSION
@@ -897,7 +902,7 @@
         Handle<String> directive = Handle<String>::cast(literal->value());
 
         // Check "use strict" directive (ES5 14.1).
-        if (scope_->is_classic_mode() &&
+        if (strict_mode() == SLOPPY &&
             directive->Equals(isolate()->heap()->use_strict_string()) &&
             token_loc.end_pos - token_loc.beg_pos ==
               isolate()->heap()->use_strict_string()->length() + 2) {
@@ -914,9 +919,7 @@
             scope_ = scope;
             mode_ = PARSE_EAGERLY;
           }
-          // TODO(ES6): Fix entering extended mode, once it is specified.
-          scope_->SetLanguageMode(allow_harmony_scoping()
-                                      ? EXTENDED_MODE : STRICT_MODE);
+          scope_->SetStrictMode(STRICT);
           // "use strict" is the only directive for now.
           directive_prologue = false;
         }
@@ -1058,7 +1061,7 @@
 
   Expect(Token::LBRACE, CHECK_OK);
   scope->set_start_position(scanner()->location().beg_pos);
-  scope->SetLanguageMode(EXTENDED_MODE);
+  scope->SetStrictMode(STRICT);
 
   {
     BlockState block_state(&scope_, scope);
@@ -1443,7 +1446,7 @@
       // In Harmony mode, this case also handles the extension:
       // Statement:
       //    GeneratorDeclaration
-      if (!scope_->is_classic_mode()) {
+      if (strict_mode() == STRICT) {
         ReportMessageAt(scanner()->peek_location(), "strict_function");
         *ok = false;
         return NULL;
@@ -1488,7 +1491,7 @@
   // Similarly, strict mode eval scope does not leak variable declarations to
   // the caller's scope so we declare all locals, too.
   if (declaration_scope->is_function_scope() ||
-      declaration_scope->is_strict_or_extended_eval_scope() ||
+      declaration_scope->is_strict_eval_scope() ||
       declaration_scope->is_block_scope() ||
       declaration_scope->is_module_scope() ||
       declaration_scope->is_global_scope()) {
@@ -1521,8 +1524,8 @@
       // because the var declaration is hoisted to the function scope where 'x'
       // is already bound.
       ASSERT(IsDeclaredVariableMode(var->mode()));
-      if (is_extended_mode()) {
-        // In harmony mode we treat re-declarations as early errors. See
+      if (FLAG_harmony_scoping && strict_mode() == STRICT) {
+        // In harmony we treat re-declarations as early errors. See
         // ES5 16 for a definition of early errors.
         SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
         const char* elms[2] = { "Variable", c_string.get() };
@@ -1559,7 +1562,7 @@
   // Runtime::DeclareContextSlot() calls.
   declaration_scope->AddDeclaration(declaration);
 
-  if (mode == CONST && declaration_scope->is_global_scope()) {
+  if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
     // For global const variables we bind the proxy to a variable.
     ASSERT(resolve);  // should be set by all callers
     Variable::Kind kind = Variable::NORMAL;
@@ -1567,8 +1570,8 @@
         declaration_scope, name, mode, true, kind,
         kNeedsInitialization, proxy->interface());
   } else if (declaration_scope->is_eval_scope() &&
-             declaration_scope->is_classic_mode()) {
-    // For variable declarations in a non-strict eval scope the proxy is bound
+             declaration_scope->strict_mode() == SLOPPY) {
+    // For variable declarations in a sloppy eval scope the proxy is bound
     // to a lookup variable to force a dynamic declaration using the
     // DeclareContextSlot runtime function.
     Variable::Kind kind = Variable::NORMAL;
@@ -1699,7 +1702,8 @@
   // In extended mode, a function behaves as a lexical binding, except in the
   // global scope.
   VariableMode mode =
-      is_extended_mode() && !scope_->is_global_scope() ? LET : VAR;
+      FLAG_harmony_scoping &&
+      strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR;
   VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
   Declaration* declaration =
       factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
@@ -1710,7 +1714,9 @@
 
 
 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
-  if (scope_->is_extended_mode()) return ParseScopedBlock(labels, ok);
+  if (FLAG_harmony_scoping && strict_mode() == STRICT) {
+    return ParseScopedBlock(labels, ok);
+  }
 
   // Block ::
   //   '{' Statement* '}'
@@ -1826,29 +1832,31 @@
     // * It is a Syntax Error if the code that matches this production is not
     //   contained in extended code.
     //
-    // However disallowing const in classic mode will break compatibility with
+    // However disallowing const in sloppy mode will break compatibility with
     // existing pages. Therefore we keep allowing const with the old
-    // non-harmony semantics in classic mode.
+    // non-harmony semantics in sloppy mode.
     Consume(Token::CONST);
-    switch (scope_->language_mode()) {
-      case CLASSIC_MODE:
-        mode = CONST;
-        init_op = Token::INIT_CONST;
+    switch (strict_mode()) {
+      case SLOPPY:
+        mode = CONST_LEGACY;
+        init_op = Token::INIT_CONST_LEGACY;
         break;
-      case STRICT_MODE:
-        ReportMessage("strict_const", Vector<const char*>::empty());
-        *ok = false;
-        return NULL;
-      case EXTENDED_MODE:
-        if (var_context == kStatement) {
-          // In extended mode 'const' declarations are only allowed in source
-          // element positions.
-          ReportMessage("unprotected_const", Vector<const char*>::empty());
+      case STRICT:
+        if (FLAG_harmony_scoping) {
+          if (var_context == kStatement) {
+            // In strict mode 'const' declarations are only allowed in source
+            // element positions.
+            ReportMessage("unprotected_const", Vector<const char*>::empty());
+            *ok = false;
+            return NULL;
+          }
+          mode = CONST;
+          init_op = Token::INIT_CONST;
+        } else {
+          ReportMessage("strict_const", Vector<const char*>::empty());
           *ok = false;
           return NULL;
         }
-        mode = CONST_HARMONY;
-        init_op = Token::INIT_CONST_HARMONY;
     }
     is_const = true;
     needs_init = true;
@@ -1859,7 +1867,9 @@
     //
     // * It is a Syntax Error if the code that matches this production is not
     //   contained in extended code.
-    if (!is_extended_mode()) {
+    //
+    // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
+    if (!FLAG_harmony_scoping || strict_mode() == SLOPPY) {
       ReportMessage("illegal_let", Vector<const char*>::empty());
       *ok = false;
       return NULL;
@@ -1964,7 +1974,7 @@
     Expression* value = NULL;
     int pos = -1;
     // Harmony consts have non-optional initializers.
-    if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
+    if (peek() == Token::ASSIGN || mode == CONST) {
       Expect(Token::ASSIGN, CHECK_OK);
       pos = position();
       value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
@@ -2032,8 +2042,8 @@
       } else {
         // Add strict mode.
         // We may want to pass singleton to avoid Literal allocations.
-        LanguageMode language_mode = initialization_scope->language_mode();
-        arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone());
+        StrictMode strict_mode = initialization_scope->strict_mode();
+        arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone());
 
         // Be careful not to assign a value to the global variable if
         // we're in a with. The initialization value should not
@@ -2333,7 +2343,7 @@
   Expect(Token::WITH, CHECK_OK);
   int pos = position();
 
-  if (!scope_->is_classic_mode()) {
+  if (strict_mode() == STRICT) {
     ReportMessage("strict_mode_with", Vector<const char*>::empty());
     *ok = false;
     return NULL;
@@ -2485,7 +2495,8 @@
     Expect(Token::RPAREN, CHECK_OK);
 
     Target target(&this->target_stack_, &catch_collector);
-    VariableMode mode = is_extended_mode() ? LET : VAR;
+    VariableMode mode =
+        FLAG_harmony_scoping && strict_mode() == STRICT ? LET : VAR;
     catch_variable =
         catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
 
@@ -2907,7 +2918,7 @@
     expression = NewThrowReferenceError(message);
   }
 
-  if (!scope_->is_classic_mode()) {
+  if (strict_mode() == STRICT) {
     // Assignment to eval or arguments is disallowed in strict mode.
     CheckStrictModeLValue(expression, CHECK_OK);
   }
@@ -2941,7 +2952,7 @@
     // name if we're dealing with "a = function(){...}();"-like
     // expression.
     if ((op == Token::INIT_VAR
-         || op == Token::INIT_CONST
+         || op == Token::INIT_CONST_LEGACY
          || op == Token::ASSIGN)
         && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
       fni_->Infer();
@@ -3131,7 +3142,7 @@
     }
 
     // "delete identifier" is a syntax error in strict mode.
-    if (op == Token::DELETE && !scope_->is_classic_mode()) {
+    if (op == Token::DELETE && strict_mode() == STRICT) {
       VariableProxy* operand = expression->AsVariableProxy();
       if (operand != NULL && !operand->is_this()) {
         ReportMessage("strict_delete", Vector<const char*>::empty());
@@ -3179,7 +3190,7 @@
       expression = NewThrowReferenceError(message);
     }
 
-    if (!scope_->is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       // Prefix expression operand in strict mode may not be eval or arguments.
       CheckStrictModeLValue(expression, CHECK_OK);
     }
@@ -3213,7 +3224,7 @@
       expression = NewThrowReferenceError(message);
     }
 
-    if (!scope_->is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       // Postfix expression operand in strict mode may not be eval or arguments.
       CheckStrictModeLValue(expression, CHECK_OK);
     }
@@ -3490,192 +3501,6 @@
 }
 
 
-Expression* Parser::ParseObjectLiteral(bool* ok) {
-  // ObjectLiteral ::
-  // '{' ((
-  //       ((IdentifierName | String | Number) ':' AssignmentExpression) |
-  //       (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
-  //      ) ',')* '}'
-  // (Except that trailing comma is not required and not allowed.)
-
-  int pos = peek_position();
-  ZoneList<ObjectLiteral::Property*>* properties =
-      new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone());
-  int number_of_boilerplate_properties = 0;
-  bool has_function = false;
-
-  ObjectLiteralChecker checker(this, scope_->language_mode());
-
-  Expect(Token::LBRACE, CHECK_OK);
-
-  while (peek() != Token::RBRACE) {
-    if (fni_ != NULL) fni_->Enter();
-
-    Literal* key = NULL;
-    Token::Value next = peek();
-    int next_pos = peek_position();
-
-    switch (next) {
-      case Token::FUTURE_RESERVED_WORD:
-      case Token::FUTURE_STRICT_RESERVED_WORD:
-      case Token::IDENTIFIER: {
-        bool is_getter = false;
-        bool is_setter = false;
-        Handle<String> id =
-            ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
-        if (fni_ != NULL) fni_->PushLiteralName(id);
-
-        if ((is_getter || is_setter) && peek() != Token::COLON) {
-          // Special handling of getter and setter syntax:
-          // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
-          // We have already read the "get" or "set" keyword.
-          Token::Value next = Next();
-          if (next != i::Token::IDENTIFIER &&
-              next != i::Token::FUTURE_RESERVED_WORD &&
-              next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
-              next != i::Token::NUMBER &&
-              next != i::Token::STRING &&
-              !Token::IsKeyword(next)) {
-            ReportUnexpectedToken(next);
-            *ok = false;
-            return NULL;
-          }
-          // Validate the property.
-          PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
-          checker.CheckProperty(next, type, CHECK_OK);
-          Handle<String> name = GetSymbol();
-          FunctionLiteral* value =
-              ParseFunctionLiteral(name,
-                                   scanner()->location(),
-                                   false,   // reserved words are allowed here
-                                   false,   // not a generator
-                                   RelocInfo::kNoPosition,
-                                   FunctionLiteral::ANONYMOUS_EXPRESSION,
-                                   CHECK_OK);
-          // Allow any number of parameters for compatibilty with JSC.
-          // Specification only allows zero parameters for get and one for set.
-          ObjectLiteral::Property* property =
-              factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
-          if (ObjectLiteral::IsBoilerplateProperty(property)) {
-            number_of_boilerplate_properties++;
-          }
-          properties->Add(property, zone());
-          if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
-
-          if (fni_ != NULL) {
-            fni_->Infer();
-            fni_->Leave();
-          }
-          continue;  // restart the while
-        }
-        // Failed to parse as get/set property, so it's just a normal property
-        // (which might be called "get" or "set" or something else).
-        key = factory()->NewLiteral(id, next_pos);
-        break;
-      }
-      case Token::STRING: {
-        Consume(Token::STRING);
-        Handle<String> string = GetSymbol();
-        if (fni_ != NULL) fni_->PushLiteralName(string);
-        uint32_t index;
-        if (!string.is_null() && string->AsArrayIndex(&index)) {
-          key = factory()->NewNumberLiteral(index, next_pos);
-          break;
-        }
-        key = factory()->NewLiteral(string, next_pos);
-        break;
-      }
-      case Token::NUMBER: {
-        Consume(Token::NUMBER);
-        ASSERT(scanner()->is_literal_ascii());
-        double value = StringToDouble(isolate()->unicode_cache(),
-                                      scanner()->literal_ascii_string(),
-                                      ALLOW_HEX | ALLOW_OCTAL |
-                                          ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY);
-        key = factory()->NewNumberLiteral(value, next_pos);
-        break;
-      }
-      default:
-        if (Token::IsKeyword(next)) {
-          Consume(next);
-          Handle<String> string = GetSymbol();
-          key = factory()->NewLiteral(string, next_pos);
-        } else {
-          Token::Value next = Next();
-          ReportUnexpectedToken(next);
-          *ok = false;
-          return NULL;
-        }
-    }
-
-    // Validate the property
-    checker.CheckProperty(next, kValueProperty, CHECK_OK);
-
-    Expect(Token::COLON, CHECK_OK);
-    Expression* value = ParseAssignmentExpression(true, CHECK_OK);
-
-    ObjectLiteral::Property* property =
-        factory()->NewObjectLiteralProperty(key, value);
-
-    // Mark top-level object literals that contain function literals and
-    // pretenure the literal so it can be added as a constant function
-    // property.
-    if (scope_->DeclarationScope()->is_global_scope() &&
-        value->AsFunctionLiteral() != NULL) {
-      has_function = true;
-      value->AsFunctionLiteral()->set_pretenure();
-    }
-
-    // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
-    if (ObjectLiteral::IsBoilerplateProperty(property)) {
-      number_of_boilerplate_properties++;
-    }
-    properties->Add(property, zone());
-
-    // TODO(1240767): Consider allowing trailing comma.
-    if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
-
-    if (fni_ != NULL) {
-      fni_->Infer();
-      fni_->Leave();
-    }
-  }
-  Expect(Token::RBRACE, CHECK_OK);
-
-  // Computation of literal_index must happen before pre parse bailout.
-  int literal_index = function_state_->NextMaterializedLiteralIndex();
-
-  return factory()->NewObjectLiteral(properties,
-                                     literal_index,
-                                     number_of_boilerplate_properties,
-                                     has_function,
-                                     pos);
-}
-
-
-ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
-  // Arguments ::
-  //   '(' (AssignmentExpression)*[','] ')'
-
-  ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone());
-  Expect(Token::LPAREN, CHECK_OK);
-  bool done = (peek() == Token::RPAREN);
-  while (!done) {
-    Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
-    result->Add(argument, zone());
-    if (result->length() > Code::kMaxArguments) {
-      ReportMessageAt(scanner()->location(), "too_many_arguments");
-      *ok = false;
-      return NULL;
-    }
-    done = (peek() == Token::RPAREN);
-    if (!done) Expect(Token::COMMA, CHECK_OK);
-  }
-  Expect(Token::RPAREN, CHECK_OK);
-  return result;
-}
-
-
 class SingletonLogger : public ParserRecorder {
  public:
   SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
@@ -3687,13 +3512,13 @@
                            int end,
                            int literals,
                            int properties,
-                           LanguageMode mode) {
+                           StrictMode strict_mode) {
     ASSERT(!has_error_);
     start_ = start;
     end_ = end;
     literals_ = literals;
     properties_ = properties;
-    mode_ = mode;
+    strict_mode_ = strict_mode;
   };
 
   // Logs a symbol creation of a literal or identifier.
@@ -3742,9 +3567,9 @@
     ASSERT(!has_error_);
     return properties_;
   }
-  LanguageMode language_mode() {
+  StrictMode strict_mode() {
     ASSERT(!has_error_);
-    return mode_;
+    return strict_mode_;
   }
   const char* message() {
     ASSERT(has_error_);
@@ -3762,7 +3587,7 @@
   // For function entries.
   int literals_;
   int properties_;
-  LanguageMode mode_;
+  StrictMode strict_mode_;
   // For error messages.
   const char* message_;
   const char* argument_opt_;
@@ -3824,7 +3649,8 @@
   Scope* declaration_scope = scope_->DeclarationScope();
   Scope* original_declaration_scope = original_scope_->DeclarationScope();
   Scope* scope =
-      function_type == FunctionLiteral::DECLARATION && !is_extended_mode() &&
+      function_type == FunctionLiteral::DECLARATION &&
+      (!FLAG_harmony_scoping || strict_mode() == SLOPPY) &&
       (original_scope_ == original_declaration_scope ||
        declaration_scope != original_declaration_scope)
           ? NewScope(declaration_scope, FUNCTION_SCOPE)
@@ -3913,10 +3739,13 @@
     // future we can change the AST to only refer to VariableProxies
     // instead of Variables and Proxis as is the case now.
     Variable* fvar = NULL;
-    Token::Value fvar_init_op = Token::INIT_CONST;
+    Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
     if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
-      if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY;
-      VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST;
+      if (FLAG_harmony_scoping && strict_mode() == STRICT) {
+        fvar_init_op = Token::INIT_CONST;
+      }
+      VariableMode fvar_mode = FLAG_harmony_scoping && strict_mode() == STRICT
+          ? CONST : CONST_LEGACY;
       fvar = new(zone()) Variable(scope_,
          function_name, fvar_mode, true /* is valid LHS */,
          Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
@@ -3986,7 +3815,7 @@
               scope->end_position() - function_block_pos);
           materialized_literal_count = entry.literal_count();
           expected_property_count = entry.property_count();
-          scope_->SetLanguageMode(entry.language_mode());
+          scope_->SetStrictMode(entry.strict_mode());
         } else {
           // This case happens when we have preparse data but it doesn't contain
           // an entry for the function. As a safety net, fall back to eager
@@ -4034,7 +3863,7 @@
             scope->end_position() - function_block_pos);
         materialized_literal_count = logger.literals();
         expected_property_count = logger.properties();
-        scope_->SetLanguageMode(logger.language_mode());
+        scope_->SetStrictMode(logger.strict_mode());
       }
     }
 
@@ -4098,7 +3927,7 @@
 
     // Validate strict mode. We can do this only after parsing the function,
     // since the function can declare itself strict.
-    if (!scope_->is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       if (IsEvalOrArguments(function_name)) {
         ReportMessageAt(function_name_location, "strict_eval_arguments");
         *ok = false;
@@ -4133,7 +3962,7 @@
     dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
   }
 
-  if (is_extended_mode()) {
+  if (FLAG_harmony_scoping && strict_mode() == STRICT) {
     CheckConflictingVarDeclarations(scope, CHECK_OK);
   }
 
@@ -4179,7 +4008,7 @@
         allow_harmony_numeric_literals());
   }
   PreParser::PreParseResult result =
-      reusable_preparser_->PreParseLazyFunction(scope_->language_mode(),
+      reusable_preparser_->PreParseLazyFunction(strict_mode(),
                                                 is_generator(),
                                                 logger);
   return result;
@@ -4261,7 +4090,7 @@
 // in strict mode.
 void Parser::CheckStrictModeLValue(Expression* expression,
                                    bool* ok) {
-  ASSERT(!scope_->is_classic_mode());
+  ASSERT(strict_mode() == STRICT);
   VariableProxy* lhs = expression != NULL
       ? expression->AsVariableProxy()
       : NULL;
diff --git a/src/parser.h b/src/parser.h
index 4a2cb02..799ec58 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -39,7 +39,6 @@
 namespace internal {
 
 class CompilationInfo;
-class FuncNameInferrer;
 class ParserLog;
 class PositionStack;
 class Target;
@@ -54,7 +53,7 @@
     kEndPositionIndex,
     kLiteralCountIndex,
     kPropertyCountIndex,
-    kLanguageModeIndex,
+    kStrictModeIndex,
     kSize
   };
 
@@ -67,11 +66,10 @@
   int end_pos() { return backing_[kEndPositionIndex]; }
   int literal_count() { return backing_[kLiteralCountIndex]; }
   int property_count() { return backing_[kPropertyCountIndex]; }
-  LanguageMode language_mode() {
-    ASSERT(backing_[kLanguageModeIndex] == CLASSIC_MODE ||
-           backing_[kLanguageModeIndex] == STRICT_MODE ||
-           backing_[kLanguageModeIndex] == EXTENDED_MODE);
-    return static_cast<LanguageMode>(backing_[kLanguageModeIndex]);
+  StrictMode strict_mode() {
+    ASSERT(backing_[kStrictModeIndex] == SLOPPY ||
+           backing_[kStrictModeIndex] == STRICT);
+    return static_cast<StrictMode>(backing_[kStrictModeIndex]);
   }
 
   bool is_valid() { return !backing_.is_empty(); }
@@ -421,7 +419,11 @@
     // Return types for traversing functions.
     typedef Handle<String> Identifier;
     typedef v8::internal::Expression* Expression;
+    typedef v8::internal::FunctionLiteral* FunctionLiteral;
+    typedef v8::internal::Literal* Literal;
+    typedef ObjectLiteral::Property* ObjectLiteralProperty;
     typedef ZoneList<v8::internal::Expression*>* ExpressionList;
+    typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
   };
 
   explicit ParserTraits(Parser* parser) : parser_(parser) {}
@@ -446,6 +448,27 @@
   // Helper functions for recursive descent.
   bool IsEvalOrArguments(Handle<String> identifier) const;
 
+  static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
+    return ObjectLiteral::IsBoilerplateProperty(property);
+  }
+
+  static bool IsArrayIndex(Handle<String> string, uint32_t* index) {
+    return !string.is_null() && string->AsArrayIndex(index);
+  }
+
+  static void PushLiteralName(FuncNameInferrer* fni, Handle<String> id) {
+    fni->PushLiteralName(id);
+  }
+
+  static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
+      Scope* scope, Expression* value, bool* has_function) {
+    if (scope->DeclarationScope()->is_global_scope() &&
+        value->AsFunctionLiteral() != NULL) {
+      *has_function = true;
+      value->AsFunctionLiteral()->set_pretenure();
+    }
+  }
+
   // Reporting errors.
   void ReportMessageAt(Scanner::Location source_location,
                        const char* message,
@@ -462,6 +485,12 @@
   static Expression* EmptyExpression() {
     return NULL;
   }
+  static Literal* EmptyLiteral() {
+    return NULL;
+  }
+  static ZoneList<Expression*>* NullExpressionList() {
+    return NULL;
+  }
 
   // Odd-ball literal creators.
   Literal* GetLiteralTheHole(int position,
@@ -473,7 +502,7 @@
                                    PretenureFlag tenured);
   Expression* ThisExpression(Scope* scope,
                              AstNodeFactory<AstConstructionVisitor>* factory);
-  Expression* ExpressionFromLiteral(
+  Literal* ExpressionFromLiteral(
       Token::Value token, int pos, Scanner* scanner,
       AstNodeFactory<AstConstructionVisitor>* factory);
   Expression* ExpressionFromIdentifier(
@@ -485,11 +514,21 @@
   ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
     return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
   }
+  ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
+    return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
+  }
 
   // Temporary glue; these functions will move to ParserBase.
-  Expression* ParseObjectLiteral(bool* ok);
   Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
   Expression* ParseV8Intrinsic(bool* ok);
+  FunctionLiteral* ParseFunctionLiteral(
+      Handle<String> name,
+      Scanner::Location function_name_location,
+      bool name_is_strict_reserved,
+      bool is_generator,
+      int function_token_position,
+      FunctionLiteral::FunctionType type,
+      bool* ok);
 
  private:
   Parser* parser_;
@@ -578,10 +617,6 @@
   bool inside_with() const { return scope_->inside_with(); }
   Mode mode() const { return mode_; }
   ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
-  bool is_extended_mode() {
-    ASSERT(scope_ != NULL);
-    return scope_->is_extended_mode();
-  }
   Scope* DeclarationScope(VariableMode mode) {
     return IsLexicalVariableMode(mode)
         ? scope_ : scope_->DeclarationScope();
@@ -655,7 +690,6 @@
                                   Expression* subject,
                                   Statement* body);
 
-  ZoneList<Expression*>* ParseArguments(bool* ok);
   FunctionLiteral* ParseFunctionLiteral(
       Handle<String> name,
       Scanner::Location function_name_location,
@@ -754,7 +788,6 @@
   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
   Target* target_stack_;  // for break, continue statements
   ScriptDataImpl* pre_parse_data_;
-  FuncNameInferrer* fni_;
 
   Mode mode_;
 
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index c91cf24..94aabe8 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -363,6 +363,9 @@
 }
 
 
+void OS::TimeZoneChanged() {}
+
+
 int OS::GetLastError() {
   return errno;
 }
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 52c3050..afcd82b 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -251,6 +251,8 @@
   // timestamp taking into account daylight saving.
   char* LocalTimezone();
 
+  static void TimeZoneChanged() { tz_initialized_ = false; }
+
  private:
   // Constants for time conversion.
   static const int64_t kTimeEpoc = 116444736000000000LL;
@@ -611,6 +613,11 @@
 }
 
 
+void OS::TimeZoneChanged() {
+  Win32Time::TimeZoneChanged();
+}
+
+
 int OS::GetLastError() {
   return ::GetLastError();
 }
diff --git a/src/platform.h b/src/platform.h
index 8af90f1..d424666 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -193,6 +193,8 @@
   // Returns the daylight savings offset for the given time.
   static double DaylightSavingsOffset(double time);
 
+  static void TimeZoneChanged();
+
   // Returns last OS error.
   static int GetLastError();
 
diff --git a/src/preparse-data.h b/src/preparse-data.h
index 15b0310..2bc42bd 100644
--- a/src/preparse-data.h
+++ b/src/preparse-data.h
@@ -49,7 +49,7 @@
                            int end,
                            int literals,
                            int properties,
-                           LanguageMode language_mode) = 0;
+                           StrictMode strict_mode) = 0;
 
   // Logs a symbol creation of a literal or identifier.
   virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
@@ -89,12 +89,12 @@
                            int end,
                            int literals,
                            int properties,
-                           LanguageMode language_mode) {
+                           StrictMode strict_mode) {
     function_store_.Add(start);
     function_store_.Add(end);
     function_store_.Add(literals);
     function_store_.Add(properties);
-    function_store_.Add(language_mode);
+    function_store_.Add(strict_mode);
   }
 
   // Logs an error message and marks the log as containing an error.
diff --git a/src/preparser.cc b/src/preparser.cc
index dfda980..a111fe7 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -122,11 +122,6 @@
 }
 
 
-PreParserExpression PreParserTraits::ParseObjectLiteral(bool* ok) {
-  return pre_parser_->ParseObjectLiteral(ok);
-}
-
-
 PreParserExpression PreParserTraits::ParseAssignmentExpression(bool accept_IN,
                                                                bool* ok) {
   return pre_parser_->ParseAssignmentExpression(accept_IN, ok);
@@ -138,13 +133,27 @@
 }
 
 
+PreParserExpression PreParserTraits::ParseFunctionLiteral(
+    PreParserIdentifier name,
+    Scanner::Location function_name_location,
+    bool name_is_strict_reserved,
+    bool is_generator,
+    int function_token_position,
+    FunctionLiteral::FunctionType type,
+    bool* ok) {
+  return pre_parser_->ParseFunctionLiteral(
+      name, function_name_location, name_is_strict_reserved, is_generator,
+      function_token_position, type, ok);
+}
+
+
 PreParser::PreParseResult PreParser::PreParseLazyFunction(
-    LanguageMode mode, bool is_generator, ParserRecorder* log) {
+    StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
   log_ = log;
   // Lazy functions always have trivial outer scopes (no with/catch scopes).
   PreParserScope top_scope(scope_, GLOBAL_SCOPE);
   FunctionState top_state(&function_state_, &scope_, &top_scope);
-  scope_->SetLanguageMode(mode);
+  scope_->SetStrictMode(strict_mode);
   PreParserScope function_scope(scope_, FUNCTION_SCOPE);
   FunctionState function_state(&function_state_, &scope_, &function_scope);
   function_state.set_is_generator(is_generator);
@@ -157,7 +166,7 @@
     ReportUnexpectedToken(scanner()->current_token());
   } else {
     ASSERT_EQ(Token::RBRACE, scanner()->peek());
-    if (!scope_->is_classic_mode()) {
+    if (scope_->strict_mode() == STRICT) {
       int end_pos = scanner()->location().end_pos;
       CheckOctalLiteral(start_position, end_pos, &ok);
     }
@@ -224,8 +233,7 @@
     Statement statement = ParseSourceElement(CHECK_OK);
     if (directive_prologue) {
       if (statement.IsUseStrictLiteral()) {
-        scope_->SetLanguageMode(allow_harmony_scoping() ?
-                                EXTENDED_MODE : STRICT_MODE);
+        scope_->SetStrictMode(STRICT);
       } else if (!statement.IsStringLiteral()) {
         directive_prologue = false;
       }
@@ -319,7 +327,7 @@
       Scanner::Location start_location = scanner()->peek_location();
       Statement statement = ParseFunctionDeclaration(CHECK_OK);
       Scanner::Location end_location = scanner()->location();
-      if (!scope_->is_classic_mode()) {
+      if (strict_mode() == STRICT) {
         PreParserTraits::ReportMessageAt(start_location.beg_pos,
                                          end_location.end_pos,
                                          "strict_function",
@@ -372,7 +380,7 @@
   //
   Expect(Token::LBRACE, CHECK_OK);
   while (peek() != Token::RBRACE) {
-    if (scope_->is_extended_mode()) {
+    if (FLAG_harmony_scoping && strict_mode() == STRICT) {
       ParseSourceElement(CHECK_OK);
     } else {
       ParseStatement(CHECK_OK);
@@ -432,28 +440,24 @@
     // * It is a Syntax Error if the code that matches this production is not
     //   contained in extended code.
     //
-    // However disallowing const in classic mode will break compatibility with
+    // However disallowing const in sloppy mode will break compatibility with
     // existing pages. Therefore we keep allowing const with the old
-    // non-harmony semantics in classic mode.
+    // non-harmony semantics in sloppy mode.
     Consume(Token::CONST);
-    switch (scope_->language_mode()) {
-      case CLASSIC_MODE:
-        break;
-      case STRICT_MODE: {
-        Scanner::Location location = scanner()->peek_location();
-        ReportMessageAt(location, "strict_const");
-        *ok = false;
-        return Statement::Default();
-      }
-      case EXTENDED_MODE:
-        if (var_context != kSourceElement &&
-            var_context != kForStatement) {
+    if (strict_mode() == STRICT) {
+      if (FLAG_harmony_scoping) {
+        if (var_context != kSourceElement && var_context != kForStatement) {
           ReportMessageAt(scanner()->peek_location(), "unprotected_const");
           *ok = false;
           return Statement::Default();
         }
         require_initializer = true;
-        break;
+      } else {
+        Scanner::Location location = scanner()->peek_location();
+        ReportMessageAt(location, "strict_const");
+        *ok = false;
+        return Statement::Default();
+      }
     }
   } else if (peek() == Token::LET) {
     // ES6 Draft Rev4 section 12.2.1:
@@ -462,7 +466,9 @@
     //
     // * It is a Syntax Error if the code that matches this production is not
     //   contained in extended code.
-    if (!scope_->is_extended_mode()) {
+    //
+    // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
+    if (!FLAG_harmony_scoping || strict_mode() == SLOPPY) {
       ReportMessageAt(scanner()->peek_location(), "illegal_let");
       *ok = false;
       return Statement::Default();
@@ -515,7 +521,7 @@
     // Expression is a single identifier, and not, e.g., a parenthesized
     // identifier.
     ASSERT(!expr.AsIdentifier().IsFutureReserved());
-    ASSERT(scope_->is_classic_mode() ||
+    ASSERT(strict_mode() == SLOPPY ||
            (!expr.AsIdentifier().IsFutureStrictReserved() &&
             !expr.AsIdentifier().IsYield()));
     Consume(Token::COLON);
@@ -613,7 +619,7 @@
   // WithStatement ::
   //   'with' '(' Expression ')' Statement
   Expect(Token::WITH, CHECK_OK);
-  if (!scope_->is_classic_mode()) {
+  if (strict_mode() == STRICT) {
     ReportMessageAt(scanner()->location(), "strict_mode_with");
     *ok = false;
     return Statement::Default();
@@ -852,7 +858,7 @@
     return expression;
   }
 
-  if (!scope_->is_classic_mode() &&
+  if (strict_mode() == STRICT &&
       expression.IsIdentifier() &&
       expression.AsIdentifier().IsEvalOrArguments()) {
     Scanner::Location after = scanner()->location();
@@ -946,7 +952,7 @@
     op = Next();
     Scanner::Location before = scanner()->peek_location();
     Expression expression = ParseUnaryExpression(CHECK_OK);
-    if (!scope_->is_classic_mode() &&
+    if (strict_mode() == STRICT &&
         expression.IsIdentifier() &&
         expression.AsIdentifier().IsEvalOrArguments()) {
       Scanner::Location after = scanner()->location();
@@ -969,7 +975,7 @@
   Expression expression = ParseLeftHandSideExpression(CHECK_OK);
   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
       Token::IsCountOp(peek())) {
-    if (!scope_->is_classic_mode() &&
+    if (strict_mode() == STRICT &&
         expression.IsIdentifier() &&
         expression.AsIdentifier().IsEvalOrArguments()) {
       Scanner::Location after = scanner()->location();
@@ -1129,113 +1135,6 @@
 }
 
 
-PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
-  // ObjectLiteral ::
-  // '{' ((
-  //       ((IdentifierName | String | Number) ':' AssignmentExpression) |
-  //       (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
-  //      ) ',')* '}'
-  // (Except that trailing comma is not required and not allowed.)
-
-  ObjectLiteralChecker checker(this, scope_->language_mode());
-
-  Expect(Token::LBRACE, CHECK_OK);
-  while (peek() != Token::RBRACE) {
-    Token::Value next = peek();
-    switch (next) {
-      case Token::IDENTIFIER:
-      case Token::FUTURE_RESERVED_WORD:
-      case Token::FUTURE_STRICT_RESERVED_WORD: {
-        bool is_getter = false;
-        bool is_setter = false;
-        ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
-        if ((is_getter || is_setter) && peek() != Token::COLON) {
-            Token::Value next = Next();
-            if (next != Token::IDENTIFIER &&
-                next != Token::FUTURE_RESERVED_WORD &&
-                next != Token::FUTURE_STRICT_RESERVED_WORD &&
-                next != Token::NUMBER &&
-                next != Token::STRING &&
-                !Token::IsKeyword(next)) {
-              ReportUnexpectedToken(next);
-              *ok = false;
-              return Expression::Default();
-            }
-            // Validate the property
-            PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
-            checker.CheckProperty(next, type, CHECK_OK);
-            PreParserIdentifier name = GetSymbol(scanner());
-            ParseFunctionLiteral(name,
-                                 scanner()->location(),
-                                 false,  // reserved words are allowed here
-                                 false,  // not a generator
-                                 RelocInfo::kNoPosition,
-                                 FunctionLiteral::ANONYMOUS_EXPRESSION,
-                                 CHECK_OK);
-            if (peek() != Token::RBRACE) {
-              Expect(Token::COMMA, CHECK_OK);
-            }
-            continue;  // restart the while
-        }
-        break;
-      }
-      case Token::STRING:
-        Consume(next);
-        LogSymbol();
-        break;
-      case Token::NUMBER:
-        Consume(next);
-        break;
-      default:
-        if (Token::IsKeyword(next)) {
-          Consume(next);
-          LogSymbol();
-        } else {
-          Token::Value next = Next();
-          ReportUnexpectedToken(next);
-          *ok = false;
-          return Expression::Default();
-        }
-    }
-
-    // Validate the property
-    checker.CheckProperty(next, kValueProperty, CHECK_OK);
-
-    Expect(Token::COLON, CHECK_OK);
-    ParseAssignmentExpression(true, CHECK_OK);
-
-    // TODO(1240767): Consider allowing trailing comma.
-    if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
-  }
-  Expect(Token::RBRACE, CHECK_OK);
-
-  function_state_->NextMaterializedLiteralIndex();
-  return Expression::Default();
-}
-
-
-PreParser::Arguments PreParser::ParseArguments(bool* ok) {
-  // Arguments ::
-  //   '(' (AssignmentExpression)*[','] ')'
-
-  Expect(Token::LPAREN, ok);
-  if (!*ok) return -1;
-  bool done = (peek() == Token::RPAREN);
-  int argc = 0;
-  while (!done) {
-    ParseAssignmentExpression(true, ok);
-    if (!*ok) return -1;
-    argc++;
-    done = (peek() == Token::RPAREN);
-    if (!done) {
-      Expect(Token::COMMA, ok);
-      if (!*ok) return -1;
-    }
-  }
-  Expect(Token::RPAREN, ok);
-  return argc;
-}
-
 PreParser::Expression PreParser::ParseFunctionLiteral(
     Identifier function_name,
     Scanner::Location function_name_location,
@@ -1313,7 +1212,7 @@
 
   // Validate strict mode. We can do this only after parsing the function,
   // since the function can declare itself strict.
-  if (!scope_->is_classic_mode()) {
+  if (strict_mode() == STRICT) {
     if (function_name.IsEvalOrArguments()) {
       ReportMessageAt(function_name_location, "strict_eval_arguments");
       *ok = false;
@@ -1362,7 +1261,7 @@
   log_->LogFunction(body_start, body_end,
                     function_state_->materialized_literal_count(),
                     function_state_->expected_property_count(),
-                    scope_->language_mode());
+                    strict_mode());
 }
 
 
diff --git a/src/preparser.h b/src/preparser.h
index 8a5517e..59a9a61 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -28,6 +28,7 @@
 #ifndef V8_PREPARSER_H
 #define V8_PREPARSER_H
 
+#include "func-name-inferrer.h"
 #include "hashmap.h"
 #include "scopes.h"
 #include "token.h"
@@ -50,6 +51,7 @@
         scope_(NULL),
         function_state_(NULL),
         extension_(extension),
+        fni_(NULL),
         scanner_(scanner),
         stack_limit_(stack_limit),
         stack_overflow_(false),
@@ -297,8 +299,7 @@
     return function_state_->factory();
   }
 
-  bool is_classic_mode() const { return scope_->is_classic_mode(); }
-
+  StrictMode strict_mode() { return scope_->strict_mode(); }
   bool is_generator() const { return function_state_->is_generator(); }
 
   // Report syntax errors.
@@ -331,8 +332,8 @@
   typename Traits::Type::Identifier ParseIdentifierName(bool* ok);
   // Parses an identifier and determines whether or not it is 'get' or 'set'.
   typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get,
-                                                                bool* is_set,
-                                                                bool* ok);
+                                                                  bool* is_set,
+                                                                  bool* ok);
 
   typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal,
                                                        bool* ok);
@@ -340,6 +341,8 @@
   typename Traits::Type::Expression ParsePrimaryExpression(bool* ok);
   typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok);
   typename Traits::Type::Expression ParseArrayLiteral(bool* ok);
+  typename Traits::Type::Expression ParseObjectLiteral(bool* ok);
+  typename Traits::Type::ExpressionList ParseArguments(bool* ok);
 
   // Used to detect duplicates in object literals. Each of the values
   // kGetterProperty, kSetterProperty and kValueProperty represents
@@ -365,10 +368,10 @@
   // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
   class ObjectLiteralChecker {
    public:
-    ObjectLiteralChecker(ParserBase* parser, LanguageMode mode)
+    ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
         : parser_(parser),
           finder_(scanner()->unicode_cache()),
-          language_mode_(mode) { }
+          strict_mode_(strict_mode) { }
 
     void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
 
@@ -392,7 +395,7 @@
 
     ParserBase* parser_;
     DuplicateFinder finder_;
-    LanguageMode language_mode_;
+    StrictMode strict_mode_;
   };
 
   // If true, the next (and immediately following) function literal is
@@ -404,6 +407,7 @@
   typename Traits::Type::Scope* scope_;  // Scope stack.
   FunctionState* function_state_;  // Function state stack.
   v8::Extension* extension_;
+  FuncNameInferrer* fni_;
 
  private:
   Scanner* scanner_;
@@ -553,8 +557,12 @@
 class PreParserExpressionList {
  public:
   // These functions make list->Add(some_expression) work (and do nothing).
+  PreParserExpressionList() : length_(0) {}
   PreParserExpressionList* operator->() { return this; }
-  void Add(PreParserExpression, void*) { }
+  void Add(PreParserExpression, void*) { ++length_; }
+  int length() const { return length_; }
+ private:
+  int length_;
 };
 
 
@@ -563,36 +571,27 @@
   explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
       : scope_type_(scope_type) {
     if (outer_scope) {
-      scope_inside_with_ =
-          outer_scope->scope_inside_with_ || is_with_scope();
-      language_mode_ = outer_scope->language_mode();
+      scope_inside_with_ = outer_scope->scope_inside_with_ || is_with_scope();
+      strict_mode_ = outer_scope->strict_mode();
     } else {
       scope_inside_with_ = is_with_scope();
-      language_mode_ = CLASSIC_MODE;
+      strict_mode_ = SLOPPY;
     }
   }
 
   bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
-  bool is_classic_mode() const {
-    return language_mode() == CLASSIC_MODE;
-  }
-  bool is_extended_mode() {
-    return language_mode() == EXTENDED_MODE;
-  }
   bool inside_with() const {
     return scope_inside_with_;
   }
 
   ScopeType type() { return scope_type_; }
-  LanguageMode language_mode() const { return language_mode_; }
-  void SetLanguageMode(LanguageMode language_mode) {
-    language_mode_ = language_mode;
-  }
+  StrictMode strict_mode() const { return strict_mode_; }
+  void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
 
  private:
   ScopeType scope_type_;
   bool scope_inside_with_;
-  LanguageMode language_mode_;
+  StrictMode strict_mode_;
 };
 
 
@@ -616,6 +615,35 @@
                                       int pos) {
     return PreParserExpression::Default();
   }
+
+  PreParserExpression NewObjectLiteralProperty(bool is_getter,
+                                               PreParserExpression value,
+                                               int pos) {
+    return PreParserExpression::Default();
+  }
+
+  PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
+                                               PreParserExpression value) {
+    return PreParserExpression::Default();
+  }
+
+  PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
+                                       int literal_index,
+                                       int boilerplate_properties,
+                                       bool has_function,
+                                       int pos) {
+    return PreParserExpression::Default();
+  }
+
+  PreParserExpression NewLiteral(PreParserIdentifier identifier,
+                                 int pos) {
+    return PreParserExpression::Default();
+  }
+
+  PreParserExpression NewNumberLiteral(double number,
+                                       int pos) {
+    return PreParserExpression::Default();
+  }
 };
 
 
@@ -637,7 +665,11 @@
     // Return types for traversing functions.
     typedef PreParserIdentifier Identifier;
     typedef PreParserExpression Expression;
+    typedef PreParserExpression FunctionLiteral;
+    typedef PreParserExpression ObjectLiteralProperty;
+    typedef PreParserExpression Literal;
     typedef PreParserExpressionList ExpressionList;
+    typedef PreParserExpressionList PropertyList;
   };
 
   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
@@ -654,6 +686,23 @@
     return identifier.IsEvalOrArguments();
   }
 
+  static bool IsBoilerplateProperty(PreParserExpression property) {
+    // PreParser doesn't count boilerplate properties.
+    return false;
+  }
+
+  static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
+    return false;
+  }
+
+  static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
+    // PreParser should not use FuncNameInferrer.
+    ASSERT(false);
+  }
+
+  static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
+      PreParserScope* scope, PreParserExpression value, bool* has_function) {}
+
   // Reporting errors.
   void ReportMessageAt(Scanner::Location location,
                        const char* message,
@@ -673,6 +722,12 @@
   static PreParserExpression EmptyExpression() {
     return PreParserExpression::Default();
   }
+  static PreParserExpression EmptyLiteral() {
+    return PreParserExpression::Default();
+  }
+  static PreParserExpressionList NullExpressionList() {
+    return PreParserExpressionList();
+  }
 
   // Odd-ball literal creators.
   static PreParserExpression GetLiteralTheHole(int position,
@@ -712,10 +767,21 @@
     return PreParserExpressionList();
   }
 
+  static PreParserExpressionList NewPropertyList(int size, void* zone) {
+    return PreParserExpressionList();
+  }
+
   // Temporary glue; these functions will move to ParserBase.
   PreParserExpression ParseAssignmentExpression(bool accept_IN, bool* ok);
-  PreParserExpression ParseObjectLiteral(bool* ok);
   PreParserExpression ParseV8Intrinsic(bool* ok);
+  PreParserExpression ParseFunctionLiteral(
+      PreParserIdentifier name,
+      Scanner::Location function_name_location,
+      bool name_is_strict_reserved,
+      bool is_generator,
+      int function_token_position,
+      FunctionLiteral::FunctionType type,
+      bool* ok);
 
  private:
   PreParser* pre_parser_;
@@ -763,7 +829,7 @@
     if (stack_overflow()) return kPreParseStackOverflow;
     if (!ok) {
       ReportUnexpectedToken(scanner()->current_token());
-    } else if (!scope_->is_classic_mode()) {
+    } else if (scope_->strict_mode() == STRICT) {
       CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
     }
     return kPreParseSuccess;
@@ -777,7 +843,7 @@
   // keyword and parameters, and have consumed the initial '{'.
   // At return, unless an error occurred, the scanner is positioned before the
   // the final '}'.
-  PreParseResult PreParseLazyFunction(LanguageMode mode,
+  PreParseResult PreParseLazyFunction(StrictMode strict_mode,
                                       bool is_generator,
                                       ParserRecorder* log);
 
@@ -852,8 +918,6 @@
     kUnknownSourceElements
   };
 
-  typedef int Arguments;
-
   // All ParseXXX functions take as the last argument an *ok parameter
   // which is set to false if parsing failed; it is unchanged otherwise.
   // By making the 'exception handling' explicit, we are forced to check
@@ -897,7 +961,6 @@
   Expression ParseObjectLiteral(bool* ok);
   Expression ParseV8Intrinsic(bool* ok);
 
-  Arguments ParseArguments(bool* ok);
   Expression ParseFunctionLiteral(
       Identifier name,
       Scanner::Location function_name_location,
@@ -975,9 +1038,8 @@
       return ReportMessageAt(source_location, "unexpected_reserved");
     case Token::YIELD:
     case Token::FUTURE_STRICT_RESERVED_WORD:
-      return ReportMessageAt(source_location,
-                             is_classic_mode() ? "unexpected_token_identifier"
-                                               : "unexpected_strict_reserved");
+      return ReportMessageAt(source_location, strict_mode() == SLOPPY
+          ? "unexpected_token_identifier" : "unexpected_strict_reserved");
     default:
       const char* name = Token::String(token);
       ASSERT(name != NULL);
@@ -995,13 +1057,14 @@
   if (next == Token::IDENTIFIER) {
     typename Traits::Type::Identifier name = this->GetSymbol(scanner());
     if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
-        !is_classic_mode() && this->IsEvalOrArguments(name)) {
+        strict_mode() == STRICT && this->IsEvalOrArguments(name)) {
       ReportMessageAt(scanner()->location(), "strict_eval_arguments");
       *ok = false;
     }
     return name;
-  } else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD ||
-                                   (next == Token::YIELD && !is_generator()))) {
+  } else if (strict_mode() == SLOPPY &&
+             (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+             (next == Token::YIELD && !is_generator()))) {
     return this->GetSymbol(scanner());
   } else {
     this->ReportUnexpectedToken(next);
@@ -1095,6 +1158,13 @@
 #define DUMMY )  // to make indentation work
 #undef DUMMY
 
+// Used in functions where the return type is not Traits::Type::Expression.
+#define CHECK_OK_CUSTOM(x) ok); \
+  if (!*ok) return this->x(); \
+  ((void)0
+#define DUMMY )  // to make indentation work
+#undef DUMMY
+
 template <class Traits>
 typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression(
     bool* ok) {
@@ -1240,7 +1310,204 @@
   return factory()->NewArrayLiteral(values, literal_index, pos);
 }
 
+
+template <class Traits>
+typename Traits::Type::Expression ParserBase<Traits>::ParseObjectLiteral(
+    bool* ok) {
+  // ObjectLiteral ::
+  // '{' ((
+  //       ((IdentifierName | String | Number) ':' AssignmentExpression) |
+  //       (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
+  //      ) ',')* '}'
+  // (Except that trailing comma is not required and not allowed.)
+
+  int pos = peek_position();
+  typename Traits::Type::PropertyList properties =
+      this->NewPropertyList(4, zone_);
+  int number_of_boilerplate_properties = 0;
+  bool has_function = false;
+
+  ObjectLiteralChecker checker(this, strict_mode());
+
+  Expect(Token::LBRACE, CHECK_OK);
+
+  while (peek() != Token::RBRACE) {
+    if (fni_ != NULL) fni_->Enter();
+
+    typename Traits::Type::Literal key = this->EmptyLiteral();
+    Token::Value next = peek();
+    int next_pos = peek_position();
+
+    switch (next) {
+      case Token::FUTURE_RESERVED_WORD:
+      case Token::FUTURE_STRICT_RESERVED_WORD:
+      case Token::IDENTIFIER: {
+        bool is_getter = false;
+        bool is_setter = false;
+        typename Traits::Type::Identifier id =
+            ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
+        if (fni_ != NULL) this->PushLiteralName(fni_, id);
+
+        if ((is_getter || is_setter) && peek() != Token::COLON) {
+          // Special handling of getter and setter syntax:
+          // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
+          // We have already read the "get" or "set" keyword.
+          Token::Value next = Next();
+          if (next != i::Token::IDENTIFIER &&
+              next != i::Token::FUTURE_RESERVED_WORD &&
+              next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
+              next != i::Token::NUMBER &&
+              next != i::Token::STRING &&
+              !Token::IsKeyword(next)) {
+            ReportUnexpectedToken(next);
+            *ok = false;
+            return this->EmptyLiteral();
+          }
+          // Validate the property.
+          PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
+          checker.CheckProperty(next, type, CHECK_OK);
+          typename Traits::Type::Identifier name = this->GetSymbol(scanner_);
+          typename Traits::Type::FunctionLiteral value =
+              this->ParseFunctionLiteral(
+                  name, scanner()->location(),
+                  false,  // reserved words are allowed here
+                  false,  // not a generator
+                  RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
+                  CHECK_OK);
+          // Allow any number of parameters for compatibilty with JSC.
+          // Specification only allows zero parameters for get and one for set.
+          typename Traits::Type::ObjectLiteralProperty property =
+              factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
+          if (this->IsBoilerplateProperty(property)) {
+            number_of_boilerplate_properties++;
+          }
+          properties->Add(property, zone());
+          if (peek() != Token::RBRACE) {
+            // Need {} because of the CHECK_OK macro.
+            Expect(Token::COMMA, CHECK_OK);
+          }
+
+          if (fni_ != NULL) {
+            fni_->Infer();
+            fni_->Leave();
+          }
+          continue;  // restart the while
+        }
+        // Failed to parse as get/set property, so it's just a normal property
+        // (which might be called "get" or "set" or something else).
+        key = factory()->NewLiteral(id, next_pos);
+        break;
+      }
+      case Token::STRING: {
+        Consume(Token::STRING);
+        typename Traits::Type::Identifier string = this->GetSymbol(scanner_);
+        if (fni_ != NULL) this->PushLiteralName(fni_, string);
+        uint32_t index;
+        if (this->IsArrayIndex(string, &index)) {
+          key = factory()->NewNumberLiteral(index, next_pos);
+          break;
+        }
+        key = factory()->NewLiteral(string, next_pos);
+        break;
+      }
+      case Token::NUMBER: {
+        Consume(Token::NUMBER);
+        key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
+                                          factory());
+        break;
+      }
+      default:
+        if (Token::IsKeyword(next)) {
+          Consume(next);
+          typename Traits::Type::Identifier string = this->GetSymbol(scanner_);
+          key = factory()->NewLiteral(string, next_pos);
+        } else {
+          Token::Value next = Next();
+          ReportUnexpectedToken(next);
+          *ok = false;
+          return this->EmptyLiteral();
+        }
+    }
+
+    // Validate the property
+    checker.CheckProperty(next, kValueProperty, CHECK_OK);
+
+    Expect(Token::COLON, CHECK_OK);
+    typename Traits::Type::Expression value =
+        this->ParseAssignmentExpression(true, CHECK_OK);
+
+    typename Traits::Type::ObjectLiteralProperty property =
+        factory()->NewObjectLiteralProperty(key, value);
+
+    // Mark top-level object literals that contain function literals and
+    // pretenure the literal so it can be added as a constant function
+    // property. (Parser only.)
+    this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
+                                                          &has_function);
+
+    // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
+    if (this->IsBoilerplateProperty(property)) {
+      number_of_boilerplate_properties++;
+    }
+    properties->Add(property, zone());
+
+    // TODO(1240767): Consider allowing trailing comma.
+    if (peek() != Token::RBRACE) {
+      // Need {} because of the CHECK_OK macro.
+      Expect(Token::COMMA, CHECK_OK);
+    }
+
+    if (fni_ != NULL) {
+      fni_->Infer();
+      fni_->Leave();
+    }
+  }
+  Expect(Token::RBRACE, CHECK_OK);
+
+  // Computation of literal_index must happen before pre parse bailout.
+  int literal_index = function_state_->NextMaterializedLiteralIndex();
+
+  return factory()->NewObjectLiteral(properties,
+                                     literal_index,
+                                     number_of_boilerplate_properties,
+                                     has_function,
+                                     pos);
+}
+
+
+template <class Traits>
+typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
+    bool* ok) {
+  // Arguments ::
+  //   '(' (AssignmentExpression)*[','] ')'
+
+  typename Traits::Type::ExpressionList result =
+      this->NewExpressionList(4, zone_);
+  Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
+  bool done = (peek() == Token::RPAREN);
+  while (!done) {
+    typename Traits::Type::Expression argument =
+        this->ParseAssignmentExpression(true,
+                                        CHECK_OK_CUSTOM(NullExpressionList));
+    result->Add(argument, zone_);
+    if (result->length() > Code::kMaxArguments) {
+      ReportMessageAt(scanner()->location(), "too_many_arguments");
+      *ok = false;
+      return this->NullExpressionList();
+    }
+    done = (peek() == Token::RPAREN);
+    if (!done) {
+      // Need {} because of the CHECK_OK_CUSTOM macro.
+      Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
+    }
+  }
+  Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
+  return result;
+}
+
+
 #undef CHECK_OK
+#undef CHECK_OK_CUSTOM
 
 
 template <typename Traits>
@@ -1260,7 +1527,7 @@
   if (HasConflict(old_type, type)) {
     if (IsDataDataConflict(old_type, type)) {
       // Both are data properties.
-      if (language_mode_ == CLASSIC_MODE) return;
+      if (strict_mode_ == SLOPPY) return;
       parser()->ReportMessageAt(scanner()->location(),
                                "strict_duplicate_property");
     } else if (IsDataAccessorConflict(old_type, type)) {
diff --git a/src/promise.js b/src/promise.js
index 2c36d4d..8e22c31 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -102,6 +102,15 @@
 }
 
 
+// For API.
+
+function PromiseNopResolver() {}
+
+function PromiseCreate() {
+  return new Promise(PromiseNopResolver)
+}
+
+
 // Convenience.
 
 function PromiseDeferred() {
@@ -217,7 +226,7 @@
 PromiseCoerce.table = new $WeakMap;
 
 function PromiseCoerce(constructor, x) {
-  if (!(IsPromise(x) || IS_NULL_OR_UNDEFINED(x))) {
+  if (!IsPromise(x) && IS_SPEC_OBJECT(x)) {
     var then = x.then;
     if (typeof then === 'function') {
       if (PromiseCoerce.table.has(x)) {
diff --git a/src/property-details-inl.h b/src/property-details-inl.h
new file mode 100644
index 0000000..98eb1cf
--- /dev/null
+++ b/src/property-details-inl.h
@@ -0,0 +1,51 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PROPERTY_DETAILS_INL_H_
+#define V8_PROPERTY_DETAILS_INL_H_
+
+#include "objects.h"
+#include "property-details.h"
+#include "v8conversions.h"
+
+namespace v8 {
+namespace internal {
+
+inline bool Representation::CanContainDouble(double value) {
+  if (IsDouble() || is_more_general_than(Representation::Double())) {
+    return true;
+  }
+  if (IsInt32Double(value)) {
+    if (IsInteger32()) return true;
+    if (IsSmi()) return Smi::IsValid(static_cast<int32_t>(value));
+  }
+  return false;
+}
+
+} }  // namespace v8::internal
+
+#endif  // V8_PROPERTY_DETAILS_INL_H_
diff --git a/src/property-details.h b/src/property-details.h
index 3405bd9..01050db 100644
--- a/src/property-details.h
+++ b/src/property-details.h
@@ -148,6 +148,8 @@
     return other.is_more_general_than(*this) || other.Equals(*this);
   }
 
+  bool CanContainDouble(double value);
+
   Representation generalize(Representation other) {
     if (other.fits_into(*this)) return *this;
     if (other.is_more_general_than(*this)) return other;
diff --git a/src/runtime.cc b/src/runtime.cc
index aa75688..140c323 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -153,25 +153,13 @@
   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
 
 
-// Assert that the given argument has a valid value for a StrictModeFlag
-// and store it in a StrictModeFlag variable with the given name.
+// Assert that the given argument has a valid value for a StrictMode
+// and store it in a StrictMode variable with the given name.
 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
   RUNTIME_ASSERT(args[index]->IsSmi());                              \
-  RUNTIME_ASSERT(args.smi_at(index) == kStrictMode ||                \
-                 args.smi_at(index) == kNonStrictMode);              \
-  StrictModeFlag name =                                              \
-      static_cast<StrictModeFlag>(args.smi_at(index));
-
-
-// Assert that the given argument has a valid value for a LanguageMode
-// and store it in a LanguageMode variable with the given name.
-#define CONVERT_LANGUAGE_MODE_ARG(name, index)                       \
-  ASSERT(args[index]->IsSmi());                                      \
-  ASSERT(args.smi_at(index) == CLASSIC_MODE ||                       \
-         args.smi_at(index) == STRICT_MODE ||                        \
-         args.smi_at(index) == EXTENDED_MODE);                       \
-  LanguageMode name =                                                \
-      static_cast<LanguageMode>(args.smi_at(index));
+  RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
+                 args.smi_at(index) == SLOPPY);                      \
+  StrictMode name = static_cast<StrictMode>(args.smi_at(index));
 
 
 static Handle<Map> ComputeObjectLiteralMap(
@@ -298,7 +286,7 @@
       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
         // Array index as string (uint32).
         result = JSObject::SetOwnElement(
-            boilerplate, element_index, value, kNonStrictMode);
+            boilerplate, element_index, value, SLOPPY);
       } else {
         Handle<String> name(String::cast(*key));
         ASSERT(!name->AsArrayIndex(&element_index));
@@ -309,7 +297,7 @@
     } else if (key->ToArrayIndex(&element_index)) {
       // Array index (uint32).
       result = JSObject::SetOwnElement(
-          boilerplate, element_index, value, kNonStrictMode);
+          boilerplate, element_index, value, SLOPPY);
     } else {
       // Non-uint32 number.
       ASSERT(key->IsNumber());
@@ -2099,7 +2087,7 @@
       attr |= READ_ONLY;
     }
 
-    LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
+    StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
 
     if (!lookup.IsFound() || is_function) {
       // If the local property exists, check that we can reconfigure it
@@ -2121,7 +2109,7 @@
       RETURN_IF_EMPTY_HANDLE(isolate,
           JSObject::SetProperty(
               global, name, value, static_cast<PropertyAttributes>(attr),
-              language_mode == CLASSIC_MODE ? kNonStrictMode : kStrictMode));
+              strict_mode));
     }
   }
 
@@ -2177,8 +2165,7 @@
         Handle<JSObject> object = Handle<JSObject>::cast(holder);
         RETURN_IF_EMPTY_HANDLE(
             isolate,
-            JSReceiver::SetProperty(object, name, initial_value, mode,
-                                    kNonStrictMode));
+            JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
       }
     }
 
@@ -2224,7 +2211,7 @@
          JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
     } else {
       RETURN_IF_EMPTY_HANDLE(isolate,
-         JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
+         JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
     }
   }
 
@@ -2245,9 +2232,7 @@
 
   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   RUNTIME_ASSERT(args[1]->IsSmi());
-  CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
-  StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
-      ? kNonStrictMode : kStrictMode;
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
 
   // According to ECMA-262, section 12.2, page 62, the property must
   // not be deletable.
@@ -2271,7 +2256,7 @@
         CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
         Handle<Object> result = JSObject::SetPropertyForResult(
             handle(lookup.holder()), &lookup, name, value, attributes,
-            strict_mode_flag);
+            strict_mode);
         RETURN_IF_EMPTY_HANDLE(isolate, result);
         return *result;
       } else {
@@ -2284,7 +2269,7 @@
     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
     Handle<GlobalObject> global(isolate->context()->global_object());
     Handle<Object> result = JSReceiver::SetProperty(
-        global, name, value, attributes, strict_mode_flag);
+        global, name, value, attributes, strict_mode);
     RETURN_IF_EMPTY_HANDLE(isolate, result);
     return *result;
   }
@@ -2335,11 +2320,10 @@
     // BUG 1213575: Handle the case where we have to set a read-only
     // property through an interceptor and only do it if it's
     // uninitialized, e.g. the hole. Nirk...
-    // Passing non-strict mode because the property is writable.
+    // Passing sloppy mode because the property is writable.
     RETURN_IF_EMPTY_HANDLE(
         isolate,
-        JSReceiver::SetProperty(global, name, value, attributes,
-                                kNonStrictMode));
+        JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
     return *value;
   }
 
@@ -2409,7 +2393,7 @@
     // Strict mode not needed (const disallowed in strict mode).
     RETURN_IF_EMPTY_HANDLE(
         isolate,
-        JSReceiver::SetProperty(global, name, value, NONE, kNonStrictMode));
+        JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
     return *value;
   }
 
@@ -2460,8 +2444,7 @@
       // Strict mode not needed (const disallowed in strict mode).
       RETURN_IF_EMPTY_HANDLE(
           isolate,
-          JSReceiver::SetProperty(object, name, value, attributes,
-                                  kNonStrictMode));
+          JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
     }
   }
 
@@ -2621,7 +2604,7 @@
                                       code,
                                       false);
   optimized->shared()->DontAdaptArguments();
-  JSReceiver::SetProperty(holder, key, optimized, NONE, kStrictMode);
+  JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT);
   return optimized;
 }
 
@@ -2643,7 +2626,7 @@
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsClassicModeFunction) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsSloppyModeFunction) {
   SealHandleScope shs(isolate);
   ASSERT(args.length() == 1);
   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
@@ -2657,7 +2640,7 @@
   }
   JSFunction* function = JSFunction::cast(callable);
   SharedFunctionInfo* shared = function->shared();
-  return isolate->heap()->ToBoolean(shared->is_classic_mode());
+  return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
 }
 
 
@@ -2677,7 +2660,7 @@
   JSFunction* function = JSFunction::cast(callable);
 
   SharedFunctionInfo* shared = function->shared();
-  if (shared->native() || !shared->is_classic_mode()) {
+  if (shared->native() || shared->strict_mode() == STRICT) {
     return isolate->heap()->undefined_value();
   }
   // Returns undefined for strict or native functions, or
@@ -5082,7 +5065,7 @@
                                             name,
                                             obj_value,
                                             handle(lookup.holder()),
-                                            kStrictMode);
+                                            STRICT);
       RETURN_IF_EMPTY_HANDLE(isolate, result_object);
       return *result_object;
     }
@@ -5155,7 +5138,7 @@
                                           Handle<Object> key,
                                           Handle<Object> value,
                                           PropertyAttributes attr,
-                                          StrictModeFlag strict_mode) {
+                                          StrictMode strict_mode) {
   SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
 
   if (object->IsUndefined() || object->IsNull()) {
@@ -5273,7 +5256,7 @@
       return value;
     }
 
-    return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
+    return JSObject::SetElement(js_object, index, value, attr, SLOPPY,
                                 false,
                                 DEFINE_PROPERTY);
   }
@@ -5281,7 +5264,7 @@
   if (key->IsName()) {
     Handle<Name> name = Handle<Name>::cast(key);
     if (name->AsArrayIndex(&index)) {
-      return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
+      return JSObject::SetElement(js_object, index, value, attr, SLOPPY,
                                   false,
                                   DEFINE_PROPERTY);
     } else {
@@ -5299,7 +5282,7 @@
   Handle<String> name = Handle<String>::cast(converted);
 
   if (name->AsArrayIndex(&index)) {
-    return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
+    return JSObject::SetElement(js_object, index, value, attr, SLOPPY,
                                 false,
                                 DEFINE_PROPERTY);
   } else {
@@ -5377,10 +5360,10 @@
   PropertyAttributes attributes =
       static_cast<PropertyAttributes>(unchecked_attributes);
 
-  StrictModeFlag strict_mode = kNonStrictMode;
+  StrictMode strict_mode = SLOPPY;
   if (args.length() == 5) {
-    CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4);
-    strict_mode = strict_mode_flag;
+    CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 4);
+    strict_mode = strict_mode_arg;
   }
 
   Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
@@ -5559,7 +5542,7 @@
   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
-  JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode)
+  JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
   Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode);
   RETURN_IF_EMPTY_HANDLE(isolate, result);
@@ -5811,7 +5794,9 @@
       }
     }
     next_copy_index += local_property_count[i];
-    if (jsproto->HasHiddenProperties()) {
+
+    // Hidden properties only show up if the filter does not skip strings.
+    if ((filter & STRING) == 0 && jsproto->HasHiddenProperties()) {
       hidden_strings++;
     }
     if (i < length - 1) {
@@ -6002,7 +5987,7 @@
   if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n);
   if (key->Equals(isolate->heap()->callee_string())) {
     JSFunction* function = frame->function();
-    if (!function->shared()->is_classic_mode()) {
+    if (function->shared()->strict_mode() == STRICT) {
       return isolate->Throw(*isolate->factory()->NewTypeError(
           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
     }
@@ -7914,11 +7899,11 @@
       Handle<FixedArray> parameter_map =
           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
       parameter_map->set_map(
-          isolate->heap()->non_strict_arguments_elements_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(NON_STRICT_ARGUMENTS_ELEMENTS);
+      new_map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
 
       result->set_map(*new_map);
       result->set_elements(*parameter_map);
@@ -8735,7 +8720,9 @@
     PrintF(" at AST id %d]\n", ast_id.ToInt());
   }
 
-  function->ReplaceCode(function->shared()->code());
+  if (!function->IsOptimized()) {
+    function->ReplaceCode(function->shared()->code());
+  }
   return NULL;
 }
 
@@ -9049,7 +9036,7 @@
         case VAR:
         case LET:
         case CONST:
-        case CONST_HARMONY: {
+        case CONST_LEGACY: {
           PropertyAttributes attr =
               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
           Handle<AccessorInfo> info =
@@ -9062,7 +9049,7 @@
         case MODULE: {
           Object* referenced_context = Context::cast(host_context)->get(index);
           Handle<JSModule> value(Context::cast(referenced_context)->module());
-          JSReceiver::SetProperty(module, name, value, FROZEN, kStrictMode);
+          JSReceiver::SetProperty(module, name, value, FROZEN, STRICT);
           break;
         }
         case INTERNAL:
@@ -9285,9 +9272,7 @@
   Handle<Object> value(args[0], isolate);
   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
-  CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
-  StrictModeFlag strict_mode = (language_mode == CLASSIC_MODE)
-      ? kNonStrictMode : kStrictMode;
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
 
   int index;
   PropertyAttributes attributes;
@@ -9314,7 +9299,7 @@
     if ((attributes & READ_ONLY) == 0) {
       // Context is a fixed array and set cannot fail.
       context->set(index, *value);
-    } else if (strict_mode == kStrictMode) {
+    } else if (strict_mode == STRICT) {
       // Setting read only property in strict mode.
       Handle<Object> error =
           isolate->factory()->NewTypeError("strict_cannot_assign",
@@ -9336,14 +9321,14 @@
     // The property was not found.
     ASSERT(attributes == ABSENT);
 
-    if (strict_mode == kStrictMode) {
+    if (strict_mode == STRICT) {
       // Throw in strict mode (assignment to undefined variable).
       Handle<Object> error =
           isolate->factory()->NewReferenceError(
               "not_defined", HandleVector(&name, 1));
       return isolate->Throw(*error);
     }
-    // In non-strict mode, the property is added to the global object.
+    // In sloppy mode, the property is added to the global object.
     attributes = NONE;
     object = Handle<JSReceiver>(isolate->context()->global_object());
   }
@@ -9354,7 +9339,7 @@
     RETURN_IF_EMPTY_HANDLE(
         isolate,
         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
-  } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
+  } else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
     // Setting read only property in strict mode.
     Handle<Object> error =
       isolate->factory()->NewTypeError(
@@ -9612,6 +9597,28 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCacheVersion) {
+  HandleScope hs(isolate);
+  ASSERT(args.length() == 0);
+  if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
+    Handle<FixedArray> date_cache_version =
+        isolate->factory()->NewFixedArray(1, TENURED);
+    date_cache_version->set(0, Smi::FromInt(0));
+    isolate->eternal_handles()->CreateSingleton(
+        isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
+  }
+  Handle<FixedArray> date_cache_version =
+      Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
+          EternalHandles::DATE_CACHE_VERSION));
+  // Return result as a JS array.
+  Handle<JSObject> result =
+      isolate->factory()->NewJSObject(isolate->array_function());
+  isolate->factory()->SetContent(Handle<JSArray>::cast(result),
+                                 date_cache_version);
+  return *result;
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
   SealHandleScope shs(isolate);
   ASSERT(args.length() == 1);
@@ -9693,7 +9700,7 @@
   ParseRestriction restriction = function_literal_only
       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
   Handle<JSFunction> fun = Compiler::GetFunctionFromEval(
-      source, context, CLASSIC_MODE, restriction, RelocInfo::kNoPosition);
+      source, context, SLOPPY, restriction, RelocInfo::kNoPosition);
   RETURN_IF_EMPTY_HANDLE(isolate, fun);
   return *fun;
 }
@@ -9702,7 +9709,7 @@
 static ObjectPair CompileGlobalEval(Isolate* isolate,
                                     Handle<String> source,
                                     Handle<Object> receiver,
-                                    LanguageMode language_mode,
+                                    StrictMode strict_mode,
                                     int scope_position) {
   Handle<Context> context = Handle<Context>(isolate->context());
   Handle<Context> native_context = Handle<Context>(context->native_context());
@@ -9722,7 +9729,7 @@
   // and return the compiled function bound in the local context.
   static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
   Handle<JSFunction> compiled = Compiler::GetFunctionFromEval(
-      source, context, language_mode, restriction, scope_position);
+      source, context, strict_mode, restriction, scope_position);
   RETURN_IF_EMPTY_HANDLE_VALUE(isolate, compiled,
                                MakePair(Failure::Exception(), NULL));
   return MakePair(*compiled, *receiver);
@@ -9745,12 +9752,14 @@
     return MakePair(*callee, isolate->heap()->undefined_value());
   }
 
-  CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
+  ASSERT(args[3]->IsSmi());
+  ASSERT(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
+  StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
   ASSERT(args[4]->IsSmi());
   return CompileGlobalEval(isolate,
                            args.at<String>(1),
                            args.at<Object>(2),
-                           language_mode,
+                           strict_mode,
                            args.smi_at(4));
 }
 
@@ -9815,7 +9824,7 @@
   // Strict not needed. Used for cycle detection in Array join implementation.
   RETURN_IF_EMPTY_HANDLE(isolate, JSObject::SetFastElement(array, length,
                                                            element,
-                                                           kNonStrictMode,
+                                                           SLOPPY,
                                                            true));
   return isolate->heap()->true_value();
 }
@@ -10000,7 +10009,7 @@
       }
       break;
     }
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
+    case SLOPPY_ARGUMENTS_ELEMENTS:
 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
     case EXTERNAL_##TYPE##_ELEMENTS:                                         \
     case TYPE##_ELEMENTS:                                                    \
@@ -11287,7 +11296,7 @@
   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
   Handle<Object> receiver(it.frame()->receiver(), isolate);
   if (!receiver->IsJSObject() &&
-      shared->is_classic_mode() &&
+      shared->strict_mode() == SLOPPY &&
       !function->IsBuiltin()) {
     // If the receiver is not a JSObject and the function is not a
     // builtin or strict-mode we have hit an optimization where a
@@ -11339,8 +11348,7 @@
 
     RETURN_IF_EMPTY_HANDLE_VALUE(
         isolate,
-        Runtime::SetObjectProperty(
-            isolate, target, name, value, NONE, kNonStrictMode),
+        Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
         Handle<JSObject>());
   }
 
@@ -11352,8 +11360,7 @@
 
     RETURN_IF_EMPTY_HANDLE_VALUE(
         isolate,
-        Runtime::SetObjectProperty(
-            isolate, target, name, value, NONE, kNonStrictMode),
+        Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
         Handle<JSObject>());
   }
 
@@ -11436,7 +11443,7 @@
                                        key,
                                        GetProperty(isolate, ext, key),
                                        NONE,
-                                       kNonStrictMode),
+                                       SLOPPY),
             Handle<JSObject>());
       }
     }
@@ -11537,8 +11544,7 @@
           // We don't expect this to do anything except replacing
           // property value.
           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
-                                     NONE,
-                                     kNonStrictMode);
+                                     NONE, SLOPPY);
           return true;
         }
       }
@@ -11586,8 +11592,7 @@
           isolate,
           Runtime::SetObjectProperty(isolate, closure_scope, key,
                                      GetProperty(isolate, ext, key),
-                                     NONE,
-                                     kNonStrictMode),
+                                     NONE, SLOPPY),
           Handle<JSObject>());
     }
   }
@@ -11619,8 +11624,7 @@
     if (JSReceiver::HasProperty(ext, variable_name)) {
       // We don't expect this to do anything except replacing property value.
       Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
-                                 NONE,
-                                 kNonStrictMode);
+                                 NONE, SLOPPY);
       return true;
     }
   }
@@ -11642,8 +11646,7 @@
   RETURN_IF_EMPTY_HANDLE_VALUE(
       isolate,
       Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
-                                 NONE,
-                                 kNonStrictMode),
+                                 NONE, SLOPPY),
       Handle<JSObject>());
   return catch_scope;
 }
@@ -12156,7 +12159,7 @@
         Smi* position_value = Smi::FromInt(break_location_iterator.position());
         JSObject::SetElement(array, len,
             Handle<Object>(position_value, isolate),
-            NONE, kNonStrictMode);
+            NONE, SLOPPY);
         len++;
       }
     }
@@ -12711,7 +12714,7 @@
                              isolate->factory()->arguments_string(),
                              arguments,
                              ::NONE,
-                             kNonStrictMode);
+                             SLOPPY);
   return target;
 }
 
@@ -12731,7 +12734,7 @@
   Handle<JSFunction> eval_fun =
       Compiler::GetFunctionFromEval(source,
                                     context,
-                                    CLASSIC_MODE,
+                                    SLOPPY,
                                     NO_PARSE_RESTRICTION,
                                     RelocInfo::kNoPosition);
   RETURN_IF_EMPTY_HANDLE(isolate, eval_fun);
@@ -12989,7 +12992,7 @@
 
   // Get the constructor function for context extension and arguments array.
   JSObject* arguments_boilerplate =
-      isolate->context()->native_context()->arguments_boilerplate();
+      isolate->context()->native_context()->sloppy_arguments_boilerplate();
   JSFunction* arguments_function =
       JSFunction::cast(arguments_boilerplate->map()->constructor());
 
@@ -14577,7 +14580,7 @@
 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(NonStrictArgumentsElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
 // Properties test sitting with elements tests - not fooling anyone.
 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
diff --git a/src/runtime.h b/src/runtime.h
index d770968..99c575f 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -64,7 +64,7 @@
   F(ToFastProperties, 1, 1) \
   F(FinishArrayPrototypeSetup, 1, 1) \
   F(SpecialArrayFunctions, 1, 1) \
-  F(IsClassicModeFunction, 1, 1) \
+  F(IsSloppyModeFunction, 1, 1) \
   F(GetDefaultReceiver, 1, 1) \
   \
   F(GetPrototype, 1, 1) \
@@ -257,6 +257,7 @@
   F(DateToUTC, 1, 1) \
   F(DateMakeDay, 2, 1) \
   F(DateSetValue, 3, 1) \
+  F(DateCacheVersion, 0, 1) \
   \
   /* Numbers */ \
   \
@@ -302,7 +303,7 @@
   /* ES5 */ \
   F(ObjectFreeze, 1, 1) \
   \
-  /* Harmony Microtasks */ \
+  /* Harmony microtasks */ \
   F(GetMicrotaskState, 0, 1) \
   \
   /* Harmony modules */ \
@@ -455,7 +456,7 @@
   F(HasFastDoubleElements, 1, 1) \
   F(HasFastHoleyElements, 1, 1) \
   F(HasDictionaryElements, 1, 1) \
-  F(HasNonStrictArgumentsElements, 1, 1) \
+  F(HasSloppyArgumentsElements, 1, 1) \
   F(HasExternalUint8ClampedElements, 1, 1) \
   F(HasExternalArrayElements, 1, 1) \
   F(HasExternalInt8Elements, 1, 1) \
@@ -785,7 +786,7 @@
       Handle<Object> key,
       Handle<Object> value,
       PropertyAttributes attr,
-      StrictModeFlag strict_mode);
+      StrictMode strict_mode);
 
   static Handle<Object> ForceSetObjectProperty(
       Isolate* isolate,
@@ -861,12 +862,12 @@
 //---------------------------------------------------------------------------
 // Constants used by interface to runtime functions.
 
-class AllocateDoubleAlignFlag:    public BitField<bool,            0, 1> {};
-class AllocateTargetSpace:        public BitField<AllocationSpace, 1, 3> {};
+class AllocateDoubleAlignFlag:  public BitField<bool,            0, 1> {};
+class AllocateTargetSpace:      public BitField<AllocationSpace, 1, 3> {};
 
-class DeclareGlobalsEvalFlag:     public BitField<bool,         0, 1> {};
-class DeclareGlobalsNativeFlag:   public BitField<bool,         1, 1> {};
-class DeclareGlobalsLanguageMode: public BitField<LanguageMode, 2, 2> {};
+class DeclareGlobalsEvalFlag:   public BitField<bool,       0, 1> {};
+class DeclareGlobalsNativeFlag: public BitField<bool,       1, 1> {};
+class DeclareGlobalsStrictMode: public BitField<StrictMode, 2, 1> {};
 
 } }  // namespace v8::internal
 
diff --git a/src/safepoint-table.h b/src/safepoint-table.h
index ea35253..cd094c5 100644
--- a/src/safepoint-table.h
+++ b/src/safepoint-table.h
@@ -219,6 +219,9 @@
   // Record deoptimization index for lazy deoptimization for the last
   // outstanding safepoints.
   void RecordLazyDeoptimizationIndex(int index);
+  void BumpLastLazySafepointIndex() {
+    last_lazy_safepoint_ = deopt_index_list_.length();
+  }
 
   // Emit the safepoint table after the body. The number of bits per
   // entry must be enough to hold all the pointer indexes.
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 03e69bf..e2ae854 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -78,7 +78,7 @@
   // Encode the flags.
   int flags = ScopeTypeField::encode(scope->scope_type()) |
       CallsEvalField::encode(scope->calls_eval()) |
-      LanguageModeField::encode(scope->language_mode()) |
+      StrictModeField::encode(scope->strict_mode()) |
       FunctionVariableField::encode(function_name_info) |
       FunctionVariableMode::encode(function_variable_mode);
   scope_info->SetFlags(flags);
@@ -164,8 +164,8 @@
 }
 
 
-LanguageMode ScopeInfo::language_mode() {
-  return length() > 0 ? LanguageModeField::decode(Flags()) : CLASSIC_MODE;
+StrictMode ScopeInfo::strict_mode() {
+  return length() > 0 ? StrictModeField::decode(Flags()) : SLOPPY;
 }
 
 
@@ -378,7 +378,7 @@
         Handle<String>(String::cast(scope_info->get(i))),
         Handle<Object>(context->get(context_index), isolate),
         ::NONE,
-        kNonStrictMode);
+        SLOPPY);
     RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, false);
   }
   return true;
diff --git a/src/scopes.cc b/src/scopes.cc
index 650f57c..bcb6435 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -190,9 +190,8 @@
   scope_contains_with_ = false;
   scope_calls_eval_ = false;
   // Inherit the strict mode from the parent scope.
-  language_mode_ = (outer_scope != NULL)
-      ? outer_scope->language_mode_ : CLASSIC_MODE;
-  outer_scope_calls_non_strict_eval_ = false;
+  strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY;
+  outer_scope_calls_sloppy_eval_ = false;
   inner_scope_calls_eval_ = false;
   force_eager_compilation_ = false;
   force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
@@ -207,7 +206,7 @@
   end_position_ = RelocInfo::kNoPosition;
   if (!scope_info.is_null()) {
     scope_calls_eval_ = scope_info->CallsEval();
-    language_mode_ = scope_info->language_mode();
+    strict_mode_ = scope_info->strict_mode();
   }
 }
 
@@ -470,7 +469,7 @@
                               InitializationFlag init_flag,
                               Interface* interface) {
   ASSERT(!already_resolved());
-  // This function handles VAR and CONST modes.  DYNAMIC variables are
+  // This function handles VAR, LET, and CONST modes.  DYNAMIC variables are
   // introduces during variable allocation, INTERNAL variables are allocated
   // explicitly, and TEMPORARY variables are allocated via NewTemporary().
   ASSERT(IsDeclaredVariableMode(mode));
@@ -643,13 +642,13 @@
 bool Scope::AllocateVariables(CompilationInfo* info,
                               AstNodeFactory<AstNullVisitor>* factory) {
   // 1) Propagate scope information.
-  bool outer_scope_calls_non_strict_eval = false;
+  bool outer_scope_calls_sloppy_eval = false;
   if (outer_scope_ != NULL) {
-    outer_scope_calls_non_strict_eval =
-        outer_scope_->outer_scope_calls_non_strict_eval() |
-        outer_scope_->calls_non_strict_eval();
+    outer_scope_calls_sloppy_eval =
+        outer_scope_->outer_scope_calls_sloppy_eval() |
+        outer_scope_->calls_sloppy_eval();
   }
-  PropagateScopeInfo(outer_scope_calls_non_strict_eval);
+  PropagateScopeInfo(outer_scope_calls_sloppy_eval);
 
   // 2) Allocate module instances.
   if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) {
@@ -881,21 +880,14 @@
   if (HasTrivialOuterContext()) {
     Indent(n1, "// scope has trivial outer context\n");
   }
-  switch (language_mode()) {
-    case CLASSIC_MODE:
-      break;
-    case STRICT_MODE:
-      Indent(n1, "// strict mode scope\n");
-      break;
-    case EXTENDED_MODE:
-      Indent(n1, "// extended mode scope\n");
-      break;
+  if (strict_mode() == STRICT) {
+    Indent(n1, "// strict mode scope\n");
   }
   if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
   if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
   if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
-  if (outer_scope_calls_non_strict_eval_) {
-    Indent(n1, "// outer scope calls 'eval' in non-strict context\n");
+  if (outer_scope_calls_sloppy_eval_) {
+    Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
   }
   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
   if (num_stack_slots_ > 0) { Indent(n1, "// ");
@@ -1017,9 +1009,9 @@
     // object).
     *binding_kind = DYNAMIC_LOOKUP;
     return NULL;
-  } else if (calls_non_strict_eval()) {
+  } else if (calls_sloppy_eval()) {
     // A variable binding may have been found in an outer scope, but the current
-    // scope makes a non-strict 'eval' call, so the found variable may not be
+    // scope makes a sloppy 'eval' call, so the found variable may not be
     // the correct one (the 'eval' may introduce a binding with the same name).
     // In that case, change the lookup result to reflect this situation.
     if (*binding_kind == BOUND) {
@@ -1071,8 +1063,7 @@
       break;
 
     case UNBOUND_EVAL_SHADOWED:
-      // No binding has been found. But some scope makes a
-      // non-strict 'eval' call.
+      // No binding has been found. But some scope makes a sloppy 'eval' call.
       var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
       break;
 
@@ -1084,7 +1075,7 @@
 
   ASSERT(var != NULL);
 
-  if (FLAG_harmony_scoping && is_extended_mode() &&
+  if (FLAG_harmony_scoping && strict_mode() == STRICT &&
       var->is_const_mode() && proxy->IsLValue()) {
     // Assignment to const. Throw a syntax error.
     MessageLocation location(
@@ -1123,7 +1114,7 @@
       Isolate* isolate = info->isolate();
       Factory* factory = isolate->factory();
       Handle<JSArray> array = factory->NewJSArray(1);
-      USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode));
+      USE(JSObject::SetElement(array, 0, var->name(), NONE, STRICT));
       Handle<Object> result =
           factory->NewSyntaxError("module_type_error", array);
       isolate->Throw(*result, &location);
@@ -1157,16 +1148,16 @@
 }
 
 
-bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) {
-  if (outer_scope_calls_non_strict_eval) {
-    outer_scope_calls_non_strict_eval_ = true;
+bool Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) {
+  if (outer_scope_calls_sloppy_eval) {
+    outer_scope_calls_sloppy_eval_ = true;
   }
 
-  bool calls_non_strict_eval =
-      this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_;
+  bool calls_sloppy_eval =
+      this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_;
   for (int i = 0; i < inner_scopes_.length(); i++) {
     Scope* inner_scope = inner_scopes_[i];
-    if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) {
+    if (inner_scope->PropagateScopeInfo(calls_sloppy_eval)) {
       inner_scope_calls_eval_ = true;
     }
     if (inner_scope->force_eager_compilation_) {
@@ -1246,7 +1237,7 @@
   Variable* arguments = LocalLookup(isolate_->factory()->arguments_string());
   ASSERT(arguments != NULL);  // functions have 'arguments' declared implicitly
 
-  bool uses_nonstrict_arguments = false;
+  bool uses_sloppy_arguments = false;
 
   if (MustAllocate(arguments) && !HasArgumentsParameter()) {
     // 'arguments' is used. Unless there is also a parameter called
@@ -1265,7 +1256,7 @@
     // In strict mode 'arguments' does not alias formal parameters.
     // Therefore in strict mode we allocate parameters as if 'arguments'
     // were not used.
-    uses_nonstrict_arguments = is_classic_mode();
+    uses_sloppy_arguments = strict_mode() == SLOPPY;
   }
 
   // The same parameter may occur multiple times in the parameters_ list.
@@ -1275,7 +1266,7 @@
   for (int i = params_.length() - 1; i >= 0; --i) {
     Variable* var = params_[i];
     ASSERT(var->scope() == this);
-    if (uses_nonstrict_arguments) {
+    if (uses_sloppy_arguments) {
       // Force context allocation of the parameter.
       var->ForceContextAllocation();
     }
diff --git a/src/scopes.h b/src/scopes.h
index 06aaa90..b0d8434 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -234,9 +234,7 @@
   void RecordEvalCall() { if (!is_global_scope()) scope_calls_eval_ = true; }
 
   // Set the strict mode flag (unless disabled by a global flag).
-  void SetLanguageMode(LanguageMode language_mode) {
-    language_mode_ = language_mode;
-  }
+  void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
 
   // Position in the source where this scope begins and ends.
   //
@@ -293,23 +291,17 @@
     return is_eval_scope() || is_function_scope() ||
         is_module_scope() || is_global_scope();
   }
-  bool is_classic_mode() const {
-    return language_mode() == CLASSIC_MODE;
-  }
-  bool is_extended_mode() const {
-    return language_mode() == EXTENDED_MODE;
-  }
-  bool is_strict_or_extended_eval_scope() const {
-    return is_eval_scope() && !is_classic_mode();
+  bool is_strict_eval_scope() const {
+    return is_eval_scope() && strict_mode_ == STRICT;
   }
 
   // Information about which scopes calls eval.
   bool calls_eval() const { return scope_calls_eval_; }
-  bool calls_non_strict_eval() {
-    return scope_calls_eval_ && is_classic_mode();
+  bool calls_sloppy_eval() {
+    return scope_calls_eval_ && strict_mode_ == SLOPPY;
   }
-  bool outer_scope_calls_non_strict_eval() const {
-    return outer_scope_calls_non_strict_eval_;
+  bool outer_scope_calls_sloppy_eval() const {
+    return outer_scope_calls_sloppy_eval_;
   }
 
   // Is this scope inside a with statement.
@@ -324,7 +316,7 @@
   ScopeType scope_type() const { return scope_type_; }
 
   // The language mode of this scope.
-  LanguageMode language_mode() const { return language_mode_; }
+  StrictMode strict_mode() const { return strict_mode_; }
 
   // The variable corresponding the 'this' value.
   Variable* receiver() { return receiver_; }
@@ -493,14 +485,14 @@
   // This scope or a nested catch scope or with scope contain an 'eval' call. At
   // the 'eval' call site this scope is the declaration scope.
   bool scope_calls_eval_;
-  // The language mode of this scope.
-  LanguageMode language_mode_;
+  // The strict mode of this scope.
+  StrictMode strict_mode_;
   // Source positions.
   int start_position_;
   int end_position_;
 
   // Computed via PropagateScopeInfo.
-  bool outer_scope_calls_non_strict_eval_;
+  bool outer_scope_calls_sloppy_eval_;
   bool inner_scope_calls_eval_;
   bool force_eager_compilation_;
   bool force_context_allocation_;
@@ -538,13 +530,13 @@
     // The variable reference could be statically resolved to a variable binding
     // which is returned. There is no 'with' statement between the reference and
     // the binding and no scope between the reference scope (inclusive) and
-    // binding scope (exclusive) makes a non-strict 'eval' call.
+    // binding scope (exclusive) makes a sloppy 'eval' call.
     BOUND,
 
     // The variable reference could be statically resolved to a variable binding
     // which is returned. There is no 'with' statement between the reference and
     // the binding, but some scope between the reference scope (inclusive) and
-    // binding scope (exclusive) makes a non-strict 'eval' call, that might
+    // binding scope (exclusive) makes a sloppy 'eval' call, that might
     // possibly introduce variable bindings shadowing the found one. Thus the
     // found variable binding is just a guess.
     BOUND_EVAL_SHADOWED,
@@ -553,13 +545,13 @@
     // and thus should be considered referencing a global variable. NULL is
     // returned. The variable reference is not inside any 'with' statement and
     // no scope between the reference scope (inclusive) and global scope
-    // (exclusive) makes a non-strict 'eval' call.
+    // (exclusive) makes a sloppy 'eval' call.
     UNBOUND,
 
     // The variable reference could not be statically resolved to any binding
     // NULL is returned. The variable reference is not inside any 'with'
     // statement, but some scope between the reference scope (inclusive) and
-    // global scope (exclusive) makes a non-strict 'eval' call, that might
+    // global scope (exclusive) makes a sloppy 'eval' call, that might
     // possibly introduce a variable binding. Thus the reference should be
     // considered referencing a global variable unless it is shadowed by an
     // 'eval' introduced binding.
@@ -591,7 +583,7 @@
                                    AstNodeFactory<AstNullVisitor>* factory);
 
   // Scope analysis.
-  bool PropagateScopeInfo(bool outer_scope_calls_non_strict_eval);
+  bool PropagateScopeInfo(bool outer_scope_calls_sloppy_eval);
   bool HasTrivialContext() const;
 
   // Predicates.
diff --git a/src/serialize.cc b/src/serialize.cc
index 46975ce..30a05d5 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -1144,15 +1144,15 @@
       // allocation point and write a pointer to it to the current object.
       ALL_SPACES(kBackref, kPlain, kStartOfObject)
       ALL_SPACES(kBackrefWithSkip, kPlain, kStartOfObject)
-#if V8_TARGET_ARCH_MIPS
+#if defined(V8_TARGET_ARCH_MIPS) || V8_OOL_CONSTANT_POOL
       // Deserialize a new object from pointer found in code and write
-      // a pointer to it to the current object. Required only for MIPS, and
-      // omitted on the other architectures because it is fully unrolled and
-      // would cause bloat.
+      // a pointer to it to the current object. Required only for MIPS or ARM
+      // with ool constant pool, and omitted on the other architectures because
+      // it is fully unrolled and would cause bloat.
       ALL_SPACES(kNewObject, kFromCode, kStartOfObject)
       // Find a recently deserialized code object using its offset from the
       // current allocation point and write a pointer to it to the current
-      // object. Required only for MIPS.
+      // object. Required only for MIPS or ARM with ool constant pool.
       ALL_SPACES(kBackref, kFromCode, kStartOfObject)
       ALL_SPACES(kBackrefWithSkip, kFromCode, kStartOfObject)
 #endif
@@ -1373,12 +1373,11 @@
   for (int i = 0; i < root_index_wave_front_; i++) {
     Object* root = heap->roots_array_start()[i];
     if (!root->IsSmi() && root == heap_object) {
-#if V8_TARGET_ARCH_MIPS
+#if defined(V8_TARGET_ARCH_MIPS) || V8_OOL_CONSTANT_POOL
       if (from == kFromCode) {
         // In order to avoid code bloat in the deserializer we don't have
         // support for the encoding that specifies a particular root should
-        // be written into the lui/ori instructions on MIPS.  Therefore we
-        // should not generate such serialization data for MIPS.
+        // be written from within code.
         return kInvalidRootIndex;
       }
 #endif
@@ -1631,6 +1630,9 @@
 
 
 void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) {
+  // Out-of-line constant pool entries will be visited by the ConstantPoolArray.
+  if (FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool()) return;
+
   int skip = OutputRawData(rinfo->target_address_address(),
                            kCanReturnSkipInsteadOfSkipping);
   HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
@@ -1676,6 +1678,9 @@
 
 
 void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
+  // Out-of-line constant pool entries will be visited by the ConstantPoolArray.
+  if (FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool()) return;
+
   int skip = OutputRawData(rinfo->target_address_address(),
                            kCanReturnSkipInsteadOfSkipping);
   Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address());
@@ -1693,6 +1698,9 @@
 
 
 void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) {
+  // Out-of-line constant pool entries will be visited by the ConstantPoolArray.
+  if (FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool()) return;
+
   int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping);
   Cell* object = Cell::cast(rinfo->target_cell());
   serializer_->SerializeObject(object, kPlain, kInnerPointer, skip);
@@ -1738,7 +1746,9 @@
       RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
       RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
   for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
-    it.rinfo()->WipeOut();
+    if (!(FLAG_enable_ool_constant_pool && it.rinfo()->IsInConstantPool())) {
+      it.rinfo()->WipeOut();
+    }
   }
 }
 
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 37562a9..52e7f4c 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -222,7 +222,7 @@
 
 Handle<Code> StubCache::ComputeKeyedStoreElement(
     Handle<Map> receiver_map,
-    StrictModeFlag strict_mode,
+    StrictMode strict_mode,
     KeyedAccessStoreMode store_mode) {
   ExtraICState extra_state =
       KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
@@ -396,7 +396,7 @@
 Handle<Code> StubCache::ComputeStoreElementPolymorphic(
     MapHandleList* receiver_maps,
     KeyedAccessStoreMode store_mode,
-    StrictModeFlag strict_mode) {
+    StrictMode strict_mode) {
   ASSERT(store_mode == STANDARD_STORE ||
          store_mode == STORE_AND_GROW_NO_TRANSITION ||
          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
@@ -722,7 +722,7 @@
 
 Handle<Code> StubCompiler::CompileStoreGeneric(Code::Flags flags) {
   ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
-  StrictModeFlag strict_mode = StoreIC::GetStrictMode(extra_state);
+  StrictMode strict_mode = StoreIC::GetStrictMode(extra_state);
   StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode);
   Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric");
   PROFILE(isolate(),
diff --git a/src/stub-cache.h b/src/stub-cache.h
index ad2b550..5d309b1 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -103,7 +103,7 @@
   Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map);
 
   Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map,
-                                        StrictModeFlag strict_mode,
+                                        StrictMode strict_mode,
                                         KeyedAccessStoreMode store_mode);
 
   // ---
@@ -122,7 +122,7 @@
   Handle<Code> ComputeLoadElementPolymorphic(MapHandleList* receiver_maps);
   Handle<Code> ComputeStoreElementPolymorphic(MapHandleList* receiver_maps,
                                               KeyedAccessStoreMode store_mode,
-                                              StrictModeFlag strict_mode);
+                                              StrictMode strict_mode);
 
   Handle<Code> ComputePolymorphicIC(Code::Kind kind,
                                     TypeHandleList* types,
diff --git a/src/token.h b/src/token.h
index 39bcc24..8efaa47 100644
--- a/src/token.h
+++ b/src/token.h
@@ -73,7 +73,7 @@
   T(INIT_VAR, "=init_var", 2)  /* AST-use only. */                      \
   T(INIT_LET, "=init_let", 2)  /* AST-use only. */                      \
   T(INIT_CONST, "=init_const", 2)  /* AST-use only. */                  \
-  T(INIT_CONST_HARMONY, "=init_const_harmony", 2)  /* AST-use only. */  \
+  T(INIT_CONST_LEGACY, "=init_const_legacy", 2)  /* AST-use only. */    \
   T(ASSIGN, "=", 2)                                                     \
   T(ASSIGN_BIT_OR, "|=", 2)                                             \
   T(ASSIGN_BIT_XOR, "^=", 2)                                            \
diff --git a/src/types.cc b/src/types.cc
index 3840e6f..cf41bb5 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -141,9 +141,11 @@
     }
     return bitset;
   } else if (this->IsClass()) {
-    return LubBitset(*this->AsClass());
+    int bitset = Config::lub_bitset(this);
+    return bitset ? bitset : LubBitset(*this->AsClass());
   } else {
-    return LubBitset(*this->AsConstant());
+    int bitset = Config::lub_bitset(this);
+    return bitset ? bitset : LubBitset(*this->AsConstant());
   }
 }
 
@@ -548,9 +550,9 @@
   if (type->IsBitset()) {
     return Config::from_bitset(type->AsBitset(), region);
   } else if (type->IsClass()) {
-    return Config::from_class(type->AsClass(), region);
+    return Config::from_class(type->AsClass(), type->LubBitset(), region);
   } else if (type->IsConstant()) {
-    return Config::from_constant(type->AsConstant(), region);
+    return Config::from_constant(type->AsConstant(), type->LubBitset(), region);
   } else {
     ASSERT(type->IsUnion());
     typename OtherType::UnionedHandle unioned = type->AsUnion();
diff --git a/src/types.h b/src/types.h
index 48b3933..20371a9 100644
--- a/src/types.h
+++ b/src/types.h
@@ -87,12 +87,17 @@
 // Consequently, do not use pointer equality for type tests, always use Is!
 //
 // Internally, all 'primitive' types, and their unions, are represented as
-// bitsets via smis. Class is a heap pointer to the respective map. Only
-// Constant's, or unions containing Class'es or Constant's, require allocation.
+// bitsets. Class is a heap pointer to the respective map. Only Constant's, or
+// unions containing Class'es or Constant's, currently require allocation.
 // Note that the bitset representation is closed under both Union and Intersect.
 //
-// The type representation is heap-allocated, so cannot (currently) be used in
-// a concurrent compilation context.
+// There are two type representations, using different allocation:
+//
+// - class Type (zone-allocated, for compiler and concurrent compilation)
+// - class HeapType (heap-allocated, for persistent types)
+//
+// Both provide the same API, and the Convert method can be used to interconvert
+// them. For zone types, no query method touches the heap, only constructors do.
 
 
 #define BITSET_TYPE_LIST(V)              \
@@ -147,14 +152,15 @@
 //   static Handle<Unioned>::type as_union(Type*);
 //   static Type* from_bitset(int bitset);
 //   static Handle<Type>::type from_bitset(int bitset, Region*);
-//   static Handle<Type>::type from_class(i::Handle<i::Map>, Region*)
-//   static Handle<Type>::type from_constant(i::Handle<i::Object>, Region*);
+//   static Handle<Type>::type from_class(i::Handle<Map>, int lub, Region*);
+//   static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*);
 //   static Handle<Type>::type from_union(Handle<Unioned>::type);
 //   static Handle<Unioned>::type union_create(int size, Region*);
 //   static void union_shrink(Handle<Unioned>::type, int size);
 //   static Handle<Type>::type union_get(Handle<Unioned>::type, int);
 //   static void union_set(Handle<Unioned>::type, int, Handle<Type>::type);
 //   static int union_length(Handle<Unioned>::type);
+//   static int lub_bitset(Type*);
 // }
 template<class Config>
 class TypeImpl : public Config::Base {
@@ -171,10 +177,10 @@
   #undef DEFINE_TYPE_CONSTRUCTOR
 
   static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
-    return Config::from_class(map, region);
+    return Config::from_class(map, LubBitset(*map), region);
   }
   static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
-    return Config::from_constant(value, region);
+    return Config::from_constant(value, LubBitset(*value), region);
   }
 
   static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
@@ -335,7 +341,7 @@
   }
   template<class T>
   static void tagged_set(Tagged* tagged, int i, T value) {
-    tagged->at(i + 1) = reinterpret_cast<T>(value);
+    tagged->at(i + 1) = reinterpret_cast<void*>(value);
   }
   static int tagged_length(Tagged* tagged) {
     return tagged->length() - 1;
@@ -375,11 +381,11 @@
   }
   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), 0));
+    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), 0));
+    return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1));
   }
   static Unioned* as_union(Type* type) {
     ASSERT(is_union(type));
@@ -399,14 +405,16 @@
   static Type* from_tagged(Tagged* tagged) {
     return reinterpret_cast<Type*>(tagged);
   }
-  static Type* from_class(i::Handle<i::Map> map, Zone* zone) {
-    Tagged* tagged = tagged_create(kClassTag, 1, zone);
-    tagged_set(tagged, 0, map.location());
+  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, Zone* zone) {
-    Tagged* tagged = tagged_create(kConstantTag, 1, zone);
-    tagged_set(tagged, 0, value.location());
+  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) {
@@ -434,6 +442,10 @@
   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));
+  }
 };
 
 
@@ -475,11 +487,12 @@
   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, Isolate* 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, Isolate* isolate) {
+      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));
   }
@@ -506,6 +519,9 @@
   static int union_length(i::Handle<Unioned> unioned) {
     return unioned->length();
   }
+  static int lub_bitset(Type* type) {
+    return 0;  // kNone, which causes recomputation.
+  }
 };
 
 typedef TypeImpl<ZoneTypeConfig> Type;
diff --git a/src/v8globals.h b/src/v8globals.h
index 7d8d1b7..2e0ead3 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -465,11 +465,11 @@
   // User declared variables:
   VAR,             // declared via 'var', and 'function' declarations
 
-  CONST,           // declared via 'const' declarations
+  CONST_LEGACY,    // declared via legacy 'const' declarations
 
   LET,             // declared via 'let' declarations (first lexical)
 
-  CONST_HARMONY,   // declared via 'const' declarations in harmony mode
+  CONST,           // declared via 'const' declarations
 
   MODULE,          // declared via 'module' declaration (last lexical)
 
@@ -510,7 +510,7 @@
 
 
 inline bool IsImmutableVariableMode(VariableMode mode) {
-  return mode == CONST || (mode >= CONST_HARMONY && mode <= MODULE);
+  return (mode >= CONST && mode <= MODULE) || mode == CONST_LEGACY;
 }
 
 
diff --git a/src/v8natives.js b/src/v8natives.js
index c850a4b..f183afb 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -1282,7 +1282,7 @@
     throw MakeTypeError("called_on_non_object", ["Object.freeze"]);
   }
   var isProxy = %IsJSProxy(obj);
-  if (isProxy || %HasNonStrictArgumentsElements(obj) || %IsObserved(obj)) {
+  if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) {
     if (isProxy) {
       ProxyFix(obj);
     }
diff --git a/src/variables.cc b/src/variables.cc
index 488da42..6c4ea52 100644
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -40,9 +40,9 @@
 const char* Variable::Mode2String(VariableMode mode) {
   switch (mode) {
     case VAR: return "VAR";
-    case CONST: return "CONST";
+    case CONST_LEGACY: return "CONST_LEGACY";
     case LET: return "LET";
-    case CONST_HARMONY: return "CONST_HARMONY";
+    case CONST: return "CONST";
     case MODULE: return "MODULE";
     case DYNAMIC: return "DYNAMIC";
     case DYNAMIC_GLOBAL: return "DYNAMIC_GLOBAL";
diff --git a/src/variables.h b/src/variables.h
index 39451d5..401d044 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -168,7 +168,7 @@
 
   // If this field is set, this variable references the stored locally bound
   // variable, but it might be shadowed by variable bindings introduced by
-  // non-strict 'eval' calls between the reference scope (inclusive) and the
+  // sloppy 'eval' calls between the reference scope (inclusive) and the
   // binding scope (exclusive).
   Variable* local_if_not_shadowed_;
 
diff --git a/src/version.cc b/src/version.cc
index 4319e1a..3c6f053 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     25
-#define BUILD_NUMBER      7
-#define PATCH_LEVEL       2
+#define BUILD_NUMBER      8
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/win32-headers.h b/src/win32-headers.h
index 98b0120..ba595b9 100644
--- a/src/win32-headers.h
+++ b/src/win32-headers.h
@@ -94,6 +94,7 @@
 #undef NONE
 #undef ANY
 #undef IGNORE
+#undef STRICT
 #undef GetObject
 #undef CreateSemaphore
 #undef Yield
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 5345e9e..d4f5e03 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -799,7 +799,7 @@
              Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
     __ j(not_zero, &shift_arguments);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ movp(rbx, args.GetArgumentOperand(1));
     __ JumpIfSmi(rbx, &convert_to_object, Label::kNear);
 
@@ -990,7 +990,7 @@
              Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
     __ j(not_equal, &push_receiver);
 
-    // Compute the receiver in non-strict mode.
+    // Compute the receiver in sloppy mode.
     __ JumpIfSmi(rbx, &call_to_object, Label::kNear);
     __ CompareRoot(rbx, Heap::kNullValueRootIndex);
     __ j(equal, &use_global_receiver);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index d6b0dd0..84706fe 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -1062,7 +1062,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   // Stack layout:
   //  rsp[0]  : return address
   //  rsp[8]  : number of parameters (tagged)
@@ -1123,7 +1123,7 @@
   __ lea(r8, Operand(r8, rcx, times_pointer_size, FixedArray::kHeaderSize));
 
   // 3. Arguments object.
-  __ addq(r8, Immediate(Heap::kArgumentsObjectSize));
+  __ addq(r8, Immediate(Heap::kSloppyArgumentsObjectSize));
 
   // Do the allocation of all three objects in one go.
   __ Allocate(r8, rax, rdx, rdi, &runtime, TAG_OBJECT);
@@ -1137,7 +1137,7 @@
   __ testq(rbx, rbx);
   __ j(not_zero, &has_mapped_parameters, Label::kNear);
 
-  const int kIndex = Context::ARGUMENTS_BOILERPLATE_INDEX;
+  const int kIndex = Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX;
   __ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex)));
   __ jmp(&copy, Label::kNear);
 
@@ -1174,7 +1174,7 @@
   // Set up the elements pointer in the allocated arguments object.
   // If we allocated a parameter map, edi will point there, otherwise to the
   // backing store.
-  __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize));
+  __ lea(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize));
   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
 
   // rax = address of new object (tagged)
@@ -1187,7 +1187,7 @@
   __ testq(rbx, rbx);
   __ j(zero, &skip_parameter_map);
 
-  __ LoadRoot(kScratchRegister, Heap::kNonStrictArgumentsElementsMapRootIndex);
+  __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex);
   // rbx contains the untagged argument count. Add 2 and tag to write.
   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
   __ Integer64PlusConstantToSmi(r9, rbx, 2);
@@ -1280,7 +1280,7 @@
 }
 
 
-void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
+void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // rsp[0]  : return address
   // rsp[8]  : number of parameters
   // rsp[16] : receiver displacement
@@ -1343,7 +1343,7 @@
   __ j(zero, &add_arguments_object, Label::kNear);
   __ lea(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize));
   __ bind(&add_arguments_object);
-  __ addq(rcx, Immediate(Heap::kArgumentsObjectSizeStrict));
+  __ addq(rcx, Immediate(Heap::kStrictArgumentsObjectSize));
 
   // Do the allocation of both objects in one go.
   __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
@@ -1352,7 +1352,7 @@
   __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
   __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
   const int offset =
-      Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
+      Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX);
   __ movp(rdi, Operand(rdi, offset));
 
   // Copy the JS object part.
@@ -1378,7 +1378,7 @@
 
   // Set up the elements pointer in the allocated arguments object and
   // initialize the header in the elements fixed array.
-  __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSizeStrict));
+  __ lea(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize));
   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
   __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index ea50191..67d94f9 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -133,10 +133,10 @@
   }
 #endif
 
-  // Classic mode functions and builtins need to replace the receiver with the
+  // Sloppy mode functions and builtins need to replace the receiver with the
   // global proxy when called as functions (without an explicit receiver
   // object).
-  if (info->is_classic_mode() && !info->is_native()) {
+  if (info->strict_mode() == SLOPPY && !info->is_native()) {
     Label ok;
     // +1 for return address.
     StackArgumentsAccessor args(rsp, info->scope()->num_parameters());
@@ -242,12 +242,12 @@
     // The stub will rewrite receiver and parameter count if the previous
     // stack frame was an arguments adapter frame.
     ArgumentsAccessStub::Type type;
-    if (!is_classic_mode()) {
+    if (strict_mode() == STRICT) {
       type = ArgumentsAccessStub::NEW_STRICT;
     } else if (function()->has_duplicate_parameters()) {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
+      type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
     } else {
-      type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
+      type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
     ArgumentsAccessStub stub(type);
     __ CallStub(&stub);
@@ -273,7 +273,7 @@
       if (scope()->is_function_scope() && scope()->function() != NULL) {
         VariableDeclaration* function = scope()->function();
         ASSERT(function->proxy()->var()->mode() == CONST ||
-               function->proxy()->var()->mode() == CONST_HARMONY);
+               function->proxy()->var()->mode() == CONST_LEGACY);
         ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
         VisitVariableDeclaration(function);
       }
@@ -756,7 +756,7 @@
   VariableProxy* proxy = declaration->proxy();
   VariableMode mode = declaration->mode();
   Variable* variable = proxy->var();
-  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
+  bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
       globals_->Add(variable->name(), zone());
@@ -1285,7 +1285,7 @@
       !pretenure &&
       scope()->is_function_scope() &&
       info->num_literals() == 0) {
-    FastNewClosureStub stub(info->language_mode(), info->is_generator());
+    FastNewClosureStub stub(info->strict_mode(), info->is_generator());
     __ Move(rbx, info);
     __ CallStub(&stub);
   } else {
@@ -1315,7 +1315,7 @@
   Scope* s = scope();
   while (s != NULL) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX),
                 Immediate(0));
@@ -1329,7 +1329,7 @@
     // If no outer scope calls eval, we do not need to check more
     // context extensions.  If we have reached an eval scope, we check
     // all extensions from this point.
-    if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break;
+    if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
     s = s->outer_scope();
   }
 
@@ -1374,7 +1374,7 @@
 
   for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
     if (s->num_heap_slots() > 0) {
-      if (s->calls_non_strict_eval()) {
+      if (s->calls_sloppy_eval()) {
         // Check that extension is NULL.
         __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX),
                 Immediate(0));
@@ -1411,14 +1411,13 @@
   } else if (var->mode() == DYNAMIC_LOCAL) {
     Variable* local = var->local_if_not_shadowed();
     __ movp(rax, ContextSlotOperandCheckExtensions(local, slow));
-    if (local->mode() == LET ||
-        local->mode() == CONST ||
-        local->mode() == CONST_HARMONY) {
+    if (local->mode() == LET || local->mode() == CONST ||
+        local->mode() == CONST_LEGACY) {
       __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
       __ j(not_equal, done);
-      if (local->mode() == CONST) {
+      if (local->mode() == CONST_LEGACY) {
         __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
-      } else {  // LET || CONST_HARMONY
+      } else {  // LET || CONST
         __ Push(var->name());
         __ CallRuntime(Runtime::kThrowReferenceError, 1);
       }
@@ -1483,7 +1482,7 @@
           // Check that we always have valid source position.
           ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
           ASSERT(proxy->position() != RelocInfo::kNoPosition);
-          skip_init_check = var->mode() != CONST &&
+          skip_init_check = var->mode() != CONST_LEGACY &&
               var->initializer_position() < proxy->position();
         }
 
@@ -1493,14 +1492,14 @@
           GetVar(rax, var);
           __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
           __ j(not_equal, &done, Label::kNear);
-          if (var->mode() == LET || var->mode() == CONST_HARMONY) {
+          if (var->mode() == LET || var->mode() == CONST) {
             // Throw a reference error when using an uninitialized let/const
             // binding in harmony mode.
             __ Push(var->name());
             __ CallRuntime(Runtime::kThrowReferenceError, 1);
           } else {
             // Uninitalized const bindings outside of harmony mode are unholed.
-            ASSERT(var->mode() == CONST);
+            ASSERT(var->mode() == CONST_LEGACY);
             __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
           }
           __ bind(&done);
@@ -2381,7 +2380,7 @@
       __ movp(rcx, rax);
       __ pop(rdx);
       __ pop(rax);  // Restore value.
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic);
@@ -2404,11 +2403,11 @@
 
 
 void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, LanguageMode mode) {
+    Handle<String> name, StrictMode strict_mode) {
   __ push(rax);  // Value.
   __ push(rsi);  // Context.
   __ Push(name);
-  __ Push(Smi::FromInt(mode));
+  __ Push(Smi::FromInt(strict_mode));
   __ CallRuntime(Runtime::kStoreContextSlot, 4);
 }
 
@@ -2421,7 +2420,7 @@
     __ movp(rdx, GlobalObjectOperand());
     CallStoreIC();
 
-  } else if (op == Token::INIT_CONST) {
+  } else if (op == Token::INIT_CONST_LEGACY) {
     // Const initializers need a write barrier.
     ASSERT(!var->IsParameter());  // No const parameters.
     if (var->IsLookupSlot()) {
@@ -2443,7 +2442,7 @@
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       Label assign;
@@ -2457,11 +2456,11 @@
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
 
-  } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
+  } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     // Assignment to var or initializing assignment to let/const
     // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), language_mode());
+      EmitCallStoreContextSlot(var->name(), strict_mode());
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       MemOperand location = VarOperand(var, rcx);
@@ -2502,7 +2501,7 @@
   __ pop(rdx);
   // Record source code position before IC call.
   SetSourcePosition(expr->position());
-  Handle<Code> ic = is_classic_mode()
+  Handle<Code> ic = strict_mode() == SLOPPY
       ? isolate()->builtins()->KeyedStoreIC_Initialize()
       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
   CallIC(ic, expr->AssignmentFeedbackId());
@@ -2552,7 +2551,7 @@
       PrepareForBailout(callee, NO_REGISTERS);
     }
     // Push undefined as receiver. This is patched in the method prologue if it
-    // is a classic mode method.
+    // is a sloppy mode method.
     __ Push(isolate()->factory()->undefined_value());
     flags = NO_CALL_FUNCTION_FLAGS;
   } else {
@@ -2670,7 +2669,7 @@
   __ push(args.GetReceiverOperand());
 
   // Push the language mode.
-  __ Push(Smi::FromInt(language_mode()));
+  __ Push(Smi::FromInt(strict_mode()));
 
   // Push the start position of the scope the calls resides in.
   __ Push(Smi::FromInt(scope()->start_position()));
@@ -4166,20 +4165,18 @@
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
-            ? kNonStrictMode : kStrictMode;
-        __ Push(Smi::FromInt(strict_mode_flag));
+        __ Push(Smi::FromInt(strict_mode()));
         __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
         context()->Plug(rax);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
         // Delete of an unqualified identifier is disallowed in strict mode
         // but "delete this" is allowed.
-        ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
+        ASSERT(strict_mode() == SLOPPY || var->is_this());
         if (var->IsUnallocated()) {
           __ push(GlobalObjectOperand());
           __ Push(var->name());
-          __ Push(Smi::FromInt(kNonStrictMode));
+          __ Push(Smi::FromInt(SLOPPY));
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
           context()->Plug(rax);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
@@ -4441,7 +4438,7 @@
     case KEYED_PROPERTY: {
       __ pop(rcx);
       __ pop(rdx);
-      Handle<Code> ic = is_classic_mode()
+      Handle<Code> ic = strict_mode() == SLOPPY
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
       CallIC(ic, expr->CountStoreFeedbackId());
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index d2340c8..40fdc60 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -734,7 +734,7 @@
 
 
 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictModeFlag strict_mode) {
+                                   StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rcx    : key
@@ -852,7 +852,7 @@
 
   // Load the elements into scratch1 and check its map. If not, jump
   // to the unmapped lookup with the parameter map in scratch1.
-  Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
+  Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
   __ movp(scratch1, FieldOperand(object, JSObject::kElementsOffset));
   __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK);
 
@@ -909,7 +909,7 @@
 }
 
 
-void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : key
   //  -- rdx    : receiver
@@ -934,7 +934,7 @@
 }
 
 
-void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
+void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rcx    : key
@@ -1151,7 +1151,7 @@
 
 
 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictModeFlag strict_mode) {
+                                         StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rcx    : name
@@ -1172,7 +1172,7 @@
 
 
 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictModeFlag strict_mode) {
+                                              StrictMode strict_mode) {
   // ----------- S t a t e -------------
   //  -- rax    : value
   //  -- rcx    : key
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 1b6a97b..e05be03 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -154,10 +154,10 @@
     }
 #endif
 
-    // Classic mode functions need to replace the receiver with the global proxy
+    // Sloppy mode functions need to replace the receiver with the global proxy
     // when called as functions (without an explicit receiver object).
     if (info_->this_has_uses() &&
-        info_->is_classic_mode() &&
+        info_->strict_mode() == SLOPPY &&
         !info_->is_native()) {
       Label ok;
       StackArgumentsAccessor args(rsp, scope()->num_parameters());
@@ -273,6 +273,13 @@
 }
 
 
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}
+
+
 bool LCodeGen::GenerateJumpTable() {
   Label needs_frame;
   if (jump_table_.length() > 0) {
@@ -1036,8 +1043,7 @@
 
   // Check for negative zero.
   HMod* hmod = instr->hydrogen();
-  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hmod->left()->CanBeNegative()) {
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label remainder_not_zero;
     __ j(not_zero, &remainder_not_zero, Label::kNear);
     __ cmpl(dividend, Immediate(0));
@@ -1048,12 +1054,7 @@
 
 
 void LCodeGen::DoModI(LModI* instr) {
-  if (instr->hydrogen()->RightIsPowerOf2()) {
-    return DoModByPowerOf2I(reinterpret_cast<LModByPowerOf2I*>(instr));
-  }
   HMod* hmod = instr->hydrogen();
-  HValue* left = hmod->left();
-  HValue* right = hmod->right();
 
   Register left_reg = ToRegister(instr->left());
   ASSERT(left_reg.is(rax));
@@ -1066,14 +1067,14 @@
   Label done;
   // Check for x % 0, idiv would signal a divide error. We have to
   // deopt in this case because we can't return a NaN.
-  if (right->CanBeZero()) {
+  if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
     __ testl(right_reg, right_reg);
     DeoptimizeIf(zero, instr->environment());
   }
 
   // Check for kMinInt % -1, idiv would signal a divide error. We
   // have to deopt if we care about -0, because we can't return that.
-  if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
+  if (hmod->CheckFlag(HValue::kCanOverflow)) {
     Label no_overflow_possible;
     __ cmpl(left_reg, Immediate(kMinInt));
     __ j(not_zero, &no_overflow_possible, Label::kNear);
@@ -1093,9 +1094,7 @@
   __ cdq();
 
   // If we care about -0, test if the dividend is <0 and the result is 0.
-  if (left->CanBeNegative() &&
-      hmod->CanBeZero() &&
-      hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label positive_left;
     __ testl(left_reg, left_reg);
     __ j(not_sign, &positive_left, Label::kNear);
@@ -1159,8 +1158,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ testl(dividend, dividend);
     DeoptimizeIf(zero, instr->environment());
   }
@@ -1178,14 +1176,12 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ testl(dividend, dividend);
     DeoptimizeIf(zero, instr->environment());
   }
   // Check for (kMinInt / -1).
-  if (hdiv->CheckFlag(HValue::kCanOverflow) &&
-      hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+  if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
     __ cmpl(dividend, Immediate(kMinInt));
     DeoptimizeIf(zero, instr->environment());
   }
@@ -1221,8 +1217,7 @@
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
-  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ testl(dividend, dividend);
     DeoptimizeIf(zero, instr->environment());
   }
@@ -1243,6 +1238,7 @@
 
 
 void LCodeGen::DoDivI(LDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
   Register dividend = ToRegister(instr->left());
   Register divisor = ToRegister(instr->right());
   Register remainder = ToRegister(instr->temp());
@@ -1254,7 +1250,6 @@
   ASSERT(!divisor.is(rdx));
 
   // Check for x / 0.
-  HBinaryOperation* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
     __ testl(divisor, divisor);
     DeoptimizeIf(zero, instr->environment());
@@ -1284,7 +1279,7 @@
   __ cdq();
   __ idivl(divisor);
 
-  if (instr->is_flooring()) {
+  if (hdiv->IsMathFloorOfDiv()) {
     Label done;
     __ testl(remainder, remainder);
     __ j(zero, &done, Label::kNear);
@@ -1292,8 +1287,7 @@
     __ sarl(remainder, Immediate(31));
     __ addl(result, remainder);
     __ bind(&done);
-  } else if (!instr->hydrogen()->CheckFlag(
-      HInstruction::kAllUsesTruncatingToInt32)) {
+  } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     // Deoptimize if remainder is not 0.
     __ testl(remainder, remainder);
     DeoptimizeIf(not_zero, instr->environment());
@@ -1913,7 +1907,6 @@
 
   BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-  __ nop();  // Signals no inlined code.
 }
 
 
@@ -3001,7 +2994,7 @@
       case FAST_HOLEY_SMI_ELEMENTS:
       case FAST_HOLEY_DOUBLE_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4062,8 +4055,7 @@
   ASSERT(ToRegister(instr->value()).is(rax));
 
   __ Move(rcx, instr->hydrogen()->name());
-  Handle<Code> ic = StoreIC::initialize_stub(isolate(),
-                                             instr->strict_mode_flag());
+  Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -4198,7 +4190,7 @@
       case FAST_HOLEY_SMI_ELEMENTS:
       case FAST_HOLEY_DOUBLE_ELEMENTS:
       case DICTIONARY_ELEMENTS:
-      case NON_STRICT_ARGUMENTS_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
         UNREACHABLE();
         break;
     }
@@ -4349,7 +4341,7 @@
   ASSERT(ToRegister(instr->key()).is(rcx));
   ASSERT(ToRegister(instr->value()).is(rax));
 
-  Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
+  Handle<Code> ic = instr->strict_mode() == STRICT
       ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
       : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -5301,7 +5293,7 @@
   // space for nested functions that don't need literals cloning.
   bool pretenure = instr->hydrogen()->pretenure();
   if (!pretenure && instr->hydrogen()->has_no_literals()) {
-    FastNewClosureStub stub(instr->hydrogen()->language_mode(),
+    FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
                             instr->hydrogen()->is_generator());
     __ Move(rbx, instr->hydrogen()->shared_info());
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index 0f1a9cd..e2c5a0a 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -130,9 +130,7 @@
 #undef DECLARE_DO
 
  private:
-  StrictModeFlag strict_mode_flag() const {
-    return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
-  }
+  StrictMode strict_mode() const { return info()->strict_mode(); }
 
   LPlatformChunk* chunk() const { return chunk_; }
   Scope* scope() const { return scope_; }
@@ -159,6 +157,7 @@
 
   // Code generation passes.  Returns true if code generation should
   // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateJumpTable();
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 74390e6..beb0f2b 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -630,15 +630,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);
 
-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -916,6 +907,26 @@
       instr = AssignEnvironment(instr);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+      LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+            SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -1248,16 +1259,15 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      (instr->CheckFlag(HValue::kCanOverflow) &&
-       instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+  LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+          dividend, divisor));
+  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
       (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
-       divisor != 1 && divisor != -1);
-  return can_deopt ? AssignEnvironment(result) : result;
+       divisor != 1 && divisor != -1)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1269,15 +1279,14 @@
   int32_t divisor = instr->right()->GetInteger32Constant();
   LOperand* temp1 = FixedTemp(rax);
   LOperand* temp2 = FixedTemp(rdx);
-  LInstruction* result =
-      DefineFixed(
-          new(zone()) LDivByConstI(dividend, divisor, temp1, temp2), rdx);
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0) ||
-      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineFixed(new(zone()) LDivByConstI(
+          dividend, divisor, temp1, temp2), rdx);
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1288,9 +1297,16 @@
   LOperand* dividend = UseFixed(instr->left(), rax);
   LOperand* divisor = UseRegister(instr->right());
   LOperand* temp = FixedTemp(rdx);
-  LInstruction* result =
-      DefineFixed(new(zone()) LDivI(dividend, divisor, temp), rax);
-  return AssignEnvironment(result);
+  LInstruction* result = DefineFixed(new(zone()) LDivI(
+          dividend, divisor, temp), rax);
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      instr->CheckFlag(HValue::kCanOverflow) ||
+      (!instr->IsMathFloorOfDiv() &&
+       !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1339,8 +1355,7 @@
                   rdx);
   bool can_deopt =
       divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->RangeCanInclude(0) && divisor < 0);
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
   return can_deopt ? AssignEnvironment(result) : result;
 }
 
@@ -1362,12 +1377,12 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegisterAtStart(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
-  bool can_deopt =
-      instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-      instr->left()->CanBeNegative();
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+          dividend, divisor));
+  if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1379,14 +1394,12 @@
   int32_t divisor = instr->right()->GetInteger32Constant();
   LOperand* temp1 = FixedTemp(rax);
   LOperand* temp2 = FixedTemp(rdx);
-  LInstruction* result =
-      DefineFixed(
-          new(zone()) LModByConstI(dividend, divisor, temp1, temp2), rax);
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-       instr->left()->CanBeNegative());
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineFixed(new(zone()) LModByConstI(
+          dividend, divisor, temp1, temp2), rax);
+  if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1397,16 +1410,13 @@
   LOperand* dividend = UseFixed(instr->left(), rax);
   LOperand* divisor = UseRegister(instr->right());
   LOperand* temp = FixedTemp(rdx);
-  LInstruction* result =
-      DefineFixed(new(zone()) LModI(dividend, divisor, temp), rdx);
-  bool can_deopt = (instr->right()->CanBeZero() ||
-                    (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-                     instr->left()->RangeCanInclude(kMinInt) &&
-                     instr->right()->RangeCanInclude(-1)) ||
-                    (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-                     instr->left()->CanBeNegative() &&
-                     instr->CanBeZero()));
-  return can_deopt ? AssignEnvironment(result) : result;
+  LInstruction* result = DefineFixed(new(zone()) LModI(
+          dividend, divisor, temp), rdx);
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2436,21 +2446,6 @@
 
 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (pending_deoptimization_ast_id_ == instr->ast_id()) {
-    LLazyBailout* lazy_bailout = new(zone()) LLazyBailout;
-    LInstruction* result = AssignEnvironment(lazy_bailout);
-    // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }
 
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 4df350d..e03604d 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -737,8 +737,6 @@
   LOperand* right() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
-  bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
   DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
 };
@@ -2172,7 +2170,7 @@
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2227,7 +2225,7 @@
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
-  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
 
 
@@ -2668,9 +2666,7 @@
         current_instruction_(NULL),
         current_block_(NULL),
         next_block_(NULL),
-        allocator_(allocator),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        allocator_(allocator) { }
 
   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -2815,8 +2811,6 @@
   HBasicBlock* current_block_;
   HBasicBlock* next_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;
 
   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };