Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / src / arm / assembler-arm.cc
index 297cdcc..96f28f9 100644 (file)
 // modified significantly by Google Inc.
 // Copyright 2012 the V8 project authors. All rights reserved.
 
-#include "v8.h"
+#include "src/v8.h"
 
 #if V8_TARGET_ARCH_ARM
 
-#include "arm/assembler-arm-inl.h"
-#include "macro-assembler.h"
-#include "serialize.h"
+#include "src/arm/assembler-arm-inl.h"
+#include "src/base/bits.h"
+#include "src/base/cpu.h"
+#include "src/macro-assembler.h"
+#include "src/serialize.h"
 
 namespace v8 {
 namespace internal {
 
-#ifdef DEBUG
-bool CpuFeatures::initialized_ = false;
-#endif
-unsigned CpuFeatures::supported_ = 0;
-unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
-unsigned CpuFeatures::cross_compile_ = 0;
-unsigned CpuFeatures::cache_line_size_ = 64;
-
-
-ExternalReference ExternalReference::cpu_features() {
-  ASSERT(CpuFeatures::initialized_);
-  return ExternalReference(&CpuFeatures::supported_);
-}
-
-
 // Get the CPU features enabled by the build. For cross compilation the
 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS
 // can be defined to enable ARMv7 and VFPv3 instructions when building the
@@ -67,19 +54,16 @@ ExternalReference ExternalReference::cpu_features() {
 static unsigned CpuFeaturesImpliedByCompiler() {
   unsigned answer = 0;
 #ifdef CAN_USE_ARMV7_INSTRUCTIONS
-  if (FLAG_enable_armv7) {
-    answer |= 1u << ARMv7;
-  }
+  if (FLAG_enable_armv7) answer |= 1u << ARMv7;
 #endif  // CAN_USE_ARMV7_INSTRUCTIONS
 #ifdef CAN_USE_VFP3_INSTRUCTIONS
-  if (FLAG_enable_vfp3) {
-    answer |= 1u << VFP3 | 1u << ARMv7;
-  }
+  if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7;
 #endif  // CAN_USE_VFP3_INSTRUCTIONS
 #ifdef CAN_USE_VFP32DREGS
-  if (FLAG_enable_32dregs) {
-    answer |= 1u << VFP32DREGS;
-  }
+  if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS;
+#endif  // CAN_USE_VFP32DREGS
+#ifdef CAN_USE_NEON
+  if (FLAG_enable_neon) answer |= 1u << NEON;
 #endif  // CAN_USE_VFP32DREGS
   if ((answer & (1u << ARMv7)) && FLAG_enable_unaligned_accesses) {
     answer |= 1u << UNALIGNED_ACCESSES;
@@ -89,178 +73,112 @@ static unsigned CpuFeaturesImpliedByCompiler() {
 }
 
 
-const char* DwVfpRegister::AllocationIndexToString(int index) {
-  ASSERT(index >= 0 && index < NumAllocatableRegisters());
-  ASSERT(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
-         kNumReservedRegisters - 1);
-  if (index >= kDoubleRegZero.code())
-    index += kNumReservedRegisters;
-
-  return VFPRegisters::Name(index, true);
-}
-
+void CpuFeatures::ProbeImpl(bool cross_compile) {
+  supported_ |= CpuFeaturesImpliedByCompiler();
+  cache_line_size_ = 64;
 
-void CpuFeatures::Probe() {
-  uint64_t standard_features = static_cast<unsigned>(
-      OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler();
-  ASSERT(supported_ == 0 || supported_ == standard_features);
-#ifdef DEBUG
-  initialized_ = true;
-#endif
-
-  // Get the features implied by the OS and the compiler settings. This is the
-  // minimal set of features which is also alowed for generated code in the
-  // snapshot.
-  supported_ |= standard_features;
-
-  if (Serializer::enabled()) {
-    // No probing for features if we might serialize (generate snapshot).
-    printf("   ");
-    PrintFeatures();
-    return;
-  }
+  // Only use statically determined features for cross compile (snapshot).
+  if (cross_compile) return;
 
 #ifndef __arm__
-  // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is
-  // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
-  if (FLAG_enable_vfp3) {
-    supported_ |=
-        static_cast<uint64_t>(1) << VFP3 |
-        static_cast<uint64_t>(1) << ARMv7;
-  }
-  if (FLAG_enable_neon) {
-    supported_ |= 1u << NEON;
-  }
-  // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled
+  // For the simulator build, use whatever the flags specify.
   if (FLAG_enable_armv7) {
-    supported_ |= static_cast<uint64_t>(1) << ARMv7;
-  }
-
-  if (FLAG_enable_sudiv) {
-    supported_ |= static_cast<uint64_t>(1) << SUDIV;
-  }
-
-  if (FLAG_enable_movw_movt) {
-    supported_ |= static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS;
-  }
-
-  if (FLAG_enable_32dregs) {
-    supported_ |= static_cast<uint64_t>(1) << VFP32DREGS;
-  }
-
-  if (FLAG_enable_unaligned_accesses) {
-    supported_ |= static_cast<uint64_t>(1) << UNALIGNED_ACCESSES;
+    supported_ |= 1u << ARMv7;
+    if (FLAG_enable_vfp3) supported_ |= 1u << VFP3;
+    if (FLAG_enable_neon) supported_ |= 1u << NEON | 1u << VFP32DREGS;
+    if (FLAG_enable_sudiv) supported_ |= 1u << SUDIV;
+    if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
+    if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS;
   }
+  if (FLAG_enable_mls) supported_ |= 1u << MLS;
+  if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
 
 #else  // __arm__
-  // Probe for additional features not already known to be available.
-  CPU cpu;
-  if (!IsSupported(VFP3) && FLAG_enable_vfp3 && cpu.has_vfp3()) {
+  // Probe for additional features at runtime.
+  base::CPU cpu;
+  if (FLAG_enable_vfp3 && cpu.has_vfp3()) {
     // This implementation also sets the VFP flags if runtime
     // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
     // 0406B, page A1-6.
-    found_by_runtime_probing_only_ |=
-        static_cast<uint64_t>(1) << VFP3 |
-        static_cast<uint64_t>(1) << ARMv7;
+    supported_ |= 1u << VFP3 | 1u << ARMv7;
   }
 
-  if (!IsSupported(NEON) && FLAG_enable_neon && cpu.has_neon()) {
-    found_by_runtime_probing_only_ |= 1u << NEON;
-  }
+  if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON;
+  if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV;
+  if (FLAG_enable_mls && cpu.has_thumb2()) supported_ |= 1u << MLS;
 
-  if (!IsSupported(ARMv7) && FLAG_enable_armv7 && cpu.architecture() >= 7) {
-    found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << ARMv7;
-  }
-
-  if (!IsSupported(SUDIV) && FLAG_enable_sudiv && cpu.has_idiva()) {
-    found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << SUDIV;
-  }
-
-  if (!IsSupported(UNALIGNED_ACCESSES) && FLAG_enable_unaligned_accesses
-      && cpu.architecture() >= 7) {
-    found_by_runtime_probing_only_ |=
-        static_cast<uint64_t>(1) << UNALIGNED_ACCESSES;
-  }
-
-  // Use movw/movt for QUALCOMM ARMv7 cores.
-  if (cpu.implementer() == CPU::QUALCOMM &&
-      cpu.architecture() >= 7 &&
-      FLAG_enable_movw_movt) {
-    found_by_runtime_probing_only_ |=
-        static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS;
+  if (cpu.architecture() >= 7) {
+    if (FLAG_enable_armv7) supported_ |= 1u << ARMv7;
+    if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
+    // Use movw/movt for QUALCOMM ARMv7 cores.
+    if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) {
+      supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
+    }
   }
 
   // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines.
-  if (cpu.implementer() == CPU::ARM &&
-      (cpu.part() == CPU::ARM_CORTEX_A5 ||
-       cpu.part() == CPU::ARM_CORTEX_A9)) {
+  if (cpu.implementer() == base::CPU::ARM &&
+      (cpu.part() == base::CPU::ARM_CORTEX_A5 ||
+       cpu.part() == base::CPU::ARM_CORTEX_A9)) {
     cache_line_size_ = 32;
   }
 
-  if (!IsSupported(VFP32DREGS) && FLAG_enable_32dregs && cpu.has_vfp3_d32()) {
-    found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP32DREGS;
-  }
-
-  supported_ |= found_by_runtime_probing_only_;
+  if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS;
 #endif
 
-  // Assert that VFP3 implies ARMv7.
-  ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7));
+  DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7));
 }
 
 
 void CpuFeatures::PrintTarget() {
   const char* arm_arch = NULL;
-  const char* arm_test = "";
+  const char* arm_target_type = "";
+  const char* arm_no_probe = "";
   const char* arm_fpu = "";
   const char* arm_thumb = "";
   const char* arm_float_abi = NULL;
 
+#if !defined __arm__
+  arm_target_type = " simulator";
+#endif
+
+#if defined ARM_TEST_NO_FEATURE_PROBE
+  arm_no_probe = " noprobe";
+#endif
+
 #if defined CAN_USE_ARMV7_INSTRUCTIONS
   arm_arch = "arm v7";
 #else
   arm_arch = "arm v6";
 #endif
 
-#ifdef __arm__
-
-# ifdef ARM_TEST
-  arm_test = " test";
-# endif
-# if defined __ARM_NEON__
+#if defined CAN_USE_NEON
   arm_fpu = " neon";
-# elif defined CAN_USE_VFP3_INSTRUCTIONS
-  arm_fpu = " vfp3";
-# else
-  arm_fpu = " vfp2";
-# endif
-# if (defined __thumb__) || (defined __thumb2__)
-  arm_thumb = " thumb";
-# endif
-  arm_float_abi = OS::ArmUsingHardFloat() ? "hard" : "softfp";
-
-#else  // __arm__
-
-  arm_test = " simulator";
-# if defined CAN_USE_VFP3_INSTRUCTIONS
+#elif defined CAN_USE_VFP3_INSTRUCTIONS
 #  if defined CAN_USE_VFP32DREGS
   arm_fpu = " vfp3";
 #  else
   arm_fpu = " vfp3-d16";
 #  endif
-# else
+#else
   arm_fpu = " vfp2";
-# endif
-# if USE_EABI_HARDFLOAT == 1
+#endif
+
+#ifdef __arm__
+  arm_float_abi = base::OS::ArmUsingHardFloat() ? "hard" : "softfp";
+#elif USE_EABI_HARDFLOAT
   arm_float_abi = "hard";
-# else
+#else
   arm_float_abi = "softfp";
-# endif
+#endif
 
-#endif  // __arm__
+#if defined __arm__ && (defined __thumb__) || (defined __thumb2__)
+  arm_thumb = " thumb";
+#endif
 
-  printf("target%s %s%s%s %s\n",
-         arm_test, arm_arch, arm_fpu, arm_thumb, arm_float_abi);
+  printf("target%s%s %s%s%s %s\n",
+         arm_target_type, arm_no_probe, arm_arch, arm_fpu, arm_thumb,
+         arm_float_abi);
 }
 
 
@@ -276,7 +194,7 @@ void CpuFeatures::PrintFeatures() {
     CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
     CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
 #ifdef __arm__
-  bool eabi_hardfloat = OS::ArmUsingHardFloat();
+  bool eabi_hardfloat = base::OS::ArmUsingHardFloat();
 #elif USE_EABI_HARDFLOAT
   bool eabi_hardfloat = true;
 #else
@@ -287,6 +205,18 @@ void CpuFeatures::PrintFeatures() {
 
 
 // -----------------------------------------------------------------------------
+// Implementation of DwVfpRegister
+
+const char* DwVfpRegister::AllocationIndexToString(int index) {
+  DCHECK(index >= 0 && index < NumAllocatableRegisters());
+  DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
+         kNumReservedRegisters - 1);
+  if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters;
+  return VFPRegisters::Name(index, true);
+}
+
+
+// -----------------------------------------------------------------------------
 // Implementation of RelocInfo
 
 const int RelocInfo::kApplyMask = 0;
@@ -302,11 +232,7 @@ bool RelocInfo::IsCodedSpecially() {
 
 
 bool RelocInfo::IsInConstantPool() {
-  if (FLAG_enable_ool_constant_pool) {
-    return Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc_));
-  } else {
-    return Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_));
-  }
+  return Assembler::is_constant_pool_load(pc_);
 }
 
 
@@ -319,7 +245,7 @@ void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
   }
 
   // Indicate that code has changed.
-  CPU::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
+  CpuFeatures::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
 }
 
 
@@ -341,7 +267,7 @@ Operand::Operand(Handle<Object> handle) {
   // Verify all Objects referred by code are NOT in new space.
   Object* obj = *handle;
   if (obj->IsHeapObject()) {
-    ASSERT(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
+    DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
     imm32_ = reinterpret_cast<intptr_t>(handle.location());
     rmode_ = RelocInfo::EMBEDDED_OBJECT;
   } else {
@@ -353,7 +279,7 @@ Operand::Operand(Handle<Object> handle) {
 
 
 Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
-  ASSERT(is_uint5(shift_imm));
+  DCHECK(is_uint5(shift_imm));
 
   rm_ = rm;
   rs_ = no_reg;
@@ -366,7 +292,7 @@ Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
     shift_op = LSL;
   } else if (shift_op == RRX) {
     // encoded as ROR with shift_imm == 0
-    ASSERT(shift_imm == 0);
+    DCHECK(shift_imm == 0);
     shift_op_ = ROR;
     shift_imm_ = 0;
   }
@@ -374,7 +300,7 @@ Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {
 
 
 Operand::Operand(Register rm, ShiftOp shift_op, Register rs) {
-  ASSERT(shift_op != RRX);
+  DCHECK(shift_op != RRX);
   rm_ = rm;
   rs_ = no_reg;
   shift_op_ = shift_op;
@@ -401,7 +327,7 @@ MemOperand::MemOperand(Register rn, Register rm, AddrMode am) {
 
 MemOperand::MemOperand(Register rn, Register rm,
                        ShiftOp shift_op, int shift_imm, AddrMode am) {
-  ASSERT(is_uint5(shift_imm));
+  DCHECK(is_uint5(shift_imm));
   rn_ = rn;
   rm_ = rm;
   shift_op_ = shift_op;
@@ -411,7 +337,7 @@ MemOperand::MemOperand(Register rn, Register rm,
 
 
 NeonMemOperand::NeonMemOperand(Register rn, AddrMode am, int align) {
-  ASSERT((am == Offset) || (am == PostIndex));
+  DCHECK((am == Offset) || (am == PostIndex));
   rn_ = rn;
   rm_ = (am == Offset) ? pc : sp;
   SetAlignment(align);
@@ -473,10 +399,6 @@ NeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) {
 // -----------------------------------------------------------------------------
 // Specific instructions, constants, and masks.
 
-// add(sp, sp, 4) instruction (aka Pop())
-const Instr kPopInstruction =
-    al | PostIndex | 4 | LeaveCC | I | kRegister_sp_Code * B16 |
-        kRegister_sp_Code * B12;
 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
 // register r is not encoded.
 const Instr kPushRegPattern =
@@ -485,14 +407,15 @@ const Instr kPushRegPattern =
 // register r is not encoded.
 const Instr kPopRegPattern =
     al | B26 | L | 4 | PostIndex | kRegister_sp_Code * B16;
-// mov lr, pc
-const Instr kMovLrPc = al | MOV | kRegister_pc_Code | kRegister_lr_Code * B12;
 // ldr rd, [pc, #offset]
-const Instr kLdrPCMask = 15 * B24 | 7 * B20 | 15 * B16;
-const Instr kLdrPCPattern = 5 * B24 | L | kRegister_pc_Code * B16;
+const Instr kLdrPCImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPCImmedPattern = 5 * B24 | L | kRegister_pc_Code * B16;
 // ldr rd, [pp, #offset]
-const Instr kLdrPpMask = 15 * B24 | 7 * B20 | 15 * B16;
-const Instr kLdrPpPattern = 5 * B24 | L | kRegister_r8_Code * B16;
+const Instr kLdrPpImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPpImmedPattern = 5 * B24 | L | kRegister_r8_Code * B16;
+// ldr rd, [pp, rn]
+const Instr kLdrPpRegMask = 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPpRegPattern = 7 * B24 | L | kRegister_r8_Code * B16;
 // vldr dd, [pc, #offset]
 const Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
 const Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8;
@@ -510,9 +433,13 @@ const Instr kMovMvnPattern = 0xd * B21;
 const Instr kMovMvnFlip = B22;
 const Instr kMovLeaveCCMask = 0xdff * B16;
 const Instr kMovLeaveCCPattern = 0x1a0 * B16;
-const Instr kMovwMask = 0xff * B20;
 const Instr kMovwPattern = 0x30 * B20;
+const Instr kMovtPattern = 0x34 * B20;
 const Instr kMovwLeaveCCFlip = 0x5 * B21;
+const Instr kMovImmedMask = 0x7f * B21;
+const Instr kMovImmedPattern = 0x1d * B21;
+const Instr kOrrImmedMask = 0x7f * B21;
+const Instr kOrrImmedPattern = 0x1c * B21;
 const Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12;
 const Instr kCmpCmnPattern = 0x15 * B20;
 const Instr kCmpCmnFlip = B21;
@@ -529,8 +456,6 @@ const Instr kLdrRegFpNegOffsetPattern =
 const Instr kStrRegFpNegOffsetPattern =
     al | B26 | NegOffset | kRegister_fp_Code * B16;
 const Instr kLdrStrInstrTypeMask = 0xffff0000;
-const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
-const Instr kLdrStrOffsetMask = 0x00000fff;
 
 
 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
@@ -548,13 +473,12 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
   first_const_pool_64_use_ = -1;
   last_bound_pos_ = 0;
   constant_pool_available_ = !FLAG_enable_ool_constant_pool;
-  constant_pool_full_ = false;
   ClearRecordedAstId();
 }
 
 
 Assembler::~Assembler() {
-  ASSERT(const_pool_blocked_nesting_ == 0);
+  DCHECK(const_pool_blocked_nesting_ == 0);
 }
 
 
@@ -562,8 +486,8 @@ void Assembler::GetCode(CodeDesc* desc) {
   if (!FLAG_enable_ool_constant_pool) {
     // Emit constant pool if necessary.
     CheckConstPool(true, false);
-    ASSERT(num_pending_32_bit_reloc_info_ == 0);
-    ASSERT(num_pending_64_bit_reloc_info_ == 0);
+    DCHECK(num_pending_32_bit_reloc_info_ == 0);
+    DCHECK(num_pending_64_bit_reloc_info_ == 0);
   }
   // Set up code descriptor.
   desc->buffer = buffer_;
@@ -575,7 +499,7 @@ void Assembler::GetCode(CodeDesc* desc) {
 
 
 void Assembler::Align(int m) {
-  ASSERT(m >= 4 && IsPowerOf2(m));
+  DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
   while ((pc_offset() & (m - 1)) != 0) {
     nop();
   }
@@ -599,7 +523,7 @@ bool Assembler::IsBranch(Instr instr) {
 
 
 int Assembler::GetBranchOffset(Instr instr) {
-  ASSERT(IsBranch(instr));
+  DCHECK(IsBranch(instr));
   // Take the jump offset in the lower 24 bits, sign extend it and multiply it
   // with 4 to get the offset in bytes.
   return ((instr & kImm24Mask) << 8) >> 6;
@@ -617,7 +541,7 @@ bool Assembler::IsVldrDRegisterImmediate(Instr instr) {
 
 
 int Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
-  ASSERT(IsLdrRegisterImmediate(instr));
+  DCHECK(IsLdrRegisterImmediate(instr));
   bool positive = (instr & B23) == B23;
   int offset = instr & kOff12Mask;  // Zero extended offset.
   return positive ? offset : -offset;
@@ -625,7 +549,7 @@ int Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
 
 
 int Assembler::GetVldrDRegisterImmediateOffset(Instr instr) {
-  ASSERT(IsVldrDRegisterImmediate(instr));
+  DCHECK(IsVldrDRegisterImmediate(instr));
   bool positive = (instr & B23) == B23;
   int offset = instr & kOff8Mask;  // Zero extended offset.
   offset <<= 2;
@@ -634,10 +558,10 @@ int Assembler::GetVldrDRegisterImmediateOffset(Instr instr) {
 
 
 Instr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsLdrRegisterImmediate(instr));
+  DCHECK(IsLdrRegisterImmediate(instr));
   bool positive = offset >= 0;
   if (!positive) offset = -offset;
-  ASSERT(is_uint12(offset));
+  DCHECK(is_uint12(offset));
   // Set bit indicating whether the offset should be added.
   instr = (instr & ~B23) | (positive ? B23 : 0);
   // Set the actual offset.
@@ -646,11 +570,11 @@ Instr Assembler::SetLdrRegisterImmediateOffset(Instr instr, int offset) {
 
 
 Instr Assembler::SetVldrDRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsVldrDRegisterImmediate(instr));
-  ASSERT((offset & ~3) == offset);  // Must be 64-bit aligned.
+  DCHECK(IsVldrDRegisterImmediate(instr));
+  DCHECK((offset & ~3) == offset);  // Must be 64-bit aligned.
   bool positive = offset >= 0;
   if (!positive) offset = -offset;
-  ASSERT(is_uint10(offset));
+  DCHECK(is_uint10(offset));
   // Set bit indicating whether the offset should be added.
   instr = (instr & ~B23) | (positive ? B23 : 0);
   // Set the actual offset. Its bottom 2 bits are zero.
@@ -664,10 +588,10 @@ bool Assembler::IsStrRegisterImmediate(Instr instr) {
 
 
 Instr Assembler::SetStrRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsStrRegisterImmediate(instr));
+  DCHECK(IsStrRegisterImmediate(instr));
   bool positive = offset >= 0;
   if (!positive) offset = -offset;
-  ASSERT(is_uint12(offset));
+  DCHECK(is_uint12(offset));
   // Set bit indicating whether the offset should be added.
   instr = (instr & ~B23) | (positive ? B23 : 0);
   // Set the actual offset.
@@ -681,9 +605,9 @@ bool Assembler::IsAddRegisterImmediate(Instr instr) {
 
 
 Instr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) {
-  ASSERT(IsAddRegisterImmediate(instr));
-  ASSERT(offset >= 0);
-  ASSERT(is_uint12(offset));
+  DCHECK(IsAddRegisterImmediate(instr));
+  DCHECK(offset >= 0);
+  DCHECK(is_uint12(offset));
   // Set the offset.
   return (instr & ~kOff12Mask) | offset;
 }
@@ -710,6 +634,24 @@ Register Assembler::GetRm(Instr instr) {
 }
 
 
+Instr Assembler::GetConsantPoolLoadPattern() {
+  if (FLAG_enable_ool_constant_pool) {
+    return kLdrPpImmedPattern;
+  } else {
+    return kLdrPCImmedPattern;
+  }
+}
+
+
+Instr Assembler::GetConsantPoolLoadMask() {
+  if (FLAG_enable_ool_constant_pool) {
+    return kLdrPpImmedMask;
+  } else {
+    return kLdrPCImmedMask;
+  }
+}
+
+
 bool Assembler::IsPush(Instr instr) {
   return ((instr & ~kRdMask) == kPushRegPattern);
 }
@@ -743,17 +685,27 @@ bool Assembler::IsLdrRegFpNegOffset(Instr instr) {
 bool Assembler::IsLdrPcImmediateOffset(Instr instr) {
   // Check the instruction is indeed a
   // ldr<cond> <Rd>, [pc +/- offset_12].
-  return (instr & kLdrPCMask) == kLdrPCPattern;
+  return (instr & kLdrPCImmedMask) == kLdrPCImmedPattern;
 }
 
 
 bool Assembler::IsLdrPpImmediateOffset(Instr instr) {
   // Check the instruction is indeed a
   // ldr<cond> <Rd>, [pp +/- offset_12].
-  return (instr & kLdrPpMask) == kLdrPpPattern;
+  return (instr & kLdrPpImmedMask) == kLdrPpImmedPattern;
+}
+
+
+bool Assembler::IsLdrPpRegOffset(Instr instr) {
+  // Check the instruction is indeed a
+  // ldr<cond> <Rd>, [pp, +/- <Rm>].
+  return (instr & kLdrPpRegMask) == kLdrPpRegPattern;
 }
 
 
+Instr Assembler::GetLdrPpRegOffsetPattern() { return kLdrPpRegPattern; }
+
+
 bool Assembler::IsVldrDPcImmediateOffset(Instr instr) {
   // Check the instruction is indeed a
   // vldr<cond> <Dd>, [pc +/- offset_10].
@@ -768,6 +720,20 @@ bool Assembler::IsVldrDPpImmediateOffset(Instr instr) {
 }
 
 
+bool Assembler::IsBlxReg(Instr instr) {
+  // Check the instruction is indeed a
+  // blxcc <Rm>
+  return (instr & kBlxRegMask) == kBlxRegPattern;
+}
+
+
+bool Assembler::IsBlxIp(Instr instr) {
+  // Check the instruction is indeed a
+  // blx ip
+  return instr == kBlxIp;
+}
+
+
 bool Assembler::IsTstImmediate(Instr instr) {
   return (instr & (B27 | B26 | I | kOpCodeMask | S | kRdMask)) ==
       (I | TST | S);
@@ -787,13 +753,13 @@ bool Assembler::IsCmpImmediate(Instr instr) {
 
 
 Register Assembler::GetCmpImmediateRegister(Instr instr) {
-  ASSERT(IsCmpImmediate(instr));
+  DCHECK(IsCmpImmediate(instr));
   return GetRn(instr);
 }
 
 
 int Assembler::GetCmpImmediateRawImmediate(Instr instr) {
-  ASSERT(IsCmpImmediate(instr));
+  DCHECK(IsCmpImmediate(instr));
   return instr & kOff12Mask;
 }
 
@@ -816,13 +782,13 @@ int Assembler::GetCmpImmediateRawImmediate(Instr instr) {
 // same position.
 
 
-int Assembler::target_at(int pos)  {
+int Assembler::target_at(int pos) {
   Instr instr = instr_at(pos);
   if (is_uint24(instr)) {
     // Emitted link to a label, not part of a branch.
     return instr;
   }
-  ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
+  DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
   int imm26 = ((instr & kImm24Mask) << 8) >> 6;
   if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
       ((instr & B24) != 0)) {
@@ -836,7 +802,7 @@ int Assembler::target_at(int pos)  {
 void Assembler::target_at_put(int pos, int target_pos) {
   Instr instr = instr_at(pos);
   if (is_uint24(instr)) {
-    ASSERT(target_pos == pos || target_pos >= 0);
+    DCHECK(target_pos == pos || target_pos >= 0);
     // Emitted link to a label, not part of a branch.
     // Load the position of the label relative to the generated code object
     // pointer in a register.
@@ -853,9 +819,9 @@ void Assembler::target_at_put(int pos, int target_pos) {
     // We extract the destination register from the emitted nop instruction.
     Register dst = Register::from_code(
         Instruction::RmValue(instr_at(pos + kInstrSize)));
-    ASSERT(IsNop(instr_at(pos + kInstrSize), dst.code()));
+    DCHECK(IsNop(instr_at(pos + kInstrSize), dst.code()));
     uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
-    ASSERT(is_uint24(target24));
+    DCHECK(is_uint24(target24));
     if (is_uint8(target24)) {
       // If the target fits in a byte then only patch with a mov
       // instruction.
@@ -904,17 +870,17 @@ void Assembler::target_at_put(int pos, int target_pos) {
     return;
   }
   int imm26 = target_pos - (pos + kPcLoadDelta);
-  ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
+  DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24
   if (Instruction::ConditionField(instr) == kSpecialCondition) {
     // blx uses bit 24 to encode bit 2 of imm26
-    ASSERT((imm26 & 1) == 0);
+    DCHECK((imm26 & 1) == 0);
     instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
   } else {
-    ASSERT((imm26 & 3) == 0);
+    DCHECK((imm26 & 3) == 0);
     instr &= ~kImm24Mask;
   }
   int imm24 = imm26 >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   instr_at_put(pos, instr | (imm24 & kImm24Mask));
 }
 
@@ -933,7 +899,7 @@ void Assembler::print(Label* L) {
       if ((instr & ~kImm24Mask) == 0) {
         PrintF("value\n");
       } else {
-        ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx
+        DCHECK((instr & 7*B25) == 5*B25);  // b, bl, or blx
         Condition cond = Instruction::ConditionField(instr);
         const char* b;
         const char* c;
@@ -978,7 +944,7 @@ void Assembler::print(Label* L) {
 
 
 void Assembler::bind_to(Label* L, int pos) {
-  ASSERT(0 <= pos && pos <= pc_offset());  // must have a valid binding position
+  DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
   while (L->is_linked()) {
     int fixup_pos = L->pos();
     next(L);  // call next before overwriting link with target at fixup_pos
@@ -994,20 +960,20 @@ void Assembler::bind_to(Label* L, int pos) {
 
 
 void Assembler::bind(Label* L) {
-  ASSERT(!L->is_bound());  // label can only be bound once
+  DCHECK(!L->is_bound());  // label can only be bound once
   bind_to(L, pc_offset());
 }
 
 
 void Assembler::next(Label* L) {
-  ASSERT(L->is_linked());
+  DCHECK(L->is_linked());
   int link = target_at(L->pos());
   if (link == L->pos()) {
     // Branch target points to the same instuction. This is the end of the link
     // chain.
     L->Unuse();
   } else {
-    ASSERT(link >= 0);
+    DCHECK(link >= 0);
     L->link_to(link);
   }
 }
@@ -1041,7 +1007,7 @@ static bool fits_shifter(uint32_t imm32,
         if (CpuFeatures::IsSupported(ARMv7)) {
           if (imm32 < 0x10000) {
             *instr ^= kMovwLeaveCCFlip;
-            *instr |= EncodeMovwImmediate(imm32);
+            *instr |= Assembler::EncodeMovwImmediate(imm32);
             *rotate_imm = *immed_8 = 0;  // Not used for movw.
             return true;
           }
@@ -1079,13 +1045,8 @@ static bool fits_shifter(uint32_t imm32,
 // encoded.
 bool Operand::must_output_reloc_info(const Assembler* assembler) const {
   if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
-    if (!Serializer::enabled()) {
-      Serializer::TooLateToEnableNow();
-    }
-#endif  // def DEBUG
     if (assembler != NULL && assembler->predictable_code_size()) return true;
-    return Serializer::enabled();
+    return assembler->serializer_enabled();
   } else if (RelocInfo::IsNone(rmode_)) {
     return false;
   }
@@ -1095,10 +1056,7 @@ bool Operand::must_output_reloc_info(const Assembler* assembler) const {
 
 static bool use_mov_immediate_load(const Operand& x,
                                    const Assembler* assembler) {
-  if (assembler != NULL && !assembler->can_use_constant_pool()) {
-    // If there is no constant pool available, we must use an mov immediate.
-    // TODO(rmcilroy): enable ARMv6 support.
-    ASSERT(CpuFeatures::IsSupported(ARMv7));
+  if (assembler != NULL && !assembler->is_constant_pool_available()) {
     return true;
   } else if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
              (assembler == NULL || !assembler->predictable_code_size())) {
@@ -1114,28 +1072,38 @@ static bool use_mov_immediate_load(const Operand& x,
 }
 
 
-bool Operand::is_single_instruction(const Assembler* assembler,
-                                    Instr instr) const {
-  if (rm_.is_valid()) return true;
+int Operand::instructions_required(const Assembler* assembler,
+                                   Instr instr) const {
+  if (rm_.is_valid()) return 1;
   uint32_t dummy1, dummy2;
   if (must_output_reloc_info(assembler) ||
       !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
     // The immediate operand cannot be encoded as a shifter operand, or use of
-    // constant pool is required. For a mov instruction not setting the
-    // condition code additional instruction conventions can be used.
-    if ((instr & ~kCondMask) == 13*B21) {  // mov, S not set
-      return !use_mov_immediate_load(*this, assembler);
+    // constant pool is required.  First account for the instructions required
+    // for the constant pool or immediate load
+    int instructions;
+    if (use_mov_immediate_load(*this, assembler)) {
+      // A movw / movt or mov / orr immediate load.
+      instructions = CpuFeatures::IsSupported(ARMv7) ? 2 : 4;
+    } else if (assembler != NULL && assembler->use_extended_constant_pool()) {
+      // An extended constant pool load.
+      instructions = CpuFeatures::IsSupported(ARMv7) ? 3 : 5;
     } else {
-      // If this is not a mov or mvn instruction there will always an additional
-      // instructions - either mov or ldr. The mov might actually be two
-      // instructions mov or movw followed by movt so including the actual
-      // instruction two or three instructions will be generated.
-      return false;
+      // A small constant pool load.
+      instructions = 1;
+    }
+
+    if ((instr & ~kCondMask) != 13 * B21) {  // mov, S not set
+      // For a mov or mvn instruction which doesn't set the condition
+      // code, the constant pool or immediate load is enough, otherwise we need
+      // to account for the actual instruction being requested.
+      instructions += 1;
     }
+    return instructions;
   } else {
     // No use of constant pool and the immediate operand can be encoded as a
     // shifter operand.
-    return true;
+    return 1;
   }
 }
 
@@ -1144,28 +1112,52 @@ void Assembler::move_32_bit_immediate(Register rd,
                                       const Operand& x,
                                       Condition cond) {
   RelocInfo rinfo(pc_, x.rmode_, x.imm32_, NULL);
+  uint32_t imm32 = static_cast<uint32_t>(x.imm32_);
   if (x.must_output_reloc_info(this)) {
     RecordRelocInfo(rinfo);
   }
 
   if (use_mov_immediate_load(x, this)) {
     Register target = rd.code() == pc.code() ? ip : rd;
-    // TODO(rmcilroy): add ARMv6 support for immediate loads.
-    ASSERT(CpuFeatures::IsSupported(ARMv7));
-    if (!FLAG_enable_ool_constant_pool && x.must_output_reloc_info(this)) {
-      // Make sure the movw/movt doesn't get separated.
-      BlockConstPoolFor(2);
+    if (CpuFeatures::IsSupported(ARMv7)) {
+      if (!FLAG_enable_ool_constant_pool && x.must_output_reloc_info(this)) {
+        // Make sure the movw/movt doesn't get separated.
+        BlockConstPoolFor(2);
+      }
+      movw(target, imm32 & 0xffff, cond);
+      movt(target, imm32 >> 16, cond);
+    } else {
+      DCHECK(FLAG_enable_ool_constant_pool);
+      mov(target, Operand(imm32 & kImm8Mask), LeaveCC, cond);
+      orr(target, target, Operand(imm32 & (kImm8Mask << 8)), LeaveCC, cond);
+      orr(target, target, Operand(imm32 & (kImm8Mask << 16)), LeaveCC, cond);
+      orr(target, target, Operand(imm32 & (kImm8Mask << 24)), LeaveCC, cond);
     }
-    emit(cond | 0x30*B20 | target.code()*B12 |
-         EncodeMovwImmediate(x.imm32_ & 0xffff));
-    movt(target, static_cast<uint32_t>(x.imm32_) >> 16, cond);
     if (target.code() != rd.code()) {
       mov(rd, target, LeaveCC, cond);
     }
   } else {
-    ASSERT(can_use_constant_pool());
-    ConstantPoolAddEntry(rinfo);
-    ldr(rd, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0), cond);
+    DCHECK(is_constant_pool_available());
+    ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
+    if (section == ConstantPoolArray::EXTENDED_SECTION) {
+      DCHECK(FLAG_enable_ool_constant_pool);
+      Register target = rd.code() == pc.code() ? ip : rd;
+      // Emit instructions to load constant pool offset.
+      if (CpuFeatures::IsSupported(ARMv7)) {
+        movw(target, 0, cond);
+        movt(target, 0, cond);
+      } else {
+        mov(target, Operand(0), LeaveCC, cond);
+        orr(target, target, Operand(0), LeaveCC, cond);
+        orr(target, target, Operand(0), LeaveCC, cond);
+        orr(target, target, Operand(0), LeaveCC, cond);
+      }
+      // Load from constant pool at offset.
+      ldr(rd, MemOperand(pp, target), cond);
+    } else {
+      DCHECK(section == ConstantPoolArray::SMALL_SECTION);
+      ldr(rd, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0), cond);
+    }
   }
 }
 
@@ -1175,7 +1167,7 @@ void Assembler::addrmod1(Instr instr,
                          Register rd,
                          const Operand& x) {
   CheckBuffer();
-  ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
+  DCHECK((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
   if (!x.rm_.is_valid()) {
     // Immediate.
     uint32_t rotate_imm;
@@ -1202,7 +1194,7 @@ void Assembler::addrmod1(Instr instr,
     instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
   } else {
     // Register shift.
-    ASSERT(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
+    DCHECK(!rn.is(pc) && !rd.is(pc) && !x.rm_.is(pc) && !x.rs_.is(pc));
     instr |= x.rs_.code()*B8 | x.shift_op_ | B4 | x.rm_.code();
   }
   emit(instr | rn.code()*B16 | rd.code()*B12);
@@ -1214,7 +1206,7 @@ void Assembler::addrmod1(Instr instr,
 
 
 void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
-  ASSERT((instr & ~(kCondMask | B | L)) == B26);
+  DCHECK((instr & ~(kCondMask | B | L)) == B26);
   int am = x.am_;
   if (!x.rm_.is_valid()) {
     // Immediate offset.
@@ -1226,28 +1218,28 @@ void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
     if (!is_uint12(offset_12)) {
       // Immediate offset cannot be encoded, load it first to register ip
       // rn (and rd in a load) should never be ip, or will be trashed.
-      ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
+      DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
       mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
       addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_));
       return;
     }
-    ASSERT(offset_12 >= 0);  // no masking needed
+    DCHECK(offset_12 >= 0);  // no masking needed
     instr |= offset_12;
   } else {
     // Register offset (shift_imm_ and shift_op_ are 0) or scaled
     // register offset the constructors make sure than both shift_imm_
     // and shift_op_ are initialized.
-    ASSERT(!x.rm_.is(pc));
+    DCHECK(!x.rm_.is(pc));
     instr |= B25 | x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
   }
-  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
+  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
   emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
 }
 
 
 void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
-  ASSERT((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
-  ASSERT(x.rn_.is_valid());
+  DCHECK((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
+  DCHECK(x.rn_.is_valid());
   int am = x.am_;
   if (!x.rm_.is_valid()) {
     // Immediate offset.
@@ -1259,60 +1251,60 @@ void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
     if (!is_uint8(offset_8)) {
       // Immediate offset cannot be encoded, load it first to register ip
       // rn (and rd in a load) should never be ip, or will be trashed.
-      ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
+      DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
       mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
       addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
       return;
     }
-    ASSERT(offset_8 >= 0);  // no masking needed
+    DCHECK(offset_8 >= 0);  // no masking needed
     instr |= B | (offset_8 >> 4)*B8 | (offset_8 & 0xf);
   } else if (x.shift_imm_ != 0) {
     // Scaled register offset not supported, load index first
     // rn (and rd in a load) should never be ip, or will be trashed.
-    ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
+    DCHECK(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
     mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
         Instruction::ConditionField(instr));
     addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
     return;
   } else {
     // Register offset.
-    ASSERT((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
+    DCHECK((am & (P|W)) == P || !x.rm_.is(pc));  // no pc index with writeback
     instr |= x.rm_.code();
   }
-  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
+  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
   emit(instr | am | x.rn_.code()*B16 | rd.code()*B12);
 }
 
 
 void Assembler::addrmod4(Instr instr, Register rn, RegList rl) {
-  ASSERT((instr & ~(kCondMask | P | U | W | L)) == B27);
-  ASSERT(rl != 0);
-  ASSERT(!rn.is(pc));
+  DCHECK((instr & ~(kCondMask | P | U | W | L)) == B27);
+  DCHECK(rl != 0);
+  DCHECK(!rn.is(pc));
   emit(instr | rn.code()*B16 | rl);
 }
 
 
 void Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
   // Unindexed addressing is not encoded by this function.
-  ASSERT_EQ((B27 | B26),
+  DCHECK_EQ((B27 | B26),
             (instr & ~(kCondMask | kCoprocessorMask | P | U | N | W | L)));
-  ASSERT(x.rn_.is_valid() && !x.rm_.is_valid());
+  DCHECK(x.rn_.is_valid() && !x.rm_.is_valid());
   int am = x.am_;
   int offset_8 = x.offset_;
-  ASSERT((offset_8 & 3) == 0);  // offset must be an aligned word offset
+  DCHECK((offset_8 & 3) == 0);  // offset must be an aligned word offset
   offset_8 >>= 2;
   if (offset_8 < 0) {
     offset_8 = -offset_8;
     am ^= U;
   }
-  ASSERT(is_uint8(offset_8));  // unsigned word offset must fit in a byte
-  ASSERT((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
+  DCHECK(is_uint8(offset_8));  // unsigned word offset must fit in a byte
+  DCHECK((am & (P|W)) == P || !x.rn_.is(pc));  // no pc base with writeback
 
   // Post-indexed addressing requires W == 1; different than in addrmod2/3.
   if ((am & P) == 0)
     am |= W;
 
-  ASSERT(offset_8 >= 0);  // no masking needed
+  DCHECK(offset_8 >= 0);  // no masking needed
   emit(instr | am | x.rn_.code()*B16 | crd.code()*B12 | offset_8);
 }
 
@@ -1341,9 +1333,9 @@ int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
 
 // Branch instructions.
 void Assembler::b(int branch_offset, Condition cond) {
-  ASSERT((branch_offset & 3) == 0);
+  DCHECK((branch_offset & 3) == 0);
   int imm24 = branch_offset >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   emit(cond | B27 | B25 | (imm24 & kImm24Mask));
 
   if (cond == al) {
@@ -1355,33 +1347,33 @@ void Assembler::b(int branch_offset, Condition cond) {
 
 void Assembler::bl(int branch_offset, Condition cond) {
   positions_recorder()->WriteRecordedPositions();
-  ASSERT((branch_offset & 3) == 0);
+  DCHECK((branch_offset & 3) == 0);
   int imm24 = branch_offset >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
 }
 
 
 void Assembler::blx(int branch_offset) {  // v5 and above
   positions_recorder()->WriteRecordedPositions();
-  ASSERT((branch_offset & 1) == 0);
+  DCHECK((branch_offset & 1) == 0);
   int h = ((branch_offset & 2) >> 1)*B24;
   int imm24 = branch_offset >> 2;
-  ASSERT(is_int24(imm24));
+  DCHECK(is_int24(imm24));
   emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
 }
 
 
 void Assembler::blx(Register target, Condition cond) {  // v5 and above
   positions_recorder()->WriteRecordedPositions();
-  ASSERT(!target.is(pc));
+  DCHECK(!target.is(pc));
   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
 }
 
 
 void Assembler::bx(Register target, Condition cond) {  // v5 and above, plus v4t
   positions_recorder()->WriteRecordedPositions();
-  ASSERT(!target.is(pc));  // use of pc is actually allowed, but discouraged
+  DCHECK(!target.is(pc));  // use of pc is actually allowed, but discouraged
   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
 }
 
@@ -1453,7 +1445,7 @@ void Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
 
 void Assembler::cmp_raw_immediate(
     Register src, int raw_immediate, Condition cond) {
-  ASSERT(is_uint12(raw_immediate));
+  DCHECK(is_uint12(raw_immediate));
   emit(cond | I | CMP | S | src.code() << 16 | raw_immediate);
 }
 
@@ -1476,7 +1468,7 @@ void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
   // Don't allow nop instructions in the form mov rn, rn to be generated using
   // the mov instruction. They must be generated using nop(int/NopMarkerTypes)
   // or MarkCode(int/NopMarkerTypes) pseudo instructions.
-  ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
+  DCHECK(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
   addrmod1(cond | MOV | s, r0, dst, src);
 }
 
@@ -1509,7 +1501,7 @@ void Assembler::mov_label_offset(Register dst, Label* label) {
     //
     // When the label gets bound: target_at extracts the link and target_at_put
     // patches the instructions.
-    ASSERT(is_uint24(link));
+    DCHECK(is_uint24(link));
     BlockConstPoolScope block_const_pool(this);
     emit(link);
     nop(dst.code());
@@ -1521,15 +1513,13 @@ void Assembler::mov_label_offset(Register dst, Label* label) {
 
 
 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
-  ASSERT(immediate < 0x10000);
-  // May use movw if supported, but on unsupported platforms will try to use
-  // equivalent rotated immed_8 value and other tricks before falling back to a
-  // constant pool load.
-  mov(reg, Operand(immediate), LeaveCC, cond);
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  emit(cond | 0x30*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
 }
 
 
 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
   emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
 }
 
@@ -1548,7 +1538,7 @@ void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
 // Multiply instructions.
 void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
                     SBit s, Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
   emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1556,7 +1546,8 @@ void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
 
 void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
                     Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
+  DCHECK(IsEnabled(MLS));
   emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1564,16 +1555,25 @@ void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
 
 void Assembler::sdiv(Register dst, Register src1, Register src2,
                      Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(IsEnabled(SUDIV));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(IsEnabled(SUDIV));
   emit(cond | B26 | B25| B24 | B20 | dst.code()*B16 | 0xf * B12 |
        src2.code()*B8 | B4 | src1.code());
 }
 
 
+void Assembler::udiv(Register dst, Register src1, Register src2,
+                     Condition cond) {
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(IsEnabled(SUDIV));
+  emit(cond | B26 | B25 | B24 | B21 | B20 | dst.code() * B16 | 0xf * B12 |
+       src2.code() * B8 | B4 | src1.code());
+}
+
+
 void Assembler::mul(Register dst, Register src1, Register src2,
                     SBit s, Condition cond) {
-  ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
   // dst goes in bits 16-19 for this instruction!
   emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1585,8 +1585,8 @@ void Assembler::smlal(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1598,8 +1598,8 @@ void Assembler::smull(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1611,8 +1611,8 @@ void Assembler::umlal(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1624,8 +1624,8 @@ void Assembler::umull(Register dstL,
                       Register src2,
                       SBit s,
                       Condition cond) {
-  ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
-  ASSERT(!dstL.is(dstH));
+  DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
+  DCHECK(!dstL.is(dstH));
   emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
        src2.code()*B8 | B7 | B4 | src1.code());
 }
@@ -1634,7 +1634,7 @@ void Assembler::umull(Register dstL,
 // Miscellaneous arithmetic instructions.
 void Assembler::clz(Register dst, Register src, Condition cond) {
   // v5 and above.
-  ASSERT(!dst.is(pc) && !src.is(pc));
+  DCHECK(!dst.is(pc) && !src.is(pc));
   emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
        15*B8 | CLZ | src.code());
 }
@@ -1648,11 +1648,11 @@ void Assembler::usat(Register dst,
                      const Operand& src,
                      Condition cond) {
   // v6 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.rm_.is(pc));
-  ASSERT((satpos >= 0) && (satpos <= 31));
-  ASSERT((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
-  ASSERT(src.rs_.is(no_reg));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.rm_.is(pc));
+  DCHECK((satpos >= 0) && (satpos <= 31));
+  DCHECK((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
+  DCHECK(src.rs_.is(no_reg));
 
   int sh = 0;
   if (src.shift_op_ == ASR) {
@@ -1676,10 +1676,10 @@ void Assembler::ubfx(Register dst,
                      int width,
                      Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 |
        lsb*B7 | B6 | B4 | src.code());
 }
@@ -1696,10 +1696,10 @@ void Assembler::sbfx(Register dst,
                      int width,
                      Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 |
        lsb*B7 | B6 | B4 | src.code());
 }
@@ -1711,10 +1711,10 @@ void Assembler::sbfx(Register dst,
 //   bfc dst, #lsb, #width
 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   int msb = lsb + width - 1;
   emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf);
 }
@@ -1730,10 +1730,10 @@ void Assembler::bfi(Register dst,
                     int width,
                     Condition cond) {
   // v7 and above.
-  ASSERT(CpuFeatures::IsSupported(ARMv7));
-  ASSERT(!dst.is(pc) && !src.is(pc));
-  ASSERT((lsb >= 0) && (lsb <= 31));
-  ASSERT((width >= 1) && (width <= (32 - lsb)));
+  DCHECK(CpuFeatures::IsSupported(ARMv7));
+  DCHECK(!dst.is(pc) && !src.is(pc));
+  DCHECK((lsb >= 0) && (lsb <= 31));
+  DCHECK((width >= 1) && (width <= (32 - lsb)));
   int msb = lsb + width - 1;
   emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
        src.code());
@@ -1747,13 +1747,13 @@ void Assembler::pkhbt(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.125.
   // cond(31-28) | 01101000(27-20) | Rn(19-16) |
   // Rd(15-12) | imm5(11-7) | 0(6) | 01(5-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src1.is(pc));
-  ASSERT(!src2.rm().is(pc));
-  ASSERT(!src2.rm().is(no_reg));
-  ASSERT(src2.rs().is(no_reg));
-  ASSERT((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
-  ASSERT(src2.shift_op() == LSL);
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.rm().is(pc));
+  DCHECK(!src2.rm().is(no_reg));
+  DCHECK(src2.rs().is(no_reg));
+  DCHECK((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
+  DCHECK(src2.shift_op() == LSL);
   emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
        src2.shift_imm_*B7 | B4 | src2.rm().code());
 }
@@ -1766,13 +1766,13 @@ void Assembler::pkhtb(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.125.
   // cond(31-28) | 01101000(27-20) | Rn(19-16) |
   // Rd(15-12) | imm5(11-7) | 1(6) | 01(5-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src1.is(pc));
-  ASSERT(!src2.rm().is(pc));
-  ASSERT(!src2.rm().is(no_reg));
-  ASSERT(src2.rs().is(no_reg));
-  ASSERT((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
-  ASSERT(src2.shift_op() == ASR);
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.rm().is(pc));
+  DCHECK(!src2.rm().is(no_reg));
+  DCHECK(src2.rs().is(no_reg));
+  DCHECK((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
+  DCHECK(src2.shift_op() == ASR);
   int asr = (src2.shift_imm_ == 32) ? 0 : src2.shift_imm_;
   emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
        asr*B7 | B6 | B4 | src2.rm().code());
@@ -1785,16 +1785,16 @@ void Assembler::uxtb(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.274.
   // cond(31-28) | 01101110(27-20) | 1111(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src.rm().is(pc));
-  ASSERT(!src.rm().is(no_reg));
-  ASSERT(src.rs().is(no_reg));
-  ASSERT((src.shift_imm_ == 0) ||
+  DCHECK(!dst.is(pc));
+  DCHECK(!src.rm().is(pc));
+  DCHECK(!src.rm().is(no_reg));
+  DCHECK(src.rs().is(no_reg));
+  DCHECK((src.shift_imm_ == 0) ||
          (src.shift_imm_ == 8) ||
          (src.shift_imm_ == 16) ||
          (src.shift_imm_ == 24));
   // Operand maps ROR #0 to LSL #0.
-  ASSERT((src.shift_op() == ROR) ||
+  DCHECK((src.shift_op() == ROR) ||
          ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
   emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
        ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
@@ -1808,17 +1808,17 @@ void Assembler::uxtab(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.271.
   // cond(31-28) | 01101110(27-20) | Rn(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src1.is(pc));
-  ASSERT(!src2.rm().is(pc));
-  ASSERT(!src2.rm().is(no_reg));
-  ASSERT(src2.rs().is(no_reg));
-  ASSERT((src2.shift_imm_ == 0) ||
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.rm().is(pc));
+  DCHECK(!src2.rm().is(no_reg));
+  DCHECK(src2.rs().is(no_reg));
+  DCHECK((src2.shift_imm_ == 0) ||
          (src2.shift_imm_ == 8) ||
          (src2.shift_imm_ == 16) ||
          (src2.shift_imm_ == 24));
   // Operand maps ROR #0 to LSL #0.
-  ASSERT((src2.shift_op() == ROR) ||
+  DCHECK((src2.shift_op() == ROR) ||
          ((src2.shift_op() == LSL) && (src2.shift_imm_ == 0)));
   emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
        ((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
@@ -1831,16 +1831,16 @@ void Assembler::uxtb16(Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.275.
   // cond(31-28) | 01101100(27-20) | 1111(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
-  ASSERT(!dst.is(pc));
-  ASSERT(!src.rm().is(pc));
-  ASSERT(!src.rm().is(no_reg));
-  ASSERT(src.rs().is(no_reg));
-  ASSERT((src.shift_imm_ == 0) ||
+  DCHECK(!dst.is(pc));
+  DCHECK(!src.rm().is(pc));
+  DCHECK(!src.rm().is(no_reg));
+  DCHECK(src.rs().is(no_reg));
+  DCHECK((src.shift_imm_ == 0) ||
          (src.shift_imm_ == 8) ||
          (src.shift_imm_ == 16) ||
          (src.shift_imm_ == 24));
   // Operand maps ROR #0 to LSL #0.
-  ASSERT((src.shift_op() == ROR) ||
+  DCHECK((src.shift_op() == ROR) ||
          ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
   emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
        ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
@@ -1849,14 +1849,14 @@ void Assembler::uxtb16(Register dst,
 
 // Status register access instructions.
 void Assembler::mrs(Register dst, SRegister s, Condition cond) {
-  ASSERT(!dst.is(pc));
+  DCHECK(!dst.is(pc));
   emit(cond | B24 | s | 15*B16 | dst.code()*B12);
 }
 
 
 void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
                     Condition cond) {
-  ASSERT(fields >= B16 && fields < B20);  // at least one field set
+  DCHECK(fields >= B16 && fields < B20);  // at least one field set
   Instr instr;
   if (!src.rm_.is_valid()) {
     // Immediate.
@@ -1871,7 +1871,7 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
     }
     instr = I | rotate_imm*B8 | immed_8;
   } else {
-    ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0);  // only rm allowed
+    DCHECK(!src.rs_.is_valid() && src.shift_imm_ == 0);  // only rm allowed
     instr = src.rm_.code();
   }
   emit(cond | instr | B24 | B21 | fields | 15*B12);
@@ -1924,22 +1924,22 @@ void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
 
 void Assembler::ldrd(Register dst1, Register dst2,
                      const MemOperand& src, Condition cond) {
-  ASSERT(IsEnabled(ARMv7));
-  ASSERT(src.rm().is(no_reg));
-  ASSERT(!dst1.is(lr));  // r14.
-  ASSERT_EQ(0, dst1.code() % 2);
-  ASSERT_EQ(dst1.code() + 1, dst2.code());
+  DCHECK(IsEnabled(ARMv7));
+  DCHECK(src.rm().is(no_reg));
+  DCHECK(!dst1.is(lr));  // r14.
+  DCHECK_EQ(0, dst1.code() % 2);
+  DCHECK_EQ(dst1.code() + 1, dst2.code());
   addrmod3(cond | B7 | B6 | B4, dst1, src);
 }
 
 
 void Assembler::strd(Register src1, Register src2,
                      const MemOperand& dst, Condition cond) {
-  ASSERT(dst.rm().is(no_reg));
-  ASSERT(!src1.is(lr));  // r14.
-  ASSERT_EQ(0, src1.code() % 2);
-  ASSERT_EQ(src1.code() + 1, src2.code());
-  ASSERT(IsEnabled(ARMv7));
+  DCHECK(dst.rm().is(no_reg));
+  DCHECK(!src1.is(lr));  // r14.
+  DCHECK_EQ(0, src1.code() % 2);
+  DCHECK_EQ(src1.code() + 1, src2.code());
+  DCHECK(IsEnabled(ARMv7));
   addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
 }
 
@@ -1949,15 +1949,15 @@ void Assembler::pld(const MemOperand& address) {
   // Instruction details available in ARM DDI 0406C.b, A8.8.128.
   // 1111(31-28) | 0111(27-24) | U(23) | R(22) | 01(21-20) | Rn(19-16) |
   // 1111(15-12) | imm5(11-07) | type(6-5) | 0(4)| Rm(3-0) |
-  ASSERT(address.rm().is(no_reg));
-  ASSERT(address.am() == Offset);
+  DCHECK(address.rm().is(no_reg));
+  DCHECK(address.am() == Offset);
   int U = B23;
   int offset = address.offset();
   if (offset < 0) {
     offset = -offset;
     U = 0;
   }
-  ASSERT(offset < 4096);
+  DCHECK(offset < 4096);
   emit(kSpecialCondition | B26 | B24 | U | B22 | B20 | address.rn().code()*B16 |
        0xf*B12 | offset);
 }
@@ -1969,7 +1969,7 @@ void Assembler::ldm(BlockAddrMode am,
                     RegList dst,
                     Condition cond) {
   // ABI stack constraint: ldmxx base, {..sp..}  base != sp  is not restartable.
-  ASSERT(base.is(sp) || (dst & sp.bit()) == 0);
+  DCHECK(base.is(sp) || (dst & sp.bit()) == 0);
 
   addrmod4(cond | B27 | am | L, base, dst);
 
@@ -1998,7 +1998,7 @@ void Assembler::stm(BlockAddrMode am,
 // enabling/disabling and a counter feature. See simulator-arm.h .
 void Assembler::stop(const char* msg, Condition cond, int32_t code) {
 #ifndef __arm__
-  ASSERT(code >= kDefaultStopCode);
+  DCHECK(code >= kDefaultStopCode);
   {
     // The Simulator will handle the stop instruction and get the message
     // address. It expects to find the address just after the svc instruction.
@@ -2024,13 +2024,13 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) {
 
 
 void Assembler::bkpt(uint32_t imm16) {  // v5 and above
-  ASSERT(is_uint16(imm16));
+  DCHECK(is_uint16(imm16));
   emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
 }
 
 
 void Assembler::svc(uint32_t imm24, Condition cond) {
-  ASSERT(is_uint24(imm24));
+  DCHECK(is_uint24(imm24));
   emit(cond | 15*B24 | imm24);
 }
 
@@ -2043,7 +2043,7 @@ void Assembler::cdp(Coprocessor coproc,
                     CRegister crm,
                     int opcode_2,
                     Condition cond) {
-  ASSERT(is_uint4(opcode_1) && is_uint3(opcode_2));
+  DCHECK(is_uint4(opcode_1) && is_uint3(opcode_2));
   emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 |
        crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code());
 }
@@ -2066,7 +2066,7 @@ void Assembler::mcr(Coprocessor coproc,
                     CRegister crm,
                     int opcode_2,
                     Condition cond) {
-  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
+  DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
   emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 |
        rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
 }
@@ -2089,7 +2089,7 @@ void Assembler::mrc(Coprocessor coproc,
                     CRegister crm,
                     int opcode_2,
                     Condition cond) {
-  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));
+  DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2));
   emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 |
        rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());
 }
@@ -2121,7 +2121,7 @@ void Assembler::ldc(Coprocessor coproc,
                     LFlag l,
                     Condition cond) {
   // Unindexed addressing.
-  ASSERT(is_uint8(option));
+  DCHECK(is_uint8(option));
   emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |
        coproc*B8 | (option & 255));
 }
@@ -2162,14 +2162,14 @@ void Assembler::vldr(const DwVfpRegister dst,
   int vd, d;
   dst.split_code(&vd, &d);
 
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
   if ((offset % 4) == 0 && (offset / 4) < 256) {
     emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 |
          0xB*B8 | ((offset / 4) & 255));
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2183,9 +2183,14 @@ void Assembler::vldr(const DwVfpRegister dst,
 void Assembler::vldr(const DwVfpRegister dst,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vldr(dst, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vldr(dst, ip, 0, cond);
+  } else {
+    vldr(dst, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2204,7 +2209,7 @@ void Assembler::vldr(const SwVfpRegister dst,
   }
   int sd, d;
   dst.split_code(&sd, &d);
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
 
   if ((offset % 4) == 0 && (offset / 4) < 256) {
   emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 |
@@ -2212,7 +2217,7 @@ void Assembler::vldr(const SwVfpRegister dst,
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2226,9 +2231,14 @@ void Assembler::vldr(const SwVfpRegister dst,
 void Assembler::vldr(const SwVfpRegister dst,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vldr(dst, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vldr(dst, ip, 0, cond);
+  } else {
+    vldr(dst, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2245,7 +2255,7 @@ void Assembler::vstr(const DwVfpRegister src,
     offset = -offset;
     u = 0;
   }
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
   int vd, d;
   src.split_code(&vd, &d);
 
@@ -2255,7 +2265,7 @@ void Assembler::vstr(const DwVfpRegister src,
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2269,9 +2279,14 @@ void Assembler::vstr(const DwVfpRegister src,
 void Assembler::vstr(const DwVfpRegister src,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vstr(src, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vstr(src, ip, 0, cond);
+  } else {
+    vstr(src, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2290,14 +2305,14 @@ void Assembler::vstr(const SwVfpRegister src,
   }
   int sd, d;
   src.split_code(&sd, &d);
-  ASSERT(offset >= 0);
+  DCHECK(offset >= 0);
   if ((offset % 4) == 0 && (offset / 4) < 256) {
     emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 |
          0xA*B8 | ((offset / 4) & 255));
   } else {
     // Larger offsets must be handled by computing the correct address
     // in the ip register.
-    ASSERT(!base.is(ip));
+    DCHECK(!base.is(ip));
     if (u == 1) {
       add(ip, base, Operand(offset));
     } else {
@@ -2311,9 +2326,14 @@ void Assembler::vstr(const SwVfpRegister src,
 void Assembler::vstr(const SwVfpRegister src,
                      const MemOperand& operand,
                      const Condition cond) {
-  ASSERT(!operand.rm().is_valid());
-  ASSERT(operand.am_ == Offset);
-  vstr(src, operand.rn(), operand.offset(), cond);
+  DCHECK(operand.am_ == Offset);
+  if (operand.rm().is_valid()) {
+    add(ip, operand.rn(),
+        Operand(operand.rm(), operand.shift_op_, operand.shift_imm_));
+    vstr(src, ip, 0, cond);
+  } else {
+    vstr(src, operand.rn(), operand.offset(), cond);
+  }
 }
 
 
@@ -2325,14 +2345,14 @@ void  Assembler::vldm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406C.b, A8-922.
   // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
   // first(15-12) | 1011(11-8) | (count * 2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
   int count = last.code() - first.code() + 1;
-  ASSERT(count <= 16);
+  DCHECK(count <= 16);
   emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 |
        0xB*B8 | count*2);
 }
@@ -2346,14 +2366,14 @@ void  Assembler::vstm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406C.b, A8-1080.
   // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
   // first(15-12) | 1011(11-8) | (count * 2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
   int count = last.code() - first.code() + 1;
-  ASSERT(count <= 16);
+  DCHECK(count <= 16);
   emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 |
        0xB*B8 | count*2);
 }
@@ -2366,9 +2386,9 @@ void  Assembler::vldm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406A, A8-626.
   // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) |
   // first(15-12) | 1010(11-8) | (count/2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
@@ -2386,9 +2406,9 @@ void  Assembler::vstm(BlockAddrMode am,
   // Instruction details available in ARM DDI 0406A, A8-784.
   // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) |
   // first(15-12) | 1011(11-8) | (count/2)
-  ASSERT_LE(first.code(), last.code());
-  ASSERT(am == ia || am == ia_w || am == db_w);
-  ASSERT(!base.is(pc));
+  DCHECK_LE(first.code(), last.code());
+  DCHECK(am == ia || am == ia_w || am == db_w);
+  DCHECK(!base.is(pc));
 
   int sd, d;
   first.split_code(&sd, &d);
@@ -2400,7 +2420,7 @@ void  Assembler::vstm(BlockAddrMode am,
 
 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
   uint64_t i;
-  OS::MemCopy(&i, &d, 8);
+  memcpy(&i, &d, 8);
 
   *lo = i & 0xffffffff;
   *hi = i >> 32;
@@ -2410,7 +2430,7 @@ static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
 // Only works for little endian floating point formats.
 // We don't support VFP on the mixed endian floating point platform.
 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
-  ASSERT(CpuFeatures::IsSupported(VFP3));
+  DCHECK(CpuFeatures::IsSupported(VFP3));
 
   // VMOV can accept an immediate of the form:
   //
@@ -2472,7 +2492,7 @@ void Assembler::vmov(const DwVfpRegister dst,
     int vd, d;
     dst.split_code(&vd, &d);
     emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc);
-  } else if (FLAG_enable_vldr_imm && can_use_constant_pool()) {
+  } else if (FLAG_enable_vldr_imm && is_constant_pool_available()) {
     // TODO(jfb) Temporarily turned off until we have constant blinding or
     //           some equivalent mitigation: an attacker can otherwise control
     //           generated data which also happens to be executable, a Very Bad
@@ -2489,8 +2509,18 @@ void Assembler::vmov(const DwVfpRegister dst,
     //           that's tricky because vldr has a limited reach. Furthermore
     //           it breaks load locality.
     RelocInfo rinfo(pc_, imm);
-    ConstantPoolAddEntry(rinfo);
-    vldr(dst, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0));
+    ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
+    if (section == ConstantPoolArray::EXTENDED_SECTION) {
+      DCHECK(FLAG_enable_ool_constant_pool);
+      // Emit instructions to load constant pool offset.
+      movw(ip, 0);
+      movt(ip, 0);
+      // Load from constant pool at offset.
+      vldr(dst, MemOperand(pp, ip));
+    } else {
+      DCHECK(section == ConstantPoolArray::SMALL_SECTION);
+      vldr(dst, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0));
+    }
   } else {
     // Synthesise the double from ARM immediates.
     uint32_t lo, hi;
@@ -2564,7 +2594,7 @@ void Assembler::vmov(const DwVfpRegister dst,
   // Instruction details available in ARM DDI 0406C.b, A8-940.
   // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) |
   // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(index.index == 0 || index.index == 1);
+  DCHECK(index.index == 0 || index.index == 1);
   int vd, d;
   dst.split_code(&vd, &d);
   emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 |
@@ -2580,7 +2610,7 @@ void Assembler::vmov(const Register dst,
   // Instruction details available in ARM DDI 0406C.b, A8.8.342.
   // cond(31-28) | 1110(27-24) | U=0(23) | opc1=0index(22-21) | 1(20) |
   // Vn(19-16) | Rt(15-12) | 1011(11-8) | N(7) | opc2=00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(index.index == 0 || index.index == 1);
+  DCHECK(index.index == 0 || index.index == 1);
   int vn, n;
   src.split_code(&vn, &n);
   emit(cond | 0xE*B24 | index.index*B21 | B20 | vn*B16 | dst.code()*B12 |
@@ -2596,7 +2626,7 @@ void Assembler::vmov(const DwVfpRegister dst,
   // Instruction details available in ARM DDI 0406C.b, A8-948.
   // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
   // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
-  ASSERT(!src1.is(pc) && !src2.is(pc));
+  DCHECK(!src1.is(pc) && !src2.is(pc));
   int vm, m;
   dst.split_code(&vm, &m);
   emit(cond | 0xC*B24 | B22 | src2.code()*B16 |
@@ -2612,7 +2642,7 @@ void Assembler::vmov(const Register dst1,
   // Instruction details available in ARM DDI 0406C.b, A8-948.
   // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
   // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
-  ASSERT(!dst1.is(pc) && !dst2.is(pc));
+  DCHECK(!dst1.is(pc) && !dst2.is(pc));
   int vm, m;
   src.split_code(&vm, &m);
   emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 |
@@ -2627,7 +2657,7 @@ void Assembler::vmov(const SwVfpRegister dst,
   // Instruction details available in ARM DDI 0406A, A8-642.
   // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) |
   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(!src.is(pc));
+  DCHECK(!src.is(pc));
   int sn, n;
   dst.split_code(&sn, &n);
   emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
@@ -2641,7 +2671,7 @@ void Assembler::vmov(const Register dst,
   // Instruction details available in ARM DDI 0406A, A8-642.
   // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) |
   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
-  ASSERT(!dst.is(pc));
+  DCHECK(!dst.is(pc));
   int sn, n;
   src.split_code(&sn, &n);
   emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
@@ -2702,7 +2732,7 @@ static void SplitRegCode(VFPType reg_type,
                          int reg_code,
                          int* vm,
                          int* m) {
-  ASSERT((reg_code >= 0) && (reg_code <= 31));
+  DCHECK((reg_code >= 0) && (reg_code <= 31));
   if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
     // 32 bit type.
     *m  = reg_code & 0x1;
@@ -2722,7 +2752,7 @@ static Instr EncodeVCVT(const VFPType dst_type,
                         const int src_code,
                         VFPConversionMode mode,
                         const Condition cond) {
-  ASSERT(src_type != dst_type);
+  DCHECK(src_type != dst_type);
   int D, Vd, M, Vm;
   SplitRegCode(src_type, src_code, &Vm, &M);
   SplitRegCode(dst_type, dst_code, &Vd, &D);
@@ -2732,7 +2762,7 @@ static Instr EncodeVCVT(const VFPType dst_type,
     // Instruction details available in ARM DDI 0406B, A8.6.295.
     // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 1(19) | opc2(18-16) |
     // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
-    ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
+    DCHECK(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
 
     int sz, opc2, op;
 
@@ -2741,7 +2771,7 @@ static Instr EncodeVCVT(const VFPType dst_type,
       sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
       op = mode;
     } else {
-      ASSERT(IsIntegerVFPType(src_type));
+      DCHECK(IsIntegerVFPType(src_type));
       opc2 = 0x0;
       sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
       op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
@@ -2823,12 +2853,13 @@ void Assembler::vcvt_f64_s32(const DwVfpRegister dst,
   // Instruction details available in ARM DDI 0406C.b, A8-874.
   // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 1010(19-16) | Vd(15-12) |
   // 101(11-9) | sf=1(8) | sx=1(7) | 1(6) | i(5) | 0(4) | imm4(3-0)
-  ASSERT(fraction_bits > 0 && fraction_bits <= 32);
-  ASSERT(CpuFeatures::IsSupported(VFP3));
+  DCHECK(fraction_bits > 0 && fraction_bits <= 32);
+  DCHECK(CpuFeatures::IsSupported(VFP3));
   int vd, d;
   dst.split_code(&vd, &d);
-  int i = ((32 - fraction_bits) >> 4) & 1;
-  int imm4 = (32 - fraction_bits) & 0xf;
+  int imm5 = 32 - fraction_bits;
+  int i = imm5 & 1;
+  int imm4 = (imm5 >> 1) & 0xf;
   emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 |
        vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4);
 }
@@ -3004,7 +3035,7 @@ void Assembler::vcmp(const DwVfpRegister src1,
   // Instruction details available in ARM DDI 0406C.b, A8-864.
   // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) |
   // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0)
-  ASSERT(src2 == 0.0);
+  DCHECK(src2 == 0.0);
   int vd, d;
   src1.split_code(&vd, &d);
   emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6);
@@ -3052,7 +3083,7 @@ void Assembler::vld1(NeonSize size,
   // Instruction details available in ARM DDI 0406C.b, A8.8.320.
   // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) |
   // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
-  ASSERT(CpuFeatures::IsSupported(NEON));
+  DCHECK(CpuFeatures::IsSupported(NEON));
   int vd, d;
   dst.base().split_code(&vd, &d);
   emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 |
@@ -3066,7 +3097,7 @@ void Assembler::vst1(NeonSize size,
   // Instruction details available in ARM DDI 0406C.b, A8.8.404.
   // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) |
   // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
-  ASSERT(CpuFeatures::IsSupported(NEON));
+  DCHECK(CpuFeatures::IsSupported(NEON));
   int vd, d;
   src.base().split_code(&vd, &d);
   emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 |
@@ -3078,7 +3109,7 @@ void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) {
   // Instruction details available in ARM DDI 0406C.b, A8.8.346.
   // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) |
   // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0)
-  ASSERT(CpuFeatures::IsSupported(NEON));
+  DCHECK(CpuFeatures::IsSupported(NEON));
   int vd, d;
   dst.split_code(&vd, &d);
   int vm, m;
@@ -3095,7 +3126,7 @@ void Assembler::nop(int type) {
   // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
   // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
   // a type.
-  ASSERT(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
+  DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
   emit(al | 13*B21 | type*B12 | type);
 }
 
@@ -3104,7 +3135,7 @@ bool Assembler::IsMovT(Instr instr) {
   instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
              ((kNumRegisters-1)*B12) |            // mask out register
              EncodeMovwImmediate(0xFFFF));        // mask out immediate value
-  return instr == 0x34*B20;
+  return instr == kMovtPattern;
 }
 
 
@@ -3112,17 +3143,63 @@ bool Assembler::IsMovW(Instr instr) {
   instr &= ~(((kNumberOfConditions - 1) << 28) |  // Mask off conditions
              ((kNumRegisters-1)*B12) |            // mask out destination
              EncodeMovwImmediate(0xFFFF));        // mask out immediate value
-  return instr == 0x30*B20;
+  return instr == kMovwPattern;
+}
+
+
+Instr Assembler::GetMovTPattern() { return kMovtPattern; }
+
+
+Instr Assembler::GetMovWPattern() { return kMovwPattern; }
+
+
+Instr Assembler::EncodeMovwImmediate(uint32_t immediate) {
+  DCHECK(immediate < 0x10000);
+  return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
+}
+
+
+Instr Assembler::PatchMovwImmediate(Instr instruction, uint32_t immediate) {
+  instruction &= ~EncodeMovwImmediate(0xffff);
+  return instruction | EncodeMovwImmediate(immediate);
+}
+
+
+int Assembler::DecodeShiftImm(Instr instr) {
+  int rotate = Instruction::RotateValue(instr) * 2;
+  int immed8 = Instruction::Immed8Value(instr);
+  return (immed8 >> rotate) | (immed8 << (32 - rotate));
+}
+
+
+Instr Assembler::PatchShiftImm(Instr instr, int immed) {
+  uint32_t rotate_imm = 0;
+  uint32_t immed_8 = 0;
+  bool immed_fits = fits_shifter(immed, &rotate_imm, &immed_8, NULL);
+  DCHECK(immed_fits);
+  USE(immed_fits);
+  return (instr & ~kOff12Mask) | (rotate_imm << 8) | immed_8;
 }
 
 
 bool Assembler::IsNop(Instr instr, int type) {
-  ASSERT(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
+  DCHECK(0 <= type && type <= 14);  // mov pc, pc isn't a nop.
   // Check for mov rx, rx where x = type.
   return instr == (al | 13*B21 | type*B12 | type);
 }
 
 
+bool Assembler::IsMovImmed(Instr instr) {
+  return (instr & kMovImmedMask) == kMovImmedPattern;
+}
+
+
+bool Assembler::IsOrrImmed(Instr instr) {
+  return (instr & kOrrImmedMask) == kOrrImmedPattern;
+}
+
+
+// static
 bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) {
   uint32_t dummy1;
   uint32_t dummy2;
@@ -3161,9 +3238,7 @@ void Assembler::RecordComment(const char* msg) {
 void Assembler::RecordConstPool(int size) {
   // We only need this for debugger support, to correctly compute offsets in the
   // code.
-#ifdef ENABLE_DEBUGGER_SUPPORT
   RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
-#endif
 }
 
 
@@ -3172,9 +3247,7 @@ void Assembler::GrowBuffer() {
 
   // Compute new buffer size.
   CodeDesc desc;  // the new buffer
-  if (buffer_size_ < 4*KB) {
-    desc.buffer_size = 4*KB;
-  } else if (buffer_size_ < 1*MB) {
+  if (buffer_size_ < 1 * MB) {
     desc.buffer_size = 2*buffer_size_;
   } else {
     desc.buffer_size = buffer_size_ + 1*MB;
@@ -3190,9 +3263,9 @@ void Assembler::GrowBuffer() {
   // Copy the data.
   int pc_delta = desc.buffer - buffer_;
   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
-  OS::MemMove(desc.buffer, buffer_, desc.instr_size);
-  OS::MemMove(reloc_info_writer.pos() + rc_delta,
-              reloc_info_writer.pos(), desc.reloc_size);
+  MemMove(desc.buffer, buffer_, desc.instr_size);
+  MemMove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
+          desc.reloc_size);
 
   // Switch buffers.
   DeleteArray(buffer_);
@@ -3209,7 +3282,7 @@ void Assembler::GrowBuffer() {
   // Relocate pending relocation entries.
   for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
     RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
-    ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
+    DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
            rinfo.rmode() != RelocInfo::POSITION);
     if (rinfo.rmode() != RelocInfo::JS_RETURN) {
       rinfo.set_pc(rinfo.pc() + pc_delta);
@@ -3217,7 +3290,7 @@ void Assembler::GrowBuffer() {
   }
   for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
     RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
-    ASSERT(rinfo.rmode() == RelocInfo::NONE64);
+    DCHECK(rinfo.rmode() == RelocInfo::NONE64);
     rinfo.set_pc(rinfo.pc() + pc_delta);
   }
   constant_pool_builder_.Relocate(pc_delta);
@@ -3228,8 +3301,8 @@ void Assembler::db(uint8_t data) {
   // No relocation info should be pending while using db. db is used
   // to write pure data with no pointers and the constant pool should
   // be emitted before using db.
-  ASSERT(num_pending_32_bit_reloc_info_ == 0);
-  ASSERT(num_pending_64_bit_reloc_info_ == 0);
+  DCHECK(num_pending_32_bit_reloc_info_ == 0);
+  DCHECK(num_pending_64_bit_reloc_info_ == 0);
   CheckBuffer();
   *reinterpret_cast<uint8_t*>(pc_) = data;
   pc_ += sizeof(uint8_t);
@@ -3240,8 +3313,8 @@ void Assembler::dd(uint32_t data) {
   // No relocation info should be pending while using dd. dd is used
   // to write pure data with no pointers and the constant pool should
   // be emitted before using dd.
-  ASSERT(num_pending_32_bit_reloc_info_ == 0);
-  ASSERT(num_pending_64_bit_reloc_info_ == 0);
+  DCHECK(num_pending_32_bit_reloc_info_ == 0);
+  DCHECK(num_pending_64_bit_reloc_info_ == 0);
   CheckBuffer();
   *reinterpret_cast<uint32_t*>(pc_) = data;
   pc_ += sizeof(uint32_t);
@@ -3265,17 +3338,11 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
 void Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
   if (!RelocInfo::IsNone(rinfo.rmode())) {
     // Don't record external references unless the heap will be serialized.
-    if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
-      if (!Serializer::enabled()) {
-        Serializer::TooLateToEnableNow();
-      }
-#endif
-      if (!Serializer::enabled() && !emit_debug_code()) {
-        return;
-      }
+    if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE &&
+        !serializer_enabled() && !emit_debug_code()) {
+      return;
     }
-    ASSERT(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
+    DCHECK(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
     if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) {
       RelocInfo reloc_info_with_ast_id(rinfo.pc(),
                                        rinfo.rmode(),
@@ -3290,18 +3357,19 @@ void Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
 }
 
 
-void Assembler::ConstantPoolAddEntry(const RelocInfo& rinfo) {
+ConstantPoolArray::LayoutSection Assembler::ConstantPoolAddEntry(
+    const RelocInfo& rinfo) {
   if (FLAG_enable_ool_constant_pool) {
-    constant_pool_builder_.AddEntry(this, rinfo);
+    return constant_pool_builder_.AddEntry(this, rinfo);
   } else {
     if (rinfo.rmode() == RelocInfo::NONE64) {
-      ASSERT(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo);
+      DCHECK(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo);
       if (num_pending_64_bit_reloc_info_ == 0) {
         first_const_pool_64_use_ = pc_offset();
       }
       pending_64_bit_reloc_info_[num_pending_64_bit_reloc_info_++] = rinfo;
     } else {
-      ASSERT(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo);
+      DCHECK(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo);
       if (num_pending_32_bit_reloc_info_ == 0) {
         first_const_pool_32_use_ = pc_offset();
       }
@@ -3310,6 +3378,7 @@ void Assembler::ConstantPoolAddEntry(const RelocInfo& rinfo) {
     // Make sure the constant pool is not emitted in place of the next
     // instruction for which we just recorded relocation info.
     BlockConstPoolFor(1);
+    return ConstantPoolArray::SMALL_SECTION;
   }
 }
 
@@ -3317,8 +3386,8 @@ void Assembler::ConstantPoolAddEntry(const RelocInfo& rinfo) {
 void Assembler::BlockConstPoolFor(int instructions) {
   if (FLAG_enable_ool_constant_pool) {
     // Should be a no-op if using an out-of-line constant pool.
-    ASSERT(num_pending_32_bit_reloc_info_ == 0);
-    ASSERT(num_pending_64_bit_reloc_info_ == 0);
+    DCHECK(num_pending_32_bit_reloc_info_ == 0);
+    DCHECK(num_pending_64_bit_reloc_info_ == 0);
     return;
   }
 
@@ -3327,10 +3396,10 @@ void Assembler::BlockConstPoolFor(int instructions) {
     // Max pool start (if we need a jump and an alignment).
 #ifdef DEBUG
     int start = pc_limit + kInstrSize + 2 * kPointerSize;
-    ASSERT((num_pending_32_bit_reloc_info_ == 0) ||
+    DCHECK((num_pending_32_bit_reloc_info_ == 0) ||
            (start - first_const_pool_32_use_ +
             num_pending_64_bit_reloc_info_ * kDoubleSize < kMaxDistToIntPool));
-    ASSERT((num_pending_64_bit_reloc_info_ == 0) ||
+    DCHECK((num_pending_64_bit_reloc_info_ == 0) ||
            (start - first_const_pool_64_use_ < kMaxDistToFPPool));
 #endif
     no_const_pool_before_ = pc_limit;
@@ -3345,8 +3414,8 @@ void Assembler::BlockConstPoolFor(int instructions) {
 void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
   if (FLAG_enable_ool_constant_pool) {
     // Should be a no-op if using an out-of-line constant pool.
-    ASSERT(num_pending_32_bit_reloc_info_ == 0);
-    ASSERT(num_pending_64_bit_reloc_info_ == 0);
+    DCHECK(num_pending_32_bit_reloc_info_ == 0);
+    DCHECK(num_pending_64_bit_reloc_info_ == 0);
     return;
   }
 
@@ -3355,7 +3424,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
   // BlockConstPoolScope.
   if (is_const_pool_blocked()) {
     // Something is wrong if emission is forced and blocked at the same time.
-    ASSERT(!force_emit);
+    DCHECK(!force_emit);
     return;
   }
 
@@ -3394,7 +3463,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
   //  * the instruction doesn't require a jump after itself to jump over the
   //    constant pool, and we're getting close to running out of range.
   if (!force_emit) {
-    ASSERT((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
+    DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
     bool need_emit = false;
     if (has_fp_values) {
       int dist64 = pc_offset() +
@@ -3444,15 +3513,15 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
     for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
       RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
 
-      ASSERT(!((uintptr_t)pc_ & 0x7));  // Check 64-bit alignment.
+      DCHECK(!((uintptr_t)pc_ & 0x7));  // Check 64-bit alignment.
 
       Instr instr = instr_at(rinfo.pc());
       // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
-      ASSERT((IsVldrDPcImmediateOffset(instr) &&
+      DCHECK((IsVldrDPcImmediateOffset(instr) &&
               GetVldrDRegisterImmediateOffset(instr) == 0));
 
       int delta = pc_ - rinfo.pc() - kPcLoadDelta;
-      ASSERT(is_uint10(delta));
+      DCHECK(is_uint10(delta));
 
       bool found = false;
       uint64_t value = rinfo.raw_data64();
@@ -3460,9 +3529,9 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
         RelocInfo& rinfo2 = pending_64_bit_reloc_info_[j];
         if (value == rinfo2.raw_data64()) {
           found = true;
-          ASSERT(rinfo2.rmode() == RelocInfo::NONE64);
+          DCHECK(rinfo2.rmode() == RelocInfo::NONE64);
           Instr instr2 = instr_at(rinfo2.pc());
-          ASSERT(IsVldrDPcImmediateOffset(instr2));
+          DCHECK(IsVldrDPcImmediateOffset(instr2));
           delta = GetVldrDRegisterImmediateOffset(instr2);
           delta += rinfo2.pc() - rinfo.pc();
           break;
@@ -3481,7 +3550,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
     // Emit 32-bit constant pool entries.
     for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
       RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
-      ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
+      DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
              rinfo.rmode() != RelocInfo::POSITION &&
              rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
              rinfo.rmode() != RelocInfo::CONST_POOL &&
@@ -3490,19 +3559,19 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
       Instr instr = instr_at(rinfo.pc());
 
       // 64-bit loads shouldn't get here.
-      ASSERT(!IsVldrDPcImmediateOffset(instr));
+      DCHECK(!IsVldrDPcImmediateOffset(instr));
 
       if (IsLdrPcImmediateOffset(instr) &&
           GetLdrRegisterImmediateOffset(instr) == 0) {
         int delta = pc_ - rinfo.pc() - kPcLoadDelta;
-        ASSERT(is_uint12(delta));
+        DCHECK(is_uint12(delta));
         // 0 is the smallest delta:
         //   ldr rd, [pc, #0]
         //   constant pool marker
         //   data
 
         bool found = false;
-        if (!Serializer::enabled() && (rinfo.rmode() >= RelocInfo::CELL)) {
+        if (!serializer_enabled() && rinfo.rmode() >= RelocInfo::CELL) {
           for (int j = 0; j < i; j++) {
             RelocInfo& rinfo2 = pending_32_bit_reloc_info_[j];
 
@@ -3525,7 +3594,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
           emit(rinfo.data());
         }
       } else {
-        ASSERT(IsMovW(instr));
+        DCHECK(IsMovW(instr));
       }
     }
 
@@ -3547,25 +3616,21 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
 }
 
 
-MaybeObject* Assembler::AllocateConstantPool(Heap* heap) {
-  ASSERT(FLAG_enable_ool_constant_pool);
-  return constant_pool_builder_.Allocate(heap);
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
+  if (!FLAG_enable_ool_constant_pool) {
+    return isolate->factory()->empty_constant_pool_array();
+  }
+  return constant_pool_builder_.New(isolate);
 }
 
 
 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
-  ASSERT(FLAG_enable_ool_constant_pool);
   constant_pool_builder_.Populate(this, constant_pool);
 }
 
 
 ConstantPoolBuilder::ConstantPoolBuilder()
-    : entries_(),
-      merged_indexes_(),
-      count_of_64bit_(0),
-      count_of_code_ptr_(0),
-      count_of_heap_ptr_(0),
-      count_of_32bit_(0) { }
+    : entries_(), current_section_(ConstantPoolArray::SMALL_SECTION) {}
 
 
 bool ConstantPoolBuilder::IsEmpty() {
@@ -3573,166 +3638,204 @@ bool ConstantPoolBuilder::IsEmpty() {
 }
 
 
-bool ConstantPoolBuilder::Is64BitEntry(RelocInfo::Mode rmode) {
-  return rmode == RelocInfo::NONE64;
-}
-
-
-bool ConstantPoolBuilder::Is32BitEntry(RelocInfo::Mode rmode) {
-  return !RelocInfo::IsGCRelocMode(rmode) && rmode != RelocInfo::NONE64;
-}
-
-
-bool ConstantPoolBuilder::IsCodePtrEntry(RelocInfo::Mode rmode) {
-  return RelocInfo::IsCodeTarget(rmode);
-}
-
-
-bool ConstantPoolBuilder::IsHeapPtrEntry(RelocInfo::Mode rmode) {
-  return RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode);
+ConstantPoolArray::Type ConstantPoolBuilder::GetConstantPoolType(
+    RelocInfo::Mode rmode) {
+  if (rmode == RelocInfo::NONE64) {
+    return ConstantPoolArray::INT64;
+  } else if (!RelocInfo::IsGCRelocMode(rmode)) {
+    return ConstantPoolArray::INT32;
+  } else if (RelocInfo::IsCodeTarget(rmode)) {
+    return ConstantPoolArray::CODE_PTR;
+  } else {
+    DCHECK(RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode));
+    return ConstantPoolArray::HEAP_PTR;
+  }
 }
 
 
-void ConstantPoolBuilder::AddEntry(Assembler* assm,
-                                   const RelocInfo& rinfo) {
+ConstantPoolArray::LayoutSection ConstantPoolBuilder::AddEntry(
+    Assembler* assm, const RelocInfo& rinfo) {
   RelocInfo::Mode rmode = rinfo.rmode();
-  ASSERT(rmode != RelocInfo::COMMENT &&
+  DCHECK(rmode != RelocInfo::COMMENT &&
          rmode != RelocInfo::POSITION &&
          rmode != RelocInfo::STATEMENT_POSITION &&
          rmode != RelocInfo::CONST_POOL);
 
-
   // Try to merge entries which won't be patched.
   int merged_index = -1;
+  ConstantPoolArray::LayoutSection entry_section = current_section_;
   if (RelocInfo::IsNone(rmode) ||
-      (!Serializer::enabled() && (rmode >= RelocInfo::CELL))) {
+      (!assm->serializer_enabled() && (rmode >= RelocInfo::CELL))) {
     size_t i;
-    std::vector<RelocInfo>::const_iterator it;
+    std::vector<ConstantPoolEntry>::const_iterator it;
     for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) {
-      if (RelocInfo::IsEqual(rinfo, *it)) {
+      if (RelocInfo::IsEqual(rinfo, it->rinfo_)) {
+        // Merge with found entry.
         merged_index = i;
+        entry_section = entries_[i].section_;
         break;
       }
     }
   }
-
-  entries_.push_back(rinfo);
-  merged_indexes_.push_back(merged_index);
+  DCHECK(entry_section <= current_section_);
+  entries_.push_back(ConstantPoolEntry(rinfo, entry_section, merged_index));
 
   if (merged_index == -1) {
     // Not merged, so update the appropriate count.
-    if (Is64BitEntry(rmode)) {
-      count_of_64bit_++;
-    } else if (Is32BitEntry(rmode)) {
-      count_of_32bit_++;
-    } else if (IsCodePtrEntry(rmode)) {
-      count_of_code_ptr_++;
-    } else {
-      ASSERT(IsHeapPtrEntry(rmode));
-      count_of_heap_ptr_++;
-    }
+    number_of_entries_[entry_section].increment(GetConstantPoolType(rmode));
   }
 
-  // Check if we still have room for another entry given Arm's ldr and vldr
-  // immediate offset range.
-  if (!(is_uint12(ConstantPoolArray::SizeFor(count_of_64bit_,
-                                             count_of_code_ptr_,
-                                             count_of_heap_ptr_,
-                                             count_of_32bit_))) &&
-        is_uint10(ConstantPoolArray::SizeFor(count_of_64bit_, 0, 0, 0))) {
-    assm->set_constant_pool_full();
+  // Check if we still have room for another entry in the small section
+  // given Arm's ldr and vldr immediate offset range.
+  if (current_section_ == ConstantPoolArray::SMALL_SECTION &&
+      !(is_uint12(ConstantPoolArray::SizeFor(*small_entries())) &&
+        is_uint10(ConstantPoolArray::MaxInt64Offset(
+            small_entries()->count_of(ConstantPoolArray::INT64))))) {
+    current_section_ = ConstantPoolArray::EXTENDED_SECTION;
   }
+  return entry_section;
 }
 
 
 void ConstantPoolBuilder::Relocate(int pc_delta) {
-  for (std::vector<RelocInfo>::iterator rinfo = entries_.begin();
-       rinfo != entries_.end(); rinfo++) {
-    ASSERT(rinfo->rmode() != RelocInfo::JS_RETURN);
-    rinfo->set_pc(rinfo->pc() + pc_delta);
+  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
+       entry != entries_.end(); entry++) {
+    DCHECK(entry->rinfo_.rmode() != RelocInfo::JS_RETURN);
+    entry->rinfo_.set_pc(entry->rinfo_.pc() + pc_delta);
   }
 }
 
 
-MaybeObject* ConstantPoolBuilder::Allocate(Heap* heap) {
+Handle<ConstantPoolArray> ConstantPoolBuilder::New(Isolate* isolate) {
   if (IsEmpty()) {
-    return heap->empty_constant_pool_array();
+    return isolate->factory()->empty_constant_pool_array();
+  } else if (extended_entries()->is_empty()) {
+    return isolate->factory()->NewConstantPoolArray(*small_entries());
   } else {
-    return heap->AllocateConstantPoolArray(count_of_64bit_, count_of_code_ptr_,
-                                           count_of_heap_ptr_, count_of_32bit_);
+    DCHECK(current_section_ == ConstantPoolArray::EXTENDED_SECTION);
+    return isolate->factory()->NewExtendedConstantPoolArray(
+        *small_entries(), *extended_entries());
   }
 }
 
 
 void ConstantPoolBuilder::Populate(Assembler* assm,
                                    ConstantPoolArray* constant_pool) {
-  ASSERT(constant_pool->count_of_int64_entries() == count_of_64bit_);
-  ASSERT(constant_pool->count_of_code_ptr_entries() == count_of_code_ptr_);
-  ASSERT(constant_pool->count_of_heap_ptr_entries() == count_of_heap_ptr_);
-  ASSERT(constant_pool->count_of_int32_entries() == count_of_32bit_);
-  ASSERT(entries_.size() == merged_indexes_.size());
-
-  int index_64bit = 0;
-  int index_code_ptr = count_of_64bit_;
-  int index_heap_ptr = count_of_64bit_ + count_of_code_ptr_;
-  int index_32bit = count_of_64bit_ + count_of_code_ptr_ + count_of_heap_ptr_;
-
-  size_t i;
-  std::vector<RelocInfo>::const_iterator rinfo;
-  for (rinfo = entries_.begin(), i = 0; rinfo != entries_.end(); rinfo++, i++) {
-    RelocInfo::Mode rmode = rinfo->rmode();
+  DCHECK_EQ(extended_entries()->is_empty(),
+            !constant_pool->is_extended_layout());
+  DCHECK(small_entries()->equals(ConstantPoolArray::NumberOfEntries(
+      constant_pool, ConstantPoolArray::SMALL_SECTION)));
+  if (constant_pool->is_extended_layout()) {
+    DCHECK(extended_entries()->equals(ConstantPoolArray::NumberOfEntries(
+        constant_pool, ConstantPoolArray::EXTENDED_SECTION)));
+  }
+
+  // Set up initial offsets.
+  int offsets[ConstantPoolArray::NUMBER_OF_LAYOUT_SECTIONS]
+             [ConstantPoolArray::NUMBER_OF_TYPES];
+  for (int section = 0; section <= constant_pool->final_section(); section++) {
+    int section_start = (section == ConstantPoolArray::EXTENDED_SECTION)
+                            ? small_entries()->total_count()
+                            : 0;
+    for (int i = 0; i < ConstantPoolArray::NUMBER_OF_TYPES; i++) {
+      ConstantPoolArray::Type type = static_cast<ConstantPoolArray::Type>(i);
+      if (number_of_entries_[section].count_of(type) != 0) {
+        offsets[section][type] = constant_pool->OffsetOfElementAt(
+            number_of_entries_[section].base_of(type) + section_start);
+      }
+    }
+  }
+
+  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
+       entry != entries_.end(); entry++) {
+    RelocInfo rinfo = entry->rinfo_;
+    RelocInfo::Mode rmode = entry->rinfo_.rmode();
+    ConstantPoolArray::Type type = GetConstantPoolType(rmode);
 
     // Update constant pool if necessary and get the entry's offset.
     int offset;
-    if (merged_indexes_[i] == -1) {
-      if (Is64BitEntry(rmode)) {
-        offset = constant_pool->OffsetOfElementAt(index_64bit) - kHeapObjectTag;
-        constant_pool->set(index_64bit++, rinfo->data64());
-      } else if (Is32BitEntry(rmode)) {
-        offset = constant_pool->OffsetOfElementAt(index_32bit) - kHeapObjectTag;
-        constant_pool->set(index_32bit++, static_cast<int32_t>(rinfo->data()));
-      } else if (IsCodePtrEntry(rmode)) {
-        offset = constant_pool->OffsetOfElementAt(index_code_ptr) -
-            kHeapObjectTag;
-        constant_pool->set(index_code_ptr++,
-                           reinterpret_cast<Object *>(rinfo->data()));
+    if (entry->merged_index_ == -1) {
+      offset = offsets[entry->section_][type];
+      offsets[entry->section_][type] += ConstantPoolArray::entry_size(type);
+      if (type == ConstantPoolArray::INT64) {
+        constant_pool->set_at_offset(offset, rinfo.data64());
+      } else if (type == ConstantPoolArray::INT32) {
+        constant_pool->set_at_offset(offset,
+                                     static_cast<int32_t>(rinfo.data()));
+      } else if (type == ConstantPoolArray::CODE_PTR) {
+        constant_pool->set_at_offset(offset,
+                                     reinterpret_cast<Address>(rinfo.data()));
       } else {
-        ASSERT(IsHeapPtrEntry(rmode));
-        offset = constant_pool->OffsetOfElementAt(index_heap_ptr) -
-            kHeapObjectTag;
-        constant_pool->set(index_heap_ptr++,
-                           reinterpret_cast<Object *>(rinfo->data()));
+        DCHECK(type == ConstantPoolArray::HEAP_PTR);
+        constant_pool->set_at_offset(offset,
+                                     reinterpret_cast<Object*>(rinfo.data()));
       }
-      merged_indexes_[i] = offset;  // Stash offset for merged entries.
+      offset -= kHeapObjectTag;
+      entry->merged_index_ = offset;  // Stash offset for merged entries.
     } else {
-      size_t merged_index = static_cast<size_t>(merged_indexes_[i]);
-      ASSERT(merged_index < merged_indexes_.size() && merged_index < i);
-      offset = merged_indexes_[merged_index];
+      DCHECK(entry->merged_index_ < (entry - entries_.begin()));
+      offset = entries_[entry->merged_index_].merged_index_;
     }
 
     // Patch vldr/ldr instruction with correct offset.
-    Instr instr = assm->instr_at(rinfo->pc());
-    if (Is64BitEntry(rmode)) {
+    Instr instr = assm->instr_at(rinfo.pc());
+    if (entry->section_ == ConstantPoolArray::EXTENDED_SECTION) {
+      if (CpuFeatures::IsSupported(ARMv7)) {
+        // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0].
+        Instr next_instr = assm->instr_at(rinfo.pc() + Assembler::kInstrSize);
+        DCHECK((Assembler::IsMovW(instr) &&
+                Instruction::ImmedMovwMovtValue(instr) == 0));
+        DCHECK((Assembler::IsMovT(next_instr) &&
+                Instruction::ImmedMovwMovtValue(next_instr) == 0));
+        assm->instr_at_put(
+            rinfo.pc(), Assembler::PatchMovwImmediate(instr, offset & 0xffff));
+        assm->instr_at_put(
+            rinfo.pc() + Assembler::kInstrSize,
+            Assembler::PatchMovwImmediate(next_instr, offset >> 16));
+      } else {
+        // Instructions to patch must be 'mov rd, [#0]' and 'orr rd, rd, [#0].
+        Instr instr_2 = assm->instr_at(rinfo.pc() + Assembler::kInstrSize);
+        Instr instr_3 = assm->instr_at(rinfo.pc() + 2 * Assembler::kInstrSize);
+        Instr instr_4 = assm->instr_at(rinfo.pc() + 3 * Assembler::kInstrSize);
+        DCHECK((Assembler::IsMovImmed(instr) &&
+                Instruction::Immed8Value(instr) == 0));
+        DCHECK((Assembler::IsOrrImmed(instr_2) &&
+                Instruction::Immed8Value(instr_2) == 0) &&
+               Assembler::GetRn(instr_2).is(Assembler::GetRd(instr_2)));
+        DCHECK((Assembler::IsOrrImmed(instr_3) &&
+                Instruction::Immed8Value(instr_3) == 0) &&
+               Assembler::GetRn(instr_3).is(Assembler::GetRd(instr_3)));
+        DCHECK((Assembler::IsOrrImmed(instr_4) &&
+                Instruction::Immed8Value(instr_4) == 0) &&
+               Assembler::GetRn(instr_4).is(Assembler::GetRd(instr_4)));
+        assm->instr_at_put(
+            rinfo.pc(), Assembler::PatchShiftImm(instr, (offset & kImm8Mask)));
+        assm->instr_at_put(
+            rinfo.pc() + Assembler::kInstrSize,
+            Assembler::PatchShiftImm(instr_2, (offset & (kImm8Mask << 8))));
+        assm->instr_at_put(
+            rinfo.pc() + 2 * Assembler::kInstrSize,
+            Assembler::PatchShiftImm(instr_3, (offset & (kImm8Mask << 16))));
+        assm->instr_at_put(
+            rinfo.pc() + 3 * Assembler::kInstrSize,
+            Assembler::PatchShiftImm(instr_4, (offset & (kImm8Mask << 24))));
+      }
+    } else if (type == ConstantPoolArray::INT64) {
       // Instruction to patch must be 'vldr rd, [pp, #0]'.
-      ASSERT((Assembler::IsVldrDPpImmediateOffset(instr) &&
+      DCHECK((Assembler::IsVldrDPpImmediateOffset(instr) &&
               Assembler::GetVldrDRegisterImmediateOffset(instr) == 0));
-      ASSERT(is_uint10(offset));
-      assm->instr_at_put(rinfo->pc(),
-          Assembler::SetVldrDRegisterImmediateOffset(instr, offset));
+      DCHECK(is_uint10(offset));
+      assm->instr_at_put(rinfo.pc(), Assembler::SetVldrDRegisterImmediateOffset(
+                                         instr, offset));
     } else {
       // Instruction to patch must be 'ldr rd, [pp, #0]'.
-      ASSERT((Assembler::IsLdrPpImmediateOffset(instr) &&
+      DCHECK((Assembler::IsLdrPpImmediateOffset(instr) &&
               Assembler::GetLdrRegisterImmediateOffset(instr) == 0));
-      ASSERT(is_uint12(offset));
-      assm->instr_at_put(rinfo->pc(),
-          Assembler::SetLdrRegisterImmediateOffset(instr, offset));
+      DCHECK(is_uint12(offset));
+      assm->instr_at_put(
+          rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset));
     }
   }
-
-  ASSERT((index_64bit == count_of_64bit_) &&
-         (index_code_ptr == (index_64bit + count_of_code_ptr_)) &&
-         (index_heap_ptr == (index_code_ptr + count_of_heap_ptr_)) &&
-         (index_32bit == (index_heap_ptr + count_of_32bit_)));
 }