Update V8 to r4924 as required by WebKit r61871

Change-Id: Ic819dad0c1c9e035b8ffd306c96656ba87c5e85a
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 6292b58..29e168c 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -216,6 +216,71 @@
 }
 
 
+void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
+                         Condition cond) {
+  if (!CpuFeatures::IsSupported(ARMv7) || src2.is_single_instruction()) {
+    and_(dst, src1, src2, LeaveCC, cond);
+    return;
+  }
+  int32_t immediate = src2.immediate();
+  if (immediate == 0) {
+    mov(dst, Operand(0), LeaveCC, cond);
+    return;
+  }
+  if (IsPowerOf2(immediate + 1) && ((immediate & 1) != 0)) {
+    ubfx(dst, src1, 0, WhichPowerOf2(immediate + 1), cond);
+    return;
+  }
+  and_(dst, src1, src2, LeaveCC, cond);
+}
+
+
+void MacroAssembler::Ubfx(Register dst, Register src1, int lsb, int width,
+                          Condition cond) {
+  ASSERT(lsb < 32);
+  if (!CpuFeatures::IsSupported(ARMv7)) {
+    int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1);
+    and_(dst, src1, Operand(mask), LeaveCC, cond);
+    if (lsb != 0) {
+      mov(dst, Operand(dst, LSR, lsb), LeaveCC, cond);
+    }
+  } else {
+    ubfx(dst, src1, lsb, width, cond);
+  }
+}
+
+
+void MacroAssembler::Sbfx(Register dst, Register src1, int lsb, int width,
+                          Condition cond) {
+  ASSERT(lsb < 32);
+  if (!CpuFeatures::IsSupported(ARMv7)) {
+    int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1);
+    and_(dst, src1, Operand(mask), LeaveCC, cond);
+    int shift_up = 32 - lsb - width;
+    int shift_down = lsb + shift_up;
+    if (shift_up != 0) {
+      mov(dst, Operand(dst, LSL, shift_up), LeaveCC, cond);
+    }
+    if (shift_down != 0) {
+      mov(dst, Operand(dst, ASR, shift_down), LeaveCC, cond);
+    }
+  } else {
+    sbfx(dst, src1, lsb, width, cond);
+  }
+}
+
+
+void MacroAssembler::Bfc(Register dst, int lsb, int width, Condition cond) {
+  ASSERT(lsb < 32);
+  if (!CpuFeatures::IsSupported(ARMv7)) {
+    int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1);
+    bic(dst, dst, Operand(mask));
+  } else {
+    bfc(dst, lsb, width, cond);
+  }
+}
+
+
 void MacroAssembler::SmiJumpTable(Register index, Vector<Label*> targets) {
   // Empty the const pool.
   CheckConstPool(true, true);
@@ -245,31 +310,32 @@
 
 
 void MacroAssembler::RecordWriteHelper(Register object,
-                                       Register offset,
-                                       Register scratch) {
+                                       Operand offset,
+                                       Register scratch0,
+                                       Register scratch1) {
   if (FLAG_debug_code) {
     // Check that the object is not in new space.
     Label not_in_new_space;
-    InNewSpace(object, scratch, ne, &not_in_new_space);
+    InNewSpace(object, scratch1, ne, &not_in_new_space);
     Abort("new-space object passed to RecordWriteHelper");
     bind(&not_in_new_space);
   }
 
-  mov(ip, Operand(Page::kPageAlignmentMask));  // Load mask only once.
-
-  // Calculate region number.
-  add(offset, object, Operand(offset));  // Add offset into the object.
-  and_(offset, offset, Operand(ip));  // Offset into page of the object.
-  mov(offset, Operand(offset, LSR, Page::kRegionSizeLog2));
+  // Add offset into the object.
+  add(scratch0, object, offset);
 
   // Calculate page address.
-  bic(object, object, Operand(ip));
+  Bfc(object, 0, kPageSizeBits);
+
+  // Calculate region number.
+  Ubfx(scratch0, scratch0, Page::kRegionSizeLog2,
+       kPageSizeBits - Page::kRegionSizeLog2);
 
   // Mark region dirty.
-  ldr(scratch, MemOperand(object, Page::kDirtyFlagOffset));
+  ldr(scratch1, MemOperand(object, Page::kDirtyFlagOffset));
   mov(ip, Operand(1));
-  orr(scratch, scratch, Operand(ip, LSL, offset));
-  str(scratch, MemOperand(object, Page::kDirtyFlagOffset));
+  orr(scratch1, scratch1, Operand(ip, LSL, scratch0));
+  str(scratch1, MemOperand(object, Page::kDirtyFlagOffset));
 }
 
 
@@ -287,21 +353,23 @@
 // Will clobber 4 registers: object, offset, scratch, ip.  The
 // register 'object' contains a heap object pointer.  The heap object
 // tag is shifted away.
-void MacroAssembler::RecordWrite(Register object, Register offset,
-                                 Register scratch) {
+void MacroAssembler::RecordWrite(Register object,
+                                 Operand offset,
+                                 Register scratch0,
+                                 Register scratch1) {
   // The compiled code assumes that record write doesn't change the
   // context register, so we check that none of the clobbered
   // registers are cp.
-  ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp));
+  ASSERT(!object.is(cp) && !scratch0.is(cp) && !scratch1.is(cp));
 
   Label done;
 
   // First, test that the object is not in the new space.  We cannot set
   // region marks for new space pages.
-  InNewSpace(object, scratch, eq, &done);
+  InNewSpace(object, scratch0, eq, &done);
 
   // Record the actual write.
-  RecordWriteHelper(object, offset, scratch);
+  RecordWriteHelper(object, offset, scratch0, scratch1);
 
   bind(&done);
 
@@ -309,8 +377,8 @@
   // turned on to provoke errors.
   if (FLAG_debug_code) {
     mov(object, Operand(BitCast<int32_t>(kZapValue)));
-    mov(offset, Operand(BitCast<int32_t>(kZapValue)));
-    mov(scratch, Operand(BitCast<int32_t>(kZapValue)));
+    mov(scratch0, Operand(BitCast<int32_t>(kZapValue)));
+    mov(scratch1, Operand(BitCast<int32_t>(kZapValue)));
   }
 }
 
@@ -1460,6 +1528,16 @@
 }
 
 
+void MacroAssembler::AssertRegisterIsRoot(Register reg,
+                                          Heap::RootListIndex index) {
+  if (FLAG_debug_code) {
+    LoadRoot(ip, index);
+    cmp(reg, ip);
+    Check(eq, "Register did not match expected root");
+  }
+}
+
+
 void MacroAssembler::Check(Condition cc, const char* msg) {
   Label L;
   b(cc, &L);
@@ -1578,6 +1656,7 @@
 void MacroAssembler::AllocateHeapNumber(Register result,
                                         Register scratch1,
                                         Register scratch2,
+                                        Register heap_number_map,
                                         Label* gc_required) {
   // Allocate an object in the heap for the heap number and tag it as a heap
   // object.
@@ -1588,9 +1667,9 @@
                      gc_required,
                      TAG_OBJECT);
 
-  // Get heap number map and store it in the allocated object.
-  LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex);
-  str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
+  // Store heap number map in the allocated object.
+  AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
+  str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
 }