Version 3.25.22 (based on bleeding_edge revision r20129)

Increase the "local variables in a function" limit (issue 3205).

Implement ES6 symbol registry and predefined symbols.

Throw exception on invalid string length instead of OOM (Chromium issue 349329).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@20133 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/a64/builtins-a64.cc b/src/a64/builtins-a64.cc
index 59d4dd2..ec452da 100644
--- a/src/a64/builtins-a64.cc
+++ b/src/a64/builtins-a64.cc
@@ -861,7 +861,7 @@
   {
     FrameScope scope(masm, StackFrame::MANUAL);
     __ Push(x0, x1, fp, lr);
-    __ Mov(x1, Operand(ExternalReference::isolate_address(masm->isolate())));
+    __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
     __ CallCFunction(
         ExternalReference::get_make_code_young_function(masm->isolate()), 2);
     __ Pop(lr, fp, x1, x0);
@@ -901,7 +901,7 @@
   {
     FrameScope scope(masm, StackFrame::MANUAL);
     __ Push(x0, x1, fp, lr);
-    __ Mov(x1, Operand(ExternalReference::isolate_address(masm->isolate())));
+    __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
     __ CallCFunction(
         ExternalReference::get_mark_code_as_executed_function(
             masm->isolate()), 2);
@@ -963,7 +963,7 @@
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
     // Pass the deoptimization type to the runtime system.
-    __ Mov(x0, Operand(Smi::FromInt(static_cast<int>(type))));
+    __ Mov(x0, Smi::FromInt(static_cast<int>(type)));
     __ Push(x0);
     __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
   }
@@ -1019,7 +1019,7 @@
 
   // If the code object is null, just return to the unoptimized code.
   Label skip;
-  __ CompareAndBranch(x0, Operand(Smi::FromInt(0)), ne, &skip);
+  __ CompareAndBranch(x0, Smi::FromInt(0), ne, &skip);
   __ Ret();
 
   __ Bind(&skip);
@@ -1358,7 +1358,7 @@
 
     // Use inline caching to access the arguments.
     __ Ldr(current, MemOperand(fp, kIndexOffset));
-    __ Add(current, current, Operand(Smi::FromInt(1)));
+    __ Add(current, current, Smi::FromInt(1));
     __ Str(current, MemOperand(fp, kIndexOffset));
 
     // Test if the copy loop has finished copying all the elements from the
@@ -1402,7 +1402,7 @@
 
 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
   __ SmiTag(x10, x0);
-  __ Mov(x11, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ Mov(x11, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ Push(lr, fp);
   __ Push(x11, x1, x10);
   __ Add(fp, jssp,
diff --git a/src/a64/code-stubs-a64.cc b/src/a64/code-stubs-a64.cc
index 5cd3974..3fd0615 100644
--- a/src/a64/code-stubs-a64.cc
+++ b/src/a64/code-stubs-a64.cc
@@ -1080,7 +1080,7 @@
       ASSERT((cond == gt) || (cond == ge));  // remaining cases
       ncr = LESS;
     }
-    __ Mov(x10, Operand(Smi::FromInt(ncr)));
+    __ Mov(x10, Smi::FromInt(ncr));
     __ Push(x10);
   }
 
@@ -1111,7 +1111,7 @@
   }
 
   AllowExternalCallThatCantCauseGC scope(masm);
-  __ Mov(x0, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ Mov(x0, ExternalReference::isolate_address(masm->isolate()));
   __ CallCFunction(
       ExternalReference::store_buffer_overflow_function(masm->isolate()),
                                                         1, 0);
@@ -1490,7 +1490,7 @@
   if (do_gc) {
     // Call Runtime::PerformGC, passing x0 (the result parameter for
     // PerformGC) and x1 (the isolate).
-    __ Mov(x1, Operand(ExternalReference::isolate_address(masm->isolate())));
+    __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
     __ CallCFunction(
         ExternalReference::perform_gc_function(isolate), 2, 0);
   }
@@ -1507,7 +1507,7 @@
   // Prepare AAPCS64 arguments to pass to the builtin.
   __ Mov(x0, argc);
   __ Mov(x1, argv);
-  __ Mov(x2, Operand(ExternalReference::isolate_address(isolate)));
+  __ Mov(x2, ExternalReference::isolate_address(isolate));
 
   // Store the return address on the stack, in the space previously allocated
   // by EnterExitFrame. The return address is queried by
@@ -1820,8 +1820,8 @@
   int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
   int64_t bad_frame_pointer = -1L;  // Bad frame pointer to fail if it is used.
   __ Mov(x13, bad_frame_pointer);
-  __ Mov(x12, Operand(Smi::FromInt(marker)));
-  __ Mov(x11, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
+  __ Mov(x12, Smi::FromInt(marker));
+  __ Mov(x11, ExternalReference(Isolate::kCEntryFPAddress, isolate));
   __ Ldr(x10, MemOperand(x11));
 
   __ Push(x13, xzr, x12, x10);
@@ -1832,11 +1832,11 @@
   // outermost JS call.
   Label non_outermost_js, done;
   ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate);
-  __ Mov(x10, Operand(ExternalReference(js_entry_sp)));
+  __ Mov(x10, ExternalReference(js_entry_sp));
   __ Ldr(x11, MemOperand(x10));
   __ Cbnz(x11, &non_outermost_js);
   __ Str(fp, MemOperand(x10));
-  __ Mov(x12, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
+  __ Mov(x12, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME));
   __ Push(x12);
   __ B(&done);
   __ Bind(&non_outermost_js);
@@ -1905,7 +1905,7 @@
   ExternalReference entry(is_construct ? Builtins::kJSConstructEntryTrampoline
                                        : Builtins::kJSEntryTrampoline,
                           isolate);
-  __ Mov(x10, Operand(entry));
+  __ Mov(x10, entry);
 
   // Call the JSEntryTrampoline.
   __ Ldr(x11, MemOperand(x10));  // Dereference the address.
@@ -1929,15 +1929,15 @@
   // Check if the current stack frame is marked as the outermost JS frame.
   Label non_outermost_js_2;
   __ Pop(x10);
-  __ Cmp(x10, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
+  __ Cmp(x10, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME));
   __ B(ne, &non_outermost_js_2);
-  __ Mov(x11, Operand(ExternalReference(js_entry_sp)));
+  __ Mov(x11, ExternalReference(js_entry_sp));
   __ Str(xzr, MemOperand(x11));
   __ Bind(&non_outermost_js_2);
 
   // Restore the top frame descriptors from the stack.
   __ Pop(x10);
-  __ Mov(x11, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
+  __ Mov(x11, ExternalReference(Isolate::kCEntryFPAddress, isolate));
   __ Str(x10, MemOperand(x11));
 
   // Reset the stack to the callee saved registers.
@@ -2017,8 +2017,8 @@
     __ LoadTrueFalseRoots(res_true, res_false);
   } else {
     // This is counter-intuitive, but correct.
-    __ Mov(res_true, Operand(Smi::FromInt(0)));
-    __ Mov(res_false, Operand(Smi::FromInt(1)));
+    __ Mov(res_true, Smi::FromInt(0));
+    __ Mov(res_false, Smi::FromInt(1));
   }
 
   // Check that the left hand side is a JS object and load its map as a side
@@ -2188,7 +2188,7 @@
   __ Ldr(caller_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   __ Ldr(caller_ctx, MemOperand(caller_fp,
                                 StandardFrameConstants::kContextOffset));
-  __ Cmp(caller_ctx, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ Csel(local_fp, fp, caller_fp, ne);
   __ B(ne, &skip_adaptor);
 
@@ -2238,7 +2238,7 @@
                          ArgumentsAdaptorFrameConstants::kLengthOffset));
   __ Poke(x11, 0 * kXRegSize);
   __ Add(x10, caller_fp, Operand::UntagSmiAndScale(x11, kPointerSizeLog2));
-  __ Add(x10, x10, Operand(StandardFrameConstants::kCallerSPOffset));
+  __ Add(x10, x10, StandardFrameConstants::kCallerSPOffset);
   __ Poke(x10, 1 * kXRegSize);
 
   __ Bind(&runtime);
@@ -2271,7 +2271,7 @@
   __ Ldr(caller_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   __ Ldr(caller_ctx, MemOperand(caller_fp,
                                 StandardFrameConstants::kContextOffset));
-  __ Cmp(caller_ctx, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ B(eq, &adaptor_frame);
 
   // No adaptor, parameter count = argument count.
@@ -2473,7 +2473,7 @@
   __ Str(index, MemOperand(elements, x10));
   __ Sub(x10, x10, kParameterMapHeaderSize - FixedArray::kHeaderSize);
   __ Str(the_hole, MemOperand(backing_store, x10));
-  __ Add(index, index, Operand(Smi::FromInt(1)));
+  __ Add(index, index, Smi::FromInt(1));
   __ Bind(&parameters_test);
   __ Cbnz(loop_count, &parameters_loop);
 
@@ -2542,7 +2542,7 @@
   __ Ldr(caller_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   __ Ldr(caller_ctx, MemOperand(caller_fp,
                                 StandardFrameConstants::kContextOffset));
-  __ Cmp(caller_ctx, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ B(ne, &try_allocate);
 
   //   x1   param_count_smi   number of parameters passed to function (smi)
@@ -2728,7 +2728,7 @@
       ExternalReference::address_of_regexp_stack_memory_address(isolate);
   ExternalReference address_of_regexp_stack_memory_size =
       ExternalReference::address_of_regexp_stack_memory_size(isolate);
-  __ Mov(x10, Operand(address_of_regexp_stack_memory_size));
+  __ Mov(x10, address_of_regexp_stack_memory_size);
   __ Ldr(x10, MemOperand(x10));
   __ Cbz(x10, &runtime);
 
@@ -2750,7 +2750,7 @@
 
   // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
   __ Ldr(x10, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset));
-  __ Cmp(x10, Operand(Smi::FromInt(JSRegExp::IRREGEXP)));
+  __ Cmp(x10, Smi::FromInt(JSRegExp::IRREGEXP));
   __ B(ne, &runtime);
 
   // Check that the number of captures fit in the static offsets vector buffer.
@@ -2905,7 +2905,7 @@
   // csp[0]: Space for the return address placed by DirectCEntryStub.
   // csp[8]: Argument 9, the current isolate address.
 
-  __ Mov(x10, Operand(ExternalReference::isolate_address(isolate)));
+  __ Mov(x10, ExternalReference::isolate_address(isolate));
   __ Poke(x10, kPointerSize);
 
   Register length = w11;
@@ -2954,8 +2954,7 @@
   __ Add(x3, x2, Operand(w10, UXTW));
 
   // Argument 5 (x4): static offsets vector buffer.
-  __ Mov(x4,
-         Operand(ExternalReference::address_of_static_offsets_vector(isolate)));
+  __ Mov(x4, ExternalReference::address_of_static_offsets_vector(isolate));
 
   // Argument 6 (x5): Set the number of capture registers to zero to force
   // global regexps to behave as non-global. This stub is not used for global
@@ -2963,9 +2962,9 @@
   __ Mov(x5, 0);
 
   // Argument 7 (x6): Start (high end) of backtracking stack memory area.
-  __ Mov(x10, Operand(address_of_regexp_stack_memory_address));
+  __ Mov(x10, address_of_regexp_stack_memory_address);
   __ Ldr(x10, MemOperand(x10));
-  __ Mov(x11, Operand(address_of_regexp_stack_memory_size));
+  __ Mov(x11, address_of_regexp_stack_memory_size);
   __ Ldr(x11, MemOperand(x11));
   __ Add(x6, x10, x11);
 
@@ -3061,7 +3060,7 @@
   // and fill the last match info.
   ExternalReference address_of_static_offsets_vector =
       ExternalReference::address_of_static_offsets_vector(isolate);
-  __ Mov(offsets_vector_index, Operand(address_of_static_offsets_vector));
+  __ Mov(offsets_vector_index, address_of_static_offsets_vector);
 
   Label next_capture, done;
   // Capture register counter starts from number of capture registers and
@@ -3556,7 +3555,7 @@
 
 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
   __ JumpIfNotSmi(code_, &slow_case_);
-  __ Cmp(code_, Operand(Smi::FromInt(String::kMaxOneByteCharCode)));
+  __ Cmp(code_, Smi::FromInt(String::kMaxOneByteCharCode));
   __ B(hi, &slow_case_);
 
   __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
@@ -3906,7 +3905,7 @@
     // Preserve some caller-saved registers.
     __ Push(x1, x0, lr);
     // Push the arguments.
-    __ Mov(op, Operand(Smi::FromInt(op_)));
+    __ Mov(op, Smi::FromInt(op_));
     __ Push(left, right, op);
 
     // Call the miss handler. This also pops the arguments.
@@ -4255,7 +4254,7 @@
   __ B(eq, &check_zero_length);
 
   __ Bind(&strings_not_equal);
-  __ Mov(result, Operand(Smi::FromInt(NOT_EQUAL)));
+  __ Mov(result, Smi::FromInt(NOT_EQUAL));
   __ Ret();
 
   // Check if the length is zero. If so, the strings must be equal (and empty.)
@@ -4263,7 +4262,7 @@
   __ Bind(&check_zero_length);
   STATIC_ASSERT(kSmiTag == 0);
   __ Cbnz(left_length, &compare_chars);
-  __ Mov(result, Operand(Smi::FromInt(EQUAL)));
+  __ Mov(result, Smi::FromInt(EQUAL));
   __ Ret();
 
   // Compare characters. Falls through if all characters are equal.
@@ -4272,7 +4271,7 @@
                                 scratch3, &strings_not_equal);
 
   // Characters in strings are equal.
-  __ Mov(result, Operand(Smi::FromInt(EQUAL)));
+  __ Mov(result, Smi::FromInt(EQUAL));
   __ Ret();
 }
 
@@ -4314,8 +4313,8 @@
   __ Bind(&result_not_equal);
   Register greater = x10;
   Register less = x11;
-  __ Mov(greater, Operand(Smi::FromInt(GREATER)));
-  __ Mov(less, Operand(Smi::FromInt(LESS)));
+  __ Mov(greater, Smi::FromInt(GREATER));
+  __ Mov(less, Smi::FromInt(LESS));
   __ CmovX(result, greater, gt);
   __ CmovX(result, less, lt);
   __ Ret();
@@ -4441,7 +4440,7 @@
   // Get the array's length and calculate new length.
   __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
   STATIC_ASSERT(kSmiTag == 0);
-  __ Add(length, length, Operand(Smi::FromInt(argc)));
+  __ Add(length, length, Smi::FromInt(argc));
 
   // Check if we could survive without allocation.
   __ Ldr(elements_length,
@@ -4568,12 +4567,12 @@
   __ Add(end_elements, elements,
          Operand::UntagSmiAndScale(length, kPointerSizeLog2));
   __ Add(end_elements, end_elements, kEndElementsOffset);
-  __ Mov(allocation_top_addr, Operand(new_space_allocation_top));
+  __ Mov(allocation_top_addr, new_space_allocation_top);
   __ Ldr(allocation_top, MemOperand(allocation_top_addr));
   __ Cmp(end_elements, allocation_top);
   __ B(ne, &call_builtin);
 
-  __ Mov(x10, Operand(new_space_allocation_limit));
+  __ Mov(x10, new_space_allocation_limit);
   __ Ldr(x10, MemOperand(x10));
   __ Add(allocation_top, allocation_top, kAllocationDelta * kPointerSize);
   __ Cmp(allocation_top, x10);
@@ -4592,9 +4591,7 @@
 
   // Update elements' and array's sizes.
   __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
-  __ Add(elements_length,
-         elements_length,
-         Operand(Smi::FromInt(kAllocationDelta)));
+  __ Add(elements_length, elements_length, Smi::FromInt(kAllocationDelta));
   __ Str(elements_length,
          FieldMemOperand(elements, FixedArray::kLengthOffset));
 
@@ -4693,7 +4690,7 @@
   __ Mov(address, regs_.address());
   __ Mov(x0, regs_.object());
   __ Mov(x1, address);
-  __ Mov(x2, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ Mov(x2, ExternalReference::isolate_address(masm->isolate()));
 
   AllowExternalCallThatCantCauseGC scope(masm);
   ExternalReference function =
@@ -4948,7 +4945,7 @@
                                         ExternalReference::BUILTIN_CALL,
                                         masm->isolate())));
   // It additionally takes an isolate as a third parameter
-  __ Mov(x2, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ Mov(x2, ExternalReference::isolate_address(masm->isolate()));
 #endif
 
   // The caller's return address is above the saved temporaries.
@@ -5335,7 +5332,7 @@
     STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
     __ Ldr(x11, FieldMemOperand(allocation_site,
                                 AllocationSite::kTransitionInfoOffset));
-    __ Add(x11, x11, Operand(Smi::FromInt(kFastElementsKindPackedToHoley)));
+    __ Add(x11, x11, Smi::FromInt(kFastElementsKindPackedToHoley));
     __ Str(x11, FieldMemOperand(allocation_site,
                                 AllocationSite::kTransitionInfoOffset));
 
@@ -5617,7 +5614,7 @@
     __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
   }
   Register isolate_reg = x5;
-  __ Mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate)));
+  __ Mov(isolate_reg, ExternalReference::isolate_address(isolate));
 
   // FunctionCallbackArguments:
   //    return value, return value default, isolate, holder.
diff --git a/src/a64/codegen-a64.cc b/src/a64/codegen-a64.cc
index b7cd5a1..32b3275 100644
--- a/src/a64/codegen-a64.cc
+++ b/src/a64/codegen-a64.cc
@@ -519,7 +519,7 @@
   // ExternalReference::InitializeMathExpData().
 
   // Load the address of the start of the array.
-  __ Mov(constants, Operand(ExternalReference::math_exp_constants(0)));
+  __ Mov(constants, ExternalReference::math_exp_constants(0));
 
   // We have to do a four-way split here:
   //  - If input <= about -708.4, the output always rounds to zero.
@@ -595,7 +595,7 @@
   __ Add(temp1, temp1, 0x3ff);
 
   // Do the final table lookup.
-  __ Mov(temp3, Operand(ExternalReference::math_exp_log_table()));
+  __ Mov(temp3, ExternalReference::math_exp_log_table());
 
   __ Add(temp3, temp3, Operand(temp2, LSL, kDRegSizeLog2));
   __ Ldp(temp2.W(), temp3.W(), MemOperand(temp3));
diff --git a/src/a64/debug-a64.cc b/src/a64/debug-a64.cc
index 05c005a..8b901d7 100644
--- a/src/a64/debug-a64.cc
+++ b/src/a64/debug-a64.cc
@@ -202,7 +202,7 @@
     __ RecordComment("// Calling from debug break to runtime - come in - over");
 #endif
     __ Mov(x0, 0);  // No arguments.
-    __ Mov(x1, Operand(ExternalReference::debug_break(masm->isolate())));
+    __ Mov(x1, ExternalReference::debug_break(masm->isolate()));
 
     CEntryStub stub(1);
     __ CallStub(&stub);
@@ -234,7 +234,7 @@
   // overwritten by the address of DebugBreakXXX.
   ExternalReference after_break_target(Debug_Address::AfterBreakTarget(),
                                        masm->isolate());
-  __ Mov(scratch, Operand(after_break_target));
+  __ Mov(scratch, after_break_target);
   __ Ldr(scratch, MemOperand(scratch));
   __ Br(scratch);
 }
diff --git a/src/a64/deoptimizer-a64.cc b/src/a64/deoptimizer-a64.cc
index f3a5fcd..e95cb96 100644
--- a/src/a64/deoptimizer-a64.cc
+++ b/src/a64/deoptimizer-a64.cc
@@ -185,7 +185,7 @@
   //  - x2: bailout id
   //  - x3: code object address
   //  - x4: fp-to-sp delta
-  __ Mov(x5, Operand(ExternalReference::isolate_address(isolate())));
+  __ Mov(x5, ExternalReference::isolate_address(isolate()));
 
   {
     // Call Deoptimizer::New().
diff --git a/src/a64/full-codegen-a64.cc b/src/a64/full-codegen-a64.cc
index 4f907a5..c95a01a 100644
--- a/src/a64/full-codegen-a64.cc
+++ b/src/a64/full-codegen-a64.cc
@@ -243,7 +243,7 @@
     int num_parameters = info->scope()->num_parameters();
     int offset = num_parameters * kPointerSize;
     __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset);
-    __ Mov(x1, Operand(Smi::FromInt(num_parameters)));
+    __ Mov(x1, Smi::FromInt(num_parameters));
     __ Push(x3, x2, x1);
 
     // Arguments to ArgumentsAccessStub:
@@ -322,14 +322,14 @@
 
 
 void FullCodeGenerator::ClearAccumulator() {
-  __ Mov(x0, Operand(Smi::FromInt(0)));
+  __ Mov(x0, Smi::FromInt(0));
 }
 
 
 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
   __ Mov(x2, Operand(profiling_counter_));
   __ Ldr(x3, FieldMemOperand(x2, Cell::kValueOffset));
-  __ Subs(x3, x3, Operand(Smi::FromInt(delta)));
+  __ Subs(x3, x3, Smi::FromInt(delta));
   __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset));
 }
 
@@ -341,7 +341,7 @@
     reset_value = FLAG_interrupt_budget >> 4;
   }
   __ Mov(x2, Operand(profiling_counter_));
-  __ Mov(x3, Operand(Smi::FromInt(reset_value)));
+  __ Mov(x3, Smi::FromInt(reset_value));
   __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset));
 }
 
@@ -831,7 +831,7 @@
       ASSERT(IsDeclaredVariableMode(mode));
       PropertyAttributes attr = IsImmutableVariableMode(mode) ? READ_ONLY
                                                               : NONE;
-      __ Mov(x1, Operand(Smi::FromInt(attr)));
+      __ Mov(x1, Smi::FromInt(attr));
       // Push initial value, if any.
       // Note: For variables we must not push an initial value (such as
       // 'undefined') because we may have a (legal) redeclaration and we
@@ -895,7 +895,7 @@
     case Variable::LOOKUP: {
       Comment cmnt(masm_, "[ Function Declaration");
       __ Mov(x2, Operand(variable->name()));
-      __ Mov(x1, Operand(Smi::FromInt(NONE)));
+      __ Mov(x1, Smi::FromInt(NONE));
       __ Push(cp, x2, x1);
       // Push initial value for function declaration.
       VisitForStackValue(declaration->fun());
@@ -971,7 +971,7 @@
   Register flags = xzr;
   if (Smi::FromInt(DeclareGlobalsFlags())) {
     flags = x10;
-  __ Mov(flags, Operand(Smi::FromInt(DeclareGlobalsFlags())));
+  __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags()));
   }
   __ Push(cp, x11, flags);
   __ CallRuntime(Runtime::kDeclareGlobals, 3);
@@ -1150,7 +1150,7 @@
 
   // Set up the four remaining stack slots.
   __ Push(x0);  // Map.
-  __ Mov(x0, Operand(Smi::FromInt(0)));
+  __ Mov(x0, Smi::FromInt(0));
   // Push enumeration cache, enumeration cache length (as smi) and zero.
   __ SmiTag(x1);
   __ Push(x2, x1, x0);
@@ -1168,10 +1168,10 @@
       isolate());
   StoreFeedbackVectorSlot(slot, feedback);
   __ LoadObject(x1, FeedbackVector());
-  __ Mov(x10, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+  __ Mov(x10, Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker));
   __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot)));
 
-  __ Mov(x1, Operand(Smi::FromInt(1)));  // Smi indicates slow check.
+  __ Mov(x1, Smi::FromInt(1));  // Smi indicates slow check.
   __ Peek(x10, 0);  // Get enumerated object.
   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
   // TODO(all): similar check was done already. Can we avoid it here?
@@ -1237,7 +1237,7 @@
   __ Bind(loop_statement.continue_label());
   // TODO(all): We could use a callee saved register to avoid popping.
   __ Pop(x0);
-  __ Add(x0, x0, Operand(Smi::FromInt(1)));
+  __ Add(x0, x0, Smi::FromInt(1));
   __ Push(x0);
 
   EmitBackEdgeBookkeeping(stmt, &loop);
@@ -1582,7 +1582,7 @@
 
   // Create regexp literal using runtime function.
   // Result will be in x0.
-  __ Mov(x3, Operand(Smi::FromInt(expr->literal_index())));
+  __ Mov(x3, Smi::FromInt(expr->literal_index()));
   __ Mov(x2, Operand(expr->pattern()));
   __ Mov(x1, Operand(expr->flags()));
   __ Push(x4, x3, x2, x1);
@@ -1596,7 +1596,7 @@
   __ B(&allocated);
 
   __ Bind(&runtime_allocate);
-  __ Mov(x10, Operand(Smi::FromInt(size)));
+  __ Mov(x10, Smi::FromInt(size));
   __ Push(x5, x10);
   __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
   __ Pop(x5);
@@ -1628,7 +1628,7 @@
   Handle<FixedArray> constant_properties = expr->constant_properties();
   __ Ldr(x3, MemOperand(fp,  JavaScriptFrameConstants::kFunctionOffset));
   __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset));
-  __ Mov(x2, Operand(Smi::FromInt(expr->literal_index())));
+  __ Mov(x2, Smi::FromInt(expr->literal_index()));
   __ Mov(x1, Operand(constant_properties));
   int flags = expr->fast_elements()
       ? ObjectLiteral::kFastElements
@@ -1636,7 +1636,7 @@
   flags |= expr->has_function()
       ? ObjectLiteral::kHasFunction
       : ObjectLiteral::kNoFlags;
-  __ Mov(x0, Operand(Smi::FromInt(flags)));
+  __ Mov(x0, Smi::FromInt(flags));
   int properties_count = constant_properties->length() / 2;
   const int max_cloned_properties =
       FastCloneShallowObjectStub::kMaximumClonedProperties;
@@ -1695,7 +1695,7 @@
           __ Push(x0);
           VisitForStackValue(key);
           VisitForStackValue(value);
-          __ Mov(x0, Operand(Smi::FromInt(NONE)));  // PropertyAttributes
+          __ Mov(x0, Smi::FromInt(NONE));  // PropertyAttributes
           __ Push(x0);
           __ CallRuntime(Runtime::kSetProperty, 4);
         } else {
@@ -1733,7 +1733,7 @@
       VisitForStackValue(it->first);
       EmitAccessor(it->second->getter);
       EmitAccessor(it->second->setter);
-      __ Mov(x10, Operand(Smi::FromInt(NONE)));
+      __ Mov(x10, Smi::FromInt(NONE));
       __ Push(x10);
       __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5);
   }
@@ -1779,8 +1779,7 @@
 
   __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset));
-  // TODO(jbramley): Can these Operand constructors be implicit?
-  __ Mov(x2, Operand(Smi::FromInt(expr->literal_index())));
+  __ Mov(x2, Smi::FromInt(expr->literal_index()));
   __ Mov(x1, Operand(constant_elements));
   if (has_fast_elements && constant_elements_values->map() ==
       isolate()->heap()->fixed_cow_array_map()) {
@@ -1793,7 +1792,7 @@
         isolate()->counters()->cow_arrays_created_stub(), 1, x10, x11);
   } else if ((expr->depth() > 1) || Serializer::enabled() ||
              length > FastCloneShallowArrayStub::kMaximumClonedLength) {
-    __ Mov(x0, Operand(Smi::FromInt(flags)));
+    __ Mov(x0, Smi::FromInt(flags));
     __ Push(x3, x2, x1, x0);
     __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
   } else {
@@ -1837,7 +1836,7 @@
                           kLRHasBeenSaved, kDontSaveFPRegs,
                           EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
     } else {
-      __ Mov(x3, Operand(Smi::FromInt(i)));
+      __ Mov(x3, Smi::FromInt(i));
       StoreArrayLiteralElementStub stub;
       __ CallStub(&stub);
     }
@@ -2160,7 +2159,7 @@
 void FullCodeGenerator::EmitCallStoreContextSlot(
     Handle<String> name, StrictMode strict_mode) {
   __ Mov(x11, Operand(name));
-  __ Mov(x10, Operand(Smi::FromInt(strict_mode)));
+  __ Mov(x10, Smi::FromInt(strict_mode));
   // jssp[0]  : mode.
   // jssp[8]  : name.
   // jssp[16] : context.
@@ -2410,7 +2409,7 @@
       TypeFeedbackInfo::UninitializedSentinel(isolate());
   StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
   __ LoadObject(x2, FeedbackVector());
-  __ Mov(x3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
+  __ Mov(x3, Smi::FromInt(expr->CallFeedbackSlot()));
 
   // Record call targets in unoptimized code.
   CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
@@ -2441,9 +2440,9 @@
   __ Push(x10, x11);
 
   // Prepare to push the language mode.
-  __ Mov(x10, Operand(Smi::FromInt(strict_mode())));
+  __ Mov(x10, 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())));
+  __ Mov(x11, Smi::FromInt(scope()->start_position()));
 
   // Push.
   __ Push(x10, x11);
@@ -2616,7 +2615,7 @@
   }
 
   __ LoadObject(x2, FeedbackVector());
-  __ Mov(x3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
+  __ Mov(x3, Smi::FromInt(expr->CallNewFeedbackSlot()));
 
   CallConstructStub stub(RECORD_CALL_TARGET);
   __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
@@ -2955,14 +2954,14 @@
   // Skip the arguments adaptor frame if it exists.
   Label check_frame_marker;
   __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kContextOffset));
-  __ Cmp(x1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ Cmp(x1, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ B(ne, &check_frame_marker);
   __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset));
 
   // Check the marker in the calling frame.
   __ Bind(&check_frame_marker);
   __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kMarkerOffset));
-  __ Cmp(x1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
+  __ Cmp(x1, Smi::FromInt(StackFrame::CONSTRUCT));
   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
   Split(eq, if_true, if_false, fall_through);
 
@@ -3001,7 +3000,7 @@
   // ArgumentsAccessStub expects the key in x1.
   VisitForAccumulatorValue(args->at(0));
   __ Mov(x1, x0);
-  __ Mov(x0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
+  __ Mov(x0, Smi::FromInt(info_->scope()->num_parameters()));
   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
   __ CallStub(&stub);
   context()->Plug(x0);
@@ -3012,12 +3011,12 @@
   ASSERT(expr->arguments()->length() == 0);
   Label exit;
   // Get the number of formal parameters.
-  __ Mov(x0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
+  __ Mov(x0, Smi::FromInt(info_->scope()->num_parameters()));
 
   // Check if the calling frame is an arguments adaptor frame.
   __ Ldr(x12, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   __ Ldr(x13, MemOperand(x12, StandardFrameConstants::kContextOffset));
-  __ Cmp(x13, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ Cmp(x13, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ B(ne, &exit);
 
   // Arguments adaptor case: Read the arguments length from the
@@ -3183,7 +3182,7 @@
   } else {
     if (index->value() < JSDate::kFirstUncachedField) {
       ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
-      __ Mov(x10, Operand(stamp));
+      __ Mov(x10, stamp);
       __ Ldr(stamp_addr, MemOperand(x10));
       __ Ldr(stamp_cache, FieldMemOperand(object, JSDate::kCacheStampOffset));
       __ Cmp(stamp_addr, stamp_cache);
@@ -3194,7 +3193,7 @@
     }
 
     __ Bind(&runtime);
-    __ Mov(x1, Operand(index));
+    __ Mov(x1, index);
     __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
     __ B(&done);
   }
@@ -3422,7 +3421,7 @@
 
   __ Bind(&need_conversion);
   // Move smi zero into the result register, which will trigger conversion.
-  __ Mov(result, Operand(Smi::FromInt(0)));
+  __ Mov(result, Smi::FromInt(0));
   __ B(&done);
 
   NopRuntimeCallHelper call_helper;
@@ -3675,7 +3674,7 @@
   //   element: Current array element.
   //   elements_end: Array end.
   if (FLAG_debug_code) {
-    __ Cmp(array_length, Operand(0));
+    __ Cmp(array_length, 0);
     __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin);
   }
   __ Bind(&loop);
@@ -3888,7 +3887,7 @@
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ Mov(x10, Operand(Smi::FromInt(strict_mode())));
+        __ Mov(x10, Smi::FromInt(strict_mode()));
         __ Push(x10);
         __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
         context()->Plug(x0);
@@ -3900,7 +3899,7 @@
         if (var->IsUnallocated()) {
           __ Ldr(x12, GlobalObjectMemOperand());
           __ Mov(x11, Operand(var->name()));
-          __ Mov(x10, Operand(Smi::FromInt(SLOPPY)));
+          __ Mov(x10, Smi::FromInt(SLOPPY));
           __ Push(x12, x11, x10);
           __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
           context()->Plug(x0);
@@ -4068,10 +4067,10 @@
       }
     }
 
-    __ Adds(x0, x0, Operand(Smi::FromInt(count_value)));
+    __ Adds(x0, x0, Smi::FromInt(count_value));
     __ B(vc, &done);
     // Call stub. Undo operation first.
-    __ Sub(x0, x0, Operand(Smi::FromInt(count_value)));
+    __ Sub(x0, x0, Smi::FromInt(count_value));
     __ B(&stub_call);
     __ Bind(&slow);
   }
@@ -4100,7 +4099,7 @@
 
   __ Bind(&stub_call);
   __ Mov(x1, x0);
-  __ Mov(x0, Operand(Smi::FromInt(count_value)));
+  __ Mov(x0, Smi::FromInt(count_value));
 
   // Record position before stub call.
   SetSourcePosition(expr->position());
@@ -4434,7 +4433,7 @@
       __ Bind(&suspend);
       VisitForAccumulatorValue(expr->generator_object());
       ASSERT((continuation.pos() > 0) && Smi::IsValid(continuation.pos()));
-      __ Mov(x1, Operand(Smi::FromInt(continuation.pos())));
+      __ Mov(x1, Smi::FromInt(continuation.pos()));
       __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
       __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
       __ Mov(x1, cp);
@@ -4457,7 +4456,7 @@
 
     case Yield::FINAL: {
       VisitForAccumulatorValue(expr->generator_object());
-      __ Mov(x1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
+      __ Mov(x1, Smi::FromInt(JSGeneratorObject::kGeneratorClosed));
       __ Str(x1, FieldMemOperand(result_register(),
                                  JSGeneratorObject::kContinuationOffset));
       // Pop value from top-of-stack slot, box result into result register.
@@ -4509,7 +4508,7 @@
       __ Peek(x0, generator_object_depth);
       __ Push(x0);                                       // g
       ASSERT((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos()));
-      __ Mov(x1, Operand(Smi::FromInt(l_continuation.pos())));
+      __ Mov(x1, Smi::FromInt(l_continuation.pos()));
       __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
       __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
       __ Mov(x1, cp);
@@ -4587,8 +4586,8 @@
                               JSGeneratorObject::kContinuationOffset));
   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ CompareAndBranch(x10, Operand(Smi::FromInt(0)), eq, &closed_state);
-  __ CompareAndBranch(x10, Operand(Smi::FromInt(0)), lt, &wrong_state);
+  __ CompareAndBranch(x10, Smi::FromInt(0), eq, &closed_state);
+  __ CompareAndBranch(x10, Smi::FromInt(0), lt, &wrong_state);
 
   // Load suspended function and context.
   __ Ldr(cp, FieldMemOperand(generator_object,
@@ -4642,7 +4641,7 @@
              UntagSmiFieldMemOperand(generator_object,
                                      JSGeneratorObject::kContinuationOffset));
     __ Add(x10, x10, x11);
-    __ Mov(x12, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
+    __ Mov(x12, Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
     __ Str(x12, FieldMemOperand(generator_object,
                                 JSGeneratorObject::kContinuationOffset));
     __ Br(x10);
@@ -4654,7 +4653,7 @@
   // up the stack and the handlers.
   __ PushMultipleTimes(the_hole, operand_stack_size);
 
-  __ Mov(x10, Operand(Smi::FromInt(resume_mode)));
+  __ Mov(x10, Smi::FromInt(resume_mode));
   __ Push(generator_object, result_register(), x10);
   __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
   // Not reached: the runtime call returns elsewhere.
@@ -4798,12 +4797,12 @@
   // Store pending message while executing finally block.
   ExternalReference pending_message_obj =
       ExternalReference::address_of_pending_message_obj(isolate());
-  __ Mov(x10, Operand(pending_message_obj));
+  __ Mov(x10, pending_message_obj);
   __ Ldr(x10, MemOperand(x10));
 
   ExternalReference has_pending_message =
       ExternalReference::address_of_has_pending_message(isolate());
-  __ Mov(x11, Operand(has_pending_message));
+  __ Mov(x11, has_pending_message);
   __ Ldr(x11, MemOperand(x11));
   __ SmiTag(x11);
 
@@ -4811,7 +4810,7 @@
 
   ExternalReference pending_message_script =
       ExternalReference::address_of_pending_message_script(isolate());
-  __ Mov(x10, Operand(pending_message_script));
+  __ Mov(x10, pending_message_script);
   __ Ldr(x10, MemOperand(x10));
   __ Push(x10);
 }
@@ -4825,18 +4824,18 @@
   __ Pop(x10, x11, x12);
   ExternalReference pending_message_script =
       ExternalReference::address_of_pending_message_script(isolate());
-  __ Mov(x13, Operand(pending_message_script));
+  __ Mov(x13, pending_message_script);
   __ Str(x10, MemOperand(x13));
 
   __ SmiUntag(x11);
   ExternalReference has_pending_message =
       ExternalReference::address_of_has_pending_message(isolate());
-  __ Mov(x13, Operand(has_pending_message));
+  __ Mov(x13, has_pending_message);
   __ Str(x11, MemOperand(x13));
 
   ExternalReference pending_message_obj =
       ExternalReference::address_of_pending_message_obj(isolate());
-  __ Mov(x13, Operand(pending_message_obj));
+  __ Mov(x13, pending_message_obj);
   __ Str(x12, MemOperand(x13));
 
   // Restore result register and cooked return address from the stack.
diff --git a/src/a64/ic-a64.cc b/src/a64/ic-a64.cc
index 71d4c66..49b36af 100644
--- a/src/a64/ic-a64.cc
+++ b/src/a64/ic-a64.cc
@@ -141,7 +141,7 @@
       NameDictionary::kElementsStartIndex * kPointerSize;
   static const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
   __ Ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
-  __ Tst(scratch1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
+  __ Tst(scratch1, Smi::FromInt(PropertyDetails::TypeField::kMask));
   __ B(ne, miss);
 
   // Get the value at the masked, scaled index and return.
@@ -376,7 +376,7 @@
   // Check if element is in the range of mapped arguments. If not, jump
   // to the unmapped lookup.
   __ Ldr(scratch1, FieldMemOperand(map, FixedArray::kLengthOffset));
-  __ Sub(scratch1, scratch1, Operand(Smi::FromInt(2)));
+  __ Sub(scratch1, scratch1, Smi::FromInt(2));
   __ Cmp(key, scratch1);
   __ B(hs, unmapped_case);
 
@@ -702,7 +702,7 @@
   ExternalReference cache_keys =
       ExternalReference::keyed_lookup_cache_keys(isolate);
 
-  __ Mov(scratch3, Operand(cache_keys));
+  __ Mov(scratch3, cache_keys);
   __ Add(scratch3, scratch3, Operand(scratch2, LSL, kPointerSizeLog2 + 1));
 
   for (int i = 0; i < kEntriesPerBucket - 1; i++) {
@@ -732,7 +732,7 @@
   // Hit on nth entry.
   for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
     __ Bind(&hit_on_nth_entry[i]);
-    __ Mov(scratch3, Operand(cache_field_offsets));
+    __ Mov(scratch3, cache_field_offsets);
     if (i != 0) {
       __ Add(scratch2, scratch2, i);
     }
@@ -939,7 +939,7 @@
 
   // Push PropertyAttributes(NONE) and strict_mode for runtime call.
   STATIC_ASSERT(NONE == 0);
-  __ Mov(x10, Operand(Smi::FromInt(strict_mode)));
+  __ Mov(x10, Smi::FromInt(strict_mode));
   __ Push(xzr, x10);
 
   __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
@@ -996,7 +996,7 @@
   __ Bind(&finish_store);
   if (increment_length == kIncrementLength) {
     // Add 1 to receiver->length.
-    __ Add(x10, key, Operand(Smi::FromInt(1)));
+    __ Add(x10, key, Smi::FromInt(1));
     __ Str(x10, FieldMemOperand(receiver, JSArray::kLengthOffset));
   }
 
@@ -1048,7 +1048,7 @@
                                  &transition_double_elements);
   if (increment_length == kIncrementLength) {
     // Add 1 to receiver->length.
-    __ Add(x10, key, Operand(Smi::FromInt(1)));
+    __ Add(x10, key, Smi::FromInt(1));
     __ Str(x10, FieldMemOperand(receiver, JSArray::kLengthOffset));
   }
   __ Ret();
@@ -1285,8 +1285,8 @@
 
   __ Push(x1, x2, x0);
 
-  __ Mov(x11, Operand(Smi::FromInt(NONE)));  // PropertyAttributes
-  __ Mov(x10, Operand(Smi::FromInt(strict_mode)));
+  __ Mov(x11, Smi::FromInt(NONE));  // PropertyAttributes
+  __ Mov(x10, Smi::FromInt(strict_mode));
   __ Push(x11, x10);
 
   // Do tail-call to runtime routine.
diff --git a/src/a64/lithium-a64.cc b/src/a64/lithium-a64.cc
index 1c3b24e..c550101 100644
--- a/src/a64/lithium-a64.cc
+++ b/src/a64/lithium-a64.cc
@@ -1762,12 +1762,17 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
-  return can_deopt ? AssignEnvironment(result) : result;
+  LOperand* temp =
+      ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
+       (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
+      NULL : TempRegister();
+  LInstruction* result = DefineAsRegister(
+      new(zone()) LFlooringDivByConstI(dividend, divisor, temp));
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1784,8 +1789,8 @@
 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
   if (instr->RightIsPowerOf2()) {
     return DoFlooringDivByPowerOf2I(instr);
-  } else if (false && instr->right()->IsConstant()) {
-    return DoFlooringDivByConstI(instr);  // TODO(svenpanne) Fix and re-enable.
+  } else if (instr->right()->IsConstant()) {
+    return DoFlooringDivByConstI(instr);
   } else {
     return DoFlooringDivI(instr);
   }
diff --git a/src/a64/lithium-a64.h b/src/a64/lithium-a64.h
index a100da8..1bd1b80 100644
--- a/src/a64/lithium-a64.h
+++ b/src/a64/lithium-a64.h
@@ -1956,16 +1956,17 @@
 };
 
 
-class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
  public:
-  LFlooringDivByConstI(LOperand* dividend, int32_t divisor) {
+  LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) {
     inputs_[0] = dividend;
     divisor_ = divisor;
+    temps_[0] = temp;
   }
 
   LOperand* dividend() { return inputs_[0]; }
   int32_t divisor() const { return divisor_; }
-  LOperand* temp1() { return temps_[0]; }
+  LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
   DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index f67eefa..060c1da 100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -801,7 +801,7 @@
         ASSERT(info()->IsStub());
         frame_is_built_ = true;
         __ Push(lr, fp, cp);
-        __ Mov(fp, Operand(Smi::FromInt(StackFrame::STUB)));
+        __ Mov(fp, Smi::FromInt(StackFrame::STUB));
         __ Push(fp);
         __ Add(fp, __ StackPointer(),
                StandardFrameConstants::kFixedFrameSizeFromFp);
@@ -855,8 +855,7 @@
       Register stub_deopt_entry = temps.AcquireX();
       Register stub_marker = temps.AcquireX();
 
-      __ Mov(stub_deopt_entry,
-             Operand(ExternalReference::ForDeoptEntry(entry)));
+      __ Mov(stub_deopt_entry, ExternalReference::ForDeoptEntry(entry));
       if (needs_frame.is_bound()) {
         __ B(&needs_frame);
       } else {
@@ -865,7 +864,7 @@
         // have a function pointer to install in the stack frame that we're
         // building, install a special marker there instead.
         ASSERT(info()->IsStub());
-        __ Mov(stub_marker, Operand(Smi::FromInt(StackFrame::STUB)));
+        __ Mov(stub_marker, Smi::FromInt(StackFrame::STUB));
         __ Push(lr, fp, cp, stub_marker);
         __ Add(fp, __ StackPointer(), 2 * kPointerSize);
         __ Call(stub_deopt_entry);
@@ -1005,7 +1004,7 @@
 
     __ Push(x0, x1, x2);
     __ Mrs(x2, NZCV);
-    __ Mov(x0, Operand(count));
+    __ Mov(x0, count);
     __ Ldr(w1, MemOperand(x0));
     __ Subs(x1, x1, 1);
     __ B(gt, &not_zero);
@@ -1552,13 +1551,13 @@
   // TODO(3095996): Get rid of this. For now, we need to make the
   // result register contain a valid pointer because it is already
   // contained in the register pointer map.
-  __ Mov(ToRegister(instr->result()), Operand(Smi::FromInt(0)));
+  __ Mov(ToRegister(instr->result()), Smi::FromInt(0));
 
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
   // We're in a SafepointRegistersScope so we can use any scratch registers.
   Register size = x0;
   if (instr->size()->IsConstantOperand()) {
-    __ Mov(size, Operand(ToSmi(LConstantOperand::cast(instr->size()))));
+    __ Mov(size, ToSmi(LConstantOperand::cast(instr->size())));
   } else {
     __ SmiTag(size, ToRegister32(instr->size()).X());
   }
@@ -1574,7 +1573,7 @@
   } else {
     flags = AllocateTargetSpace::update(flags, NEW_SPACE);
   }
-  __ Mov(x10, Operand(Smi::FromInt(flags)));
+  __ Mov(x10, Smi::FromInt(flags));
   __ Push(size, x10);
 
   CallRuntimeFromDeferred(
@@ -1654,7 +1653,7 @@
            MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
     __ Ldr(result,
            MemOperand(previous_fp, StandardFrameConstants::kContextOffset));
-    __ Cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+    __ Cmp(result, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
     __ Csel(result, fp, previous_fp, ne);
   }
 }
@@ -1779,9 +1778,9 @@
         ToInteger32(LConstantOperand::cast(instr->index()));
 
     if (instr->hydrogen()->length()->representation().IsSmi()) {
-      __ Cmp(length, Operand(Smi::FromInt(constant_index)));
+      __ Cmp(length, Smi::FromInt(constant_index));
     } else {
-      __ Cmp(length, Operand(constant_index));
+      __ Cmp(length, constant_index);
     }
   } else {
   ASSERT(instr->hydrogen()->index()->representation().IsInteger32());
@@ -1819,7 +1818,7 @@
       EmitBranch(instr, eq);
     } else if (type.IsSmi()) {
       ASSERT(!info()->IsStub());
-      EmitCompareAndBranch(instr, ne, value, Operand(Smi::FromInt(0)));
+      EmitCompareAndBranch(instr, ne, value, Smi::FromInt(0));
     } else if (type.IsJSArray()) {
       ASSERT(!info()->IsStub());
       EmitGoto(instr->TrueDestination(chunk()));
@@ -3029,7 +3028,7 @@
     Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
     __ LoadRelocated(scratch, Operand(Handle<Object>(cell)));
     __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset));
-    __ cmp(map, Operand(scratch));
+    __ cmp(map, scratch);
     __ b(&cache_miss, ne);
     // The address of this instruction is computed relative to the map check
     // above, so check the size of the code generated.
@@ -3141,7 +3140,7 @@
   // Skip the arguments adaptor frame if it exists.
   Label check_frame_marker;
   __ Ldr(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
-  __ Cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  __ Cmp(temp2, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
   __ B(ne, &check_frame_marker);
   __ Ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
 
@@ -3892,8 +3891,31 @@
     DeoptimizeIf(eq, instr->environment());
   }
 
-  // TODO(svenpanne) Add correction terms.
-  __ TruncatingDiv(result, dividend, divisor);
+  // Easy case: We need no dynamic check for the dividend and the flooring
+  // division is the same as the truncating division.
+  if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
+      (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
+    __ TruncatingDiv(result, dividend, Abs(divisor));
+    if (divisor < 0) __ Neg(result, result);
+    return;
+  }
+
+  // In the general case we may need to adjust before and after the truncating
+  // division to get a flooring division.
+  Register temp = ToRegister32(instr->temp());
+  ASSERT(!AreAliased(temp, dividend, result));
+  Label needs_adjustment, done;
+  __ Cmp(dividend, 0);
+  __ B(divisor > 0 ? lt : gt, &needs_adjustment);
+  __ TruncatingDiv(result, dividend, Abs(divisor));
+  if (divisor < 0) __ Neg(result, result);
+  __ B(&done);
+  __ bind(&needs_adjustment);
+  __ Add(temp, dividend, Operand(divisor > 0 ? 1 : -1));
+  __ TruncatingDiv(result, temp, Abs(divisor));
+  if (divisor < 0) __ Neg(result, result);
+  __ Sub(result, result, Operand(1));
+  __ bind(&done);
 }
 
 
@@ -4027,7 +4049,6 @@
   DoubleRegister temp1 = ToDoubleRegister(instr->temp1());
   Register result = ToRegister(instr->result());
   Label try_rounding;
-  Label deopt;
   Label done;
 
   // Math.round() rounds to the nearest integer, with ties going towards
@@ -4049,8 +4070,7 @@
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     __ Fmov(result, input);
-    __ Cmp(result, 0);
-    DeoptimizeIf(mi, instr->environment());  // [-0.5, -0.0].
+    DeoptimizeIfNegative(result, instr->environment());  // [-0.5, -0.0].
   }
   __ Fcmp(input, dot_five);
   __ Mov(result, 1);  // +0.5.
@@ -4059,9 +4079,6 @@
   __ Csel(result, result, xzr, eq);
   __ B(&done);
 
-  __ Bind(&deopt);
-  Deoptimize(instr->environment());
-
   __ Bind(&try_rounding);
   // Since we're providing a 32-bit result, we can implement ties-to-infinity by
   // adding 0.5 to the input, then taking the floor of the result. This does not
@@ -4076,7 +4093,7 @@
   //  * the result is not representable using a 32-bit integer.
   __ Fcmp(input, 0.0);
   __ Ccmp(result, Operand(result.W(), SXTW), NoFlag, vc);
-  __ B(ne, &deopt);
+  DeoptimizeIf(ne, instr->environment());
 
   __ Bind(&done);
 }
@@ -4140,7 +4157,7 @@
     __ B(pl, &dividend_is_not_negative);
     // Note that this is correct even for kMinInt operands.
     __ Neg(dividend, dividend);
-    __ And(dividend, dividend, Operand(mask));
+    __ And(dividend, dividend, mask);
     __ Negs(dividend, dividend);
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
       DeoptimizeIf(eq, instr->environment());
@@ -4149,7 +4166,7 @@
   }
 
   __ bind(&dividend_is_not_negative);
-  __ And(dividend, dividend, Operand(mask));
+  __ And(dividend, dividend, mask);
   __ bind(&done);
 }
 
@@ -4879,7 +4896,7 @@
   // TODO(all): if Mov could handle object in new space then it could be used
   // here.
   __ LoadHeapObject(scratch1, instr->hydrogen()->pairs());
-  __ Mov(scratch2, Operand(Smi::FromInt(instr->hydrogen()->flags())));
+  __ Mov(scratch2, Smi::FromInt(instr->hydrogen()->flags()));
   __ Push(cp, scratch1, scratch2);  // The context is the first argument.
   CallRuntime(Runtime::kDeclareGlobals, 3, instr);
 }
@@ -5592,7 +5609,7 @@
   __ B(&allocated);
 
   __ Bind(&runtime_allocate);
-  __ Mov(x0, Operand(Smi::FromInt(size)));
+  __ Mov(x0, Smi::FromInt(size));
   __ Push(x1, x0);
   CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
   __ Pop(x1);
@@ -5826,7 +5843,7 @@
   __ AssertSmi(index);
 
   Label out_of_object, done;
-  __ Cmp(index, Operand(Smi::FromInt(0)));
+  __ Cmp(index, Smi::FromInt(0));
   __ B(lt, &out_of_object);
 
   STATIC_ASSERT(kPointerSizeLog2 > kSmiTagSize);
diff --git a/src/a64/lithium-gap-resolver-a64.cc b/src/a64/lithium-gap-resolver-a64.cc
index 3087a3e..a92ef85 100644
--- a/src/a64/lithium-gap-resolver-a64.cc
+++ b/src/a64/lithium-gap-resolver-a64.cc
@@ -257,7 +257,7 @@
     if (destination->IsRegister()) {
       Register dst = cgen_->ToRegister(destination);
       if (cgen_->IsSmi(constant_source)) {
-        __ Mov(dst, Operand(cgen_->ToSmi(constant_source)));
+        __ Mov(dst, cgen_->ToSmi(constant_source));
       } else if (cgen_->IsInteger32Constant(constant_source)) {
         __ Mov(dst, cgen_->ToInteger32(constant_source));
       } else {
@@ -271,7 +271,7 @@
       ASSERT(!in_cycle_);  // Constant moves happen after all cycles are gone.
       need_to_restore_root_ = true;
       if (cgen_->IsSmi(constant_source)) {
-        __ Mov(kSavedValue, Operand(cgen_->ToSmi(constant_source)));
+        __ Mov(kSavedValue, cgen_->ToSmi(constant_source));
       } else if (cgen_->IsInteger32Constant(constant_source)) {
         __ Mov(kSavedValue, cgen_->ToInteger32(constant_source));
       } else {
diff --git a/src/a64/macro-assembler-a64.cc b/src/a64/macro-assembler-a64.cc
index 1fad909..851f10a 100644
--- a/src/a64/macro-assembler-a64.cc
+++ b/src/a64/macro-assembler-a64.cc
@@ -1253,7 +1253,7 @@
 void MacroAssembler::EnumLengthSmi(Register dst, Register map) {
   STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
   Ldr(dst, FieldMemOperand(map, Map::kBitField3Offset));
-  And(dst, dst, Operand(Smi::FromInt(Map::EnumLengthBits::kMask)));
+  And(dst, dst, Smi::FromInt(Map::EnumLengthBits::kMask));
 }
 
 
@@ -1326,10 +1326,10 @@
 
   Add(scratch1, receiver,
       JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag);
-  Cmp(scratch1, Operand(new_space_start));
+  Cmp(scratch1, new_space_start);
   B(lt, no_memento_found);
 
-  Mov(scratch2, Operand(new_space_allocation_top));
+  Mov(scratch2, new_space_allocation_top);
   Ldr(scratch2, MemOperand(scratch2));
   Cmp(scratch1, scratch2);
   B(gt, no_memento_found);
@@ -1367,8 +1367,8 @@
   ASSERT(cond == eq || cond == ne);
   UseScratchRegisterScope temps(this);
   Register temp = temps.AcquireX();
-  And(temp, object, Operand(ExternalReference::new_space_mask(isolate())));
-  Cmp(temp, Operand(ExternalReference::new_space_start(isolate())));
+  And(temp, object, ExternalReference::new_space_mask(isolate()));
+  Cmp(temp, ExternalReference::new_space_start(isolate()));
   B(cond, branch);
 }
 
@@ -1471,7 +1471,7 @@
   RecordComment((msg != NULL) ? msg : "UNKNOWN");
 #endif
 
-  Mov(x0, Operand(Smi::FromInt(reason)));
+  Mov(x0, Smi::FromInt(reason));
   Push(x0);
 
   // Disable stub call restrictions to always allow calls to throw.
@@ -1600,7 +1600,7 @@
 
   // Place the necessary arguments.
   Mov(x0, num_arguments);
-  Mov(x1, Operand(ExternalReference(f, isolate())));
+  Mov(x1, ExternalReference(f, isolate()));
 
   CEntryStub stub(1, save_doubles);
   CallStub(&stub);
@@ -1639,7 +1639,7 @@
   Mov(x10, reinterpret_cast<uintptr_t>(is_profiling_flag));
   Ldrb(w10, MemOperand(x10));
   Cbz(w10, &profiler_disabled);
-  Mov(x3, Operand(thunk_ref));
+  Mov(x3, thunk_ref);
   B(&end_profiler_check);
 
   Bind(&profiler_disabled);
@@ -1662,7 +1662,7 @@
   Register limit_reg = x20;
   Register level_reg = w21;
 
-  Mov(handle_scope_base, Operand(next_address));
+  Mov(handle_scope_base, next_address);
   Ldr(next_address_reg, MemOperand(handle_scope_base, kNextOffset));
   Ldr(limit_reg, MemOperand(handle_scope_base, kLimitOffset));
   Ldr(level_reg, MemOperand(handle_scope_base, kLevelOffset));
@@ -1672,7 +1672,7 @@
   if (FLAG_log_timer_events) {
     FrameScope frame(this, StackFrame::MANUAL);
     PushSafepointRegisters();
-    Mov(x0, Operand(ExternalReference::isolate_address(isolate())));
+    Mov(x0, ExternalReference::isolate_address(isolate()));
     CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
     PopSafepointRegisters();
   }
@@ -1686,7 +1686,7 @@
   if (FLAG_log_timer_events) {
     FrameScope frame(this, StackFrame::MANUAL);
     PushSafepointRegisters();
-    Mov(x0, Operand(ExternalReference::isolate_address(isolate())));
+    Mov(x0, ExternalReference::isolate_address(isolate()));
     CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1);
     PopSafepointRegisters();
   }
@@ -1722,7 +1722,7 @@
   Peek(x22, (spill_offset + 3) * kXRegSize);
 
   // Check if the function scheduled an exception.
-  Mov(x5, Operand(ExternalReference::scheduled_exception_address(isolate())));
+  Mov(x5, ExternalReference::scheduled_exception_address(isolate()));
   Ldr(x5, MemOperand(x5));
   JumpIfNotRoot(x5, Heap::kTheHoleValueRootIndex, &promote_scheduled_exception);
   Bind(&exception_handled);
@@ -1750,7 +1750,7 @@
   // Save the return value in a callee-save register.
   Register saved_result = x19;
   Mov(saved_result, x0);
-  Mov(x0, Operand(ExternalReference::isolate_address(isolate())));
+  Mov(x0, ExternalReference::isolate_address(isolate()));
   CallCFunction(
       ExternalReference::delete_handle_scope_extensions(isolate()), 1);
   Mov(x0, saved_result);
@@ -1761,7 +1761,7 @@
 void MacroAssembler::CallExternalReference(const ExternalReference& ext,
                                            int num_arguments) {
   Mov(x0, num_arguments);
-  Mov(x1, Operand(ext));
+  Mov(x1, ext);
 
   CEntryStub stub(1);
   CallStub(&stub);
@@ -1769,7 +1769,7 @@
 
 
 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
-  Mov(x1, Operand(builtin));
+  Mov(x1, builtin);
   CEntryStub stub(1);
   Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
 }
@@ -1881,7 +1881,7 @@
                                    int num_of_double_args) {
   UseScratchRegisterScope temps(this);
   Register temp = temps.AcquireX();
-  Mov(temp, Operand(function));
+  Mov(temp, function);
   CallCFunction(temp, num_of_reg_args, num_of_double_args);
 }
 
@@ -2912,7 +2912,7 @@
     ASSERT(StackPointer().Is(jssp));
     UseScratchRegisterScope temps(this);
     Register temp = temps.AcquireX();
-    __ Mov(temp, Operand(Smi::FromInt(StackFrame::STUB)));
+    __ Mov(temp, Smi::FromInt(StackFrame::STUB));
     // Compiled stubs don't age, and so they don't need the predictable code
     // ageing sequence.
     __ Push(lr, fp, cp, temp);
@@ -2935,7 +2935,7 @@
   Register code_reg = temps.AcquireX();
 
   Push(lr, fp, cp);
-  Mov(type_reg, Operand(Smi::FromInt(type)));
+  Mov(type_reg, Smi::FromInt(type));
   Mov(code_reg, Operand(CodeObject()));
   Push(type_reg, code_reg);
   // jssp[4] : lr
@@ -3092,7 +3092,7 @@
                                 Register scratch1, Register scratch2) {
   if (FLAG_native_code_counters && counter->Enabled()) {
     Mov(scratch1, value);
-    Mov(scratch2, Operand(ExternalReference(counter)));
+    Mov(scratch2, ExternalReference(counter));
     Str(scratch1, MemOperand(scratch2));
   }
 }
@@ -3102,7 +3102,7 @@
                                       Register scratch1, Register scratch2) {
   ASSERT(value != 0);
   if (FLAG_native_code_counters && counter->Enabled()) {
-    Mov(scratch2, Operand(ExternalReference(counter)));
+    Mov(scratch2, ExternalReference(counter));
     Ldr(scratch1, MemOperand(scratch2));
     Add(scratch1, scratch1, value);
     Str(scratch1, MemOperand(scratch2));
@@ -3135,7 +3135,7 @@
 #ifdef ENABLE_DEBUGGER_SUPPORT
 void MacroAssembler::DebugBreak() {
   Mov(x0, 0);
-  Mov(x1, Operand(ExternalReference(Runtime::kDebugBreak, isolate())));
+  Mov(x1, ExternalReference(Runtime::kDebugBreak, isolate()));
   CEntryStub ces(1);
   ASSERT(AllowThisStubCall(&ces));
   Call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK);
@@ -3174,7 +3174,7 @@
   }
 
   // Link the current handler as the next handler.
-  Mov(x11, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+  Mov(x11, ExternalReference(Isolate::kHandlerAddress, isolate()));
   Ldr(x10, MemOperand(x11));
   Push(x10);
   // Set this new handler as the current one.
@@ -3185,7 +3185,7 @@
 void MacroAssembler::PopTryHandler() {
   STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
   Pop(x10);
-  Mov(x11, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+  Mov(x11, ExternalReference(Isolate::kHandlerAddress, isolate()));
   Drop(StackHandlerConstants::kSize - kXRegSize, kByteSizeInBytes);
   Str(x10, MemOperand(x11));
 }
@@ -3307,7 +3307,7 @@
   // Set up allocation top address and object size registers.
   Register top_address = scratch1;
   Register allocation_limit = scratch2;
-  Mov(top_address, Operand(heap_allocation_top));
+  Mov(top_address, heap_allocation_top);
 
   if ((flags & RESULT_CONTAINS_TOP) == 0) {
     // Load allocation top into result and the allocation limit.
@@ -3360,13 +3360,13 @@
   Bic(object, object, kHeapObjectTagMask);
 #ifdef DEBUG
   // Check that the object un-allocated is below the current top.
-  Mov(scratch, Operand(new_space_allocation_top));
+  Mov(scratch, new_space_allocation_top);
   Ldr(scratch, MemOperand(scratch));
   Cmp(object, scratch);
   Check(lt, kUndoAllocationOfNonAllocatedMemory);
 #endif
   // Write the address of the object to un-allocate as the current top.
-  Mov(scratch, Operand(new_space_allocation_top));
+  Mov(scratch, new_space_allocation_top);
   Str(object, MemOperand(scratch));
 }
 
@@ -3459,7 +3459,7 @@
 
   ExternalReference high_promotion_mode = ExternalReference::
       new_space_high_promotion_mode_active_address(isolate());
-  Mov(scratch1, Operand(high_promotion_mode));
+  Mov(scratch1, high_promotion_mode);
   Ldr(scratch1, MemOperand(scratch1));
   Cbz(scratch1, &allocate_new_space);
 
@@ -4112,7 +4112,7 @@
   Register scratch2 = temps.AcquireX();
 
   // Load store buffer top.
-  Mov(scratch2, Operand(ExternalReference::store_buffer_top(isolate())));
+  Mov(scratch2, ExternalReference::store_buffer_top(isolate()));
   Ldr(scratch1, MemOperand(scratch2));
   // Store pointer to buffer and increment buffer top.
   Str(address, MemOperand(scratch1, kPointerSize, PostIndex));
@@ -4621,7 +4621,7 @@
     UseScratchRegisterScope temps(this);
     Register temp = temps.AcquireX();
     STATIC_ASSERT(kSmiTag == 0);
-    Tst(object, Operand(kSmiTagMask));
+    Tst(object, kSmiTagMask);
     Check(ne, kOperandIsNotAString);
     Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset));
     CompareInstanceType(temp, temp, FIRST_NONSTRING_TYPE);
@@ -4676,7 +4676,7 @@
     // Avoid infinite recursion; Push contains some assertions that use Abort.
     NoUseRealAbortsScope no_real_aborts(this);
 
-    Mov(x0, Operand(Smi::FromInt(reason)));
+    Mov(x0, Smi::FromInt(reason));
     Push(x0);
 
     if (!has_frame_) {
@@ -5078,7 +5078,7 @@
   ASSERT(!AreAliased(result, dividend));
   ASSERT(result.Is32Bits() && dividend.Is32Bits());
   MultiplierAndShift ms(divisor);
-  Mov(result, Operand(ms.multiplier()));
+  Mov(result, ms.multiplier());
   Smull(result.X(), dividend, result);
   Asr(result.X(), result.X(), 32);
   if (divisor > 0 && ms.multiplier() < 0) Add(result, result, dividend);
diff --git a/src/a64/regexp-macro-assembler-a64.cc b/src/a64/regexp-macro-assembler-a64.cc
index be0a75d..0b6ade8 100644
--- a/src/a64/regexp-macro-assembler-a64.cc
+++ b/src/a64/regexp-macro-assembler-a64.cc
@@ -408,7 +408,7 @@
     // Address of current input position.
     __ Add(x1, input_end(), Operand(current_input_offset(), SXTW));
     // Isolate.
-    __ Mov(x3, Operand(ExternalReference::isolate_address(isolate())));
+    __ Mov(x3, ExternalReference::isolate_address(isolate()));
 
     {
       AllowExternalCallThatCantCauseGC scope(masm_);
@@ -634,7 +634,7 @@
       CompareAndBranchOrBacktrack(current_character(), 'z', hi, on_no_match);
     }
     ExternalReference map = ExternalReference::re_word_character_map();
-    __ Mov(x10, Operand(map));
+    __ Mov(x10, map);
     __ Ldrb(w10, MemOperand(x10, current_character(), UXTW));
     CompareAndBranchOrBacktrack(w10, 0, eq, on_no_match);
     return true;
@@ -647,7 +647,7 @@
       __ B(hi, &done);
     }
     ExternalReference map = ExternalReference::re_word_character_map();
-    __ Mov(x10, Operand(map));
+    __ Mov(x10, map);
     __ Ldrb(w10, MemOperand(x10, current_character(), UXTW));
     CompareAndBranchOrBacktrack(w10, 0, ne, on_no_match);
     __ Bind(&done);
@@ -736,7 +736,7 @@
 
   ExternalReference stack_limit =
       ExternalReference::address_of_stack_limit(isolate());
-  __ Mov(x10, Operand(stack_limit));
+  __ Mov(x10, stack_limit);
   __ Ldr(x10, MemOperand(x10));
   __ Subs(x10, csp, x10);
 
@@ -1031,7 +1031,7 @@
     // The cached registers need to be retained.
     __ PushCPURegList(cached_registers);
     // Call GrowStack(backtrack_stackpointer(), &stack_base)
-    __ Mov(x2, Operand(ExternalReference::isolate_address(isolate())));
+    __ Mov(x2, ExternalReference::isolate_address(isolate()));
     __ Add(x1, frame_pointer(), kStackBase);
     __ Mov(x0, backtrack_stackpointer());
     ExternalReference grow_stack =
@@ -1455,7 +1455,7 @@
 
   ExternalReference check_stack_guard_state =
       ExternalReference::re_check_stack_guard_state(isolate());
-  __ Mov(scratch, Operand(check_stack_guard_state));
+  __ Mov(scratch, check_stack_guard_state);
   DirectCEntryStub stub;
   stub.GenerateCall(masm_, scratch);
 
@@ -1519,7 +1519,7 @@
   // Check for preemption.
   ExternalReference stack_limit =
       ExternalReference::address_of_stack_limit(isolate());
-  __ Mov(x10, Operand(stack_limit));
+  __ Mov(x10, stack_limit);
   __ Ldr(x10, MemOperand(x10));
   ASSERT(csp.Is(__ StackPointer()));
   __ Cmp(csp, x10);
@@ -1530,7 +1530,7 @@
 void RegExpMacroAssemblerA64::CheckStackLimit() {
   ExternalReference stack_limit =
       ExternalReference::address_of_regexp_stack_limit(isolate());
-  __ Mov(x10, Operand(stack_limit));
+  __ Mov(x10, stack_limit);
   __ Ldr(x10, MemOperand(x10));
   __ Cmp(backtrack_stackpointer(), x10);
   CallIf(&stack_overflow_label_, ls);
diff --git a/src/a64/simulator-a64.cc b/src/a64/simulator-a64.cc
index 3801bf7..d414bf5 100644
--- a/src/a64/simulator-a64.cc
+++ b/src/a64/simulator-a64.cc
@@ -51,6 +51,34 @@
 #define SScanF sscanf  // NOLINT
 
 
+// Helpers for colors.
+// Depending on your terminal configuration, the colour names may not match the
+// observed colours.
+#define COLOUR(colour_code)  "\033[" colour_code "m"
+#define BOLD(colour_code)    "1;" colour_code
+#define NORMAL ""
+#define GREY   "30"
+#define GREEN  "32"
+#define ORANGE "33"
+#define BLUE   "34"
+#define PURPLE "35"
+#define INDIGO "36"
+#define WHITE  "37"
+typedef char const * const TEXT_COLOUR;
+TEXT_COLOUR clr_normal         = FLAG_log_colour ? COLOUR(NORMAL)       : "";
+TEXT_COLOUR clr_flag_name      = FLAG_log_colour ? COLOUR(BOLD(GREY))   : "";
+TEXT_COLOUR clr_flag_value     = FLAG_log_colour ? COLOUR(BOLD(WHITE))  : "";
+TEXT_COLOUR clr_reg_name       = FLAG_log_colour ? COLOUR(BOLD(BLUE))   : "";
+TEXT_COLOUR clr_reg_value      = FLAG_log_colour ? COLOUR(BOLD(INDIGO)) : "";
+TEXT_COLOUR clr_fpreg_name     = FLAG_log_colour ? COLOUR(BOLD(ORANGE)) : "";
+TEXT_COLOUR clr_fpreg_value    = FLAG_log_colour ? COLOUR(BOLD(PURPLE)) : "";
+TEXT_COLOUR clr_memory_value   = FLAG_log_colour ? COLOUR(BOLD(GREEN))  : "";
+TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR(GREEN)        : "";
+TEXT_COLOUR clr_debug_number   = FLAG_log_colour ? COLOUR(BOLD(ORANGE)) : "";
+TEXT_COLOUR clr_debug_message  = FLAG_log_colour ? COLOUR(ORANGE)       : "";
+TEXT_COLOUR clr_printf         = FLAG_log_colour ? COLOUR(GREEN)        : "";
+
+
 // This is basically the same as PrintF, with a guard for FLAG_trace_sim.
 void PRINTF_CHECKING TraceSim(const char* format, ...) {
   if (FLAG_trace_sim) {
@@ -469,7 +497,9 @@
     return reinterpret_cast<void*>(&redirect_call_);
   }
 
-  void* external_function() { return external_function_; }
+  template <typename T>
+  T external_function() { return reinterpret_cast<T>(external_function_); }
+
   ExternalReference::Type type() { return type_; }
 
   static Redirection* Get(void* external_function,
@@ -495,7 +525,7 @@
   static void* ReverseRedirection(int64_t reg) {
     Redirection* redirection =
         FromHltInstruction(reinterpret_cast<Instruction*>(reg));
-    return redirection->external_function();
+    return redirection->external_function<void*>();
   }
 
  private:
@@ -506,6 +536,223 @@
 };
 
 
+// Calls into the V8 runtime are based on this very simple interface.
+// Note: To be able to return two values from some calls the code in runtime.cc
+// uses the ObjectPair structure.
+// The simulator assumes all runtime calls return two 64-bits values. If they
+// don't, register x1 is clobbered. This is fine because x1 is caller-saved.
+struct ObjectPair {
+  int64_t res0;
+  int64_t res1;
+};
+
+
+typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0,
+                                           int64_t arg1,
+                                           int64_t arg2,
+                                           int64_t arg3,
+                                           int64_t arg4,
+                                           int64_t arg5,
+                                           int64_t arg6,
+                                           int64_t arg7);
+
+typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2);
+typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2);
+typedef double (*SimulatorRuntimeFPCall)(double arg1);
+typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2);
+
+// This signature supports direct call in to API function native callback
+// (refer to InvocationCallback in v8.h).
+typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0);
+typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1);
+
+// This signature supports direct call to accessor getter callback.
+typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1);
+typedef void (*SimulatorRuntimeProfilingGetterCall)(int64_t arg0, int64_t arg1,
+                                                    void* arg2);
+
+void Simulator::DoRuntimeCall(Instruction* instr) {
+  Redirection* redirection = Redirection::FromHltInstruction(instr);
+
+  // The called C code might itself call simulated code, so any
+  // caller-saved registers (including lr) could still be clobbered by a
+  // redirected call.
+  Instruction* return_address = lr();
+
+  int64_t external = redirection->external_function<int64_t>();
+
+  TraceSim("Call to host function at %p\n",
+           redirection->external_function<void*>());
+
+  // SP must be 16-byte-aligned at the call interface.
+  bool stack_alignment_exception = ((sp() & 0xf) != 0);
+  if (stack_alignment_exception) {
+    TraceSim("  with unaligned stack 0x%016" PRIx64 ".\n", sp());
+    FATAL("ALIGNMENT EXCEPTION");
+  }
+
+  switch (redirection->type()) {
+    default:
+      TraceSim("Type: Unknown.\n");
+      UNREACHABLE();
+      break;
+
+    case ExternalReference::BUILTIN_CALL: {
+      // MaybeObject* f(v8::internal::Arguments).
+      TraceSim("Type: BUILTIN_CALL\n");
+      SimulatorRuntimeCall target =
+        reinterpret_cast<SimulatorRuntimeCall>(external);
+
+      // We don't know how many arguments are being passed, but we can
+      // pass 8 without touching the stack. They will be ignored by the
+      // host function if they aren't used.
+      TraceSim("Arguments: "
+               "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
+               "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
+               "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
+               "0x%016" PRIx64 ", 0x%016" PRIx64,
+               xreg(0), xreg(1), xreg(2), xreg(3),
+               xreg(4), xreg(5), xreg(6), xreg(7));
+      ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3),
+                                 xreg(4), xreg(5), xreg(6), xreg(7));
+      TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64 "}\n",
+               result.res0, result.res1);
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      set_xreg(0, result.res0);
+      set_xreg(1, result.res1);
+      break;
+    }
+
+    case ExternalReference::DIRECT_API_CALL: {
+      // void f(v8::FunctionCallbackInfo&)
+      TraceSim("Type: DIRECT_API_CALL\n");
+      SimulatorRuntimeDirectApiCall target =
+        reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
+      TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0));
+      target(xreg(0));
+      TraceSim("No return value.");
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      break;
+    }
+
+    case ExternalReference::BUILTIN_COMPARE_CALL: {
+      // int f(double, double)
+      TraceSim("Type: BUILTIN_COMPARE_CALL\n");
+      SimulatorRuntimeCompareCall target =
+        reinterpret_cast<SimulatorRuntimeCompareCall>(external);
+      TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1));
+      int64_t result = target(dreg(0), dreg(1));
+      TraceSim("Returned: %" PRId64 "\n", result);
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      set_xreg(0, result);
+      break;
+    }
+
+    case ExternalReference::BUILTIN_FP_CALL: {
+      // double f(double)
+      TraceSim("Type: BUILTIN_FP_CALL\n");
+      SimulatorRuntimeFPCall target =
+        reinterpret_cast<SimulatorRuntimeFPCall>(external);
+      TraceSim("Argument: %f\n", dreg(0));
+      double result = target(dreg(0));
+      TraceSim("Returned: %f\n", result);
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      set_dreg(0, result);
+      break;
+    }
+
+    case ExternalReference::BUILTIN_FP_FP_CALL: {
+      // double f(double, double)
+      TraceSim("Type: BUILTIN_FP_FP_CALL\n");
+      SimulatorRuntimeFPFPCall target =
+        reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
+      TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1));
+      double result = target(dreg(0), dreg(1));
+      TraceSim("Returned: %f\n", result);
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      set_dreg(0, result);
+      break;
+    }
+
+    case ExternalReference::BUILTIN_FP_INT_CALL: {
+      // double f(double, int)
+      TraceSim("Type: BUILTIN_FP_INT_CALL\n");
+      SimulatorRuntimeFPIntCall target =
+        reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
+      TraceSim("Arguments: %f, %d\n", dreg(0), wreg(0));
+      double result = target(dreg(0), wreg(0));
+      TraceSim("Returned: %f\n", result);
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      set_dreg(0, result);
+      break;
+    }
+
+    case ExternalReference::DIRECT_GETTER_CALL: {
+      // void f(Local<String> property, PropertyCallbackInfo& info)
+      TraceSim("Type: DIRECT_GETTER_CALL\n");
+      SimulatorRuntimeDirectGetterCall target =
+        reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
+      TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 "\n",
+               xreg(0), xreg(1));
+      target(xreg(0), xreg(1));
+      TraceSim("No return value.");
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      break;
+    }
+
+    case ExternalReference::PROFILING_API_CALL: {
+      // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
+      TraceSim("Type: PROFILING_API_CALL\n");
+      SimulatorRuntimeProfilingApiCall target =
+        reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+      void* arg1 = Redirection::ReverseRedirection(xreg(1));
+      TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1);
+      target(xreg(0), arg1);
+      TraceSim("No return value.");
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      break;
+    }
+
+    case ExternalReference::PROFILING_GETTER_CALL: {
+      // void f(Local<String> property, PropertyCallbackInfo& info,
+      //        AccessorGetterCallback callback)
+      TraceSim("Type: PROFILING_GETTER_CALL\n");
+      SimulatorRuntimeProfilingGetterCall target =
+        reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(
+            external);
+      void* arg2 = Redirection::ReverseRedirection(xreg(2));
+      TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 ", %p\n",
+               xreg(0), xreg(1), arg2);
+      target(xreg(0), xreg(1), arg2);
+      TraceSim("No return value.");
+#ifdef DEBUG
+      CorruptAllCallerSavedCPURegisters();
+#endif
+      break;
+    }
+  }
+
+  set_lr(return_address);
+  set_pc(return_address);
+}
+
+
 void* Simulator::RedirectExternalReference(void* external_function,
                                            ExternalReference::Type type) {
   Redirection* redirection = Redirection::Get(external_function, type);
@@ -820,12 +1067,6 @@
 void Simulator::PrintSystemRegisters(bool print_all) {
   static bool first_run = true;
 
-  // Define some colour codes to use for the register dump.
-  // TODO(jbramley): Find a more elegant way of defining these.
-  char const * const clr_normal     = (FLAG_log_colour) ? ("\033[m") : ("");
-  char const * const clr_flag_name  = (FLAG_log_colour) ? ("\033[1;30m") : ("");
-  char const * const clr_flag_value = (FLAG_log_colour) ? ("\033[1;37m") : ("");
-
   static SimSystemRegister last_nzcv;
   if (print_all || first_run || (last_nzcv.RawValue() != nzcv().RawValue())) {
     fprintf(stream_, "# %sFLAGS: %sN:%d Z:%d C:%d V:%d%s\n",
@@ -861,12 +1102,6 @@
   static bool first_run = true;
   static int64_t last_regs[kNumberOfRegisters];
 
-  // Define some colour codes to use for the register dump.
-  // TODO(jbramley): Find a more elegant way of defining these.
-  char const * const clr_normal    = (FLAG_log_colour) ? ("\033[m") : ("");
-  char const * const clr_reg_name  = (FLAG_log_colour) ? ("\033[1;34m") : ("");
-  char const * const clr_reg_value = (FLAG_log_colour) ? ("\033[1;36m") : ("");
-
   for (unsigned i = 0; i < kNumberOfRegisters; i++) {
     if (print_all_regs || first_run ||
         (last_regs[i] != xreg(i, Reg31IsStackPointer))) {
@@ -889,12 +1124,6 @@
   static bool first_run = true;
   static uint64_t last_regs[kNumberOfFPRegisters];
 
-  // Define some colour codes to use for the register dump.
-  // TODO(jbramley): Find a more elegant way of defining these.
-  char const * const clr_normal    = (FLAG_log_colour) ? ("\033[m") : ("");
-  char const * const clr_reg_name  = (FLAG_log_colour) ? ("\033[1;33m") : ("");
-  char const * const clr_reg_value = (FLAG_log_colour) ? ("\033[1;35m") : ("");
-
   // Print as many rows of registers as necessary, keeping each individual
   // register in the same column each time (to make it easy to visually scan
   // for changes).
@@ -902,18 +1131,18 @@
     if (print_all_regs || first_run || (last_regs[i] != dreg_bits(i))) {
       fprintf(stream_,
               "# %s %4s:%s 0x%016" PRIx64 "%s (%s%s:%s %g%s %s:%s %g%s)\n",
-              clr_reg_name,
+              clr_fpreg_name,
               VRegNameForCode(i),
-              clr_reg_value,
+              clr_fpreg_value,
               dreg_bits(i),
               clr_normal,
-              clr_reg_name,
+              clr_fpreg_name,
               DRegNameForCode(i),
-              clr_reg_value,
+              clr_fpreg_value,
               dreg(i),
-              clr_reg_name,
+              clr_fpreg_name,
               SRegNameForCode(i),
-              clr_reg_value,
+              clr_fpreg_value,
               sreg(i),
               clr_normal);
     }
@@ -2949,14 +3178,6 @@
 
 
 bool Simulator::PrintValue(const char* desc) {
-  // Define some colour codes to use for the register dump.
-  // TODO(jbramley): Find a more elegant way of defining these.
-  char const * const clr_normal    = FLAG_log_colour ? "\033[m" : "";
-  char const * const clr_reg_name  = FLAG_log_colour ? "\033[1;34m" : "";
-  char const * const clr_reg_value = FLAG_log_colour ? "\033[1;36m" : "";
-  char const * const clr_fpreg_name  = FLAG_log_colour ? "\033[1;33m" : "";
-  char const * const clr_fpreg_value = FLAG_log_colour ? "\033[1;35m" : "";
-
   if (strcmp(desc, "csp") == 0) {
     ASSERT(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode));
     PrintF("%s csp:%s 0x%016" PRIx64 "%s\n",
@@ -3299,53 +3520,7 @@
 }
 
 
-// Calls into the V8 runtime are based on this very simple interface.
-// Note: To be able to return two values from some calls the code in runtime.cc
-// uses the ObjectPair structure.
-// The simulator assumes all runtime calls return two 64-bits values. If they
-// don't, register x1 is clobbered. This is fine because x1 is caller-saved.
-struct ObjectPair {
-  int64_t res0;
-  int64_t res1;
-};
-
-
-typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0,
-                                           int64_t arg1,
-                                           int64_t arg2,
-                                           int64_t arg3,
-                                           int64_t arg4,
-                                           int64_t arg5,
-                                           int64_t arg6,
-                                           int64_t arg7);
-
-typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2);
-typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2);
-typedef double (*SimulatorRuntimeFPCall)(double arg1);
-typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2);
-
-// This signature supports direct call in to API function native callback
-// (refer to InvocationCallback in v8.h).
-typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0);
-typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1);
-
-// This signature supports direct call to accessor getter callback.
-typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1);
-typedef void (*SimulatorRuntimeProfilingGetterCall)(int64_t arg0, int64_t arg1,
-                                                    void* arg2);
-
 void Simulator::VisitException(Instruction* instr) {
-  // Define some colour codes to use for log messages.
-  // TODO(jbramley): Find a more elegant way of defining these.
-  char const* const clr_normal        = (FLAG_log_colour) ? ("\033[m")
-                                                          : ("");
-  char const* const clr_debug_number  = (FLAG_log_colour) ? ("\033[1;33m")
-                                                          : ("");
-  char const* const clr_debug_message = (FLAG_log_colour) ? ("\033[0;33m")
-                                                          : ("");
-  char const* const clr_printf        = (FLAG_log_colour) ? ("\033[0;32m")
-                                                          : ("");
-
   switch (instr->Mask(ExceptionMask)) {
     case HLT: {
       if (instr->ImmException() == kImmExceptionIsDebug) {
@@ -3421,190 +3596,7 @@
         if (parameters & BREAK) Debug();
 
       } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) {
-        // TODO(all): Extract the call redirection code into a separate
-        // function.
-
-        Redirection* redirection = Redirection::FromHltInstruction(instr);
-
-        // The called C code might itself call simulated code, so any
-        // caller-saved registers (including lr) could still be clobbered by a
-        // redirected call.
-        Instruction* return_address = lr();
-
-        // TODO(jbramley): Make external_function() a template so that we don't
-        // have to explicitly cast the result for each redirection type.
-        int64_t external =
-            reinterpret_cast<int64_t>(redirection->external_function());
-
-        TraceSim("Call to host function at %p\n",
-                 reinterpret_cast<void*>(redirection->external_function()));
-
-        // SP must be 16 bytes aligned at the call interface.
-        bool stack_alignment_exception = ((sp() & 0xf) != 0);
-        if (stack_alignment_exception) {
-          TraceSim("  with unaligned stack 0x%016" PRIx64 ".\n", sp());
-          FATAL("ALIGNMENT EXCEPTION");
-        }
-
-        switch (redirection->type()) {
-          default:
-            TraceSim("Type: Unknown.\n");
-            UNREACHABLE();
-            break;
-
-          case ExternalReference::BUILTIN_CALL: {
-            // MaybeObject* f(v8::internal::Arguments).
-            TraceSim("Type: BUILTIN_CALL\n");
-            SimulatorRuntimeCall target =
-                reinterpret_cast<SimulatorRuntimeCall>(external);
-
-            // We don't know how many arguments are being passed, but we can
-            // pass 8 without touching the stack. They will be ignored by the
-            // host function if they aren't used.
-            TraceSim("Arguments: "
-                     "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
-                     "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
-                     "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
-                     "0x%016" PRIx64 ", 0x%016" PRIx64,
-                     xreg(0), xreg(1), xreg(2), xreg(3),
-                     xreg(4), xreg(5), xreg(6), xreg(7));
-            ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3),
-                                       xreg(4), xreg(5), xreg(6), xreg(7));
-            TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64"}\n",
-                     result.res0, result.res1);
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            set_xreg(0, result.res0);
-            set_xreg(1, result.res1);
-            break;
-          }
-
-          case ExternalReference::DIRECT_API_CALL: {
-            // void f(v8::FunctionCallbackInfo&)
-            TraceSim("Type: DIRECT_API_CALL\n");
-            SimulatorRuntimeDirectApiCall target =
-                reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
-            TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0));
-            target(xreg(0));
-            TraceSim("No return value.");
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            break;
-          }
-
-          case ExternalReference::BUILTIN_COMPARE_CALL: {
-            // int f(double, double)
-            TraceSim("Type: BUILTIN_COMPARE_CALL\n");
-            SimulatorRuntimeCompareCall target =
-                reinterpret_cast<SimulatorRuntimeCompareCall>(external);
-            TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1));
-            int64_t result = target(dreg(0), dreg(1));
-            TraceSim("Returned: %" PRId64 "\n", result);
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            set_xreg(0, result);
-            break;
-          }
-
-          case ExternalReference::BUILTIN_FP_CALL: {
-            // double f(double)
-            TraceSim("Type: BUILTIN_FP_CALL\n");
-            SimulatorRuntimeFPCall target =
-                reinterpret_cast<SimulatorRuntimeFPCall>(external);
-            TraceSim("Argument: %f\n", dreg(0));
-            double result = target(dreg(0));
-            TraceSim("Returned: %f\n", result);
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            set_dreg(0, result);
-            break;
-          }
-
-          case ExternalReference::BUILTIN_FP_FP_CALL: {
-            // double f(double, double)
-            TraceSim("Type: BUILTIN_FP_FP_CALL\n");
-            SimulatorRuntimeFPFPCall target =
-                reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
-            TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1));
-            double result = target(dreg(0), dreg(1));
-            TraceSim("Returned: %f\n", result);
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            set_dreg(0, result);
-            break;
-          }
-
-          case ExternalReference::BUILTIN_FP_INT_CALL: {
-            // double f(double, int)
-            TraceSim("Type: BUILTIN_FP_INT_CALL\n");
-            SimulatorRuntimeFPIntCall target =
-                reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
-            TraceSim("Arguments: %f, %d\n", dreg(0), wreg(0));
-            double result = target(dreg(0), wreg(0));
-            TraceSim("Returned: %f\n", result);
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            set_dreg(0, result);
-            break;
-          }
-
-          case ExternalReference::DIRECT_GETTER_CALL: {
-            // void f(Local<String> property, PropertyCallbackInfo& info)
-            TraceSim("Type: DIRECT_GETTER_CALL\n");
-            SimulatorRuntimeDirectGetterCall target =
-                reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
-            TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 "\n",
-                     xreg(0), xreg(1));
-            target(xreg(0), xreg(1));
-            TraceSim("No return value.");
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            break;
-          }
-
-          case ExternalReference::PROFILING_API_CALL: {
-            // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
-            TraceSim("Type: PROFILING_API_CALL\n");
-            SimulatorRuntimeProfilingApiCall target =
-                reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
-            void* arg1 = Redirection::ReverseRedirection(xreg(1));
-            TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1);
-            target(xreg(0), arg1);
-            TraceSim("No return value.");
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            break;
-          }
-
-          case ExternalReference::PROFILING_GETTER_CALL: {
-            // void f(Local<String> property, PropertyCallbackInfo& info,
-            //        AccessorGetterCallback callback)
-            TraceSim("Type: PROFILING_GETTER_CALL\n");
-            SimulatorRuntimeProfilingGetterCall target =
-                reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(
-                    external);
-            void* arg2 = Redirection::ReverseRedirection(xreg(2));
-            TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 ", %p\n",
-                     xreg(0), xreg(1), arg2);
-            target(xreg(0), xreg(1), arg2);
-            TraceSim("No return value.");
-#ifdef DEBUG
-            CorruptAllCallerSavedCPURegisters();
-#endif
-            break;
-          }
-        }
-
-        set_lr(return_address);
-        set_pc(return_address);
+        DoRuntimeCall(instr);
       } else if (instr->ImmException() == kImmExceptionIsPrintf) {
         // Read the argument encoded inline in the instruction stream.
         uint32_t type;
@@ -3631,9 +3623,12 @@
           result = fprintf(stream_, "%s", format);
         }
         fputs(clr_normal, stream_);
-        set_xreg(0, result);
 
-        // TODO(jbramley): Consider clobbering all caller-saved registers here.
+#ifdef DEBUG
+        CorruptAllCallerSavedCPURegisters();
+#endif
+
+        set_xreg(0, result);
 
         // The printf parameters are inlined in the code, so skip them.
         set_pc(pc_->InstructionAtOffset(kPrintfLength));
diff --git a/src/a64/simulator-a64.h b/src/a64/simulator-a64.h
index 959644b..0d973e8 100644
--- a/src/a64/simulator-a64.h
+++ b/src/a64/simulator-a64.h
@@ -311,6 +311,7 @@
   // Runtime call support.
   static void* RedirectExternalReference(void* external_function,
                                          ExternalReference::Type type);
+  void DoRuntimeCall(Instruction* instr);
 
   // Run the simulator.
   static const Instruction* kEndOfSimAddress;
diff --git a/src/a64/stub-cache-a64.cc b/src/a64/stub-cache-a64.cc
index 291da65..1e59c0e 100644
--- a/src/a64/stub-cache-a64.cc
+++ b/src/a64/stub-cache-a64.cc
@@ -125,7 +125,7 @@
   __ Add(scratch3, offset, Operand(offset, LSL, 1));
 
   // Calculate the base address of the entry.
-  __ Mov(scratch, Operand(key_offset));
+  __ Mov(scratch, key_offset);
   __ Add(scratch, scratch, Operand(scratch3, LSL, kPointerSizeLog2));
 
   // Check that the key in the entry matches the name.
@@ -461,16 +461,11 @@
   // TODO(verwaest): Share this code as a code stub.
   SmiCheck smi_check = representation.IsTagged()
       ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  Register prop_reg = representation.IsDouble() ? storage_reg : value_reg;
   if (index < 0) {
     // Set the property straight into the object.
     int offset = object->map()->instance_size() + (index * kPointerSize);
-    // TODO(jbramley): This construct appears in several places in this
-    // function. Try to clean it up, perhaps using a result_reg.
-    if (representation.IsDouble()) {
-      __ Str(storage_reg, FieldMemOperand(receiver_reg, offset));
-    } else {
-      __ Str(value_reg, FieldMemOperand(receiver_reg, offset));
-    }
+    __ Str(prop_reg, FieldMemOperand(receiver_reg, offset));
 
     if (!representation.IsSmi()) {
       // Update the write barrier for the array address.
@@ -492,11 +487,7 @@
     // Get the properties array
     __ Ldr(scratch1,
            FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ Str(storage_reg, FieldMemOperand(scratch1, offset));
-    } else {
-      __ Str(value_reg, FieldMemOperand(scratch1, offset));
-    }
+    __ Str(prop_reg, FieldMemOperand(scratch1, offset));
 
     if (!representation.IsSmi()) {
       // Update the write barrier for the array address.
@@ -761,7 +752,7 @@
   ExternalReference ref = ExternalReference(&fun,
                                             ExternalReference::DIRECT_API_CALL,
                                             masm->isolate());
-  __ Mov(api_function_address, Operand(ref));
+  __ Mov(api_function_address, ref);
 
   // Jump to stub.
   CallApiFunctionStub stub(is_store, call_data_undefined, argc);
@@ -1022,7 +1013,7 @@
   // together. Can we use scratch1() here?
   __ LoadRoot(scratch4(), Heap::kUndefinedValueRootIndex);
   __ Push(scratch3(), scratch4());
-  __ Mov(scratch3(), Operand(ExternalReference::isolate_address(isolate())));
+  __ Mov(scratch3(), ExternalReference::isolate_address(isolate()));
   __ Push(scratch4(), scratch3(), reg, name());
 
   Register args_addr = scratch2();
@@ -1044,7 +1035,7 @@
   ApiFunction fun(getter_address);
   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
   ExternalReference ref = ExternalReference(&fun, type, isolate());
-  __ Mov(getter_address_reg, Operand(ref));
+  __ Mov(getter_address_reg, ref);
 
   CallApiGetterStub stub;
   __ TailCallStub(&stub);
diff --git a/src/api.cc b/src/api.cc
index d0c9d26..402598f 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2203,9 +2203,10 @@
   ENTER_V8(isolate);
   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSArray> self = Utils::OpenHandle(this);
-  i::Object* raw_object = self->GetElementNoExceptionThrown(isolate, index);
-  i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
-  return scope.Escape(Utils::StackFrameToLocal(obj));
+  i::Handle<i::Object> obj =
+      i::Object::GetElementNoExceptionThrown(isolate, self, index);
+  i::Handle<i::JSObject> jsobj = i::Handle<i::JSObject>::cast(obj);
+  return scope.Escape(Utils::StackFrameToLocal(jsobj));
 }
 
 
@@ -5475,6 +5476,8 @@
   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
   i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
                                                                   right_string);
+  // We do not expect this to throw an exception. Change this if it does.
+  CHECK_NOT_EMPTY_HANDLE(isolate, result);
   return Utils::ToLocal(result);
 }
 
@@ -6966,9 +6969,12 @@
     return ToApiHandle<String>(
         isolate->factory()->InternalizeUtf8String(entry->name()));
   } else {
-    return ToApiHandle<String>(isolate->factory()->NewConsString(
+    i::Handle<i::String> cons = isolate->factory()->NewConsString(
         isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
-        isolate->factory()->InternalizeUtf8String(entry->name())));
+        isolate->factory()->InternalizeUtf8String(entry->name()));
+    // We do not expect this to throw an exception. Change this if it does.
+    CHECK_NOT_EMPTY_HANDLE(isolate, cons);
+    return ToApiHandle<String>(cons);
   }
 }
 
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index fac89e4..55705b8 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1332,20 +1332,25 @@
   ASSERT(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   int32_t divisor = instr->right()->GetInteger32Constant();
-  LInstruction* result =
-      DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
-  return can_deopt ? AssignEnvironment(result) : result;
+  LOperand* temp =
+      ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
+       (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
+      NULL : TempRegister();
+  LInstruction* result = DefineAsRegister(
+      new(zone()) LFlooringDivByConstI(dividend, divisor, temp));
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
   if (instr->RightIsPowerOf2()) {
     return DoFlooringDivByPowerOf2I(instr);
-  } else if (false && instr->right()->IsConstant()) {
-    return DoFlooringDivByConstI(instr);  // TODO(svenpanne) Fix and re-enable.
+  } else if (instr->right()->IsConstant()) {
+    return DoFlooringDivByConstI(instr);
   } else {
     return DoDivI(instr);
   }
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 631efc7..34eb510 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -747,16 +747,17 @@
 };
 
 
-class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
  public:
-  LFlooringDivByConstI(LOperand* dividend, int32_t divisor) {
+  LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) {
     inputs_[0] = dividend;
     divisor_ = divisor;
+    temps_[0] = temp;
   }
 
   LOperand* dividend() { return inputs_[0]; }
   int32_t divisor() const { return divisor_; }
-  LOperand* temp1() { return temps_[0]; }
+  LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
   DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 33ac25f..dc31547 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1507,8 +1507,31 @@
     DeoptimizeIf(eq, instr->environment());
   }
 
-  // TODO(svenpanne) Add correction terms.
-  __ TruncatingDiv(result, dividend, divisor);
+  // Easy case: We need no dynamic check for the dividend and the flooring
+  // division is the same as the truncating division.
+  if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
+      (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
+    __ TruncatingDiv(result, dividend, Abs(divisor));
+    if (divisor < 0) __ rsb(result, result, Operand::Zero());
+    return;
+  }
+
+  // In the general case we may need to adjust before and after the truncating
+  // division to get a flooring division.
+  Register temp = ToRegister(instr->temp());
+  ASSERT(!temp.is(dividend) && !temp.is(result));
+  Label needs_adjustment, done;
+  __ cmp(dividend, Operand::Zero());
+  __ b(divisor > 0 ? lt : gt, &needs_adjustment);
+  __ TruncatingDiv(result, dividend, Abs(divisor));
+  if (divisor < 0) __ rsb(result, result, Operand::Zero());
+  __ jmp(&done);
+  __ bind(&needs_adjustment);
+  __ add(temp, dividend, Operand(divisor > 0 ? 1 : -1));
+  __ TruncatingDiv(result, temp, Abs(divisor));
+  if (divisor < 0) __ rsb(result, result, Operand::Zero());
+  __ sub(result, result, Operand(1));
+  __ bind(&done);
 }
 
 
diff --git a/src/builtins.cc b/src/builtins.cc
index b48de7f..be9051c 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -367,6 +367,7 @@
 }
 
 
+// TODO(ishell): Handlify when all Array* builtins are handlified.
 static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
                                                      JSArray* receiver) {
   if (!FLAG_clever_optimizations) return false;
@@ -406,23 +407,21 @@
 
 
 BUILTIN(ArrayPush) {
-  Heap* heap = isolate->heap();
-  Object* receiver = *args.receiver();
-  FixedArrayBase* elms_obj;
-  MaybeObject* maybe_elms_obj =
-      EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1);
-  if (maybe_elms_obj == NULL) {
-    return CallJsBuiltin(isolate, "ArrayPush", args);
-  }
-  if (!maybe_elms_obj->To(&elms_obj)) return maybe_elms_obj;
+  HandleScope scope(isolate);
+  Handle<Object> receiver = args.receiver();
+  Handle<Object> elms_or_null =
+      EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 1);
+  RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null);
+  if (*elms_or_null == NULL) return CallJsBuiltin(isolate, "ArrayPush", args);
 
-  JSArray* array = JSArray::cast(receiver);
+  Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
+  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   ASSERT(!array->map()->is_observed());
 
   ElementsKind kind = array->GetElementsKind();
 
   if (IsFastSmiOrObjectElementsKind(kind)) {
-    FixedArray* elms = FixedArray::cast(elms_obj);
+    Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
 
     int len = Smi::cast(array->length())->value();
     int to_add = args.length() - 1;
@@ -438,16 +437,13 @@
     if (new_length > elms->length()) {
       // New backing storage is needed.
       int capacity = new_length + (new_length >> 1) + 16;
-      FixedArray* new_elms;
-      MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
-      if (!maybe_obj->To(&new_elms)) return maybe_obj;
+      Handle<FixedArray> new_elms =
+          isolate->factory()->NewUninitializedFixedArray(capacity);
 
       ElementsAccessor* accessor = array->GetElementsAccessor();
-      MaybeObject* maybe_failure = accessor->CopyElements(
-           NULL, 0, kind, new_elms, 0,
-           ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
-      ASSERT(!maybe_failure->IsFailure());
-      USE(maybe_failure);
+      accessor->CopyElements(
+          Handle<JSObject>::null(), 0, kind, new_elms, 0,
+          ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
 
       elms = new_elms;
     }
@@ -459,8 +455,8 @@
       elms->set(index + len, args[index + 1], mode);
     }
 
-    if (elms != array->elements()) {
-      array->set_elements(elms);
+    if (*elms != array->elements()) {
+      array->set_elements(*elms);
     }
 
     // Set the length.
@@ -480,25 +476,22 @@
 
     int new_length = len + to_add;
 
-    FixedDoubleArray* new_elms;
+    Handle<FixedDoubleArray> new_elms;
 
     if (new_length > elms_len) {
       // New backing storage is needed.
       int capacity = new_length + (new_length >> 1) + 16;
-      MaybeObject* maybe_obj =
-          heap->AllocateUninitializedFixedDoubleArray(capacity);
-      if (!maybe_obj->To(&new_elms)) return maybe_obj;
+      new_elms = isolate->factory()->NewFixedDoubleArray(capacity);
 
       ElementsAccessor* accessor = array->GetElementsAccessor();
-      MaybeObject* maybe_failure = accessor->CopyElements(
-              NULL, 0, kind, new_elms, 0,
-              ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
-      ASSERT(!maybe_failure->IsFailure());
-      USE(maybe_failure);
+      accessor->CopyElements(
+          Handle<JSObject>::null(), 0, kind, new_elms, 0,
+          ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
+
     } else {
       // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the
       // empty_fixed_array.
-      new_elms = FixedDoubleArray::cast(elms_obj);
+      new_elms = Handle<FixedDoubleArray>::cast(elms_obj);
     }
 
     // Add the provided values.
@@ -509,8 +502,8 @@
       new_elms->set(index + len, arg->Number());
     }
 
-    if (new_elms != array->elements()) {
-      array->set_elements(new_elms);
+    if (*new_elms != array->elements()) {
+      array->set_elements(*new_elms);
     }
 
     // Set the length.
@@ -583,19 +576,19 @@
 
 
 BUILTIN(ArrayShift) {
+  HandleScope scope(isolate);
   Heap* heap = isolate->heap();
-  Object* receiver = *args.receiver();
-  FixedArrayBase* elms_obj;
-  MaybeObject* maybe_elms_obj =
-      EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
-  if (maybe_elms_obj == NULL)
-      return CallJsBuiltin(isolate, "ArrayShift", args);
-  if (!maybe_elms_obj->To(&elms_obj)) return maybe_elms_obj;
-
-  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
+  Handle<Object> receiver = args.receiver();
+  Handle<Object> elms_or_null =
+      EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, NULL, 0);
+  RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null);
+  if ((*elms_or_null == NULL) ||
+      !IsJSArrayFastElementMovingAllowed(heap,
+                                         *Handle<JSArray>::cast(receiver))) {
     return CallJsBuiltin(isolate, "ArrayShift", args);
   }
-  JSArray* array = JSArray::cast(receiver);
+  Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
+  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   ASSERT(!array->map()->is_observed());
 
   int len = Smi::cast(array->length())->value();
@@ -603,25 +596,23 @@
 
   // Get first element
   ElementsAccessor* accessor = array->GetElementsAccessor();
-  Object* first;
-  MaybeObject* maybe_first = accessor->Get(receiver, array, 0, elms_obj);
-  if (!maybe_first->To(&first)) return maybe_first;
+  Handle<Object> first = accessor->Get(receiver, array, 0, elms_obj);
   if (first->IsTheHole()) {
-    first = heap->undefined_value();
+    first = isolate->factory()->undefined_value();
   }
 
-  if (!heap->lo_space()->Contains(elms_obj)) {
-    array->set_elements(LeftTrimFixedArray(heap, elms_obj, 1));
+  if (!heap->lo_space()->Contains(*elms_obj)) {
+    array->set_elements(LeftTrimFixedArray(heap, *elms_obj, 1));
   } else {
     // Shift the elements.
     if (elms_obj->IsFixedArray()) {
-      FixedArray* elms = FixedArray::cast(elms_obj);
+      Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
       DisallowHeapAllocation no_gc;
-      heap->MoveElements(elms, 0, 1, len - 1);
+      heap->MoveElements(*elms, 0, 1, len - 1);
       elms->set(len - 1, heap->the_hole_value());
     } else {
-      FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
-      MoveDoubleElements(elms, 0, elms, 1, len - 1);
+      Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj);
+      MoveDoubleElements(*elms, 0, *elms, 1, len - 1);
       elms->set_the_hole(len - 1);
     }
   }
@@ -629,7 +620,7 @@
   // Set the length.
   array->set_length(Smi::FromInt(len - 1));
 
-  return first;
+  return *first;
 }
 
 
diff --git a/src/elements.cc b/src/elements.cc
index d935fb1..5d3ef13 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -639,6 +639,19 @@
         receiver, holder, key, backing_store);
   }
 
+  // TODO(ishell): Temporary wrapper until handlified.
+  MUST_USE_RESULT virtual Handle<Object> Get(
+      Handle<Object> receiver,
+      Handle<JSObject> holder,
+      uint32_t key,
+      Handle<FixedArrayBase> backing_store) {
+    CALL_HEAP_FUNCTION(holder->GetIsolate(),
+                       Get(*receiver, *holder, key,
+                           backing_store.is_null()
+                           ? NULL : *backing_store),
+                       Object);
+  }
+
   MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver,
                                            JSObject* holder,
                                            uint32_t key,
@@ -768,9 +781,10 @@
     return obj;
   }
 
-  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
-                                              uint32_t key,
-                                              JSReceiver::DeleteMode mode) = 0;
+  MUST_USE_RESULT virtual Handle<Object> Delete(
+      Handle<JSObject> obj,
+      uint32_t key,
+      JSReceiver::DeleteMode mode) = 0;
 
   MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
                                                        uint32_t from_start,
@@ -783,6 +797,21 @@
     return NULL;
   }
 
+  virtual void CopyElements(
+      Handle<JSObject> from_holder,
+      uint32_t from_start,
+      ElementsKind from_kind,
+      Handle<FixedArrayBase> to,
+      uint32_t to_start,
+      int copy_size,
+      Handle<FixedArrayBase> from) {
+    CALL_HEAP_FUNCTION_VOID(from_holder->GetIsolate(),
+                            CopyElements(
+                                from_holder.is_null() ? NULL : *from_holder,
+                                from_start, from_kind, *to, to_start, copy_size,
+                                from.is_null() ? NULL : *from));
+  }
+
   MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder,
                                                     uint32_t from_start,
                                                     ElementsKind from_kind,
@@ -999,42 +1028,38 @@
                        Object);
   }
 
-  static MaybeObject* DeleteCommon(JSObject* obj,
-                                   uint32_t key,
-                                   JSReceiver::DeleteMode mode) {
+  static Handle<Object> DeleteCommon(Handle<JSObject> obj,
+                                     uint32_t key,
+                                     JSReceiver::DeleteMode mode) {
     ASSERT(obj->HasFastSmiOrObjectElements() ||
            obj->HasFastDoubleElements() ||
            obj->HasFastArgumentsElements());
+    Isolate* isolate = obj->GetIsolate();
     Heap* heap = obj->GetHeap();
-    Object* elements = obj->elements();
-    if (elements == heap->empty_fixed_array()) {
-      return heap->true_value();
+    Handle<Object> elements = handle(obj->elements(), isolate);
+    if (*elements == heap->empty_fixed_array()) {
+      return isolate->factory()->true_value();
     }
-    typename KindTraits::BackingStore* backing_store =
-        KindTraits::BackingStore::cast(elements);
+    Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
     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));
+      backing_store = Handle<BackingStore>::cast(
+          handle(Handle<FixedArray>::cast(backing_store)->get(1), isolate));
     }
     uint32_t length = static_cast<uint32_t>(
         obj->IsJSArray()
-        ? Smi::cast(JSArray::cast(obj)->length())->value()
+        ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value()
         : backing_store->length());
     if (key < length) {
       if (!is_sloppy_arguments_elements_map) {
         ElementsKind kind = KindTraits::Kind;
         if (IsFastPackedElementsKind(kind)) {
-          MaybeObject* transitioned =
-              obj->TransitionElementsKind(GetHoleyElementsKind(kind));
-          if (transitioned->IsFailure()) return transitioned;
+          JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind));
         }
         if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
-          Object* writable;
-          MaybeObject* maybe = obj->EnsureWritableFastElements();
-          if (!maybe->ToObject(&writable)) return maybe;
-          backing_store = KindTraits::BackingStore::cast(writable);
+          Handle<Object> writable = JSObject::EnsureWritableFastElements(obj);
+          backing_store = Handle<BackingStore>::cast(writable);
         }
       }
       backing_store->set_the_hole(key);
@@ -1044,7 +1069,7 @@
       // one adjacent hole to the value being deleted.
       const int kMinLengthForSparsenessCheck = 64;
       if (backing_store->length() >= kMinLengthForSparsenessCheck &&
-          !heap->InNewSpace(backing_store) &&
+          !heap->InNewSpace(*backing_store) &&
           ((key > 0 && backing_store->is_the_hole(key - 1)) ||
            (key + 1 < length && backing_store->is_the_hole(key + 1)))) {
         int num_used = 0;
@@ -1054,17 +1079,16 @@
           if (4 * num_used > backing_store->length()) break;
         }
         if (4 * num_used <= backing_store->length()) {
-          MaybeObject* result = obj->NormalizeElements();
-          if (result->IsFailure()) return result;
+          JSObject::NormalizeElements(obj);
         }
       }
     }
-    return heap->true_value();
+    return isolate->factory()->true_value();
   }
 
-  virtual MaybeObject* Delete(JSObject* obj,
-                              uint32_t key,
-                              JSReceiver::DeleteMode mode) {
+  virtual Handle<Object> Delete(Handle<JSObject> obj,
+                                uint32_t key,
+                                JSReceiver::DeleteMode mode) {
     return DeleteCommon(obj, key, mode);
   }
 
@@ -1396,11 +1420,11 @@
     return obj;
   }
 
-  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
-                                              uint32_t key,
-                                              JSReceiver::DeleteMode mode) {
+  MUST_USE_RESULT virtual Handle<Object> Delete(Handle<JSObject> obj,
+                                                uint32_t key,
+                                                JSReceiver::DeleteMode mode) {
     // External arrays always ignore deletes.
-    return obj->GetHeap()->true_value();
+    return obj->GetIsolate()->factory()->true_value();
   }
 
   static bool HasElementImpl(Object* receiver,
@@ -1555,6 +1579,16 @@
     return heap->true_value();
   }
 
+  // TODO(ishell): Temporary wrapper until handlified.
+  MUST_USE_RESULT static Handle<Object> DeleteCommon(
+      Handle<JSObject> obj,
+      uint32_t key,
+      JSReceiver::DeleteMode mode) {
+    CALL_HEAP_FUNCTION(obj->GetIsolate(),
+                       DeleteCommon(*obj, key, mode),
+                       Object);
+  }
+
   MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
                                                        uint32_t from_start,
                                                        FixedArrayBase* to,
@@ -1571,9 +1605,9 @@
   friend class ElementsAccessorBase<DictionaryElementsAccessor,
                                     ElementsKindTraits<DICTIONARY_ELEMENTS> >;
 
-  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
-                                              uint32_t key,
-                                              JSReceiver::DeleteMode mode) {
+  MUST_USE_RESULT virtual Handle<Object> Delete(Handle<JSObject> obj,
+                                                uint32_t key,
+                                                JSReceiver::DeleteMode mode) {
     return DeleteCommon(obj, key, mode);
   }
 
@@ -1763,18 +1797,21 @@
     return obj;
   }
 
-  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
-                                              uint32_t key,
-                                              JSReceiver::DeleteMode mode) {
-    FixedArray* parameter_map = FixedArray::cast(obj->elements());
-    Object* probe = GetParameterMapArg(obj, parameter_map, key);
+  MUST_USE_RESULT virtual Handle<Object> Delete(Handle<JSObject> obj,
+                                                uint32_t key,
+                                                JSReceiver::DeleteMode mode) {
+    Isolate* isolate = obj->GetIsolate();
+    Handle<FixedArray> parameter_map =
+        handle(FixedArray::cast(obj->elements()), isolate);
+    Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
     if (!probe->IsTheHole()) {
       // TODO(kmillikin): We could check if this was the last aliased
       // parameter, and revert to normal elements in that case.  That
       // would enable GC of the context.
       parameter_map->set_the_hole(key + 2);
     } else {
-      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+      Handle<FixedArray> arguments =
+          handle(FixedArray::cast(parameter_map->get(1)), isolate);
       if (arguments->IsDictionary()) {
         return DictionaryElementsAccessor::DeleteCommon(obj, key, mode);
       } else {
@@ -1784,7 +1821,7 @@
         return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode);
       }
     }
-    return obj->GetHeap()->true_value();
+    return isolate->factory()->true_value();
   }
 
   MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
@@ -1827,6 +1864,7 @@
   }
 
  private:
+  // TODO(ishell): remove when all usages are handlified.
   static Object* GetParameterMapArg(JSObject* holder,
                                     FixedArray* parameter_map,
                                     uint32_t key) {
@@ -1837,6 +1875,18 @@
         ? parameter_map->get(key + 2)
         : parameter_map->GetHeap()->the_hole_value();
   }
+
+  static Handle<Object> GetParameterMapArg(Handle<JSObject> holder,
+                                           Handle<FixedArray> parameter_map,
+                                           uint32_t key) {
+    Isolate* isolate = holder->GetIsolate();
+    uint32_t length = holder->IsJSArray()
+        ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value()
+        : parameter_map->length();
+    return key < (length - 2)
+        ? handle(parameter_map->get(key + 2), isolate)
+        : Handle<Object>::cast(isolate->factory()->the_hole_value());
+  }
 };
 
 
diff --git a/src/elements.h b/src/elements.h
index 1353869..bd5e722 100644
--- a/src/elements.h
+++ b/src/elements.h
@@ -65,6 +65,13 @@
   // can optionally pass in the backing store to use for the check, which must
   // be compatible with the ElementsKind of the ElementsAccessor. If
   // backing_store is NULL, the holder->elements() is used as the backing store.
+  MUST_USE_RESULT virtual Handle<Object> Get(
+      Handle<Object> receiver,
+      Handle<JSObject> holder,
+      uint32_t key,
+      Handle<FixedArrayBase> backing_store =
+          Handle<FixedArrayBase>::null()) = 0;
+
   MUST_USE_RESULT virtual MaybeObject* Get(
       Object* receiver,
       JSObject* holder,
@@ -124,9 +131,10 @@
                                                             int length) = 0;
 
   // Deletes an element in an object, returning a new elements backing store.
-  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* holder,
-                                              uint32_t key,
-                                              JSReceiver::DeleteMode mode) = 0;
+  MUST_USE_RESULT virtual Handle<Object> Delete(
+      Handle<JSObject> holder,
+      uint32_t key,
+      JSReceiver::DeleteMode mode) = 0;
 
   // If kCopyToEnd is specified as the copy_size to CopyElements, it copies all
   // of elements from source after source_start to the destination array.
@@ -141,6 +149,14 @@
   // the source JSObject or JSArray in source_holder. If the holder's backing
   // store is available, it can be passed in source and source_holder is
   // ignored.
+  virtual void CopyElements(
+      Handle<JSObject> source_holder,
+      uint32_t source_start,
+      ElementsKind source_kind,
+      Handle<FixedArrayBase> destination,
+      uint32_t destination_start,
+      int copy_size,
+      Handle<FixedArrayBase> source = Handle<FixedArrayBase>::null()) = 0;
   MUST_USE_RESULT virtual MaybeObject* CopyElements(
       JSObject* source_holder,
       uint32_t source_start,
diff --git a/src/execution.cc b/src/execution.cc
index 924814c..1e0a6a8 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -819,10 +819,10 @@
   if (!data->do_not_cache()) {
     // Fast case: see if the function has already been instantiated
     int serial_number = Smi::cast(data->serial_number())->value();
-    Object* elm =
-        isolate->native_context()->function_cache()->
-            GetElementNoExceptionThrown(isolate, serial_number);
-    if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
+    Handle<JSObject> cache(isolate->native_context()->function_cache());
+    Handle<Object> elm =
+        Object::GetElementNoExceptionThrown(isolate, cache, serial_number);
+    if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm);
   }
   // The function has not yet been instantiated in this context; do it.
   Handle<Object> args[] = { data };
diff --git a/src/factory.cc b/src/factory.cc
index 57574d1..5577607 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -69,6 +69,14 @@
 }
 
 
+Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
+  CALL_HEAP_FUNCTION(
+      isolate(),
+      isolate()->heap()->AllocateUninitializedFixedArray(size),
+      FixedArray);
+}
+
+
 Handle<FixedDoubleArray> Factory::NewFixedDoubleArray(int size,
                                                       PretenureFlag pretenure) {
   ASSERT(0 <= size);
@@ -377,9 +385,7 @@
   // Make sure that an out of memory exception is thrown if the length
   // of the new cons string is too large.
   if (length > String::kMaxLength || length < 0) {
-    isolate()->context()->mark_out_of_memory();
-    V8::FatalProcessOutOfMemory("String concatenation result too large.");
-    UNREACHABLE();
+    isolate()->ThrowInvalidStringLength();
     return Handle<String>::null();
   }
 
@@ -1132,8 +1138,7 @@
       space--;
       if (space > 0) {
         Handle<String> arg_str = Handle<String>::cast(
-            Object::GetElement(isolate(), args, i));
-        CHECK_NOT_EMPTY_HANDLE(isolate(), arg_str);
+            Object::GetElementNoExceptionThrown(isolate(), args, i));
         SmartArrayPointer<char> arg = arg_str->ToCString();
         Vector<char> v2(p, static_cast<int>(space));
         OS::StrNCpy(v2, arg.get(), space);
diff --git a/src/factory.h b/src/factory.h
index f712880..22ec4d3 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -44,7 +44,7 @@
       Handle<Object> value,
       PretenureFlag pretenure = NOT_TENURED);
 
-  // Allocate a new uninitialized fixed array.
+  // Allocates a fixed array initialized with undefined values.
   Handle<FixedArray> NewFixedArray(
       int size,
       PretenureFlag pretenure = NOT_TENURED);
@@ -54,6 +54,9 @@
       int size,
       PretenureFlag pretenure = NOT_TENURED);
 
+  // Allocates an uninitialized fixed array. It must be filled by the caller.
+  Handle<FixedArray> NewUninitializedFixedArray(int size);
+
   // Allocate a new uninitialized fixed double array.
   Handle<FixedDoubleArray> NewFixedDoubleArray(
       int size,
diff --git a/src/func-name-inferrer.cc b/src/func-name-inferrer.cc
index 5409a4e..441113b 100644
--- a/src/func-name-inferrer.cc
+++ b/src/func-name-inferrer.cc
@@ -83,11 +83,14 @@
     return MakeNameFromStackHelper(pos + 1, prev);
   } else {
     if (prev->length() > 0) {
+      Handle<String> name = names_stack_.at(pos).name;
+      if (prev->length() + name->length() + 1 > String::kMaxLength) return prev;
       Factory* factory = isolate()->factory();
-      Handle<String> curr = factory->NewConsString(
-          factory->dot_string(), names_stack_.at(pos).name);
-      return MakeNameFromStackHelper(pos + 1,
-                                     factory->NewConsString(prev, curr));
+      Handle<String> curr = factory->NewConsString(factory->dot_string(), name);
+      CHECK_NOT_EMPTY_HANDLE(isolate(), curr);
+      curr = factory->NewConsString(prev, curr);
+      CHECK_NOT_EMPTY_HANDLE(isolate(), curr);
+      return MakeNameFromStackHelper(pos + 1, curr);
     } else {
       return MakeNameFromStackHelper(pos + 1, names_stack_.at(pos).name);
     }
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index b2f1708..66ce9e1 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1833,6 +1833,14 @@
       ClearFlag(kLeftCanBeMinInt);
     }
 
+    if (!a->CanBeNegative()) {
+      ClearFlag(HValue::kLeftCanBeNegative);
+    }
+
+    if (!a->CanBePositive()) {
+      ClearFlag(HValue::kLeftCanBePositive);
+    }
+
     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
       ClearFlag(kCanOverflow);
     }
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 5a6f4c2..109cff0 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -624,6 +624,7 @@
     kCanBeDivByZero,
     kLeftCanBeMinInt,
     kLeftCanBeNegative,
+    kLeftCanBePositive,
     kAllowUndefinedAsNaN,
     kIsArguments,
     kTruncatingToInt32,
@@ -4105,6 +4106,8 @@
     SetFlag(kCanOverflow);
     SetFlag(kCanBeDivByZero);
     SetFlag(kLeftCanBeMinInt);
+    SetFlag(kLeftCanBeNegative);
+    SetFlag(kLeftCanBePositive);
     SetFlag(kAllowUndefinedAsNaN);
   }
 
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index f6e22d8..282fae7 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1793,11 +1793,8 @@
                                              HValue* right_length) {
   // Compute the combined string length and check against max string length.
   HValue* length = AddUncasted<HAdd>(left_length, right_length);
-  IfBuilder if_nooverflow(this);
-  if_nooverflow.If<HCompareNumericAndBranch>(
-      length, Add<HConstant>(String::kMaxLength), Token::LTE);
-  if_nooverflow.Then();
-  if_nooverflow.ElseDeopt("String length exceeds limit");
+  HValue* max_length = Add<HConstant>(String::kMaxLength);
+  Add<HBoundsCheck>(length, max_length);
   return length;
 }
 
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 3e36d71..cd283cf 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1665,8 +1665,31 @@
     DeoptimizeIf(zero, instr->environment());
   }
 
-  // TODO(svenpanne) Add correction terms.
-  __ TruncatingDiv(dividend, divisor);
+  // Easy case: We need no dynamic check for the dividend and the flooring
+  // division is the same as the truncating division.
+  if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
+      (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
+    __ TruncatingDiv(dividend, Abs(divisor));
+    if (divisor < 0) __ neg(edx);
+    return;
+  }
+
+  // In the general case we may need to adjust before and after the truncating
+  // division to get a flooring division.
+  Register temp = ToRegister(instr->temp3());
+  ASSERT(!temp.is(dividend) && !temp.is(eax) && !temp.is(edx));
+  Label needs_adjustment, done;
+  __ cmp(dividend, Immediate(0));
+  __ j(divisor > 0 ? less : greater, &needs_adjustment, Label::kNear);
+  __ TruncatingDiv(dividend, Abs(divisor));
+  if (divisor < 0) __ neg(edx);
+  __ jmp(&done, Label::kNear);
+  __ bind(&needs_adjustment);
+  __ lea(temp, Operand(dividend, divisor > 0 ? 1 : -1));
+  __ TruncatingDiv(temp, Abs(divisor));
+  if (divisor < 0) __ neg(edx);
+  __ dec(edx);
+  __ bind(&done);
 }
 
 
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 930b7ed..de3bf9e 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1427,24 +1427,30 @@
   int32_t divisor = instr->right()->GetInteger32Constant();
   LOperand* temp1 = FixedTemp(eax);
   LOperand* temp2 = FixedTemp(edx);
+  LOperand* temp3 =
+      ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
+       (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
+      NULL : TempRegister();
   LInstruction* result =
       DefineFixed(new(zone()) LFlooringDivByConstI(dividend,
                                                    divisor,
                                                    temp1,
-                                                   temp2),
+                                                   temp2,
+                                                   temp3),
                   edx);
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
-  return can_deopt ? AssignEnvironment(result) : result;
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
   if (instr->RightIsPowerOf2()) {
     return DoFlooringDivByPowerOf2I(instr);
-  } else if (false && instr->right()->IsConstant()) {
-    return DoFlooringDivByConstI(instr);  // TODO(svenpanne) Fix and re-enable.
+  } else if (instr->right()->IsConstant()) {
+    return DoFlooringDivByConstI(instr);
   } else {
     return DoDivI(instr);
   }
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index fa4ea0f..7964b7f 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -778,22 +778,25 @@
 };
 
 
-class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
+class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 3> {
  public:
   LFlooringDivByConstI(LOperand* dividend,
                        int32_t divisor,
                        LOperand* temp1,
-                       LOperand* temp2) {
+                       LOperand* temp2,
+                       LOperand* temp3) {
     inputs_[0] = dividend;
     divisor_ = divisor;
     temps_[0] = temp1;
     temps_[1] = temp2;
+    temps_[2] = temp3;
   }
 
   LOperand* dividend() { return inputs_[0]; }
   int32_t divisor() const { return divisor_; }
   LOperand* temp1() { return temps_[0]; }
   LOperand* temp2() { return temps_[1]; }
+  LOperand* temp3() { return temps_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
   DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
diff --git a/src/ic.cc b/src/ic.cc
index 4924dbb..89bd87a 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1452,7 +1452,8 @@
     if (IsTransitionStoreMode(store_mode)) {
       transitioned_receiver_map = ComputeTransitionedMap(receiver, store_mode);
     }
-    if (receiver_map.is_identical_to(previous_receiver_map) ||
+    if ((receiver_map.is_identical_to(previous_receiver_map) &&
+         IsTransitionStoreMode(store_mode)) ||
         IsTransitionOfMonomorphicTarget(
             MapToType<HeapType>(transitioned_receiver_map, isolate()))) {
       // If the "old" and "new" maps are in the same elements map family, or
diff --git a/src/isolate.cc b/src/isolate.cc
index 50b402b..fed4b4a 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -951,6 +951,12 @@
 }
 
 
+Failure* Isolate::ThrowInvalidStringLength() {
+  return Throw(*factory()->NewRangeError(
+      "invalid_string_length", HandleVector<Object>(NULL, 0)));
+}
+
+
 void Isolate::ScheduleThrow(Object* exception) {
   // When scheduling a throw we first throw the exception to get the
   // error reporting if it is uncaught before rescheduling it.
diff --git a/src/isolate.h b/src/isolate.h
index d1f7003..0a24404 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -789,6 +789,7 @@
   // Return pending location if any or unfilled structure.
   MessageLocation GetMessageLocation();
   Failure* ThrowIllegalOperation();
+  Failure* ThrowInvalidStringLength();
 
   // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
   Failure* PromoteScheduledException();
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index 175b9a1..a75b3de 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -51,6 +51,8 @@
 
   enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW };
 
+  void Accumulate();
+
   void Extend();
 
   void ChangeEncoding();
@@ -178,6 +180,7 @@
   int current_index_;
   int part_length_;
   bool is_ascii_;
+  bool overflowed_;
 
   static const int kJsonEscapeTableEntrySize = 8;
   static const char* const JsonEscapeTable;
@@ -254,7 +257,10 @@
 
 
 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
-    : isolate_(isolate), current_index_(0), is_ascii_(true) {
+    : isolate_(isolate),
+      current_index_(0),
+      is_ascii_(true),
+      overflowed_(false) {
   factory_ = isolate_->factory();
   accumulator_store_ = Handle<JSValue>::cast(
                            factory_->ToObject(factory_->empty_string()));
@@ -269,9 +275,12 @@
   switch (SerializeObject(object)) {
     case UNCHANGED:
       return isolate_->heap()->undefined_value();
-    case SUCCESS:
+    case SUCCESS: {
       ShrinkCurrentPart();
-      return *factory_->NewConsString(accumulator(), current_part_);
+      Accumulate();
+      if (overflowed_) return isolate_->ThrowInvalidStringLength();
+      return *accumulator();
+    }
     case CIRCULAR:
       return isolate_->Throw(*factory_->NewTypeError(
                  "circular_structure", HandleVector<Object>(NULL, 0)));
@@ -486,7 +495,9 @@
   part_length_ = kInitialPartLength;  // Allocate conservatively.
   Extend();             // Attach current part and allocate new part.
   // Attach result string to the accumulator.
-  set_accumulator(factory_->NewConsString(accumulator(), result_string));
+  Handle<String> cons = factory_->NewConsString(accumulator(), result_string);
+  RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, cons, EXCEPTION);
+  set_accumulator(cons);
   return SUCCESS;
 }
 
@@ -708,8 +719,20 @@
 }
 
 
+void BasicJsonStringifier::Accumulate() {
+  if (accumulator()->length() + current_part_->length() > String::kMaxLength) {
+    // Screw it.  Simply set the flag and carry on.  Throw exception at the end.
+    // We most likely will trigger a real OOM before even reaching this point.
+    set_accumulator(factory_->empty_string());
+    overflowed_ = true;
+  } else {
+    set_accumulator(factory_->NewConsString(accumulator(), current_part_));
+  }
+}
+
+
 void BasicJsonStringifier::Extend() {
-  set_accumulator(factory_->NewConsString(accumulator(), current_part_));
+  Accumulate();
   if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
     part_length_ *= kPartLengthGrowthFactor;
   }
@@ -724,7 +747,7 @@
 
 void BasicJsonStringifier::ChangeEncoding() {
   ShrinkCurrentPart();
-  set_accumulator(factory_->NewConsString(accumulator(), current_part_));
+  Accumulate();
   current_part_ = factory_->NewRawTwoByteString(part_length_);
   current_index_ = 0;
   is_ascii_ = false;
diff --git a/src/liveedit.cc b/src/liveedit.cc
index aa906b2..a812b75 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -669,13 +669,13 @@
                      field_position,
                      Handle<Smi>(Smi::FromInt(value), isolate()));
   }
-  Object* GetField(int field_position) {
-    return array_->GetElementNoExceptionThrown(isolate(), field_position);
+  Handle<Object> GetField(int field_position) {
+    return Object::GetElementNoExceptionThrown(
+        isolate(), array_, field_position);
   }
   int GetSmiValueField(int field_position) {
-    Object* res = GetField(field_position);
-    CHECK(res->IsSmi());
-    return Smi::cast(res)->value();
+    Handle<Object> res = GetField(field_position);
+    return Handle<Smi>::cast(res)->value();
   }
 
  private:
@@ -724,17 +724,15 @@
     return this->GetSmiValueField(kParentIndexOffset_);
   }
   Handle<Code> GetFunctionCode() {
-    Object* element = this->GetField(kCodeOffset_);
-    CHECK(element->IsJSValue());
-    Handle<JSValue> value_wrapper(JSValue::cast(element));
+    Handle<Object> element = this->GetField(kCodeOffset_);
+    Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
     Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
     CHECK(raw_result->IsCode());
     return Handle<Code>::cast(raw_result);
   }
   Handle<Object> GetCodeScopeInfo() {
-    Object* element = this->GetField(kCodeScopeInfoOffset_);
-    CHECK(element->IsJSValue());
-    return UnwrapJSValue(Handle<JSValue>(JSValue::cast(element)));
+    Handle<Object> element = this->GetField(kCodeScopeInfoOffset_);
+    return UnwrapJSValue(Handle<JSValue>::cast(element));
   }
   int GetStartPosition() {
     return this->GetSmiValueField(kStartPositionOffset_);
@@ -767,8 +765,8 @@
  public:
   static bool IsInstance(Handle<JSArray> array) {
     return array->length() == Smi::FromInt(kSize_) &&
-        array->GetElementNoExceptionThrown(
-            array->GetIsolate(), kSharedInfoOffset_)->IsJSValue();
+        Object::GetElementNoExceptionThrown(
+            array->GetIsolate(), array, kSharedInfoOffset_)->IsJSValue();
   }
 
   explicit SharedInfoWrapper(Handle<JSArray> array)
@@ -785,9 +783,8 @@
     this->SetSmiValueField(kEndPositionOffset_, end_position);
   }
   Handle<SharedFunctionInfo> GetInfo() {
-    Object* element = this->GetField(kSharedInfoOffset_);
-    CHECK(element->IsJSValue());
-    Handle<JSValue> value_wrapper(JSValue::cast(element));
+    Handle<Object> element = this->GetField(kSharedInfoOffset_);
+    Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
     return UnwrapSharedFunctionInfoFromJSValue(value_wrapper);
   }
 
@@ -826,8 +823,8 @@
     HandleScope scope(isolate());
     FunctionInfoWrapper info =
         FunctionInfoWrapper::cast(
-            result_->GetElementNoExceptionThrown(
-                isolate(), current_parent_index_));
+            *Object::GetElementNoExceptionThrown(
+                isolate(), result_, current_parent_index_));
     current_parent_index_ = info.GetParentIndex();
   }
 
@@ -836,8 +833,8 @@
   void FunctionCode(Handle<Code> function_code) {
     FunctionInfoWrapper info =
         FunctionInfoWrapper::cast(
-            result_->GetElementNoExceptionThrown(
-                isolate(), current_parent_index_));
+            *Object::GetElementNoExceptionThrown(
+                isolate(), result_, current_parent_index_));
     info.SetFunctionCode(function_code,
                          Handle<HeapObject>(isolate()->heap()->null_value()));
   }
@@ -851,8 +848,8 @@
     }
     FunctionInfoWrapper info =
         FunctionInfoWrapper::cast(
-            result_->GetElementNoExceptionThrown(
-                isolate(), current_parent_index_));
+            *Object::GetElementNoExceptionThrown(
+                isolate(), result_, current_parent_index_));
     info.SetFunctionCode(Handle<Code>(shared->code()),
                          Handle<HeapObject>(shared->scope_info()));
     info.SetSharedFunctionInfo(shared);
@@ -987,7 +984,7 @@
   for (int i = 0; i < len; i++) {
     Handle<SharedFunctionInfo> info(
         SharedFunctionInfo::cast(
-            array->GetElementNoExceptionThrown(isolate, i)));
+            *Object::GetElementNoExceptionThrown(isolate, array, i)));
     SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(isolate);
     Handle<String> name_handle(String::cast(info->name()));
     info_wrapper.SetProperties(name_handle, info->start_position(),
@@ -1361,23 +1358,24 @@
   Isolate* isolate = position_change_array->GetIsolate();
   // TODO(635): binary search may be used here
   for (int i = 0; i < array_len; i += 3) {
-    Object* element =
-        position_change_array->GetElementNoExceptionThrown(isolate, i);
+    HandleScope scope(isolate);
+    Handle<Object> element = Object::GetElementNoExceptionThrown(
+        isolate, position_change_array, i);
     CHECK(element->IsSmi());
-    int chunk_start = Smi::cast(element)->value();
+    int chunk_start = Handle<Smi>::cast(element)->value();
     if (original_position < chunk_start) {
       break;
     }
-    element = position_change_array->GetElementNoExceptionThrown(isolate,
-                                                                 i + 1);
+    element = Object::GetElementNoExceptionThrown(
+        isolate, position_change_array, i + 1);
     CHECK(element->IsSmi());
-    int chunk_end = Smi::cast(element)->value();
+    int chunk_end = Handle<Smi>::cast(element)->value();
     // Position mustn't be inside a chunk.
     ASSERT(original_position >= chunk_end);
-    element = position_change_array->GetElementNoExceptionThrown(isolate,
-                                                                 i + 2);
+    element = Object::GetElementNoExceptionThrown(
+        isolate, position_change_array, i + 2);
     CHECK(element->IsSmi());
-    int chunk_changed_end = Smi::cast(element)->value();
+    int chunk_changed_end = Handle<Smi>::cast(element)->value();
     position_diff = chunk_changed_end - chunk_end;
   }
 
@@ -1472,7 +1470,6 @@
                                 code->instruction_start());
 
   {
-    DisallowHeapAllocation no_allocation;
     for (RelocIterator it(*code); !it.done(); it.next()) {
       RelocInfo* rinfo = it.rinfo();
       if (RelocInfo::IsPosition(rinfo->rmode())) {
@@ -1631,10 +1628,10 @@
   Isolate* isolate = shared_info_array->GetIsolate();
   int len = GetArrayLength(shared_info_array);
   for (int i = 0; i < len; i++) {
-    Object* element =
-        shared_info_array->GetElementNoExceptionThrown(isolate, i);
-    CHECK(element->IsJSValue());
-    Handle<JSValue> jsvalue(JSValue::cast(element));
+    HandleScope scope(isolate);
+    Handle<Object> element =
+        Object::GetElementNoExceptionThrown(isolate, shared_info_array, i);
+    Handle<JSValue> jsvalue = Handle<JSValue>::cast(element);
     Handle<SharedFunctionInfo> shared =
         UnwrapSharedFunctionInfoFromJSValue(jsvalue);
 
@@ -1949,8 +1946,8 @@
 
   // Replace "blocked on active" with "replaced on active" status.
   for (int i = 0; i < array_len; i++) {
-    Handle<Object> obj = Object::GetElement(isolate, result, i);
-    CHECK_NOT_EMPTY_HANDLE(isolate, obj);
+    Handle<Object> obj =
+        Object::GetElementNoExceptionThrown(isolate, result, i);
     if (*obj == Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
       Handle<Object> replaced(
           Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate);
diff --git a/src/log.cc b/src/log.cc
index e01692e..942170c 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -1206,9 +1206,9 @@
     if (c == '%' && i <= format.length() - 2) {
       i++;
       ASSERT('0' <= format[i] && format[i] <= '9');
-      Handle<Object> obj = Object::GetElement(isolate_, args, format[i] - '0');
       // No exception expected when getting an element from an array literal.
-      CHECK_NOT_EMPTY_HANDLE(isolate_, obj);
+      Handle<Object> obj =
+          Object::GetElementNoExceptionThrown(isolate_, args, format[i] - '0');
       i++;
       switch (format[i]) {
         case 's':
diff --git a/src/messages.js b/src/messages.js
index e6365a4..bc14785 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -157,7 +157,7 @@
   strict_eval_arguments:         ["Unexpected eval or arguments in strict mode"],
   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)"],
+  too_many_variables:            ["Too many variables declared (only 4194303 allowed)"],
   strict_param_dupe:             ["Strict mode function may not have duplicate parameter names"],
   strict_octal_literal:          ["Octal literals are not allowed in strict mode."],
   strict_duplicate_property:     ["Duplicate data property in object literal not allowed in strict mode"],
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 83f11e7..811b2f9 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1077,11 +1077,20 @@
 }
 
 
-Object* Object::GetElementNoExceptionThrown(Isolate* isolate, uint32_t index) {
-  MaybeObject* maybe = GetElementWithReceiver(isolate, this, index);
-  ASSERT(!maybe->IsFailure());
-  Object* result = NULL;  // Initialization to please compiler.
-  maybe->ToObject(&result);
+static Handle<Object> GetElementNoExceptionThrownHelper(Isolate* isolate,
+                                                        Handle<Object> object,
+                                                        uint32_t index) {
+  CALL_HEAP_FUNCTION(isolate,
+                     object->GetElementWithReceiver(isolate, *object, index),
+                     Object);
+}
+
+Handle<Object> Object::GetElementNoExceptionThrown(Isolate* isolate,
+                                                   Handle<Object> object,
+                                                   uint32_t index) {
+  Handle<Object> result =
+      GetElementNoExceptionThrownHelper(isolate, object, index);
+  CHECK_NOT_EMPTY_HANDLE(isolate, result);
   return result;
 }
 
diff --git a/src/objects.cc b/src/objects.cc
index 897c52a..88e7234 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -5103,18 +5103,6 @@
 }
 
 
-// TODO(mstarzinger): Temporary wrapper until handlified.
-static Handle<Object> AccessorDelete(Handle<JSObject> object,
-                                     uint32_t index,
-                                     JSObject::DeleteMode mode) {
-  CALL_HEAP_FUNCTION(object->GetIsolate(),
-                     object->GetElementsAccessor()->Delete(*object,
-                                                           index,
-                                                           mode),
-                     Object);
-}
-
-
 Handle<Object> JSObject::DeleteElementWithInterceptor(Handle<JSObject> object,
                                                       uint32_t index) {
   Isolate* isolate = object->GetIsolate();
@@ -5141,7 +5129,8 @@
     // Rebox CustomArguments::kReturnValueOffset before returning.
     return handle(*result_internal, isolate);
   }
-  Handle<Object> delete_result = AccessorDelete(object, index, NORMAL_DELETION);
+  Handle<Object> delete_result = object->GetElementsAccessor()->Delete(
+      object, index, NORMAL_DELETION);
   RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
   return delete_result;
 }
@@ -5190,8 +5179,7 @@
       if (object->GetLocalElementAccessorPair(index) != NULL) {
         old_value = Handle<Object>::cast(factory->the_hole_value());
       } else {
-        old_value = Object::GetElement(isolate, object, index);
-        CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
+        old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
       }
     }
   }
@@ -5201,7 +5189,7 @@
   if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
     result = DeleteElementWithInterceptor(object, index);
   } else {
-    result = AccessorDelete(object, index, mode);
+    result = object->GetElementsAccessor()->Delete(object, index, mode);
   }
 
   if (should_enqueue_change_record && !HasLocalElement(object, index)) {
@@ -6360,8 +6348,7 @@
     if (is_element) {
       preexists = HasLocalElement(object, index);
       if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
-        old_value = Object::GetElement(isolate, object, index);
-        CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
+        old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
       }
     } else {
       LookupResult lookup(isolate);
@@ -11343,8 +11330,7 @@
   if (object->GetLocalElementAccessorPair(index) != NULL) {
     value = Handle<Object>::cast(isolate->factory()->the_hole_value());
   } else {
-    value = Object::GetElement(isolate, object, index);
-    CHECK_NOT_EMPTY_HANDLE(isolate, value);
+    value = Object::GetElementNoExceptionThrown(isolate, object, index);
   }
   old_values->Add(value);
   indices->Add(index);
@@ -12564,8 +12550,7 @@
 
   if (old_attributes != ABSENT) {
     if (object->GetLocalElementAccessorPair(index) == NULL) {
-      old_value = Object::GetElement(isolate, object, index);
-      CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
+      old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
     }
   } else if (object->IsJSArray()) {
     // Store old array length in case adding an element grows the array.
@@ -12611,8 +12596,8 @@
   } else if (old_value->IsTheHole()) {
     EnqueueChangeRecord(object, "reconfigure", name, old_value);
   } else {
-    Handle<Object> new_value = Object::GetElement(isolate, object, index);
-    CHECK_NOT_EMPTY_HANDLE(isolate, new_value);
+    Handle<Object> new_value =
+        Object::GetElementNoExceptionThrown(isolate, object, index);
     bool value_changed = !old_value->SameValue(*new_value);
     if (old_attributes != new_attributes) {
       if (!value_changed) old_value = isolate->factory()->the_hole_value();
diff --git a/src/objects.h b/src/objects.h
index a87e389..25dbcbb 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1586,7 +1586,10 @@
                                           uint32_t index);
 
   // For use when we know that no exception can be thrown.
-  inline Object* GetElementNoExceptionThrown(Isolate* isolate, uint32_t index);
+  static inline Handle<Object> GetElementNoExceptionThrown(
+      Isolate* isolate,
+      Handle<Object> object,
+      uint32_t index);
   MUST_USE_RESULT MaybeObject* GetElementWithReceiver(Isolate* isolate,
                                                       Object* receiver,
                                                       uint32_t index);
diff --git a/src/parser.cc b/src/parser.cc
index 0d1ba00..9fe6a3b 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -2922,6 +2922,7 @@
         Factory* heap_factory = isolate()->factory();
         Handle<String> tempstr =
             heap_factory->NewConsString(heap_factory->dot_for_string(), name);
+        RETURN_IF_EMPTY_HANDLE_VALUE(isolate(), tempstr, 0);
         Handle<String> tempname = heap_factory->InternalizeString(tempstr);
         Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname);
         VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
diff --git a/src/parser.h b/src/parser.h
index 3d2f032..f3984e8 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -618,7 +618,14 @@
  private:
   friend class ParserTraits;
 
-  static const int kMaxNumFunctionLocals = 131071;  // 2^17-1
+  // Limit the allowed number of local variables in a function. The hard limit
+  // is that offsets computed by FullCodeGenerator::StackOperand and similar
+  // functions are ints, and they should not overflow. In addition, accessing
+  // local variables creates user-controlled constants in the generated code,
+  // and we don't want too much user-controlled memory inside the code (this was
+  // the reason why this limit was introduced in the first place; see
+  // https://codereview.chromium.org/7003030/ ).
+  static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
 
   enum Mode {
     PARSE_LAZILY,
diff --git a/src/preparser.cc b/src/preparser.cc
index 398f327..474e642 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -874,7 +874,7 @@
         if (result.IsThis()) {
           result = Expression::ThisProperty();
         } else {
-          result = Expression::Default();
+          result = Expression::Property();
         }
         break;
       }
@@ -891,7 +891,7 @@
         if (result.IsThis()) {
           result = Expression::ThisProperty();
         } else {
-          result = Expression::Default();
+          result = Expression::Property();
         }
         break;
       }
@@ -913,13 +913,17 @@
   if (peek() == Token::NEW) {
     Consume(Token::NEW);
     ParseMemberWithNewPrefixesExpression(CHECK_OK);
+    Expression expression = Expression::Default();
     if (peek() == Token::LPAREN) {
       // NewExpression with arguments.
       ParseArguments(CHECK_OK);
-      // The expression can still continue with . or [ after the arguments.
-      ParseMemberExpressionContinuation(Expression::Default(), CHECK_OK);
+      // The expression can still continue with . or [ after the arguments. Here
+      // we need to transmit the "is valid left hand side" property of the
+      // expression.
+      expression =
+          ParseMemberExpressionContinuation(Expression::Default(), CHECK_OK);
     }
-    return Expression::Default();
+    return expression;
   }
   // No 'new' keyword.
   return ParseMemberExpression(ok);
@@ -980,7 +984,7 @@
         if (expression.IsThis()) {
           expression = Expression::ThisProperty();
         } else {
-          expression = Expression::Default();
+          expression = Expression::Property();
         }
         break;
       }
@@ -990,7 +994,7 @@
         if (expression.IsThis()) {
           expression = Expression::ThisProperty();
         } else {
-          expression = Expression::Default();
+          expression = Expression::Property();
         }
         break;
       }
@@ -1102,7 +1106,6 @@
 
     int end_position = scanner()->location().end_pos;
     CheckOctalLiteral(start_position, end_position, CHECK_OK);
-    return Expression::StrictFunction();
   }
 
   return Expression::Default();
diff --git a/src/preparser.h b/src/preparser.h
index 05ff972..b6d97f7 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -554,8 +554,8 @@
     return PreParserExpression(kThisPropertyExpression);
   }
 
-  static PreParserExpression StrictFunction() {
-    return PreParserExpression(kStrictFunctionExpression);
+  static PreParserExpression Property() {
+    return PreParserExpression(kPropertyExpression);
   }
 
   bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; }
@@ -576,7 +576,9 @@
 
   bool IsThisProperty() { return code_ == kThisPropertyExpression; }
 
-  bool IsStrictFunction() { return code_ == kStrictFunctionExpression; }
+  bool IsProperty() {
+    return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
+  }
 
   // Dummy implementation for making expression->AsCall() work (see below).
   PreParserExpression* operator->() { return this; }
@@ -590,9 +592,11 @@
   void set_index(int index) {}  // For YieldExpressions
 
  private:
-  // First two/three bits are used as flags.
-  // Bit 0 and 1 represent identifiers or strings literals, and are
-  // mutually exclusive, but can both be absent.
+  // Least significant 2 bits are used as flags. Bits 0 and 1 represent
+  // identifiers or strings literals, and are mutually exclusive, but can both
+  // be absent. If the expression is an identifier or a string literal, the
+  // other bits describe the type (see PreParserIdentifier::Type and string
+  // literal constants below).
   enum {
     kUnknownExpression = 0,
     // Identifiers
@@ -604,10 +608,11 @@
     kUseStrictString = kStringLiteralFlag | 8,
     kStringLiteralMask = kUseStrictString,
 
-    // Below here applies if neither identifier nor string literal.
-    kThisExpression = 4,
-    kThisPropertyExpression = 8,
-    kStrictFunctionExpression = 12
+    // Below here applies if neither identifier nor string literal. Reserve the
+    // 2 least significant bits for flags.
+    kThisExpression = 1 << 2,
+    kThisPropertyExpression = 2 << 2,
+    kPropertyExpression = 3 << 2
   };
 
   explicit PreParserExpression(int expression_code) : code_(expression_code) {}
@@ -830,8 +835,7 @@
 
   // Determine whether the expression is a valid assignment left-hand side.
   static bool IsValidLeftHandSide(PreParserExpression expression) {
-    // TODO(marja): check properly; for now, leave it to parser.
-    return true;
+    return expression.IsIdentifier() || expression.IsProperty();
   }
 
   static PreParserExpression MarkExpressionAsLValue(
diff --git a/src/runtime.cc b/src/runtime.cc
index 762b7a5..cc7942f 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -3330,7 +3330,8 @@
         array_builder_(heap->isolate(), estimated_part_count),
         subject_(subject),
         character_count_(0),
-        is_ascii_(subject->IsOneByteRepresentation()) {
+        is_ascii_(subject->IsOneByteRepresentation()),
+        overflowed_(false) {
     // Require a non-zero initial size. Ensures that doubling the size to
     // extend the array will work.
     ASSERT(estimated_part_count > 0);
@@ -3378,6 +3379,11 @@
 
 
   Handle<String> ToString() {
+    if (overflowed_) {
+      heap_->isolate()->ThrowInvalidStringLength();
+      return Handle<String>();
+    }
+
     if (array_builder_.length() == 0) {
       return heap_->isolate()->factory()->empty_string();
     }
@@ -3409,7 +3415,7 @@
 
   void IncrementCharacterCount(int by) {
     if (character_count_ > String::kMaxLength - by) {
-      V8::FatalProcessOutOfMemory("String.replace result too large.");
+      overflowed_ = true;
     }
     character_count_ += by;
   }
@@ -3436,6 +3442,7 @@
   Handle<String> subject_;
   int character_count_;
   bool is_ascii_;
+  bool overflowed_;
 };
 
 
@@ -4034,7 +4041,9 @@
                                capture_count,
                                global_cache.LastSuccessfulMatch());
 
-  return *(builder.ToString());
+  Handle<String> result = builder.ToString();
+  RETURN_IF_EMPTY_HANDLE(isolate, result);
+  return *result;
 }
 
 
@@ -4180,8 +4189,8 @@
                                        replace,
                                        found,
                                        recursion_limit - 1);
-    if (*found) return isolate->factory()->NewConsString(new_first, second);
     if (new_first.is_null()) return new_first;
+    if (*found) return isolate->factory()->NewConsString(new_first, second);
 
     Handle<String> new_second =
         StringReplaceOneCharWithString(isolate,
@@ -4190,8 +4199,8 @@
                                        replace,
                                        found,
                                        recursion_limit - 1);
-    if (*found) return isolate->factory()->NewConsString(first, new_second);
     if (new_second.is_null()) return new_second;
+    if (*found) return isolate->factory()->NewConsString(first, new_second);
 
     return subject;
   } else {
@@ -4200,6 +4209,7 @@
     *found = true;
     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
     Handle<String> cons1 = isolate->factory()->NewConsString(first, replace);
+    RETURN_IF_EMPTY_HANDLE_VALUE(isolate, cons1, Handle<String>());
     Handle<String> second =
         isolate->factory()->NewSubString(subject, index + 1, subject->length());
     return isolate->factory()->NewConsString(cons1, second);
@@ -4225,6 +4235,7 @@
                                                          &found,
                                                          kRecursionLimit);
   if (!result.is_null()) return *result;
+  if (isolate->has_pending_exception()) return Failure::Exception();
   return *StringReplaceOneCharWithString(isolate,
                                          FlattenGetString(subject),
                                          search,
@@ -6225,7 +6236,7 @@
   Handle<String> result = string->IsOneByteRepresentationUnderneath()
       ? URIEscape::Escape<uint8_t>(isolate, source)
       : URIEscape::Escape<uc16>(isolate, source);
-  if (result.is_null()) return Failure::OutOfMemoryException(0x12);
+  RETURN_IF_EMPTY_HANDLE(isolate, result);
   return *result;
 }
 
@@ -6359,9 +6370,9 @@
         int char_length = mapping->get(current, 0, chars);
         if (char_length == 0) char_length = 1;
         current_length += char_length;
-        if (current_length > Smi::kMaxValue) {
-          isolate->context()->mark_out_of_memory();
-          return Failure::OutOfMemoryException(0x13);
+        if (current_length > String::kMaxLength) {
+          AllowHeapAllocation allocate_error_and_return;
+          return isolate->ThrowInvalidStringLength();
         }
       }
       // Try again with the real length.  Return signed if we need
@@ -7016,7 +7027,9 @@
   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
   isolate->counters()->string_add_runtime()->Increment();
-  return *isolate->factory()->NewConsString(str1, str2);
+  Handle<String> result = isolate->factory()->NewConsString(str1, str2);
+  RETURN_IF_EMPTY_HANDLE(isolate, result);
+  return *result;
 }
 
 
@@ -7063,10 +7076,7 @@
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
-  if (!args[1]->IsSmi()) {
-    isolate->context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException(0x14);
-  }
+  if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
   int array_length = args.smi_at(1);
   CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
 
@@ -7140,8 +7150,7 @@
       return isolate->Throw(isolate->heap()->illegal_argument_string());
     }
     if (increment > String::kMaxLength - position) {
-      isolate->context()->mark_out_of_memory();
-      return Failure::OutOfMemoryException(0x15);
+      return isolate->ThrowInvalidStringLength();
     }
     position += increment;
   }
@@ -7176,20 +7185,15 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   ASSERT(args.length() == 3);
-  CONVERT_ARG_CHECKED(JSArray, array, 0);
-  if (!args[1]->IsSmi()) {
-    isolate->context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException(0x16);
-  }
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+  if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
   int array_length = args.smi_at(1);
-  CONVERT_ARG_CHECKED(String, separator, 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
+  RUNTIME_ASSERT(array->HasFastObjectElements());
 
-  if (!array->HasFastObjectElements()) {
-    return isolate->Throw(isolate->heap()->illegal_argument_string());
-  }
-  FixedArray* fixed_array = FixedArray::cast(array->elements());
+  Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
   if (fixed_array->length() < array_length) {
     array_length = fixed_array->length();
   }
@@ -7198,38 +7202,32 @@
     return isolate->heap()->empty_string();
   } else if (array_length == 1) {
     Object* first = fixed_array->get(0);
-    if (first->IsString()) return first;
+    RUNTIME_ASSERT(first->IsString());
+    return first;
   }
 
   int separator_length = separator->length();
   int max_nof_separators =
       (String::kMaxLength + separator_length - 1) / separator_length;
   if (max_nof_separators < (array_length - 1)) {
-      isolate->context()->mark_out_of_memory();
-      return Failure::OutOfMemoryException(0x17);
+    return isolate->ThrowInvalidStringLength();
   }
   int length = (array_length - 1) * separator_length;
   for (int i = 0; i < array_length; i++) {
     Object* element_obj = fixed_array->get(i);
-    if (!element_obj->IsString()) {
-      // TODO(1161): handle this case.
-      return isolate->Throw(isolate->heap()->illegal_argument_string());
-    }
+    RUNTIME_ASSERT(element_obj->IsString());
     String* element = String::cast(element_obj);
     int increment = element->length();
     if (increment > String::kMaxLength - length) {
-      isolate->context()->mark_out_of_memory();
-      return Failure::OutOfMemoryException(0x18);
+      return isolate->ThrowInvalidStringLength();
     }
     length += increment;
   }
 
-  Object* object;
-  { MaybeObject* maybe_object =
-        isolate->heap()->AllocateRawTwoByteString(length);
-    if (!maybe_object->ToObject(&object)) return maybe_object;
-  }
-  SeqTwoByteString* answer = SeqTwoByteString::cast(object);
+  Handle<SeqTwoByteString> answer =
+      isolate->factory()->NewRawTwoByteString(length);
+
+  DisallowHeapAllocation no_gc;
 
   uc16* sink = answer->GetChars();
 #ifdef DEBUG
@@ -7237,13 +7235,14 @@
 #endif
 
   String* first = String::cast(fixed_array->get(0));
+  String* seperator_raw = *separator;
   int first_length = first->length();
   String::WriteToFlat(first, sink, 0, first_length);
   sink += first_length;
 
   for (int i = 1; i < array_length; i++) {
     ASSERT(sink + separator_length <= end);
-    String::WriteToFlat(separator, sink, 0, separator_length);
+    String::WriteToFlat(seperator_raw, sink, 0, separator_length);
     sink += separator_length;
 
     String* element = String::cast(fixed_array->get(i));
@@ -7256,7 +7255,7 @@
 
   // Use %_FastAsciiArrayJoin instead.
   ASSERT(!answer->IsOneByteRepresentation());
-  return answer;
+  return *answer;
 }
 
 template <typename Char>
@@ -7357,9 +7356,7 @@
     // Throw an exception if the resulting string is too large. See
     // https://code.google.com/p/chromium/issues/detail?id=336820
     // for details.
-    return isolate->Throw(*isolate->factory()->
-                          NewRangeError("invalid_string_length",
-                                        HandleVector<Object>(NULL, 0)));
+    return isolate->ThrowInvalidStringLength();
   }
 
   if (is_ascii) {
@@ -13045,20 +13042,20 @@
 // args[1]: constructor function for instances to exclude (Mirror)
 // args[2]: the the maximum number of objects to return
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   ASSERT(args.length() == 3);
 
   // First perform a full GC in order to avoid references from dead objects.
-  isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
-                                     "%DebugReferencedBy");
+  Heap* heap = isolate->heap();
+  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugReferencedBy");
   // The heap iterator reserves the right to do a GC to make the heap iterable.
   // Due to the GC above we know it won't need to do that, but it seems cleaner
   // to get the heap iterator constructed before we start having unprotected
   // Object* locals that are not protected by handles.
 
   // Check parameters.
-  CONVERT_ARG_CHECKED(JSObject, target, 0);
-  Object* instance_filter = args[1];
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
+  Handle<Object> instance_filter = args.at<Object>(1);
   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
                  instance_filter->IsJSObject());
   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
@@ -13066,40 +13063,36 @@
 
 
   // Get the constructor function for context extension and arguments array.
-  JSObject* arguments_boilerplate =
-      isolate->context()->native_context()->sloppy_arguments_boilerplate();
-  JSFunction* arguments_function =
-      JSFunction::cast(arguments_boilerplate->map()->constructor());
+  Handle<JSObject> arguments_boilerplate(
+      isolate->context()->native_context()->sloppy_arguments_boilerplate());
+  Handle<JSFunction> arguments_function(
+      JSFunction::cast(arguments_boilerplate->map()->constructor()));
 
   // Get the number of referencing objects.
   int count;
-  Heap* heap = isolate->heap();
   HeapIterator heap_iterator(heap);
   count = DebugReferencedBy(&heap_iterator,
-                            target, instance_filter, max_references,
-                            NULL, 0, arguments_function);
+                            *target, *instance_filter, max_references,
+                            NULL, 0, *arguments_function);
 
   // Allocate an array to hold the result.
-  Object* object;
-  { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
-    if (!maybe_object->ToObject(&object)) return maybe_object;
-  }
-  FixedArray* instances = FixedArray::cast(object);
+  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
 
   // Fill the referencing objects.
   // AllocateFixedArray above does not make the heap non-iterable.
   ASSERT(heap->IsHeapIterable());
   HeapIterator heap_iterator2(heap);
   count = DebugReferencedBy(&heap_iterator2,
-                            target, instance_filter, max_references,
-                            instances, count, arguments_function);
+                            *target, *instance_filter, max_references,
+                            *instances, count, *arguments_function);
 
   // Return result as JS array.
-  Object* result;
-  MaybeObject* maybe_result = heap->AllocateJSObject(
+  Handle<JSFunction> constructor(
       isolate->context()->native_context()->array_function());
-  if (!maybe_result->ToObject(&result)) return maybe_result;
-  return JSArray::cast(result)->SetContent(instances);
+
+  Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
+  isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
+  return *result;
 }
 
 
@@ -13139,7 +13132,7 @@
 // args[0]: the constructor to find instances of
 // args[1]: the the maximum number of objects to return
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
-  SealHandleScope shs(isolate);
+  HandleScope scope(isolate);
   ASSERT(args.length() == 2);
 
   // First perform a full GC in order to avoid dead objects.
@@ -13147,7 +13140,7 @@
   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
 
   // Check parameters.
-  CONVERT_ARG_CHECKED(JSFunction, constructor, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
   RUNTIME_ASSERT(max_references >= 0);
 
@@ -13155,34 +13148,29 @@
   int count;
   HeapIterator heap_iterator(heap);
   count = DebugConstructedBy(&heap_iterator,
-                             constructor,
+                             *constructor,
                              max_references,
                              NULL,
                              0);
 
   // Allocate an array to hold the result.
-  Object* object;
-  { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
-    if (!maybe_object->ToObject(&object)) return maybe_object;
-  }
-  FixedArray* instances = FixedArray::cast(object);
+  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
 
-  ASSERT(isolate->heap()->IsHeapIterable());
+  ASSERT(heap->IsHeapIterable());
   // Fill the referencing objects.
   HeapIterator heap_iterator2(heap);
   count = DebugConstructedBy(&heap_iterator2,
-                             constructor,
+                             *constructor,
                              max_references,
-                             instances,
+                             *instances,
                              count);
 
   // Return result as JS array.
-  Object* result;
-  { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
+  Handle<JSFunction> array_function(
       isolate->context()->native_context()->array_function());
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
-  return JSArray::cast(result)->SetContent(instances);
+  Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
+  isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
+  return *result;
 }
 
 
diff --git a/src/uri.h b/src/uri.h
index ee1baeb..81ec0c5 100644
--- a/src/uri.h
+++ b/src/uri.h
@@ -264,7 +264,8 @@
       // We don't allow strings that are longer than a maximal length.
       ASSERT(String::kMaxLength < 0x7fffffff - 6);  // Cannot overflow.
       if (escaped_length > String::kMaxLength) {
-        isolate->context()->mark_out_of_memory();
+        AllowHeapAllocation allocate_error_and_return;
+        isolate->ThrowInvalidStringLength();
         return Handle<String>::null();
       }
     }
diff --git a/src/version.cc b/src/version.cc
index 9aa66c9..9dab767 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     25
-#define BUILD_NUMBER      21
+#define BUILD_NUMBER      22
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 49068e7..d1c893d 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1160,8 +1160,31 @@
     DeoptimizeIf(zero, instr->environment());
   }
 
-  // TODO(svenpanne) Add correction terms.
-  __ TruncatingDiv(dividend, divisor);
+  // Easy case: We need no dynamic check for the dividend and the flooring
+  // division is the same as the truncating division.
+  if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
+      (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
+    __ TruncatingDiv(dividend, Abs(divisor));
+    if (divisor < 0) __ negl(rdx);
+    return;
+  }
+
+  // In the general case we may need to adjust before and after the truncating
+  // division to get a flooring division.
+  Register temp = ToRegister(instr->temp3());
+  ASSERT(!temp.is(dividend) && !temp.is(rax) && !temp.is(rdx));
+  Label needs_adjustment, done;
+  __ cmpl(dividend, Immediate(0));
+  __ j(divisor > 0 ? less : greater, &needs_adjustment, Label::kNear);
+  __ TruncatingDiv(dividend, Abs(divisor));
+  if (divisor < 0) __ negl(rdx);
+  __ jmp(&done, Label::kNear);
+  __ bind(&needs_adjustment);
+  __ leal(temp, Operand(dividend, divisor > 0 ? 1 : -1));
+  __ TruncatingDiv(temp, Abs(divisor));
+  if (divisor < 0) __ negl(rdx);
+  __ decl(rdx);
+  __ bind(&done);
 }
 
 
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index aad9597..13df32c 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1349,24 +1349,30 @@
   int32_t divisor = instr->right()->GetInteger32Constant();
   LOperand* temp1 = FixedTemp(rax);
   LOperand* temp2 = FixedTemp(rdx);
+  LOperand* temp3 =
+      ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
+       (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
+      NULL : TempRegister();
   LInstruction* result =
       DefineFixed(new(zone()) LFlooringDivByConstI(dividend,
                                                    divisor,
                                                    temp1,
-                                                   temp2),
+                                                   temp2,
+                                                   temp3),
                   rdx);
-  bool can_deopt =
-      divisor == 0 ||
-      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
-  return can_deopt ? AssignEnvironment(result) : result;
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
   if (instr->RightIsPowerOf2()) {
     return DoFlooringDivByPowerOf2I(instr);
-  } else if (false && instr->right()->IsConstant()) {
-    return DoFlooringDivByConstI(instr);  // TODO(svenpanne) Fix and re-enable.
+  } else if (instr->right()->IsConstant()) {
+    return DoFlooringDivByConstI(instr);
   } else {
     return DoDivI(instr);
   }
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 8ae1319..cbe7a39 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -759,22 +759,25 @@
 };
 
 
-class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
+class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 3> {
  public:
   LFlooringDivByConstI(LOperand* dividend,
                        int32_t divisor,
                        LOperand* temp1,
-                       LOperand* temp2) {
+                       LOperand* temp2,
+                       LOperand* temp3) {
     inputs_[0] = dividend;
     divisor_ = divisor;
     temps_[0] = temp1;
     temps_[1] = temp2;
+    temps_[2] = temp3;
   }
 
   LOperand* dividend() { return inputs_[0]; }
   int32_t divisor() const { return divisor_; }
   LOperand* temp1() { return temps_[0]; }
-  LOperand* temp2() { return temps_[0]; }
+  LOperand* temp2() { return temps_[1]; }
+  LOperand* temp3() { return temps_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
   DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)