Version 3.16.3

Improved GC performance when moving parts of a FixedArray (issue 2452).

Enabled readline on d8 while building a shared lib (issue 1781).

Fixed missing exception check in typed array constructor (Chromium issue 168545).

Check for read-only-ness when preparing for array sort (issue 2419).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@13346 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index b926c22..352b63d 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -3124,7 +3124,7 @@
 
   } else {
     i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
-    if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
+    if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Arguments"))) {
       return v8::String::New("[object Object]");
 
     } else {
@@ -4145,11 +4145,14 @@
     FlattenString(str);  // Flatten the string for efficiency.
   }
 
-  if (str->IsOneByteRepresentation()) {
+  if (str->HasOnlyAsciiChars()) {
     // WriteToFlat is faster than using the StringCharacterStream.
     if (length == -1) length = str->length() + 1;
     int len = i::Min(length, str->length() - start);
-    i::String::WriteToFlat(*str, buffer, start, start + len);
+    i::String::WriteToFlat(*str,
+                           reinterpret_cast<uint8_t*>(buffer),
+                           start,
+                           start + len);
     if (!(options & PRESERVE_ASCII_NULL)) {
       for (int i = 0; i < len; i++) {
         if (buffer[i] == '\0') buffer[i] = ' ';
@@ -5183,14 +5186,14 @@
 
 
 static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
-  char flags_buf[3];
+  uint8_t flags_buf[3];
   int num_flags = 0;
   if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
   if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
   if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
   ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
   return FACTORY->LookupOneByteSymbol(
-      i::Vector<const char>(flags_buf, num_flags));
+      i::Vector<const uint8_t>(flags_buf, num_flags));
 }
 
 
diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h
index a31b7e9..02dc907 100644
--- a/src/arm/assembler-arm-inl.h
+++ b/src/arm/assembler-arm-inl.h
@@ -344,7 +344,7 @@
 Operand::Operand(Smi* value) {
   rm_ = no_reg;
   imm32_ =  reinterpret_cast<intptr_t>(value);
-  rmode_ = RelocInfo::NONE;
+  rmode_ = RelocInfo::NONE32;
 }
 
 
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 9cd8675..b80e23d 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -234,7 +234,7 @@
   } else {
     // no relocation needed
     imm32_ =  reinterpret_cast<intptr_t>(obj);
-    rmode_ = RelocInfo::NONE;
+    rmode_ = RelocInfo::NONE32;
   }
 }
 
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index ca63288..27befaa 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -386,7 +386,7 @@
  public:
   // immediate
   INLINE(explicit Operand(int32_t immediate,
-         RelocInfo::Mode rmode = RelocInfo::NONE));
+         RelocInfo::Mode rmode = RelocInfo::NONE32));
   INLINE(static Operand Zero()) {
     return Operand(static_cast<int32_t>(0));
   }
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 28e00dd..3be8e92 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -140,7 +140,7 @@
   __ LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex);
   __ str(scratch1, FieldMemOperand(result, JSArray::kPropertiesOffset));
   // Field JSArray::kElementsOffset is initialized later.
-  __ mov(scratch3,  Operand(0, RelocInfo::NONE));
+  __ mov(scratch3,  Operand::Zero());
   __ str(scratch3, FieldMemOperand(result, JSArray::kLengthOffset));
 
   if (initial_capacity == 0) {
@@ -319,7 +319,7 @@
       has_non_smi_element, finish, cant_transition_map, not_double;
 
   // Check for array construction with zero arguments or one.
-  __ cmp(r0, Operand(0, RelocInfo::NONE));
+  __ cmp(r0, Operand::Zero());
   __ b(ne, &argc_one_or_more);
 
   // Handle construction of an empty array.
@@ -347,7 +347,7 @@
   __ tst(r2, r2);
   __ b(ne, &not_empty_array);
   __ Drop(1);  // Adjust stack.
-  __ mov(r0, Operand(0));  // Treat this as a call with argc of zero.
+  __ mov(r0, Operand::Zero());  // Treat this as a call with argc of zero.
   __ b(&empty_array);
 
   __ bind(&not_empty_array);
@@ -590,7 +590,7 @@
 
   // Load the first arguments in r0 and get rid of the rest.
   Label no_arguments;
-  __ cmp(r0, Operand(0, RelocInfo::NONE));
+  __ cmp(r0, Operand::Zero());
   __ b(eq, &no_arguments);
   // First args = sp[(argc - 1) * 4].
   __ sub(r0, r0, Operand(1));
@@ -634,7 +634,7 @@
     __ cmp(r4, Operand(JSValue::kSize >> kPointerSizeLog2));
     __ Assert(eq, "Unexpected string wrapper instance size");
     __ ldrb(r4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset));
-    __ cmp(r4, Operand(0, RelocInfo::NONE));
+    __ cmp(r4, Operand::Zero());
     __ Assert(eq, "Unexpected unused properties of string wrapper");
   }
   __ str(map, FieldMemOperand(r0, HeapObject::kMapOffset));
@@ -1097,7 +1097,7 @@
   // r5-r7, cp may be clobbered
 
   // Clear the context before we push it when entering the internal frame.
-  __ mov(cp, Operand(0, RelocInfo::NONE));
+  __ mov(cp, Operand::Zero());
 
   // Enter an internal frame.
   {
@@ -1259,7 +1259,7 @@
 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
 
 
-void Builtins::Generate_NotifyICMiss(MacroAssembler* masm) {
+void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
@@ -1268,7 +1268,7 @@
     // registers.
     __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved);
     // Pass the function and deoptimization type to the runtime system.
-    __ CallRuntime(Runtime::kNotifyICMiss, 0);
+    __ CallRuntime(Runtime::kNotifyStubFailure, 0);
     __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved);
   }
 
@@ -1375,7 +1375,7 @@
   // 1. Make sure we have at least one argument.
   // r0: actual number of arguments
   { Label done;
-    __ cmp(r0, Operand(0));
+    __ cmp(r0, Operand::Zero());
     __ b(ne, &done);
     __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
     __ push(r2);
@@ -1396,7 +1396,7 @@
   // r0: actual number of arguments
   // r1: function
   Label shift_arguments;
-  __ mov(r4, Operand(0, RelocInfo::NONE));  // indicate regular JS_FUNCTION
+  __ mov(r4, Operand::Zero());  // indicate regular JS_FUNCTION
   { Label convert_to_object, use_global_receiver, patch_receiver;
     // Change context eagerly in case we need the global receiver.
     __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
@@ -1451,7 +1451,7 @@
 
     // Restore the function to r1, and the flag to r4.
     __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
-    __ mov(r4, Operand(0, RelocInfo::NONE));
+    __ mov(r4, Operand::Zero());
     __ jmp(&patch_receiver);
 
     // Use the global receiver object from the called function as the
@@ -1473,11 +1473,11 @@
 
   // 3b. Check for function proxy.
   __ bind(&slow);
-  __ mov(r4, Operand(1, RelocInfo::NONE));  // indicate function proxy
+  __ mov(r4, Operand(1, RelocInfo::NONE32));  // indicate function proxy
   __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE));
   __ b(eq, &shift_arguments);
   __ bind(&non_function);
-  __ mov(r4, Operand(2, RelocInfo::NONE));  // indicate non-function
+  __ mov(r4, Operand(2, RelocInfo::NONE32));  // indicate non-function
 
   // 3c. Patch the first argument when calling a non-function.  The
   //     CALL_NON_FUNCTION builtin expects the non-function callee as
@@ -1521,7 +1521,7 @@
     __ tst(r4, r4);
     __ b(eq, &function);
     // Expected number of arguments is 0 for CALL_NON_FUNCTION.
-    __ mov(r2, Operand(0, RelocInfo::NONE));
+    __ mov(r2, Operand::Zero());
     __ SetCallKind(r5, CALL_AS_METHOD);
     __ cmp(r4, Operand(1));
     __ b(ne, &non_proxy);
@@ -1599,7 +1599,7 @@
     // Push current limit and index.
     __ bind(&okay);
     __ push(r0);  // limit
-    __ mov(r1, Operand(0, RelocInfo::NONE));  // initial index
+    __ mov(r1, Operand::Zero());  // initial index
     __ push(r1);
 
     // Get the receiver.
@@ -1711,7 +1711,7 @@
     __ bind(&call_proxy);
     __ push(r1);  // add function proxy as last argument
     __ add(r0, r0, Operand(1));
-    __ mov(r2, Operand(0, RelocInfo::NONE));
+    __ mov(r2, Operand::Zero());
     __ SetCallKind(r5, CALL_AS_METHOD);
     __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
     __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 3ab09a2..e5c1c3e 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -44,7 +44,7 @@
   descriptor->register_param_count_ = 2;
   descriptor->register_params_ = registers;
   descriptor->deoptimization_handler_ =
-      isolate->builtins()->KeyedLoadIC_Miss();
+      FUNCTION_ADDR(KeyedLoadIC_Miss);
 }
 
 
@@ -344,6 +344,7 @@
     MacroAssembler* masm,
     int length,
     FastCloneShallowArrayStub::Mode mode,
+    AllocationSiteInfoMode allocation_site_info_mode,
     Label* fail) {
   // Registers on entry:
   //
@@ -357,7 +358,12 @@
         ? FixedDoubleArray::SizeFor(length)
         : FixedArray::SizeFor(length);
   }
-  int size = JSArray::kSize + elements_size;
+  int size = JSArray::kSize;
+  int allocation_info_start = size;
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    size += AllocationSiteInfo::kSize;
+  }
+  size += elements_size;
 
   // Allocate both the JS array and the elements array in one big
   // allocation. This avoids multiple limit checks.
@@ -367,6 +373,13 @@
   }
   __ AllocateInNewSpace(size, r0, r1, r2, fail, flags);
 
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    __ mov(r2, Operand(Handle<Map>(masm->isolate()->heap()->
+                                   allocation_site_info_map())));
+    __ str(r2, FieldMemOperand(r0, allocation_info_start));
+    __ str(r3, FieldMemOperand(r0, allocation_info_start + kPointerSize));
+  }
+
   // Copy the JS array part.
   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
     if ((i != JSArray::kElementsOffset) || (length == 0)) {
@@ -379,7 +392,11 @@
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
     __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
-    __ add(r2, r0, Operand(JSArray::kSize));
+    if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+      __ add(r2, r0, Operand(JSArray::kSize + AllocationSiteInfo::kSize));
+    } else {
+      __ add(r2, r0, Operand(JSArray::kSize));
+    }
     __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset));
 
     // Copy the elements array.
@@ -406,6 +423,13 @@
   __ b(eq, &slow_case);
 
   FastCloneShallowArrayStub::Mode mode = mode_;
+  AllocationSiteInfoMode allocation_site_info_mode =
+      DONT_TRACK_ALLOCATION_SITE_INFO;
+  if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
+    mode = CLONE_ANY_ELEMENTS;
+    allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
+  }
+
   if (mode == CLONE_ANY_ELEMENTS) {
     Label double_elements, check_fast_elements;
     __ ldr(r0, FieldMemOperand(r3, JSArray::kElementsOffset));
@@ -413,7 +437,9 @@
     __ CompareRoot(r0, Heap::kFixedCOWArrayMapRootIndex);
     __ b(ne, &check_fast_elements);
     GenerateFastCloneShallowArrayCommon(masm, 0,
-                                        COPY_ON_WRITE_ELEMENTS, &slow_case);
+                                        COPY_ON_WRITE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     // Return and remove the on-stack parameters.
     __ add(sp, sp, Operand(3 * kPointerSize));
     __ Ret();
@@ -422,7 +448,9 @@
     __ CompareRoot(r0, Heap::kFixedArrayMapRootIndex);
     __ b(ne, &double_elements);
     GenerateFastCloneShallowArrayCommon(masm, length_,
-                                        CLONE_ELEMENTS, &slow_case);
+                                        CLONE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     // Return and remove the on-stack parameters.
     __ add(sp, sp, Operand(3 * kPointerSize));
     __ Ret();
@@ -454,7 +482,8 @@
     __ pop(r3);
   }
 
-  GenerateFastCloneShallowArrayCommon(masm, length_, mode, &slow_case);
+  GenerateFastCloneShallowArrayCommon(masm, length_, mode,
+                                      allocation_site_info_mode, &slow_case);
 
   // Return and remove the on-stack parameters.
   __ add(sp, sp, Operand(3 * kPointerSize));
@@ -560,7 +589,7 @@
   STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u);
   __ and_(exponent, source_, Operand(HeapNumber::kSignMask), SetCC);
   // Subtract from 0 if source was negative.
-  __ rsb(source_, source_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+  __ rsb(source_, source_, Operand::Zero(), LeaveCC, ne);
 
   // We have -1, 0 or 1, which we treat specially. Register source_ contains
   // absolute value: it is either equal to 1 (special case of -1 and 1),
@@ -573,7 +602,7 @@
       HeapNumber::kExponentBias << HeapNumber::kExponentShift;
   __ orr(exponent, exponent, Operand(exponent_word_for_1), LeaveCC, eq);
   // 1, 0 and -1 all have 0 for the second word.
-  __ mov(mantissa, Operand(0, RelocInfo::NONE));
+  __ mov(mantissa, Operand::Zero());
   __ Ret();
 
   __ bind(&not_special);
@@ -1141,7 +1170,7 @@
   // Set the sign bit in scratch_ if the value was negative.
   __ orr(scratch_, scratch_, Operand(HeapNumber::kSignMask), LeaveCC, cs);
   // Subtract from 0 if the value was negative.
-  __ rsb(the_int_, the_int_, Operand(0, RelocInfo::NONE), LeaveCC, cs);
+  __ rsb(the_int_, the_int_, Operand::Zero(), LeaveCC, cs);
   // We should be masking the implict first digit of the mantissa away here,
   // but it just ends up combining harmlessly with the last digit of the
   // exponent that happens to be 1.  The sign bit is 0 so we shift 10 to get
@@ -1164,7 +1193,7 @@
   non_smi_exponent += 1 << HeapNumber::kExponentShift;
   __ mov(ip, Operand(HeapNumber::kSignMask | non_smi_exponent));
   __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kExponentOffset));
-  __ mov(ip, Operand(0, RelocInfo::NONE));
+  __ mov(ip, Operand::Zero());
   __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset));
   __ Ret();
 }
@@ -1380,7 +1409,7 @@
          Operand(lhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord),
          SetCC);
   __ b(ne, &one_is_nan);
-  __ cmp(lhs_mantissa, Operand(0, RelocInfo::NONE));
+  __ cmp(lhs_mantissa, Operand::Zero());
   __ b(ne, &one_is_nan);
 
   __ bind(lhs_not_nan);
@@ -1395,7 +1424,7 @@
          Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord),
          SetCC);
   __ b(ne, &one_is_nan);
-  __ cmp(rhs_mantissa, Operand(0, RelocInfo::NONE));
+  __ cmp(rhs_mantissa, Operand::Zero());
   __ b(eq, &neither_is_nan);
 
   __ bind(&one_is_nan);
@@ -1922,7 +1951,7 @@
       __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
       __ tst(ip, Operand(1 << Map::kIsUndetectable));
       // Undetectable -> false.
-      __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+      __ mov(tos_, Operand::Zero(), LeaveCC, ne);
       __ Ret(ne);
     }
   }
@@ -1955,14 +1984,14 @@
       // "tos_" is a register, and contains a non zero value by default.
       // Hence we only need to overwrite "tos_" with zero to return false for
       // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
-      __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq);  // for FP_ZERO
-      __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs);  // for FP_NAN
+      __ mov(tos_, Operand::Zero(), LeaveCC, eq);  // for FP_ZERO
+      __ mov(tos_, Operand::Zero(), LeaveCC, vs);  // for FP_NAN
     } else {
       Label done, not_nan, not_zero;
       __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kExponentOffset));
       // -0 maps to false:
       __ bic(
-          temp, temp, Operand(HeapNumber::kSignMask, RelocInfo::NONE), SetCC);
+          temp, temp, Operand(HeapNumber::kSignMask, RelocInfo::NONE32), SetCC);
       __ b(ne, &not_zero);
       // If exponent word is zero then the answer depends on the mantissa word.
       __ ldr(tos_, FieldMemOperand(tos_, HeapNumber::kMantissaOffset));
@@ -1975,25 +2004,25 @@
       __ mov(temp, Operand(temp, LSR, HeapNumber::kMantissaBitsInTopWord));
       unsigned int shifted_exponent_mask =
           HeapNumber::kExponentMask >> HeapNumber::kMantissaBitsInTopWord;
-      __ cmp(temp, Operand(shifted_exponent_mask, RelocInfo::NONE));
+      __ cmp(temp, Operand(shifted_exponent_mask, RelocInfo::NONE32));
       __ b(ne, &not_nan);  // If exponent is not 0x7ff then it can't be a NaN.
 
       // Reload exponent word.
       __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kExponentOffset));
-      __ tst(temp, Operand(HeapNumber::kMantissaMask, RelocInfo::NONE));
+      __ tst(temp, Operand(HeapNumber::kMantissaMask, RelocInfo::NONE32));
       // If mantissa is not zero then we have a NaN, so return 0.
-      __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+      __ mov(tos_, Operand::Zero(), LeaveCC, ne);
       __ b(ne, &done);
 
       // Load mantissa word.
       __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kMantissaOffset));
-      __ cmp(temp, Operand(0, RelocInfo::NONE));
+      __ cmp(temp, Operand::Zero());
       // If mantissa is not zero then we have a NaN, so return 0.
-      __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+      __ mov(tos_, Operand::Zero(), LeaveCC, ne);
       __ b(ne, &done);
 
       __ bind(&not_nan);
-      __ mov(tos_, Operand(1, RelocInfo::NONE));
+      __ mov(tos_, Operand(1, RelocInfo::NONE32));
       __ bind(&done);
     }
     __ Ret();
@@ -2016,7 +2045,7 @@
     // The value of a root is never NULL, so we can avoid loading a non-null
     // value into tos_ when we want to return 'true'.
     if (!result) {
-      __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq);
+      __ mov(tos_, Operand::Zero(), LeaveCC, eq);
     }
     __ Ret(eq);
   }
@@ -2161,7 +2190,7 @@
   __ b(eq, slow);
 
   // Return '0 - value'.
-  __ rsb(r0, r0, Operand(0, RelocInfo::NONE));
+  __ rsb(r0, r0, Operand::Zero());
   __ Ret();
 }
 
@@ -2429,7 +2458,7 @@
       __ cmp(ip, Operand(scratch2));
       __ b(ne, &not_smi_result);
       // Go slow on zero result to handle -0.
-      __ cmp(scratch1, Operand(0));
+      __ cmp(scratch1, Operand::Zero());
       __ mov(right, Operand(scratch1), LeaveCC, ne);
       __ Ret(ne);
       // We need -0 if we were multiplying a negative number with 0 to get 0.
@@ -2444,7 +2473,7 @@
       Label div_with_sdiv;
 
       // Check for 0 divisor.
-      __ cmp(right, Operand(0));
+      __ cmp(right, Operand::Zero());
       __ b(eq, &not_smi_result);
 
       // Check for power of two on the right hand side.
@@ -2456,7 +2485,7 @@
         __ tst(left, scratch1);
         __ b(ne, &not_smi_result);
         // Check for positive left hand side.
-        __ cmp(left, Operand(0));
+        __ cmp(left, Operand::Zero());
         __ b(mi, &div_with_sdiv);
       } else {
         __ b(ne, &not_smi_result);
@@ -2480,12 +2509,12 @@
         __ sdiv(scratch1, left, right);
         // Check that the remainder is zero.
         __ mls(scratch2, scratch1, right, left);
-        __ cmp(scratch2, Operand(0));
+        __ cmp(scratch2, Operand::Zero());
         __ b(ne, &not_smi_result);
         // Check for negative zero result.
-        __ cmp(scratch1, Operand(0));
+        __ cmp(scratch1, Operand::Zero());
         __ b(ne, &result_not_zero);
-        __ cmp(right, Operand(0));
+        __ cmp(right, Operand::Zero());
         __ b(lt, &not_smi_result);
         __ bind(&result_not_zero);
         // Check for the corner case of dividing the most negative smi by -1.
@@ -2502,7 +2531,7 @@
 
       if (CpuFeatures::IsSupported(SUDIV)) {
         // Check for x % 0.
-        __ cmp(right, Operand(0));
+        __ cmp(right, Operand::Zero());
         __ b(eq, &not_smi_result);
 
         // Check for two positive smis.
@@ -2535,10 +2564,10 @@
         __ sdiv(scratch1, left, right);
         __ mls(right, scratch1, right, left);
         // Return if the result is not 0.
-        __ cmp(right, Operand(0));
+        __ cmp(right, Operand::Zero());
         __ Ret(ne);
         // The result is 0, check for -0 case.
-        __ cmp(left, Operand(0));
+        __ cmp(left, Operand::Zero());
         __ Ret(pl);
         // This is a -0 case, restore the value of right.
         __ mov(right, scratch2);
@@ -3478,7 +3507,7 @@
     __ ldr(cache_entry, MemOperand(cache_entry, cache_array_index));
     // r0 points to the cache for the type type_.
     // If NULL, the cache hasn't been initialized yet, so go through runtime.
-    __ cmp(cache_entry, Operand(0, RelocInfo::NONE));
+    __ cmp(cache_entry, Operand::Zero());
     __ b(eq, &invalid_cache);
 
 #ifdef DEBUG
@@ -3789,8 +3818,8 @@
   __ vmov(double_result, 1.0, scratch2);
 
   // Get absolute value of exponent.
-  __ cmp(scratch, Operand(0));
-  __ mov(scratch2, Operand(0), LeaveCC, mi);
+  __ cmp(scratch, Operand::Zero());
+  __ mov(scratch2, Operand::Zero(), LeaveCC, mi);
   __ sub(scratch, scratch2, scratch, LeaveCC, mi);
 
   Label while_true;
@@ -3800,7 +3829,7 @@
   __ vmul(double_scratch, double_scratch, double_scratch, ne);
   __ b(ne, &while_true);
 
-  __ cmp(exponent, Operand(0));
+  __ cmp(exponent, Operand::Zero());
   __ b(ge, &done);
   __ vmov(double_scratch, 1.0, scratch);
   __ vdiv(double_result, double_scratch, double_result);
@@ -3903,6 +3932,18 @@
 }
 
 
+static void JumpIfOOM(MacroAssembler* masm,
+                      Register value,
+                      Register scratch,
+                      Label* oom_label) {
+  STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3);
+  STATIC_ASSERT(kFailureTag == 3);
+  __ and_(scratch, value, Operand(0xf));
+  __ cmp(scratch, Operand(0xf));
+  __ b(eq, oom_label);
+}
+
+
 void CEntryStub::GenerateCore(MacroAssembler* masm,
                               Label* throw_normal_exception,
                               Label* throw_termination_exception,
@@ -4002,9 +4043,7 @@
   __ b(eq, &retry);
 
   // Special handling of out of memory exceptions.
-  Failure* out_of_memory = Failure::OutOfMemoryException();
-  __ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
-  __ b(eq, throw_out_of_memory_exception);
+  JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception);
 
   // Retrieve the pending exception and clear the variable.
   __ mov(r3, Operand(isolate->factory()->the_hole_value()));
@@ -4091,13 +4130,16 @@
   Isolate* isolate = masm->isolate();
   ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress,
                                     isolate);
-  __ mov(r0, Operand(false, RelocInfo::NONE));
+  __ mov(r0, Operand(false, RelocInfo::NONE32));
   __ mov(r2, Operand(external_caught));
   __ str(r0, MemOperand(r2));
 
   // Set pending exception and r0 to out of memory exception.
-  Failure* out_of_memory = Failure::OutOfMemoryException();
+  Label already_have_failure;
+  JumpIfOOM(masm, r0, ip, &already_have_failure);
+  Failure* out_of_memory = Failure::OutOfMemoryException(0x1);
   __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
+  __ bind(&already_have_failure);
   __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
                                        isolate)));
   __ str(r0, MemOperand(r2));
@@ -4773,7 +4815,7 @@
   // of the arguments object and the elements array in words.
   Label add_arguments_object;
   __ bind(&try_allocate);
-  __ cmp(r1, Operand(0, RelocInfo::NONE));
+  __ cmp(r1, Operand::Zero());
   __ b(eq, &add_arguments_object);
   __ mov(r1, Operand(r1, LSR, kSmiTagSize));
   __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
@@ -4806,7 +4848,7 @@
 
   // If there are no actual arguments, we're done.
   Label done;
-  __ cmp(r1, Operand(0, RelocInfo::NONE));
+  __ cmp(r1, Operand::Zero());
   __ b(eq, &done);
 
   // Get the parameters pointer from the stack.
@@ -4833,7 +4875,7 @@
   // Post-increment r4 with kPointerSize on each iteration.
   __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
   __ sub(r1, r1, Operand(1));
-  __ cmp(r1, Operand(0, RelocInfo::NONE));
+  __ cmp(r1, Operand::Zero());
   __ b(ne, &loop);
 
   // Return and remove the on-stack parameters.
@@ -4885,7 +4927,7 @@
       ExternalReference::address_of_regexp_stack_memory_size(isolate);
   __ mov(r0, Operand(address_of_regexp_stack_memory_size));
   __ ldr(r0, MemOperand(r0, 0));
-  __ cmp(r0, Operand(0));
+  __ cmp(r0, Operand::Zero());
   __ b(eq, &runtime);
 
   // Check that the first argument is a JSRegExp object.
@@ -4967,7 +5009,7 @@
   __ b(gt, &runtime);
 
   // Reset offset for possibly sliced string.
-  __ mov(r9, Operand(0));
+  __ mov(r9, Operand::Zero());
   // subject: Subject string
   // regexp_data: RegExp data (FixedArray)
   // Check the representation and encoding of the subject string.
@@ -5088,7 +5130,7 @@
 
   // Argument 6: Set the number of capture registers to zero to force global
   // regexps to behave as non-global.  This does not affect non-global regexps.
-  __ mov(r0, Operand(0));
+  __ mov(r0, Operand::Zero());
   __ str(r0, MemOperand(sp, 2 * kPointerSize));
 
   // Argument 5 (sp[4]): static offsets vector buffer.
@@ -5343,7 +5385,7 @@
   // r3: Start of elements in FixedArray.
   // r5: Number of elements to fill.
   Label loop;
-  __ cmp(r5, Operand(0));
+  __ cmp(r5, Operand::Zero());
   __ bind(&loop);
   __ b(le, &done);  // Jump if r5 is negative or zero.
   __ sub(r5, r5, Operand(1), SetCC);
@@ -5469,8 +5511,8 @@
   __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE));
   __ b(ne, &non_function);
   __ push(r1);  // put proxy as additional argument
-  __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE));
-  __ mov(r2, Operand(0, RelocInfo::NONE));
+  __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32));
+  __ mov(r2, Operand::Zero());
   __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
   __ SetCallKind(r5, CALL_AS_METHOD);
   {
@@ -5484,7 +5526,7 @@
   __ bind(&non_function);
   __ str(r1, MemOperand(sp, argc_ * kPointerSize));
   __ mov(r0, Operand(argc_));  // Set up the number of arguments.
-  __ mov(r2, Operand(0, RelocInfo::NONE));
+  __ mov(r2, Operand::Zero());
   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
   __ SetCallKind(r5, CALL_AS_METHOD);
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
@@ -5527,7 +5569,7 @@
   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
   __ bind(&do_call);
   // Set expected number of arguments to zero (not changing r0).
-  __ mov(r2, Operand(0, RelocInfo::NONE));
+  __ mov(r2, Operand::Zero());
   __ SetCallKind(r5, CALL_AS_METHOD);
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
@@ -5632,10 +5674,10 @@
   // Fast case of Heap::LookupSingleCharacterStringFromCode.
   STATIC_ASSERT(kSmiTag == 0);
   STATIC_ASSERT(kSmiShiftSize == 0);
-  ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
+  ASSERT(IsPowerOf2(String::kMaxOneByteCharCode + 1));
   __ tst(code_,
          Operand(kSmiTagMask |
-                 ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
+                 ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
   __ b(ne, &slow_case_);
 
   __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
@@ -5696,7 +5738,7 @@
   if (!ascii) {
     __ add(count, count, Operand(count), SetCC);
   } else {
-    __ cmp(count, Operand(0, RelocInfo::NONE));
+    __ cmp(count, Operand::Zero());
   }
   __ b(eq, &done);
 
@@ -5751,7 +5793,7 @@
   if (!ascii) {
     __ add(count, count, Operand(count), SetCC);
   } else {
-    __ cmp(count, Operand(0, RelocInfo::NONE));
+    __ cmp(count, Operand::Zero());
   }
   __ b(eq, &done);
 
@@ -6274,7 +6316,7 @@
   Label compare_chars;
   __ bind(&check_zero_length);
   STATIC_ASSERT(kSmiTag == 0);
-  __ cmp(length, Operand(0));
+  __ cmp(length, Operand::Zero());
   __ b(ne, &compare_chars);
   __ mov(r0, Operand(Smi::FromInt(EQUAL)));
   __ Ret();
@@ -6307,7 +6349,7 @@
   __ mov(scratch1, scratch2, LeaveCC, gt);
   Register min_length = scratch1;
   STATIC_ASSERT(kSmiTag == 0);
-  __ cmp(min_length, Operand(0));
+  __ cmp(min_length, Operand::Zero());
   __ b(eq, &compare_lengths);
 
   // Compare loop.
@@ -7124,7 +7166,7 @@
   __ mov(r1, Operand(Handle<String>(name)));
   StringDictionaryLookupStub stub(NEGATIVE_LOOKUP);
   __ CallStub(&stub);
-  __ cmp(r0, Operand(0));
+  __ cmp(r0, Operand::Zero());
   __ ldm(ia_w, sp, spill_mask);
 
   __ b(eq, done);
@@ -7200,7 +7242,7 @@
   }
   StringDictionaryLookupStub stub(POSITIVE_LOOKUP);
   __ CallStub(&stub);
-  __ cmp(r0, Operand(0));
+  __ cmp(r0, Operand::Zero());
   __ mov(scratch2, Operand(r2));
   __ ldm(ia_w, sp, spill_mask);
 
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 3f1791c..9d00823 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -179,6 +179,10 @@
   Label loop, entry, convert_hole, gc_required, only_change_map, done;
   bool vfp2_supported = CpuFeatures::IsSupported(VFP2);
 
+  if (FLAG_track_allocation_sites) {
+    masm->TestJSArrayForAllocationSiteInfo(r2, r4, fail);
+  }
+
   // Check for empty arrays, which only require a map transition and no changes
   // to the backing store.
   __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset));
diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc
index c2941be..e9a65b2 100644
--- a/src/arm/debug-arm.cc
+++ b/src/arm/debug-arm.cc
@@ -161,7 +161,7 @@
 #ifdef DEBUG
     __ RecordComment("// Calling from debug break to runtime - come in - over");
 #endif
-    __ mov(r0, Operand(0, RelocInfo::NONE));  // no arguments
+    __ mov(r0, Operand::Zero());  // no arguments
     __ mov(r1, Operand(ExternalReference::debug_break(masm->isolate())));
 
     CEntryStub ceb(1);
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index a263cb7..55139dd 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -80,12 +80,12 @@
     // this is optimized code, so we don't have to have a predictable size.
     int call_size_in_bytes =
         MacroAssembler::CallSizeNotPredictableCodeSize(deopt_entry,
-                                                       RelocInfo::NONE);
+                                                       RelocInfo::NONE32);
     int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize;
     ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0);
     ASSERT(call_size_in_bytes <= patch_size());
     CodePatcher patcher(call_address, call_size_in_words);
-    patcher.masm()->Call(deopt_entry, RelocInfo::NONE);
+    patcher.masm()->Call(deopt_entry, RelocInfo::NONE32);
     ASSERT(prev_call_address == NULL ||
            call_address >= prev_call_address + patch_size());
     ASSERT(call_address + patch_size() <= code->instruction_end());
@@ -458,35 +458,39 @@
   //               FROM                                  TO             <-fp
   //    |          ....           |          |          ....           |
   //    +-------------------------+          +-------------------------+
-  //    | JSFunction continuation |          | JSFunction continuation |
+  //    | JSFunction continuation |          |       parameter 1       |
+  //    +-------------------------+          +-------------------------+
+  // |  |   saved frame (fp)      |          |          ....           |
+  // |  +=========================+<-fp      +-------------------------+
+  // |  |   JSFunction context    |          |       parameter n       |
+  // v  +-------------------------+          +-------------------------|
+  //    |   COMPILED_STUB marker  |          | JSFunction continuation |
   //    +-------------------------+          +-------------------------+<-sp
-  // |  |   saved frame (fp)      |
-  // |  +=========================+<-fp
-  // |  |   JSFunction context    |
-  // v  +-------------------------+
-  //    |   COMPILED_STUB marker  |          fp = saved frame
-  //    +-------------------------+          f8 = JSFunction context
-  //    |                         |
-  //    | ...                     |
-  //    |                         |
-  //    +-------------------------+<-sp
+  //    |                         |          r0 = number of parameters
+  //    | ...                     |          r1 = failure handler address
+  //    |                         |          fp = saved frame
+  //    +-------------------------+<-sp      cp = JSFunction context
   //
   //
-  int output_frame_size = 1 * kPointerSize;
-  FrameDescription* output_frame =
-      new(output_frame_size) FrameDescription(output_frame_size, 0);
-  Code* notify_miss =
-      isolate_->builtins()->builtin(Builtins::kNotifyICMiss);
-  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
-  output_frame->SetContinuation(
-      reinterpret_cast<intptr_t>(notify_miss->entry()));
 
   ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
   int major_key = compiled_code_->major_key();
   CodeStubInterfaceDescriptor* descriptor =
       isolate_->code_stub_interface_descriptor(major_key);
-  Handle<Code> miss_ic(descriptor->deoptimization_handler_);
-  output_frame->SetPc(reinterpret_cast<intptr_t>(miss_ic->instruction_start()));
+
+  int output_frame_size =
+      (1 + descriptor->register_param_count_) * kPointerSize;
+  FrameDescription* output_frame =
+      new(output_frame_size) FrameDescription(output_frame_size, 0);
+  Code* notify_failure =
+      isolate_->builtins()->builtin(Builtins::kNotifyStubFailure);
+  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
+  output_frame->SetContinuation(
+      reinterpret_cast<uint32_t>(notify_failure->entry()));
+
+  Code* code;
+  CEntryStub(1, kSaveFPRegs).FindCodeInCache(&code, isolate_);
+  output_frame->SetPc(reinterpret_cast<intptr_t>(code->instruction_start()));
   unsigned input_frame_size = input_->GetFrameSize();
   intptr_t value = input_->GetFrameSlot(input_frame_size - kPointerSize);
   output_frame->SetFrameSlot(0, value);
@@ -496,20 +500,23 @@
   value = input_->GetFrameSlot(input_frame_size - 3 * kPointerSize);
   output_frame->SetRegister(cp.code(), value);
 
-  Translation::Opcode opcode =
-      static_cast<Translation::Opcode>(iterator->Next());
-  ASSERT(opcode == Translation::REGISTER);
-  USE(opcode);
-  int input_reg = iterator->Next();
-  intptr_t input_value = input_->GetRegister(input_reg);
-  output_frame->SetRegister(r1.code(), input_value);
+  int parameter_offset = kPointerSize * descriptor->register_param_count_;
+  for (int i = 0; i < descriptor->register_param_count_; ++i) {
+    Translation::Opcode opcode =
+        static_cast<Translation::Opcode>(iterator->Next());
+    ASSERT(opcode == Translation::REGISTER);
+    USE(opcode);
+    int input_reg = iterator->Next();
+    intptr_t reg_value = input_->GetRegister(input_reg);
+    output_frame->SetFrameSlot(parameter_offset, reg_value);
+    parameter_offset -= kPointerSize;
+  }
 
-  int32_t next = iterator->Next();
-  opcode = static_cast<Translation::Opcode>(next);
-  ASSERT(opcode == Translation::REGISTER);
-  input_reg = iterator->Next();
-  input_value = input_->GetRegister(input_reg);
-  output_frame->SetRegister(r0.code(), input_value);
+  ApiFunction function(descriptor->deoptimization_handler_);
+  ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
+  intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
+  output_frame->SetRegister(r0.code(), descriptor->register_param_count_);
+  output_frame->SetRegister(r1.code(), handler);
 
   ASSERT(frame_index == 0);
   output_[frame_index] = output_frame;
@@ -1009,7 +1016,7 @@
   // address for lazy deoptimization) and compute the fp-to-sp delta in
   // register r4.
   if (type() == EAGER) {
-    __ mov(r3, Operand(0));
+    __ mov(r3, Operand::Zero());
     // Correct one word for bailout id.
     __ add(r4, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize)));
   } else if (type() == OSR) {
@@ -1124,7 +1131,7 @@
   __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset()));
   __ push(r7);
   __ bind(&inner_loop_header);
-  __ cmp(r3, Operand(0));
+  __ cmp(r3, Operand::Zero());
   __ b(ne, &inner_push_loop);  // test for gt?
   __ add(r0, r0, Operand(kPointerSize));
   __ bind(&outer_loop_header);
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index b6f3e67..6a97201 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -138,7 +138,7 @@
 
 #ifdef DEBUG
   if (strlen(FLAG_stop_at) > 0 &&
-      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+      info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
     __ stop("stop-at");
   }
 #endif
@@ -149,7 +149,7 @@
   // function calls.
   if (!info->is_classic_mode() || info->is_native()) {
     Label ok;
-    __ cmp(r5, Operand(0));
+    __ cmp(r5, Operand::Zero());
     __ b(eq, &ok);
     int receiver_offset = info->scope()->num_parameters() * kPointerSize;
     __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
@@ -1039,7 +1039,7 @@
     CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
     patch_site.EmitPatchInfo();
 
-    __ cmp(r0, Operand(0));
+    __ cmp(r0, Operand::Zero());
     __ b(ne, &next_test);
     __ Drop(1);  // Switch value is no longer needed.
     __ b(clause->body_target());
@@ -1733,6 +1733,15 @@
     FastCloneShallowArrayStub::Mode mode = has_fast_elements
       ? FastCloneShallowArrayStub::CLONE_ELEMENTS
       : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+
+    // Tracking allocation info allows us to pre-transition later if it makes
+    // sense.
+    if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
+        FLAG_track_allocation_sites) {
+      mode = FastCloneShallowArrayStub::
+          CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+    }
+
     FastCloneShallowArrayStub stub(mode, length);
     __ CallStub(&stub);
   }
@@ -1991,7 +2000,7 @@
       __ mov(ip, Operand(scratch1, ASR, 31));
       __ cmp(ip, Operand(scratch2));
       __ b(ne, &stub_call);
-      __ cmp(scratch1, Operand(0));
+      __ cmp(scratch1, Operand::Zero());
       __ mov(right, Operand(scratch1), LeaveCC, ne);
       __ b(ne, &done);
       __ add(scratch2, right, Operand(left), SetCC);
@@ -2687,7 +2696,7 @@
 
   // Skip loop if no descriptors are valid.
   __ NumberOfOwnDescriptors(r3, r1);
-  __ cmp(r3, Operand(0));
+  __ cmp(r3, Operand::Zero());
   __ b(eq, &done);
 
   __ LoadInstanceDescriptors(r1, r4);
@@ -3018,7 +3027,7 @@
     // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
     __ vmov(d7, r0, r1);
     // Move 0x4130000000000000 to VFP.
-    __ mov(r0, Operand(0, RelocInfo::NONE));
+    __ mov(r0, Operand::Zero());
     __ vmov(d8, r0, r1);
     // Subtract and store the result in the heap number.
     __ vsub(d7, d7, d8);
@@ -3634,7 +3643,7 @@
 
   // Check that all array elements are sequential ASCII strings, and
   // accumulate the sum of their lengths, as a smi-encoded value.
-  __ mov(string_length, Operand(0));
+  __ mov(string_length, Operand::Zero());
   __ add(element,
          elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
@@ -3647,7 +3656,7 @@
   //   element: Current array element.
   //   elements_end: Array end.
   if (generate_debug_code_) {
-    __ cmp(array_length, Operand(0));
+    __ cmp(array_length, Operand::Zero());
     __ Assert(gt, "No empty arrays here in EmitFastAsciiArrayJoin");
   }
   __ bind(&loop);
@@ -3690,7 +3699,7 @@
   __ smull(scratch2, ip, array_length, scratch1);
   // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
   // zero.
-  __ cmp(ip, Operand(0));
+  __ cmp(ip, Operand::Zero());
   __ b(ne, &bailout);
   __ tst(scratch2, Operand(0x80000000));
   __ b(ne, &bailout);
@@ -4357,7 +4366,7 @@
       CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
       patch_site.EmitPatchInfo();
       PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-      __ cmp(r0, Operand(0));
+      __ cmp(r0, Operand::Zero());
       Split(cond, if_true, if_false, fall_through);
     }
   }
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 29a3687..5e17694 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -862,7 +862,7 @@
   __ mov(r0, r2);
   __ Ret();
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -891,7 +891,7 @@
   __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs);
   __ Ret();
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -925,7 +925,7 @@
 Object* KeyedLoadIC_Miss(Arguments args);
 
 
-void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
   //  -- r0     : key
@@ -938,7 +938,7 @@
   __ Push(r1, r0);
 
   // Perform tail call to the entry.
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
       ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric), isolate)
       : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
 
@@ -1158,7 +1158,7 @@
   char_at_generator.GenerateSlow(masm, call_helper);
 
   __ bind(&miss);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -1198,11 +1198,11 @@
       1);
 
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
-void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ---------- S t a t e --------------
   //  -- r0     : value
   //  -- r1     : key
@@ -1213,7 +1213,7 @@
   // Push receiver, key and value for runtime call.
   __ Push(r2, r1, r0);
 
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
       ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
                           masm->isolate())
       : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index e2a0f2d..c7fe06c 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -121,7 +121,7 @@
 
 #ifdef DEBUG
     if (strlen(FLAG_stop_at) > 0 &&
-        info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+        info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
       __ stop("stop_at");
     }
 #endif
@@ -137,7 +137,7 @@
     // function calls.
     if (!info_->is_classic_mode() || info_->is_native()) {
       Label ok;
-      __ cmp(r5, Operand(0));
+      __ cmp(r5, Operand::Zero());
       __ b(eq, &ok);
       int receiver_offset = scope()->num_parameters() * kPointerSize;
       __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
@@ -524,11 +524,11 @@
     return Operand(ToRegister(op));
   } else if (op->IsDoubleRegister()) {
     Abort("ToOperand IsDoubleRegister unimplemented");
-    return Operand(0);
+    return Operand::Zero();
   }
   // Stack slots not implemented, use ToMemOperand instead.
   UNREACHABLE();
-  return Operand(0);
+  return Operand::Zero();
 }
 
 
@@ -1076,14 +1076,14 @@
     if (divisor < 0) divisor = -divisor;
 
     Label positive_dividend, done;
-    __ cmp(dividend, Operand(0));
+    __ cmp(dividend, Operand::Zero());
     __ b(pl, &positive_dividend);
-    __ rsb(result, dividend, Operand(0));
+    __ rsb(result, dividend, Operand::Zero());
     __ and_(result, result, Operand(divisor - 1), SetCC);
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       DeoptimizeIf(eq, instr->environment());
     }
-    __ rsb(result, result, Operand(0));
+    __ rsb(result, result, Operand::Zero());
     __ b(&done);
     __ bind(&positive_dividend);
     __ and_(result, dividend, Operand(divisor - 1));
@@ -1101,7 +1101,7 @@
     CpuFeatures::Scope scope(SUDIV);
     // Check for x % 0.
     if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
-      __ cmp(right, Operand(0));
+      __ cmp(right, Operand::Zero());
       DeoptimizeIf(eq, instr->environment());
     }
 
@@ -1121,11 +1121,11 @@
 
     __ sdiv(result, left, right);
     __ mls(result, result, right, left);
-    __ cmp(result, Operand(0));
+    __ cmp(result, Operand::Zero());
     __ b(ne, &done);
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-       __ cmp(left, Operand(0));
+       __ cmp(left, Operand::Zero());
        DeoptimizeIf(lt, instr->environment());
     }
   } else {
@@ -1148,14 +1148,14 @@
 
     // Check for x % 0.
     if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
-      __ cmp(right, Operand(0));
+      __ cmp(right, Operand::Zero());
       DeoptimizeIf(eq, instr->environment());
     }
 
     __ Move(result, left);
 
     // (0 % x) must yield 0 (if x is finite, which is the case here).
-    __ cmp(left, Operand(0));
+    __ cmp(left, Operand::Zero());
     __ b(eq, &done);
     // Preload right in a vfp register.
     __ vmov(divisor.low(), right);
@@ -1175,7 +1175,7 @@
 
     __ bind(&right_negative);
     // Negate right. The sign of the divisor does not matter.
-    __ rsb(right, right, Operand(0));
+    __ rsb(right, right, Operand::Zero());
 
     __ bind(&both_positive);
     const int kUnfolds = 3;
@@ -1226,7 +1226,7 @@
       // Check for -0.
       __ sub(scratch2, left, scratch, SetCC);
       __ b(ne, &ok);
-      __ cmp(left, Operand(0));
+      __ cmp(left, Operand::Zero());
       DeoptimizeIf(mi, instr->environment());
       __ bind(&ok);
       // Load the result and we are done.
@@ -1261,11 +1261,11 @@
       if (divisor > 0) {
         __ Move(result, dividend);
       } else {
-        __ rsb(result, dividend, Operand(0), SetCC);
+        __ rsb(result, dividend, Operand::Zero(), SetCC);
         DeoptimizeIf(vs, environment);
       }
       // Compute the remainder.
-      __ mov(remainder, Operand(0));
+      __ mov(remainder, Operand::Zero());
       return;
 
     default:
@@ -1283,7 +1283,7 @@
         // handled separately.
         if (divisor < 0) {
           ASSERT(divisor != -1);
-          __ rsb(result, result, Operand(0));
+          __ rsb(result, result, Operand::Zero());
         }
         // Compute the remainder.
         if (divisor > 0) {
@@ -1319,7 +1319,7 @@
           __ mov(scratch, Operand(scratch, ASR, s));
         }
         __ add(result, scratch, Operand(dividend, LSR, 31));
-        if (divisor < 0) __ rsb(result, result, Operand(0));
+        if (divisor < 0) __ rsb(result, result, Operand::Zero());
         // Compute the remainder.
         __ mov(ip, Operand(divisor));
         // This sequence could be replaced with 'mls' when
@@ -1354,16 +1354,16 @@
 
   // Check for x / 0.
   if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
-    __ cmp(right, Operand(0));
+    __ cmp(right, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
   }
 
   // Check for (0 / -x) that will produce negative zero.
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label left_not_zero;
-    __ cmp(left, Operand(0));
+    __ cmp(left, Operand::Zero());
     __ b(ne, &left_not_zero);
-    __ cmp(right, Operand(0));
+    __ cmp(right, Operand::Zero());
     DeoptimizeIf(mi, instr->environment());
     __ bind(&left_not_zero);
   }
@@ -1441,7 +1441,7 @@
     int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
     ASSERT(LChunkBuilder::HasMagicNumberForDivisor(divisor));
     if (divisor < 0) {
-      __ cmp(left, Operand(0));
+      __ cmp(left, Operand::Zero());
       DeoptimizeIf(eq, instr->environment());
     }
     EmitSignedIntegerDivisionByConstant(result,
@@ -1451,7 +1451,7 @@
                                         scratch,
                                         instr->environment());
     // We performed a truncating division. Correct the result if necessary.
-    __ cmp(remainder, Operand(0));
+    __ cmp(remainder, Operand::Zero());
     __ teq(remainder, Operand(divisor), ne);
     __ sub(result, result, Operand(1), LeaveCC, mi);
   } else {
@@ -1459,7 +1459,7 @@
     const Register right = ToRegister(instr->right());
 
     // Check for x / 0.
-    __ cmp(right, Operand(0));
+    __ cmp(right, Operand::Zero());
     DeoptimizeIf(eq, instr->environment());
 
     // Check for (kMinInt / -1).
@@ -1474,8 +1474,8 @@
 
     // Check for (0 / -x) that will produce negative zero.
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      __ cmp(right, Operand(0));
-      __ cmp(left, Operand(0), mi);
+      __ cmp(right, Operand::Zero());
+      __ cmp(left, Operand::Zero(), mi);
       // "right" can't be null because the code would have already been
       // deoptimized. The Z flag is set only if (right < 0) and (left == 0).
       // In this case we need to deoptimize to produce a -0.
@@ -1490,7 +1490,7 @@
 
     // Check if the result needs to be corrected.
     __ mls(remainder, result, right, left);
-    __ cmp(remainder, Operand(0));
+    __ cmp(remainder, Operand::Zero());
     __ sub(result, result, Operand(1), LeaveCC, ne);
 
     __ bind(&done);
@@ -1549,22 +1549,22 @@
     if (bailout_on_minus_zero && (constant < 0)) {
       // The case of a null constant will be handled separately.
       // If constant is negative and left is null, the result should be -0.
-      __ cmp(left, Operand(0));
+      __ cmp(left, Operand::Zero());
       DeoptimizeIf(eq, instr->environment());
     }
 
     switch (constant) {
       case -1:
-        __ rsb(result, left, Operand(0));
+        __ rsb(result, left, Operand::Zero());
         break;
       case 0:
         if (bailout_on_minus_zero) {
           // If left is strictly negative and the constant is null, the
           // result is -0. Deoptimize if required, otherwise return 0.
-          __ cmp(left, Operand(0));
+          __ cmp(left, Operand::Zero());
           DeoptimizeIf(mi, instr->environment());
         }
-        __ mov(result, Operand(0));
+        __ mov(result, Operand::Zero());
         break;
       case 1:
         __ Move(result, left);
@@ -1591,7 +1591,7 @@
           }
 
           // Correct the sign of the result is the constant is negative.
-          if (constant < 0)  __ rsb(result, result, Operand(0));
+          if (constant < 0)  __ rsb(result, result, Operand::Zero());
 
         } else {
           // Generate standard code.
@@ -1618,9 +1618,9 @@
     if (bailout_on_minus_zero) {
       // Bail out if the result is supposed to be negative zero.
       Label done;
-      __ cmp(result, Operand(0));
+      __ cmp(result, Operand::Zero());
       __ b(ne, &done);
-      __ cmp(ToRegister(instr->temp()), Operand(0));
+      __ cmp(ToRegister(instr->temp()), Operand::Zero());
       DeoptimizeIf(mi, instr->environment());
       __ bind(&done);
     }
@@ -2100,7 +2100,7 @@
   Representation r = instr->hydrogen()->value()->representation();
   if (r.IsInteger32()) {
     Register reg = ToRegister(instr->value());
-    __ cmp(reg, Operand(0));
+    __ cmp(reg, Operand::Zero());
     EmitBranch(true_block, false_block, ne);
   } else if (r.IsDouble()) {
     CpuFeatures::Scope scope(VFP2);
@@ -2119,7 +2119,7 @@
       __ CompareRoot(reg, Heap::kTrueValueRootIndex);
       EmitBranch(true_block, false_block, eq);
     } else if (type.IsSmi()) {
-      __ cmp(reg, Operand(0));
+      __ cmp(reg, Operand::Zero());
       EmitBranch(true_block, false_block, ne);
     } else {
       Label* true_label = chunk_->GetAssemblyLabel(true_block);
@@ -2149,7 +2149,7 @@
 
       if (expected.Contains(ToBooleanStub::SMI)) {
         // Smis: 0 -> false, all other -> true.
-        __ cmp(reg, Operand(0));
+        __ cmp(reg, Operand::Zero());
         __ b(eq, false_label);
         __ JumpIfSmi(reg, true_label);
       } else if (expected.NeedsMap()) {
@@ -2182,7 +2182,7 @@
         __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
         __ b(ge, &not_string);
         __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset));
-        __ cmp(ip, Operand(0));
+        __ cmp(ip, Operand::Zero());
         __ b(ne, true_label);
         __ b(false_label);
         __ bind(&not_string);
@@ -2477,7 +2477,8 @@
 
   Handle<Code> ic = CompareIC::GetUninitialized(op);
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
-  __ cmp(r0, Operand(0));  // This instruction also signals no smi code inlined.
+  // This instruction also signals no smi code inlined.
+  __ cmp(r0, Operand::Zero());
 
   Condition condition = ComputeCompareCondition(op);
 
@@ -2561,7 +2562,7 @@
 
   __ JumpIfSmi(input, is_false);
 
-  if (class_name->IsEqualTo(CStrVector("Function"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) {
     // Assuming the following assertions, we can use the same compares to test
     // for both being a function type and being in the object type range.
     STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
@@ -2592,7 +2593,7 @@
 
   // Objects with a non-function constructor have class 'Object'.
   __ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE);
-  if (class_name->IsEqualTo(CStrVector("Object"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) {
     __ b(ne, is_true);
   } else {
     __ b(ne, is_false);
@@ -2651,7 +2652,7 @@
   InstanceofStub stub(InstanceofStub::kArgsInRegisters);
   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 
-  __ cmp(r0, Operand(0));
+  __ cmp(r0, Operand::Zero());
   __ mov(r0, Operand(factory()->false_value()), LeaveCC, ne);
   __ mov(r0, Operand(factory()->true_value()), LeaveCC, eq);
 }
@@ -2795,7 +2796,8 @@
 
   Handle<Code> ic = CompareIC::GetUninitialized(op);
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
-  __ cmp(r0, Operand(0));  // This instruction also signals no smi code inlined.
+  // This instruction also signals no smi code inlined.
+  __ cmp(r0, Operand::Zero());
 
   Condition condition = ComputeCompareCondition(op);
   __ LoadRoot(ToRegister(instr->result()),
@@ -3535,7 +3537,7 @@
   // stack.
   Label invoke, loop;
   // length is a small non-negative integer, due to the test above.
-  __ cmp(length, Operand(0));
+  __ cmp(length, Operand::Zero());
   __ b(eq, &invoke);
   __ bind(&loop);
   __ ldr(scratch, MemOperand(elements, length, LSL, 2));
@@ -3739,12 +3741,12 @@
 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
   Register input = ToRegister(instr->value());
   Register result = ToRegister(instr->result());
-  __ cmp(input, Operand(0));
+  __ cmp(input, Operand::Zero());
   __ Move(result, input, pl);
   // We can make rsb conditional because the previous cmp instruction
   // will clear the V (overflow) flag and rsb won't set this flag
   // if input is positive.
-  __ rsb(result, input, Operand(0), SetCC, mi);
+  __ rsb(result, input, Operand::Zero(), SetCC, mi);
   // Deoptimize on overflow.
   DeoptimizeIf(vs, instr->environment());
 }
@@ -3803,7 +3805,7 @@
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Test for -0.
     Label done;
-    __ cmp(result, Operand(0));
+    __ cmp(result, Operand::Zero());
     __ b(ne, &done);
     __ vmov(scratch, input.high());
     __ tst(scratch, Operand(HeapNumber::kSignMask));
@@ -3830,7 +3832,7 @@
 
   // If the number is in ]-0.5, +0.5[, the result is +/- 0.
   __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2));
-  __ mov(result, Operand(0), LeaveCC, le);
+  __ mov(result, Operand::Zero(), LeaveCC, le);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     __ b(le, &check_sign_on_zero);
   } else {
@@ -3855,7 +3857,7 @@
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     DeoptimizeIf(mi, instr->environment());
   } else {
-    __ mov(result, Operand(0), LeaveCC, mi);
+    __ mov(result, Operand::Zero(), LeaveCC, mi);
     __ b(mi, &done);
   }
 
@@ -3868,7 +3870,7 @@
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Test for -0.
-    __ cmp(result, Operand(0));
+    __ cmp(result, Operand::Zero());
     __ b(ne, &done);
     __ bind(&check_sign_on_zero);
     __ vmov(scratch, input.high());
@@ -3972,7 +3974,7 @@
 
   // Load state[0].
   __ ldr(r1, FieldMemOperand(r2, ByteArray::kHeaderSize));
-  __ cmp(r1, Operand(0));
+  __ cmp(r1, Operand::Zero());
   __ b(eq, deferred->entry());
   // Load state[1].
   __ ldr(r0, FieldMemOperand(r2, ByteArray::kHeaderSize + kSeedSize));
@@ -4007,7 +4009,7 @@
   // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
   __ vmov(d7, r0, r1);
   // Move 0x4130000000000000 to VFP.
-  __ mov(r0, Operand(0, RelocInfo::NONE));
+  __ mov(r0, Operand::Zero());
   __ vmov(d8, r0, r1);
   // Subtract and store the result in the heap number.
   __ vsub(d7, d7, d8);
@@ -4582,7 +4584,7 @@
   // TODO(3095996): Get rid of this. For now, we need to make the
   // result register contain a valid pointer because it is already
   // contained in the register pointer map.
-  __ mov(result, Operand(0));
+  __ mov(result, Operand::Zero());
 
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
   __ push(string);
@@ -4623,7 +4625,7 @@
   Register result = ToRegister(instr->result());
   ASSERT(!char_code.is(result));
 
-  __ cmp(char_code, Operand(String::kMaxAsciiCharCode));
+  __ cmp(char_code, Operand(String::kMaxOneByteCharCode));
   __ b(hi, deferred->entry());
   __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
   __ add(result, result, Operand(char_code, LSL, kPointerSizeLog2));
@@ -4642,7 +4644,7 @@
   // TODO(3095996): Get rid of this. For now, we need to make the
   // result register contain a valid pointer because it is already
   // contained in the register pointer map.
-  __ mov(result, Operand(0));
+  __ mov(result, Operand::Zero());
 
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
   __ SmiTag(char_code);
@@ -4763,7 +4765,7 @@
     masm->orr(hiword, scratch,
               Operand(hiword, LSR, mantissa_shift_for_hi_word));
   } else {
-    masm->mov(loword, Operand(0, RelocInfo::NONE));
+    masm->mov(loword, Operand::Zero());
     masm->orr(hiword, scratch,
               Operand(hiword, LSL, -mantissa_shift_for_hi_word));
   }
@@ -4841,7 +4843,7 @@
   // TODO(3095996): Put a valid pointer value in the stack slot where the result
   // register is stored, as this register is in the pointer map, but contains an
   // integer value.
-  __ mov(ip, Operand(0));
+  __ mov(ip, Operand::Zero());
   __ StoreToSafepointRegisterSlot(ip, dst);
   CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
   __ Move(dst, r0);
@@ -4906,7 +4908,7 @@
   // result register contain a valid pointer because it is already
   // contained in the register pointer map.
   Register reg = ToRegister(instr->result());
-  __ mov(reg, Operand(0));
+  __ mov(reg, Operand::Zero());
 
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
   CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
@@ -4977,7 +4979,7 @@
   __ vldr(result_reg, ip, HeapNumber::kValueOffset);
   if (deoptimize_on_minus_zero) {
     __ vmov(ip, result_reg.low());
-    __ cmp(ip, Operand(0));
+    __ cmp(ip, Operand::Zero());
     __ b(ne, &done);
     __ vmov(ip, result_reg.high());
     __ cmp(ip, Operand(HeapNumber::kSignMask));
@@ -5032,7 +5034,7 @@
     __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
     __ cmp(input_reg, Operand(ip));
     DeoptimizeIf(ne, instr->environment());
-    __ mov(input_reg, Operand(0));
+    __ mov(input_reg, Operand::Zero());
     __ b(&done);
 
     __ bind(&heap_number);
@@ -5062,7 +5064,7 @@
     DeoptimizeIf(ne, instr->environment());
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      __ cmp(input_reg, Operand(0));
+      __ cmp(input_reg, Operand::Zero());
       __ b(ne, &done);
       __ vmov(scratch1, double_scratch.high());
       __ tst(scratch1, Operand(HeapNumber::kSignMask));
@@ -5293,7 +5295,7 @@
   // conversions.
   __ cmp(input_reg, Operand(factory()->undefined_value()));
   DeoptimizeIf(ne, instr->environment());
-  __ mov(result_reg, Operand(0));
+  __ mov(result_reg, Operand::Zero());
   __ jmp(&done);
 
   // Heap number
@@ -5415,7 +5417,7 @@
   // TODO(3095996): Get rid of this. For now, we need to make the
   // result register contain a valid pointer because it is already
   // contained in the register pointer map.
-  __ mov(result, Operand(0));
+  __ mov(result, Operand::Zero());
 
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
   __ mov(r0, Operand(Smi::FromInt(instance_size)));
@@ -6044,7 +6046,7 @@
          FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
   __ ldr(result,
          FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
-  __ cmp(result, Operand(0));
+  __ cmp(result, Operand::Zero());
   DeoptimizeIf(eq, instr->environment());
 
   __ bind(&done);
@@ -6067,7 +6069,7 @@
   Register scratch = scratch0();
 
   Label out_of_object, done;
-  __ cmp(index, Operand(0));
+  __ cmp(index, Operand::Zero());
   __ b(lt, &out_of_object);
 
   STATIC_ASSERT(kPointerSizeLog2 > kSmiTagSize);
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 0764e09..d7ea107 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -304,7 +304,7 @@
   if (!src2.is_reg() &&
       !src2.must_output_reloc_info(this) &&
       src2.immediate() == 0) {
-    mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond);
+    mov(dst, Operand::Zero(), LeaveCC, cond);
   } else if (!src2.is_single_instruction(this) &&
              !src2.must_output_reloc_info(this) &&
              CpuFeatures::IsSupported(ARMv7) &&
@@ -410,7 +410,7 @@
     }
     tst(dst, Operand(~satval));
     b(eq, &done);
-    mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, mi);  // 0 if negative.
+    mov(dst, Operand::Zero(), LeaveCC, mi);  // 0 if negative.
     mov(dst, Operand(satval), LeaveCC, pl);  // satval if positive.
     bind(&done);
   } else {
@@ -864,7 +864,7 @@
   // Reserve room for saved entry sp and code object.
   sub(sp, sp, Operand(2 * kPointerSize));
   if (emit_debug_code()) {
-    mov(ip, Operand(0));
+    mov(ip, Operand::Zero());
     str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
   }
   mov(ip, Operand(CodeObject()));
@@ -948,7 +948,7 @@
   }
 
   // Clear top frame.
-  mov(r3, Operand(0, RelocInfo::NONE));
+  mov(r3, Operand::Zero());
   mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
   str(r3, MemOperand(ip));
 
@@ -1218,7 +1218,7 @@
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 void MacroAssembler::DebugBreak() {
-  mov(r0, Operand(0, RelocInfo::NONE));
+  mov(r0, Operand::Zero());
   mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate())));
   CEntryStub ces(1);
   ASSERT(AllowThisStubCall(&ces));
@@ -1249,7 +1249,7 @@
   // Push the frame pointer, context, state, and code object.
   if (kind == StackHandler::JS_ENTRY) {
     mov(r7, Operand(Smi::FromInt(0)));  // Indicates no context.
-    mov(ip, Operand(0, RelocInfo::NONE));  // NULL frame pointer.
+    mov(ip, Operand::Zero());  // NULL frame pointer.
     stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | ip.bit());
   } else {
     stm(db_w, sp, r5.bit() | r6.bit() | cp.bit() | fp.bit());
@@ -1373,7 +1373,7 @@
   ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset));
   // In debug mode, make sure the lexical context is set.
 #ifdef DEBUG
-  cmp(scratch, Operand(0, RelocInfo::NONE));
+  cmp(scratch, Operand::Zero());
   Check(ne, "we should not have an empty lexical context");
 #endif
 
@@ -2025,7 +2025,7 @@
   // it's an Infinity, and the non-NaN code path applies.
   b(gt, &is_nan);
   ldr(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
-  cmp(mantissa_reg, Operand(0));
+  cmp(mantissa_reg, Operand::Zero());
   b(eq, &have_double_value);
   bind(&is_nan);
   // Load canonical NaN for storing into the double array.
@@ -2277,7 +2277,7 @@
 
   // If result is non-zero, dereference to get the result value
   // otherwise set it to undefined.
-  cmp(r0, Operand(0));
+  cmp(r0, Operand::Zero());
   LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
   ldr(r0, MemOperand(r0), ne);
 
@@ -2456,7 +2456,7 @@
          HeapNumber::kExponentBits);
     // Load dest with zero.  We use this either for the final shift or
     // for the answer.
-    mov(dest, Operand(0, RelocInfo::NONE));
+    mov(dest, Operand::Zero());
     // Check whether the exponent matches a 32 bit signed int that is not a Smi.
     // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). This is
     // the exponent that we are fastest at and also the highest exponent we can
@@ -2510,7 +2510,7 @@
     // Move down according to the exponent.
     mov(dest, Operand(scratch, LSR, dest));
     // Fix sign if sign bit was set.
-    rsb(dest, dest, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+    rsb(dest, dest, Operand::Zero(), LeaveCC, ne);
     bind(&done);
   }
 }
@@ -2601,7 +2601,7 @@
 
   // Check for Infinity and NaNs, which should return 0.
   cmp(result, Operand(HeapNumber::kExponentMask));
-  mov(result, Operand(0), LeaveCC, eq);
+  mov(result, Operand::Zero(), LeaveCC, eq);
   b(eq, &done);
 
   // Express exponent as delta to (number of mantissa bits + 31).
@@ -2613,7 +2613,7 @@
   // If the delta is strictly positive, all bits would be shifted away,
   // which means that we can return 0.
   b(le, &normal_exponent);
-  mov(result, Operand(0));
+  mov(result, Operand::Zero());
   b(&done);
 
   bind(&normal_exponent);
@@ -2641,7 +2641,7 @@
   b(&pos_shift, ge);
 
   // Negate scratch.
-  rsb(scratch, scratch, Operand(0));
+  rsb(scratch, scratch, Operand::Zero());
   mov(input_low, Operand(input_low, LSL, scratch));
   b(&shift_done);
 
@@ -2651,10 +2651,10 @@
   bind(&shift_done);
   orr(input_high, input_high, Operand(input_low));
   // Restore sign if necessary.
-  cmp(sign, Operand(0));
+  cmp(sign, Operand::Zero());
   result = sign;
   sign = no_reg;
-  rsb(result, input_high, Operand(0), LeaveCC, ne);
+  rsb(result, input_high, Operand::Zero(), LeaveCC, ne);
   mov(result, input_high, LeaveCC, eq);
   bind(&done);
 }
@@ -3295,7 +3295,7 @@
 
   // Align src before copying in word size chunks.
   bind(&align_loop);
-  cmp(length, Operand(0));
+  cmp(length, Operand::Zero());
   b(eq, &done);
   bind(&align_loop_1);
   tst(src, Operand(kPointerSize - 1));
@@ -3330,7 +3330,7 @@
 
   // Copy the last bytes if any left.
   bind(&byte_loop);
-  cmp(length, Operand(0));
+  cmp(length, Operand::Zero());
   b(eq, &done);
   bind(&byte_loop_1);
   ldrb(scratch, MemOperand(src, 1, PostIndex));
@@ -3368,7 +3368,7 @@
   // Order of the next two lines is important: zeros register
   // can be the same as source register.
   Move(scratch, source);
-  mov(zeros, Operand(0, RelocInfo::NONE));
+  mov(zeros, Operand::Zero());
   // Top 16.
   tst(scratch, Operand(0xffff0000));
   add(zeros, zeros, Operand(16), LeaveCC, eq);
@@ -3800,7 +3800,7 @@
   b(gt, &above_zero);
 
   // Double value is less than zero, NaN or Inf, return 0.
-  mov(result_reg, Operand(0));
+  mov(result_reg, Operand::Zero());
   b(al, &done);
 
   // Double value is >= 255, return 255.
@@ -3883,6 +3883,29 @@
 }
 
 
+void MacroAssembler::TestJSArrayForAllocationSiteInfo(
+    Register receiver_reg,
+    Register scratch_reg,
+    Label* allocation_info_present) {
+  Label no_info_available;
+  ExternalReference new_space_start =
+      ExternalReference::new_space_start(isolate());
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address(isolate());
+  ldr(scratch_reg, FieldMemOperand(receiver_reg,
+                                   JSArray::kSize + AllocationSiteInfo::kSize));
+  cmp(scratch_reg, Operand(new_space_start));
+  b(lt, &no_info_available);
+  cmp(scratch_reg, Operand(new_space_allocation_top));
+  b(hs, &no_info_available);
+  ldr(scratch_reg, MemOperand(scratch_reg, 0));
+  cmp(scratch_reg,
+      Operand(Handle<Map>(isolate()->heap()->allocation_site_info_map())));
+  b(eq, allocation_info_present);
+  bind(&no_info_available);
+}
+
+
 #ifdef DEBUG
 bool AreAliased(Register reg1,
                 Register reg2,
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 454e645..d1b94cd 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -1309,6 +1309,16 @@
   // in r0.  Assumes that any other register can be used as a scratch.
   void CheckEnumCache(Register null_value, Label* call_runtime);
 
+  // AllocationSiteInfo support. Arrays may have an associated
+  // AllocationSiteInfo object that can be checked for in order to pretransition
+  // to another type.
+  // On entry, receiver_reg should point to the array object.
+  // scratch_reg gets clobbered.
+  // If allocation info is present, jump to allocation_info_present
+  void TestJSArrayForAllocationSiteInfo(Register receiver_reg,
+                                        Register scratch_reg,
+                                        Label* allocation_info_present);
+
  private:
   void CallCFunctionHelper(Register function,
                            int num_reg_arguments,
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index d852d23..acb24ef 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -204,7 +204,7 @@
   Label not_at_start;
   // Did we start the match at the start of the string at all?
   __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
-  __ cmp(r0, Operand(0, RelocInfo::NONE));
+  __ cmp(r0, Operand::Zero());
   BranchOrBacktrack(ne, &not_at_start);
 
   // If we did, are we still at the start of the input?
@@ -219,7 +219,7 @@
 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) {
   // Did we start the match at the start of the string at all?
   __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
-  __ cmp(r0, Operand(0, RelocInfo::NONE));
+  __ cmp(r0, Operand::Zero());
   BranchOrBacktrack(ne, on_not_at_start);
   // If we did, are we still at the start of the input?
   __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
@@ -261,7 +261,7 @@
   for (int i = 0; i < str.length(); i++) {
     if (mode_ == ASCII) {
       __ ldrb(r1, MemOperand(r0, char_size(), PostIndex));
-      ASSERT(str[i] <= String::kMaxAsciiCharCode);
+      ASSERT(str[i] <= String::kMaxOneByteCharCode);
       __ cmp(r1, Operand(str[i]));
     } else {
       __ ldrh(r1, MemOperand(r0, char_size(), PostIndex));
@@ -337,8 +337,17 @@
     __ b(ne, &fail);
     __ sub(r3, r3, Operand('a'));
     __ cmp(r3, Operand('z' - 'a'));  // Is r3 a lowercase letter?
+#ifndef ENABLE_LATIN_1
     __ b(hi, &fail);
-
+#else
+    __ b(ls, &loop_check);  // In range 'a'-'z'.
+    // Latin-1: Check for values in range [224,254] but not 247.
+    __ sub(r3, r3, Operand(224 - 'a'));
+    __ cmp(r3, Operand(254 - 224));
+    __ b(hi, &fail);  // Weren't Latin-1 letters.
+    __ cmp(r3, Operand(247 - 224));  // Check for 247.
+    __ b(eq, &fail);
+#endif
 
     __ bind(&loop_check);
     __ cmp(r0, r1);
@@ -385,7 +394,7 @@
     }
 
     // Check if function returned non-zero for success or zero for failure.
-    __ cmp(r0, Operand(0, RelocInfo::NONE));
+    __ cmp(r0, Operand::Zero());
     BranchOrBacktrack(eq, on_no_match);
     // On success, increment position by length of capture.
     __ add(current_input_offset(), current_input_offset(), Operand(r4));
@@ -508,7 +517,7 @@
     Handle<ByteArray> table,
     Label* on_bit_set) {
   __ mov(r0, Operand(table));
-  if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) {
+  if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) {
     __ and_(r1, current_character(), Operand(kTableSize - 1));
     __ add(r1, r1, Operand(ByteArray::kHeaderSize - kHeapObjectTag));
   } else {
@@ -517,7 +526,7 @@
            Operand(ByteArray::kHeaderSize - kHeapObjectTag));
   }
   __ ldrb(r0, MemOperand(r0, r1));
-  __ cmp(r0, Operand(0));
+  __ cmp(r0, Operand::Zero());
   BranchOrBacktrack(ne, on_bit_set);
 }
 
@@ -613,7 +622,7 @@
     ExternalReference map = ExternalReference::re_word_character_map();
     __ mov(r0, Operand(map));
     __ ldrb(r0, MemOperand(r0, current_character()));
-    __ cmp(r0, Operand(0));
+    __ cmp(r0, Operand::Zero());
     BranchOrBacktrack(eq, on_no_match);
     return true;
   }
@@ -627,7 +636,7 @@
     ExternalReference map = ExternalReference::re_word_character_map();
     __ mov(r0, Operand(map));
     __ ldrb(r0, MemOperand(r0, current_character()));
-    __ cmp(r0, Operand(0));
+    __ cmp(r0, Operand::Zero());
     BranchOrBacktrack(ne, on_no_match);
     if (mode_ != ASCII) {
       __ bind(&done);
@@ -675,7 +684,7 @@
   // Set frame pointer in space for it if this is not a direct call
   // from generated code.
   __ add(frame_pointer(), sp, Operand(4 * kPointerSize));
-  __ mov(r0, Operand(0, RelocInfo::NONE));
+  __ mov(r0, Operand::Zero());
   __ push(r0);  // Make room for success counter and initialize it to 0.
   __ push(r0);  // Make room for "position - 1" constant (value is irrelevant).
   // Check if we have space on the stack for registers.
@@ -700,7 +709,7 @@
 
   __ bind(&stack_limit_hit);
   CallCheckStackGuardState(r0);
-  __ cmp(r0, Operand(0, RelocInfo::NONE));
+  __ cmp(r0, Operand::Zero());
   // If returned value is non-zero, we exit with the returned value as result.
   __ b(ne, &return_r0);
 
@@ -728,7 +737,7 @@
 
   Label load_char_start_regexp, start_regexp;
   // Load newline if index is at start, previous character otherwise.
-  __ cmp(r1, Operand(0, RelocInfo::NONE));
+  __ cmp(r1, Operand::Zero());
   __ b(ne, &load_char_start_regexp);
   __ mov(current_character(), Operand('\n'), LeaveCC, eq);
   __ jmp(&start_regexp);
@@ -834,7 +843,7 @@
         // Not a zero-length match, restart.
         __ b(ne, &load_char_start_regexp);
         // Offset from the end is zero if we already reached the end.
-        __ cmp(current_input_offset(), Operand(0));
+        __ cmp(current_input_offset(), Operand::Zero());
         __ b(eq, &exit_label_);
         // Advance current position after a zero-length match.
         __ add(current_input_offset(),
@@ -873,7 +882,7 @@
     SafeCallTarget(&check_preempt_label_);
 
     CallCheckStackGuardState(r0);
-    __ cmp(r0, Operand(0, RelocInfo::NONE));
+    __ cmp(r0, Operand::Zero());
     // If returning non-zero, we should end execution with the given
     // result as return value.
     __ b(ne, &return_r0);
@@ -900,7 +909,7 @@
     __ CallCFunction(grow_stack, num_arguments);
     // If return NULL, we have failed to grow the stack, and
     // must exit with a stack-overflow exception.
-    __ cmp(r0, Operand(0, RelocInfo::NONE));
+    __ cmp(r0, Operand::Zero());
     __ b(eq, &exit_with_exception);
     // Otherwise use return value as new stack pointer.
     __ mov(backtrack_stackpointer(), r0);
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index d11e340..c143cc5 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -1776,7 +1776,7 @@
         if (::v8::internal::FLAG_trace_sim) {
           PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
         }
-        set_register(r0, (int32_t) *result);
+        set_register(r0, reinterpret_cast<int32_t>(*result));
       } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
         SimulatorRuntimeDirectGetterCall target =
             reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
@@ -1793,7 +1793,7 @@
         if (::v8::internal::FLAG_trace_sim) {
           PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
         }
-        set_register(r0, (int32_t) *result);
+        set_register(r0, reinterpret_cast<int32_t>(*result));
       } else {
         // builtin call.
         ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
@@ -3083,15 +3083,15 @@
 
     if (src_precision == kDoublePrecision) {
       if (unsigned_integer) {
-        set_d_register_from_double(dst,
-                                   static_cast<double>((uint32_t)val));
+        set_d_register_from_double(
+            dst, static_cast<double>(static_cast<uint32_t>(val)));
       } else {
         set_d_register_from_double(dst, static_cast<double>(val));
       }
     } else {
       if (unsigned_integer) {
-        set_s_register_from_float(dst,
-                                  static_cast<float>((uint32_t)val));
+        set_s_register_from_float(
+            dst, static_cast<float>(static_cast<uint32_t>(val)));
       } else {
         set_s_register_from_float(dst, static_cast<float>(val));
       }
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index dd5db30..dcc88f7 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -735,7 +735,7 @@
   __ mov(ip, Operand(argc));
   __ str(ip, MemOperand(r0, 2 * kPointerSize));
   // v8::Arguments::is_construct_call = 0
-  __ mov(ip, Operand(0));
+  __ mov(ip, Operand::Zero());
   __ str(ip, MemOperand(r0, 3 * kPointerSize));
 
   const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
@@ -1008,7 +1008,7 @@
 
     __ and_(fval, ival, Operand(kBinary32SignMask), SetCC);
     // Negate value if it is negative.
-    __ rsb(ival, ival, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+    __ rsb(ival, ival, Operand::Zero(), LeaveCC, ne);
 
     // We have -1, 0 or 1, which we treat specially. Register ival contains
     // absolute value: it is either equal to 1 (special case of -1 and 1),
@@ -2241,7 +2241,7 @@
   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
 
   // Check for -0.
-  __ cmp(r0, Operand(0, RelocInfo::NONE));
+  __ cmp(r0, Operand::Zero());
   __ b(&restore_fpscr_and_return, ne);
   // r5 already holds the HeapNumber exponent.
   __ tst(r5, Operand(HeapNumber::kSignMask));
@@ -3327,7 +3327,7 @@
   __ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3431,7 +3431,7 @@
   __ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3944,18 +3944,18 @@
         // and infinities. All these should be converted to 0.
         __ mov(r7, Operand(HeapNumber::kExponentMask));
         __ and_(r9, r5, Operand(r7), SetCC);
-        __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq);
+        __ mov(r5, Operand::Zero(), LeaveCC, eq);
         __ b(eq, &done);
 
         __ teq(r9, Operand(r7));
-        __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, eq);
+        __ mov(r5, Operand::Zero(), LeaveCC, eq);
         __ b(eq, &done);
 
         // Unbias exponent.
         __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift));
         __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC);
         // If exponent is negative then result is 0.
-        __ mov(r5, Operand(0, RelocInfo::NONE), LeaveCC, mi);
+        __ mov(r5, Operand::Zero(), LeaveCC, mi);
         __ b(mi, &done);
 
         // If exponent is too big then result is minimal value.
@@ -3971,14 +3971,14 @@
         __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl);
         __ b(pl, &sign);
 
-        __ rsb(r9, r9, Operand(0, RelocInfo::NONE));
+        __ rsb(r9, r9, Operand::Zero());
         __ mov(r5, Operand(r5, LSL, r9));
         __ rsb(r9, r9, Operand(meaningfull_bits));
         __ orr(r5, r5, Operand(r6, LSR, r9));
 
         __ bind(&sign);
-        __ teq(r7, Operand(0, RelocInfo::NONE));
-        __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne);
+        __ teq(r7, Operand::Zero());
+        __ rsb(r5, r5, Operand::Zero(), LeaveCC, ne);
 
         __ bind(&done);
         switch (elements_kind) {
diff --git a/src/assembler.cc b/src/assembler.cc
index f1d5de1..e284974 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -692,7 +692,7 @@
 #ifdef ENABLE_DISASSEMBLER
 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
   switch (rmode) {
-    case RelocInfo::NONE:
+    case RelocInfo::NONE32:
       return "no reloc 32";
     case RelocInfo::NONE64:
       return "no reloc 64";
@@ -818,7 +818,7 @@
     case INTERNAL_REFERENCE:
     case CONST_POOL:
     case DEBUG_BREAK_SLOT:
-    case NONE:
+    case NONE32:
     case NONE64:
       break;
     case NUMBER_OF_MODES:
@@ -1403,7 +1403,8 @@
 
 
 double power_double_double(double x, double y) {
-#ifdef __MINGW64_VERSION_MAJOR
+#if defined(__MINGW64_VERSION_MAJOR) && \
+    (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1)
   // MinGW64 has a custom implementation for pow.  This handles certain
   // special cases that are different.
   if ((x == 0.0 || isinf(x)) && isfinite(y)) {
diff --git a/src/assembler.h b/src/assembler.h
index cebd60a..ebddf82 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -248,7 +248,7 @@
     // add more as needed
     // Pseudo-types
     NUMBER_OF_MODES,  // There are at most 15 modes with noncompact encoding.
-    NONE,  // never recorded 32-bit value
+    NONE32,  // never recorded 32-bit value
     NONE64,  // never recorded 64-bit value
     CODE_AGE_SEQUENCE,  // Not stored in RelocInfo array, used explictly by
                         // code aging.
@@ -320,7 +320,7 @@
     return mode == DEBUG_BREAK_SLOT;
   }
   static inline bool IsNone(Mode mode) {
-    return mode == NONE || mode == NONE64;
+    return mode == NONE32 || mode == NONE64;
   }
   static inline bool IsCodeAgeSequence(Mode mode) {
     return mode == CODE_AGE_SEQUENCE;
diff --git a/src/ast.cc b/src/ast.cc
index c43b913..e2acd20 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -430,7 +430,7 @@
   } else if (is_monomorphic_) {
     receiver_types_.Add(oracle->LoadMonomorphicReceiverType(this),
                         zone);
-  } else if (oracle->LoadIsMegamorphicWithTypeInfo(this)) {
+  } else if (oracle->LoadIsPolymorphic(this)) {
     receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
     oracle->CollectKeyedReceiverTypes(PropertyFeedbackId(), &receiver_types_);
   }
@@ -452,7 +452,7 @@
   } else if (is_monomorphic_) {
     // Record receiver type for monomorphic keyed stores.
     receiver_types_.Add(oracle->StoreMonomorphicReceiverType(id), zone);
-  } else if (oracle->StoreIsMegamorphicWithTypeInfo(id)) {
+  } else if (oracle->StoreIsPolymorphic(id)) {
     receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
     oracle->CollectKeyedReceiverTypes(id, &receiver_types_);
   }
@@ -468,7 +468,7 @@
     // Record receiver type for monomorphic keyed stores.
     receiver_types_.Add(
         oracle->StoreMonomorphicReceiverType(id), zone);
-  } else if (oracle->StoreIsMegamorphicWithTypeInfo(id)) {
+  } else if (oracle->StoreIsPolymorphic(id)) {
     receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
     oracle->CollectKeyedReceiverTypes(id, &receiver_types_);
   }
@@ -1083,8 +1083,9 @@
     // optimize them.
     add_flag(kDontInline);
   } else if (node->function()->intrinsic_type == Runtime::INLINE &&
-      (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
-       node->name()->IsEqualTo(CStrVector("_Arguments")))) {
+      (node->name()->IsOneByteEqualTo(
+          STATIC_ASCII_VECTOR("_ArgumentsLength")) ||
+       node->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_Arguments")))) {
     // Don't inline the %_ArgumentsLength or %_Arguments because their
     // implementation will not work.  There is no stack frame to get them
     // from.
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index bf96c8c..762c4f9 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -499,7 +499,8 @@
           Builtins::kEmptyFunction));
   empty_function->set_code(*code);
   empty_function->shared()->set_code(*code);
-  Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
+  Handle<String> source =
+      factory->NewStringFromOneByte(STATIC_ASCII_VECTOR("() {}"));
   Handle<Script> script = factory->NewScript(source);
   script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
   empty_function->shared()->set_script(*script);
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index d61c031..fead456 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -55,7 +55,7 @@
   bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) {
     for (int i = 0; i < cache_->length(); i+=2) {
       SeqOneByteString* str = SeqOneByteString::cast(cache_->get(i));
-      if (str->IsEqualTo(name)) {
+      if (str->IsUtf8EqualTo(name)) {
         *handle = Handle<SharedFunctionInfo>(
             SharedFunctionInfo::cast(cache_->get(i + 1)));
         return true;
diff --git a/src/builtins.cc b/src/builtins.cc
index 3143dd9..786627d 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -337,26 +337,6 @@
 }
 
 
-static void MoveElements(Heap* heap,
-                         AssertNoAllocation* no_gc,
-                         FixedArray* dst,
-                         int dst_index,
-                         FixedArray* src,
-                         int src_index,
-                         int len) {
-  if (len == 0) return;
-  ASSERT(dst->map() != HEAP->fixed_cow_array_map());
-  memmove(dst->data_start() + dst_index,
-          src->data_start() + src_index,
-          len * kPointerSize);
-  WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
-  if (mode == UPDATE_WRITE_BARRIER) {
-    heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
-  }
-  heap->incremental_marking()->RecordWrites(dst);
-}
-
-
 static void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
   ASSERT(dst->map() != heap->fixed_cow_array_map());
   MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
@@ -724,7 +704,7 @@
     if (elms_obj->IsFixedArray()) {
       FixedArray* elms = FixedArray::cast(elms_obj);
       AssertNoAllocation no_gc;
-      MoveElements(heap, &no_gc, elms, 0, elms, 1, len - 1);
+      heap->MoveElements(elms, 0, 1, len - 1);
       elms->set(len - 1, heap->the_hole_value());
     } else {
       FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
@@ -794,7 +774,7 @@
     array->set_elements(elms);
   } else {
     AssertNoAllocation no_gc;
-    MoveElements(heap, &no_gc, elms, to_add, elms, 0, len);
+    heap->MoveElements(elms, to_add, 0, len);
   }
 
   // Add the provided values.
@@ -1060,7 +1040,7 @@
       } else {
         FixedArray* elms = FixedArray::cast(elms_obj);
         AssertNoAllocation no_gc;
-        MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start);
+        heap->MoveElements(elms, delta, 0, actual_start);
       }
 
       elms_obj = LeftTrimFixedArray(heap, elms_obj, delta);
@@ -1076,10 +1056,9 @@
       } else {
         FixedArray* elms = FixedArray::cast(elms_obj);
         AssertNoAllocation no_gc;
-        MoveElements(heap, &no_gc,
-                     elms, actual_start + item_count,
-                     elms, actual_start + actual_delete_count,
-                     (len - actual_delete_count - actual_start));
+        heap->MoveElements(elms, actual_start + item_count,
+                           actual_start + actual_delete_count,
+                           (len - actual_delete_count - actual_start));
         FillWithHoles(heap, elms, new_length, len);
       }
     }
@@ -1119,10 +1098,9 @@
       elms_changed = true;
     } else {
       AssertNoAllocation no_gc;
-      MoveElements(heap, &no_gc,
-                   elms, actual_start + item_count,
-                   elms, actual_start + actual_delete_count,
-                   (len - actual_delete_count - actual_start));
+      heap->MoveElements(elms, actual_start + item_count,
+                         actual_start + actual_delete_count,
+                         (len - actual_delete_count - actual_start));
     }
   }
 
@@ -1536,12 +1514,12 @@
 
 
 static void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
-  KeyedLoadIC::GenerateMiss(masm, false);
+  KeyedLoadIC::GenerateMiss(masm, MISS);
 }
 
 
 static void Generate_KeyedLoadIC_MissForceGeneric(MacroAssembler* masm) {
-  KeyedLoadIC::GenerateMiss(masm, true);
+  KeyedLoadIC::GenerateMiss(masm, MISS_FORCE_GENERIC);
 }
 
 
@@ -1638,12 +1616,12 @@
 
 
 static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateMiss(masm, false);
+  KeyedStoreIC::GenerateMiss(masm, MISS);
 }
 
 
 static void Generate_KeyedStoreIC_MissForceGeneric(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateMiss(masm, true);
+  KeyedStoreIC::GenerateMiss(masm, MISS_FORCE_GENERIC);
 }
 
 
diff --git a/src/builtins.h b/src/builtins.h
index 1ca4053..4b50b43 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -107,7 +107,7 @@
                                     Code::kNoExtraICState)              \
   V(NotifyLazyDeoptimized,          BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
-  V(NotifyICMiss,                   BUILTIN, UNINITIALIZED,             \
+  V(NotifyStubFailure,              BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
   V(NotifyOSR,                      BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
@@ -388,7 +388,7 @@
   static void Generate_NotifyDeoptimized(MacroAssembler* masm);
   static void Generate_NotifyLazyDeoptimized(MacroAssembler* masm);
   static void Generate_NotifyOSR(MacroAssembler* masm);
-  static void Generate_NotifyICMiss(MacroAssembler* masm);
+  static void Generate_NotifyStubFailure(MacroAssembler* masm);
   static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm);
 
   static void Generate_FunctionCall(MacroAssembler* masm);
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 527abde..a02a959 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -247,7 +247,7 @@
         register_params_(NULL) { }
   int register_param_count_;
   Register* register_params_;
-  Handle<Code> deoptimization_handler_;
+  Address deoptimization_handler_;
 };
 
 
@@ -422,14 +422,17 @@
  public:
   // Maximum length of copied elements array.
   static const int kMaximumClonedLength = 8;
-
   enum Mode {
     CLONE_ELEMENTS,
     CLONE_DOUBLE_ELEMENTS,
     COPY_ON_WRITE_ELEMENTS,
-    CLONE_ANY_ELEMENTS
+    CLONE_ANY_ELEMENTS,
+    CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO,
+    LAST_CLONE_MODE = CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO
   };
 
+  static const int kFastCloneModeCount = LAST_CLONE_MODE + 1;
+
   FastCloneShallowArrayStub(Mode mode, int length)
       : mode_(mode),
         length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) {
@@ -445,8 +448,8 @@
 
   Major MajorKey() { return FastCloneShallowArray; }
   int MinorKey() {
-    ASSERT(mode_ == 0 || mode_ == 1 || mode_ == 2 || mode_ == 3);
-    return length_ * 4 +  mode_;
+    ASSERT(mode_ >= 0 && mode_ <= LAST_CLONE_MODE);
+    return length_ * kFastCloneModeCount + mode_;
   }
 };
 
diff --git a/src/codegen.cc b/src/codegen.cc
index 47eddb0..2eebef6 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -174,7 +174,7 @@
   }
   Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
   if (FLAG_log_regexp) {
-    if (name->IsEqualTo(CStrVector("regexp")))
+    if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("regexp")))
       return true;
   }
   return false;
diff --git a/src/compiler.cc b/src/compiler.cc
index ceac829..c4c8f99 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -316,8 +316,8 @@
   if (*FLAG_hydrogen_filter != '\0') {
     Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
     if ((filter[0] == '-'
-         && name->IsEqualTo(filter.SubVector(1, filter.length())))
-        || (filter[0] != '-' && !name->IsEqualTo(filter))) {
+         && name->IsUtf8EqualTo(filter.SubVector(1, filter.length())))
+        || (filter[0] != '-' && !name->IsUtf8EqualTo(filter))) {
       info()->SetCode(code);
       return SetLastStatus(BAILED_OUT);
     }
diff --git a/src/conversions-inl.h b/src/conversions-inl.h
index e272fe6..1b53912 100644
--- a/src/conversions-inl.h
+++ b/src/conversions-inl.h
@@ -212,7 +212,7 @@
       }
 
       // Rounding up may cause overflow.
-      if ((number & ((int64_t)1 << 53)) != 0) {
+      if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
         exponent++;
         number >>= 1;
       }
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index ed7721c..8989263 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -25,8 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
 #include <cstdio>  // NOLINT
+#include <string.h> // NOLINT
 #include <readline/readline.h> // NOLINT
 #include <readline/history.h> // NOLINT
 
@@ -35,7 +35,6 @@
 
 #include "d8.h"
 
-
 // There are incompatibilities between different versions and different
 // implementations of readline.  This smooths out one known incompatibility.
 #if RL_READLINE_VERSION >= 0x0500
@@ -58,8 +57,10 @@
   static const int kMaxHistoryEntries;
 
  private:
+#ifndef V8_SHARED
   static char** AttemptedCompletion(const char* text, int start, int end);
   static char* CompletionGenerator(const char* text, int state);
+#endif  // V8_SHARED
   static char kWordBreakCharacters[];
 };
 
@@ -76,7 +77,15 @@
 
 bool ReadLineEditor::Open() {
   rl_initialize();
+
+#ifdef V8_SHARED
+  // Don't do completion on shared library mode
+  // http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC24
+  rl_bind_key('\t', rl_insert);
+#else
   rl_attempted_completion_function = AttemptedCompletion;
+#endif  // V8_SHARED
+
   rl_completer_word_break_characters = kWordBreakCharacters;
   rl_bind_key('\t', rl_complete);
   using_history();
@@ -122,6 +131,7 @@
 }
 
 
+#ifndef V8_SHARED
 char** ReadLineEditor::AttemptedCompletion(const char* text,
                                            int start,
                                            int end) {
@@ -155,6 +165,7 @@
     return NULL;
   }
 }
+#endif  // V8_SHARED
 
 
 }  // namespace v8
diff --git a/src/d8.cc b/src/d8.cc
index 8233f86..5361869 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -532,8 +532,9 @@
     if (args[0]->IsObject() &&
         args[0]->ToObject()->Has(Symbols::length(isolate))) {
       // Construct from array.
-      length = convertToUint(
-          args[0]->ToObject()->Get(Symbols::length(isolate)), &try_catch);
+      Local<Value> value = args[0]->ToObject()->Get(Symbols::length(isolate));
+      if (try_catch.HasCaught()) return try_catch.ReThrow();
+      length = convertToUint(value, &try_catch);
       if (try_catch.HasCaught()) return try_catch.ReThrow();
       init_from_array = true;
     } else {
@@ -888,9 +889,7 @@
 
 Handle<Value> Shell::Quit(const Arguments& args) {
   int exit_code = args[0]->Int32Value();
-#ifndef V8_SHARED
   OnExit();
-#endif  // V8_SHARED
   exit(exit_code);
   return Undefined();
 }
@@ -1340,9 +1339,13 @@
   return strcmp(static_cast<const CounterAndKey*>(a)->key,
                 static_cast<const CounterAndKey*>(b)->key);
 }
+#endif  // V8_SHARED
 
 
 void Shell::OnExit() {
+  LineEditor* line_editor = LineEditor::Get();
+  if (line_editor) line_editor->Close();
+#ifndef V8_SHARED
   if (i::FLAG_dump_counters) {
     int number_of_counters = 0;
     for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
@@ -1377,8 +1380,9 @@
   }
   delete counters_file_;
   delete counter_map_;
-}
 #endif  // V8_SHARED
+}
+
 
 
 static FILE* FOpen(const char* path, const char* mode) {
@@ -1503,7 +1507,6 @@
     ExecuteString(input, name, true, true);
   }
   printf("\n");
-  console->Close();
 }
 
 
@@ -1954,9 +1957,7 @@
   }
   V8::Dispose();
 
-#ifndef V8_SHARED
   OnExit();
-#endif  // V8_SHARED
 
   return result;
 }
diff --git a/src/d8.gyp b/src/d8.gyp
index a8361e6..cce8f2a 100644
--- a/src/d8.gyp
+++ b/src/d8.gyp
@@ -45,6 +45,10 @@
         'd8.cc',
       ],
       'conditions': [
+        [ 'console=="readline"', {
+          'libraries': [ '-lreadline', ],
+          'sources': [ 'd8-readline.cc' ],
+        }],
         [ 'component!="shared_library"', {
           'sources': [ 'd8-debug.cc', '<(SHARED_INTERMEDIATE_DIR)/d8-js.cc', ],
           'conditions': [
@@ -57,10 +61,6 @@
                 'd8_js2c',
               ],
             }],
-            [ 'console=="readline"', {
-              'libraries': [ '-lreadline', ],
-              'sources': [ 'd8-readline.cc' ],
-            }],
             ['(OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="netbsd" \
                or OS=="openbsd" or OS=="solaris" or OS=="android")', {
               'sources': [ 'd8-posix.cc', ]
diff --git a/src/d8.h b/src/d8.h
index 161c653..07699e8 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -277,11 +277,11 @@
   static int RunMain(Isolate* isolate, int argc, char* argv[]);
   static int Main(int argc, char* argv[]);
   static void Exit(int exit_code);
+  static void OnExit();
 
 #ifndef V8_SHARED
   static Handle<Array> GetCompletions(Handle<String> text,
                                       Handle<String> full);
-  static void OnExit();
   static int* LookupCounter(const char* name);
   static void* CreateHistogram(const char* name,
                                int min,
diff --git a/src/data-flow.h b/src/data-flow.h
index 71f56e7..7eeb794 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -199,6 +199,61 @@
   uint32_t* data_;
 };
 
+class GrowableBitVector BASE_EMBEDDED {
+ public:
+  class Iterator BASE_EMBEDDED {
+   public:
+    Iterator(const GrowableBitVector* target, Zone* zone)
+        : it_(target->bits_ == NULL
+              ? new(zone) BitVector(1, zone)
+              : target->bits_) { }
+    bool Done() const { return it_.Done(); }
+    void Advance() { it_.Advance(); }
+    int Current() const { return it_.Current(); }
+   private:
+    BitVector::Iterator it_;
+  };
+
+  GrowableBitVector() : bits_(NULL) { }
+
+  bool Contains(int value) const {
+    if (!InBitsRange(value)) return false;
+    return bits_->Contains(value);
+  }
+
+  void Add(int value, Zone* zone) {
+    EnsureCapacity(value, zone);
+    bits_->Add(value);
+  }
+
+  void Union(const GrowableBitVector& other, Zone* zone) {
+    for (Iterator it(&other, zone); !it.Done(); it.Advance()) {
+      Add(it.Current(), zone);
+    }
+  }
+
+  void Clear() { if (bits_ != NULL) bits_->Clear(); }
+
+ private:
+  static const int kInitialLength = 1024;
+
+  bool InBitsRange(int value) const {
+    return bits_ != NULL && bits_->length() > value;
+  }
+
+  void EnsureCapacity(int value, Zone* zone) {
+    if (InBitsRange(value)) return;
+    int new_length = bits_ == NULL ? kInitialLength : bits_->length();
+    while (new_length <= value) new_length *= 2;
+    BitVector* new_bits = new(zone) BitVector(new_length, zone);
+    if (bits_ != NULL) new_bits->CopyFrom(*bits_);
+    bits_ = new_bits;
+  }
+
+  BitVector* bits_;
+};
+
+
 } }  // namespace v8::internal
 
 
diff --git a/src/execution.cc b/src/execution.cc
index e43ea65..fa41167 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -127,7 +127,7 @@
   ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception());
   if (*has_pending_exception) {
     isolate->ReportPendingMessages();
-    if (isolate->pending_exception() == Failure::OutOfMemoryException()) {
+    if (isolate->pending_exception()->IsOutOfMemory()) {
       if (!isolate->ignore_out_of_memory()) {
         V8::FatalProcessOutOfMemory("JS", true);
       }
diff --git a/src/extensions/externalize-string-extension.cc b/src/extensions/externalize-string-extension.cc
index a126a5a..614c243 100644
--- a/src/extensions/externalize-string-extension.cc
+++ b/src/extensions/externalize-string-extension.cc
@@ -94,10 +94,10 @@
         "externalizeString() can't externalize twice."));
   }
   if (string->IsOneByteRepresentation() && !force_two_byte) {
-    char* data = new char[string->length()];
+    uint8_t* data = new uint8_t[string->length()];
     String::WriteToFlat(*string, data, 0, string->length());
     SimpleAsciiStringResource* resource = new SimpleAsciiStringResource(
-        data, string->length());
+        reinterpret_cast<char*>(data), string->length());
     result = string->MakeExternal(resource);
     if (result && !string->IsSymbol()) {
       HEAP->external_string_table()->AddString(*string);
diff --git a/src/factory.cc b/src/factory.cc
index 8adae4e..25f197b 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -171,7 +171,7 @@
                      String);
 }
 
-Handle<String> Factory::LookupOneByteSymbol(Vector<const char> string) {
+Handle<String> Factory::LookupOneByteSymbol(Vector<const uint8_t> string) {
   CALL_HEAP_FUNCTION(isolate(),
                      isolate()->heap()->LookupOneByteSymbol(string),
                      String);
@@ -196,8 +196,8 @@
 }
 
 
-Handle<String> Factory::NewStringFromAscii(Vector<const char> string,
-                                           PretenureFlag pretenure) {
+Handle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
+                                             PretenureFlag pretenure) {
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateStringFromOneByte(string, pretenure),
diff --git a/src/factory.h b/src/factory.h
index 5493335..522639d 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -84,7 +84,7 @@
     return LookupUtf8Symbol(CStrVector(str));
   }
   Handle<String> LookupSymbol(Handle<String> str);
-  Handle<String> LookupOneByteSymbol(Vector<const char> str);
+  Handle<String> LookupOneByteSymbol(Vector<const uint8_t> str);
   Handle<String> LookupOneByteSymbol(Handle<SeqOneByteString>,
                                    int from,
                                    int length);
@@ -113,9 +113,15 @@
   //     two byte.
   //
   // ASCII strings are pretenured when used as keys in the SourceCodeCache.
-  Handle<String> NewStringFromAscii(
-      Vector<const char> str,
+  Handle<String> NewStringFromOneByte(
+      Vector<const uint8_t> str,
       PretenureFlag pretenure = NOT_TENURED);
+  // TODO(dcarney): remove this function.
+  inline Handle<String> NewStringFromAscii(
+      Vector<const char> str,
+      PretenureFlag pretenure = NOT_TENURED) {
+    return NewStringFromOneByte(Vector<const uint8_t>::cast(str), pretenure);
+  }
 
   // UTF8 strings are pretenured when used for regexp literal patterns and
   // flags in the parser.
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 149c65d..a7a2573 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -209,7 +209,8 @@
             "perform array index dehoisting")
 DEFINE_bool(dead_code_elimination, true, "use dead code elimination")
 DEFINE_bool(trace_dead_code_elimination, false, "trace dead code elimination")
-
+DEFINE_bool(track_allocation_sites, true,
+            "Use allocation site info to reduce transitions")
 DEFINE_bool(trace_osr, false, "trace on-stack replacement")
 DEFINE_int(stress_runs, 0, "number of stress runs")
 DEFINE_bool(optimize_closures, true, "optimize closures")
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index faf111f..b49337a 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -448,18 +448,8 @@
       StateField::encode(state) | PcField::encode(masm_->pc_offset());
   ASSERT(Smi::IsValid(pc_and_state));
   BailoutEntry entry = { id, pc_and_state };
-#ifdef DEBUG
-  if (FLAG_enable_slow_asserts) {
-    // Assert that we don't have multiple bailout entries for the same node.
-    for (int i = 0; i < bailout_entries_.length(); i++) {
-      if (bailout_entries_.at(i).id == entry.id) {
-        AstPrinter printer;
-        PrintF("%s", printer.PrintProgram(info_->function()));
-        UNREACHABLE();
-      }
-    }
-  }
-#endif  // DEBUG
+  ASSERT(!prepared_bailout_ids_.Contains(id.ToInt()));
+  prepared_bailout_ids_.Add(id.ToInt(), zone());
   bailout_entries_.Add(entry, zone());
 }
 
diff --git a/src/full-codegen.h b/src/full-codegen.h
index c25076a..c4f3fcc 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -35,6 +35,7 @@
 #include "code-stubs.h"
 #include "codegen.h"
 #include "compiler.h"
+#include "data-flow.h"
 
 namespace v8 {
 namespace internal {
@@ -816,6 +817,7 @@
   int module_index_;
   const ExpressionContext* context_;
   ZoneList<BailoutEntry> bailout_entries_;
+  GrowableBitVector prepared_bailout_ids_;
   // TODO(svenpanne) Rename this to something like back_edges_ and rename
   // related functions accordingly.
   ZoneList<BailoutEntry> stack_checks_;
diff --git a/src/globals.h b/src/globals.h
index babffbf..1606996 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -253,15 +253,13 @@
 // other bits set.
 const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51;
 
-// ASCII/UTF-16 constants
+// Latin1/UTF-16 constants
 // Code-point values in Unicode 4.0 are 21 bits wide.
 // Code units in UTF-16 are 16 bits wide.
 typedef uint16_t uc16;
 typedef int32_t uc32;
-const int kASCIISize    = kCharSize;
+const int kOneByteSize    = kCharSize;
 const int kUC16Size     = sizeof(uc16);      // NOLINT
-const uc32 kMaxAsciiCharCode = 0x7f;
-const uint32_t kMaxAsciiCharCodeU = 0x7fu;
 
 
 // The expression OFFSET_OF(type, field) computes the byte-offset
diff --git a/src/handles.cc b/src/handles.cc
index 16fe0c7..ed92c41 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -423,7 +423,7 @@
                               Vector<const SourceChar> src,
                               bool with_last_line) {
   const int src_len = src.length();
-  StringSearch<char, SourceChar> search(isolate, CStrVector("\n"));
+  StringSearch<uint8_t, SourceChar> search(isolate, STATIC_ASCII_VECTOR("\n"));
 
   // Find and record line ends.
   int position = 0;
@@ -457,7 +457,7 @@
     if (content.IsAscii()) {
       CalculateLineEnds(isolate,
                         &line_ends,
-                        content.ToAsciiVector(),
+                        content.ToOneByteVector(),
                         with_last_line);
     } else {
       CalculateLineEnds(isolate,
diff --git a/src/heap-inl.h b/src/heap-inl.h
index deb767e..6f4b69c 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -112,10 +112,12 @@
 }
 
 
-MaybeObject* Heap::AllocateSymbol(Vector<const char> str,
-                                  int chars,
-                                  uint32_t hash_field) {
-  if (IsOneByte(str, chars)) return AllocateAsciiSymbol(str, hash_field);
+MaybeObject* Heap::AllocateSymbolFromUtf8(Vector<const char> str,
+                                          int chars,
+                                          uint32_t hash_field) {
+  if (IsOneByte(str, chars)) {
+    return AllocateOneByteSymbol(Vector<const uint8_t>::cast(str), hash_field);
+  }
   return AllocateInternalSymbol<false>(str, chars, hash_field);
 }
 
@@ -129,10 +131,10 @@
 }
 
 
-MaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str,
+MaybeObject* Heap::AllocateOneByteSymbol(Vector<const uint8_t> str,
                                        uint32_t hash_field) {
   if (str.length() > SeqOneByteString::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x2);
   }
   // Compute map and object size.
   Map* map = ascii_symbol_map();
@@ -166,7 +168,7 @@
 MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str,
                                          uint32_t hash_field) {
   if (str.length() > SeqTwoByteString::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x3);
   }
   // Compute map and object size.
   Map* map = symbol_map();
@@ -261,8 +263,9 @@
 
 MaybeObject* Heap::NumberFromUint32(
     uint32_t value, PretenureFlag pretenure) {
-  if ((int32_t)value >= 0 && Smi::IsValid((int32_t)value)) {
-    return Smi::FromInt((int32_t)value);
+  if (static_cast<int32_t>(value) >= 0 &&
+      Smi::IsValid(static_cast<int32_t>(value))) {
+    return Smi::FromInt(static_cast<int32_t>(value));
   }
   // Bypass NumberFromDouble to avoid various redundant checks.
   return AllocateHeapNumber(FastUI2D(value), pretenure);
diff --git a/src/heap.cc b/src/heap.cc
index 401f4f7..013a18c 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -677,6 +677,29 @@
 }
 
 
+void Heap::MoveElements(FixedArray* array,
+                        int dst_index,
+                        int src_index,
+                        int len) {
+  if (len == 0) return;
+
+  ASSERT(array->map() != HEAP->fixed_cow_array_map());
+  Object** dst_objects = array->data_start() + dst_index;
+  memmove(dst_objects,
+          array->data_start() + src_index,
+          len * kPointerSize);
+  if (!InNewSpace(array)) {
+    for (int i = 0; i < len; i++) {
+      // TODO(hpayer): check store buffer for entries
+      if (InNewSpace(dst_objects[i])) {
+        RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i));
+      }
+    }
+  }
+  incremental_marking()->RecordWrites(array);
+}
+
+
 #ifdef VERIFY_HEAP
 // Helper class for verifying the symbol table.
 class SymbolTableVerifier : public ObjectVisitor {
@@ -2785,7 +2808,7 @@
   // hash code in place. The hash code for the hidden_symbol is zero to ensure
   // that it will always be at the first entry in property descriptors.
   { MaybeObject* maybe_obj =
-        AllocateSymbol(CStrVector(""), 0, String::kEmptyStringHash);
+        AllocateOneByteSymbol(OneByteVector("", 0), String::kEmptyStringHash);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
   hidden_symbol_ = String::cast(obj);
@@ -2838,9 +2861,9 @@
   }
   set_number_string_cache(FixedArray::cast(obj));
 
-  // Allocate cache for single character ASCII strings.
+  // Allocate cache for single character one byte strings.
   { MaybeObject* maybe_obj =
-        AllocateFixedArray(String::kMaxAsciiCharCode + 1, TENURED);
+        AllocateFixedArray(String::kMaxOneByteCharCode + 1, TENURED);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
   set_single_character_string_cache(FixedArray::cast(obj));
@@ -3309,16 +3332,16 @@
     return symbol;
   // Now we know the length is 2, we might as well make use of that fact
   // when building the new string.
-  } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxAsciiCharCodeU) {
+  } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
     // We can do this.
-    ASSERT(IsPowerOf2(String::kMaxAsciiCharCodeU + 1));  // because of this.
+    ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1));  // because of this.
     Object* result;
     { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2);
       if (!maybe_result->ToObject(&result)) return maybe_result;
     }
-    char* dest = SeqOneByteString::cast(result)->GetChars();
-    dest[0] = static_cast<char>(c1);
-    dest[1] = static_cast<char>(c2);
+    uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
+    dest[0] = static_cast<uint8_t>(c1);
+    dest[1] = static_cast<uint8_t>(c2);
     return result;
   } else {
     Object* result;
@@ -3355,19 +3378,18 @@
     return MakeOrFindTwoCharacterString(this, c1, c2);
   }
 
-  bool first_is_ascii = first->IsOneByteRepresentation();
-  bool second_is_ascii = second->IsOneByteRepresentation();
-  bool is_ascii = first_is_ascii && second_is_ascii;
-
+  bool first_is_one_byte = first->IsOneByteRepresentation();
+  bool second_is_one_byte = second->IsOneByteRepresentation();
+  bool is_one_byte = first_is_one_byte && second_is_one_byte;
   // Make sure that an out of memory exception is thrown if the length
   // of the new cons string is too large.
   if (length > String::kMaxLength || length < 0) {
     isolate()->context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x4);
   }
 
   bool is_ascii_data_in_two_byte_string = false;
-  if (!is_ascii) {
+  if (!is_one_byte) {
     // At least one of the strings uses two-byte representation so we
     // can't use the fast case code for short ASCII strings below, but
     // we can try to save memory if all chars actually fit in ASCII.
@@ -3384,15 +3406,15 @@
     STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
     ASSERT(first->IsFlat());
     ASSERT(second->IsFlat());
-    if (is_ascii) {
+    if (is_one_byte) {
       Object* result;
       { MaybeObject* maybe_result = AllocateRawOneByteString(length);
         if (!maybe_result->ToObject(&result)) return maybe_result;
       }
       // Copy the characters into the new object.
-      char* dest = SeqOneByteString::cast(result)->GetChars();
+      uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
       // Copy first part.
-      const char* src;
+      const uint8_t* src;
       if (first->IsExternalString()) {
         src = ExternalAsciiString::cast(first)->GetChars();
       } else {
@@ -3414,7 +3436,7 @@
           if (!maybe_result->ToObject(&result)) return maybe_result;
         }
         // Copy the characters into the new object.
-        char* dest = SeqOneByteString::cast(result)->GetChars();
+        uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
         String::WriteToFlat(first, dest, 0, first_length);
         String::WriteToFlat(second, dest + first_length, 0, second_length);
         isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
@@ -3433,7 +3455,7 @@
     }
   }
 
-  Map* map = (is_ascii || is_ascii_data_in_two_byte_string) ?
+  Map* map = (is_one_byte || is_ascii_data_in_two_byte_string) ?
       cons_ascii_string_map() : cons_string_map();
 
   Object* result;
@@ -3481,17 +3503,17 @@
     // WriteToFlat takes care of the case when an indirect string has a
     // different encoding from its underlying string.  These encodings may
     // differ because of externalization.
-    bool is_ascii = buffer->IsOneByteRepresentation();
-    { MaybeObject* maybe_result = is_ascii
+    bool is_one_byte = buffer->IsOneByteRepresentation();
+    { MaybeObject* maybe_result = is_one_byte
                                   ? AllocateRawOneByteString(length, pretenure)
                                   : AllocateRawTwoByteString(length, pretenure);
       if (!maybe_result->ToObject(&result)) return maybe_result;
     }
     String* string_result = String::cast(result);
     // Copy the characters into the new object.
-    if (is_ascii) {
+    if (is_one_byte) {
       ASSERT(string_result->IsOneByteRepresentation());
-      char* dest = SeqOneByteString::cast(string_result)->GetChars();
+      uint8_t* dest = SeqOneByteString::cast(string_result)->GetChars();
       String::WriteToFlat(buffer, dest, start, end);
     } else {
       ASSERT(string_result->IsTwoByteRepresentation());
@@ -3551,7 +3573,7 @@
   size_t length = resource->length();
   if (length > static_cast<size_t>(String::kMaxLength)) {
     isolate()->context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x5);
   }
 
   ASSERT(String::IsAscii(resource->data(), static_cast<int>(length)));
@@ -3576,15 +3598,15 @@
   size_t length = resource->length();
   if (length > static_cast<size_t>(String::kMaxLength)) {
     isolate()->context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x6);
   }
 
   // For small strings we check whether the resource contains only
-  // ASCII characters.  If yes, we use a different string map.
+  // one byte characters.  If yes, we use a different string map.
   static const size_t kAsciiCheckLengthLimit = 32;
-  bool is_ascii = length <= kAsciiCheckLengthLimit &&
-      String::IsAscii(resource->data(), static_cast<int>(length));
-  Map* map = is_ascii ?
+  bool is_one_byte = length <= kAsciiCheckLengthLimit &&
+      String::IsOneByte(resource->data(), static_cast<int>(length));
+  Map* map = is_one_byte ?
       external_string_with_ascii_data_map() : external_string_map();
   Object* result;
   { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
@@ -3601,15 +3623,15 @@
 
 
 MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
-  if (code <= String::kMaxAsciiCharCode) {
+  if (code <= String::kMaxOneByteCharCode) {
     Object* value = single_character_string_cache()->get(code);
     if (value != undefined_value()) return value;
 
-    char buffer[1];
-    buffer[0] = static_cast<char>(code);
+    uint8_t buffer[1];
+    buffer[0] = static_cast<uint8_t>(code);
     Object* result;
     MaybeObject* maybe_result =
-        LookupOneByteSymbol(Vector<const char>(buffer, 1));
+        LookupOneByteSymbol(Vector<const uint8_t>(buffer, 1));
 
     if (!maybe_result->ToObject(&result)) return maybe_result;
     single_character_string_cache()->set(code, result);
@@ -3628,7 +3650,7 @@
 
 MaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
   if (length < 0 || length > ByteArray::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x7);
   }
   if (pretenure == NOT_TENURED) {
     return AllocateByteArray(length);
@@ -3650,7 +3672,7 @@
 
 MaybeObject* Heap::AllocateByteArray(int length) {
   if (length < 0 || length > ByteArray::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x8);
   }
   int size = ByteArray::SizeFor(length);
   AllocationSpace space =
@@ -4520,7 +4542,7 @@
 }
 
 
-MaybeObject* Heap::AllocateStringFromOneByte(Vector<const char> string,
+MaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string,
                                            PretenureFlag pretenure) {
   int length = string.length();
   if (length == 1) {
@@ -4533,7 +4555,9 @@
   }
 
   // Copy the characters into the new object.
-  CopyChars(SeqOneByteString::cast(result)->GetChars(), string.start(), length);
+  CopyChars(SeqOneByteString::cast(result)->GetChars(),
+            string.start(),
+            length);
   return result;
 }
 
@@ -4579,11 +4603,11 @@
   int length = string.length();
   const uc16* start = string.start();
 
-  if (String::IsAscii(start, length)) {
+  if (String::IsOneByte(start, length)) {
     MaybeObject* maybe_result = AllocateRawOneByteString(length, pretenure);
     if (!maybe_result->ToObject(&result)) return maybe_result;
     CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length);
-  } else {  // It's not an ASCII string.
+  } else {  // It's not a one byte string.
     MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure);
     if (!maybe_result->ToObject(&result)) return maybe_result;
     CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length);
@@ -4630,7 +4654,7 @@
 class AllocateInternalSymbolHelper< Vector<const char> > {
  public:
   static inline void WriteOneByteData(Vector<const char> vector,
-                                      char* chars,
+                                      uint8_t* chars,
                                       int len) {
     // Only works for ascii.
     ASSERT(vector.length() == len);
@@ -4672,7 +4696,7 @@
 template<>
 class AllocateInternalSymbolHelper<String*> {
  public:
-  static inline void WriteOneByteData(String* s, char* chars, int len) {
+  static inline void WriteOneByteData(String* s, uint8_t* chars, int len) {
     ASSERT(s->length() == len);
     String::WriteToFlat(s, chars, 0, len);
   }
@@ -4699,13 +4723,13 @@
 
   if (is_one_byte) {
     if (chars > SeqOneByteString::kMaxLength) {
-      return Failure::OutOfMemoryException();
+      return Failure::OutOfMemoryException(0x9);
     }
     map = ascii_symbol_map();
     size = SeqOneByteString::SizeFor(chars);
   } else {
     if (chars > SeqTwoByteString::kMaxLength) {
-      return Failure::OutOfMemoryException();
+      return Failure::OutOfMemoryException(0xa);
     }
     map = symbol_map();
     size = SeqTwoByteString::SizeFor(chars);
@@ -4750,7 +4774,7 @@
 MaybeObject* Heap::AllocateRawOneByteString(int length,
                                             PretenureFlag pretenure) {
   if (length < 0 || length > SeqOneByteString::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0xb);
   }
 
   int size = SeqOneByteString::SizeFor(length);
@@ -4782,14 +4806,16 @@
   String::cast(result)->set_hash_field(String::kEmptyHashField);
   ASSERT_EQ(size, HeapObject::cast(result)->Size());
 
+#ifndef ENABLE_LATIN_1
 #ifdef VERIFY_HEAP
   if (FLAG_verify_heap) {
     // Initialize string's content to ensure ASCII-ness (character range 0-127)
     // as required when verifying the heap.
-    char* dest = SeqOneByteString::cast(result)->GetChars();
+    uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
     memset(dest, 0x0F, length * kCharSize);
   }
 #endif
+#endif
 
   return result;
 }
@@ -4798,7 +4824,7 @@
 MaybeObject* Heap::AllocateRawTwoByteString(int length,
                                             PretenureFlag pretenure) {
   if (length < 0 || length > SeqTwoByteString::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0xc);
   }
   int size = SeqTwoByteString::SizeFor(length);
   ASSERT(size <= SeqTwoByteString::kMaxSize);
@@ -4867,7 +4893,7 @@
 
 MaybeObject* Heap::AllocateRawFixedArray(int length) {
   if (length < 0 || length > FixedArray::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0xd);
   }
   ASSERT(length > 0);
   // Use the general function if we're forced to always allocate.
@@ -4943,7 +4969,7 @@
 
 MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) {
   if (length < 0 || length > FixedArray::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0xe);
   }
 
   AllocationSpace space =
@@ -5076,7 +5102,7 @@
 MaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
                                                PretenureFlag pretenure) {
   if (length < 0 || length > FixedDoubleArray::kMaxLength) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0xf);
   }
 
   AllocationSpace space =
@@ -5628,7 +5654,7 @@
 }
 
 
-MaybeObject* Heap::LookupOneByteSymbol(Vector<const char> string) {
+MaybeObject* Heap::LookupOneByteSymbol(Vector<const uint8_t> string) {
   Object* symbol = NULL;
   Object* new_table;
   { MaybeObject* maybe_new_table =
diff --git a/src/heap.h b/src/heap.h
index 9281fa9..a2564a5 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -699,8 +699,15 @@
   // failed.
   // Please note this does not perform a garbage collection.
   MUST_USE_RESULT MaybeObject* AllocateStringFromOneByte(
-      Vector<const char> str,
+      Vector<const uint8_t> str,
       PretenureFlag pretenure = NOT_TENURED);
+  // TODO(dcarney): remove this function.
+  MUST_USE_RESULT inline MaybeObject* AllocateStringFromOneByte(
+      Vector<const char> str,
+      PretenureFlag pretenure = NOT_TENURED) {
+    return AllocateStringFromOneByte(Vector<const uint8_t>::cast(str),
+                                     pretenure);
+  }
   MUST_USE_RESULT inline MaybeObject* AllocateStringFromUtf8(
       Vector<const char> str,
       PretenureFlag pretenure = NOT_TENURED);
@@ -716,12 +723,13 @@
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
   // failed.
   // Please note this function does not perform a garbage collection.
-  MUST_USE_RESULT inline MaybeObject* AllocateSymbol(Vector<const char> str,
-                                                     int chars,
-                                                     uint32_t hash_field);
+  MUST_USE_RESULT inline MaybeObject* AllocateSymbolFromUtf8(
+      Vector<const char> str,
+      int chars,
+      uint32_t hash_field);
 
-  MUST_USE_RESULT inline MaybeObject* AllocateAsciiSymbol(
-        Vector<const char> str,
+  MUST_USE_RESULT inline MaybeObject* AllocateOneByteSymbol(
+        Vector<const uint8_t> str,
         uint32_t hash_field);
 
   MUST_USE_RESULT inline MaybeObject* AllocateTwoByteSymbol(
@@ -805,6 +813,10 @@
   // Please note this does not perform a garbage collection.
   MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedArray(int length);
 
+  // Move len elements within a given array from src_index index to dst_index
+  // index.
+  void MoveElements(FixedArray* array, int dst_index, int src_index, int len);
+
   // Make a copy of src and return it. Returns
   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
   MUST_USE_RESULT inline MaybeObject* CopyFixedArray(FixedArray* src);
@@ -1038,7 +1050,7 @@
   MUST_USE_RESULT MaybeObject* LookupUtf8Symbol(const char* str) {
     return LookupUtf8Symbol(CStrVector(str));
   }
-  MUST_USE_RESULT MaybeObject* LookupOneByteSymbol(Vector<const char> str);
+  MUST_USE_RESULT MaybeObject* LookupOneByteSymbol(Vector<const uint8_t> str);
   MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str);
   MUST_USE_RESULT MaybeObject* LookupSymbol(String* str);
   MUST_USE_RESULT MaybeObject* LookupOneByteSymbol(
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 55beb3a..c39f8a4 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -152,8 +152,11 @@
   for (int i = 0; i < push_count; ++i) {
     instr->AddPushedValue(environment->ExpressionStackAt(i));
   }
-  for (int i = 0; i < environment->assigned_variables()->length(); ++i) {
-    int index = environment->assigned_variables()->at(i);
+  for (GrowableBitVector::Iterator it(environment->assigned_variables(),
+                                      zone());
+       !it.Done();
+       it.Advance()) {
+    int index = it.Current();
     instr->AddAssignedValue(index, environment->Lookup(index));
   }
   environment->ClearHistory();
@@ -5399,6 +5402,10 @@
                                   Handle<String> name,
                                   LookupResult* lookup,
                                   bool is_store) {
+  if (type->has_named_interceptor()) {
+    lookup->InterceptorResult(NULL);
+    return false;
+  }
   // If we directly find a field, the access can be inlined.
   type->LookupDescriptor(NULL, *name, lookup);
   if (lookup->IsField()) return true;
@@ -6599,7 +6606,7 @@
   HInstruction* result = NULL;
   if (expr->key()->IsPropertyName()) {
     Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
-    if (!name->IsEqualTo(CStrVector("length"))) return false;
+    if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false;
 
     if (function_state()->outer() == NULL) {
       HInstruction* elements = AddInstruction(
@@ -8495,7 +8502,9 @@
   Literal* literal = expr->right()->AsLiteral();
   if (literal == NULL) return false;
   if (!literal->handle()->IsString()) return false;
-  if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false;
+  if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) {
+    return false;
+  }
   ASSERT(call->arguments()->length() == 1);
   return true;
 }
@@ -9566,7 +9575,6 @@
                            Zone* zone)
     : closure_(closure),
       values_(0, zone),
-      assigned_variables_(4, zone),
       frame_type_(JS_FUNCTION),
       parameter_count_(0),
       specials_count_(1),
@@ -9583,7 +9591,6 @@
 
 HEnvironment::HEnvironment(Zone* zone)
     : values_(0, zone),
-      assigned_variables_(0, zone),
       frame_type_(STUB),
       parameter_count_(0),
       specials_count_(0),
@@ -9600,7 +9607,6 @@
 
 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
     : values_(0, zone),
-      assigned_variables_(0, zone),
       frame_type_(JS_FUNCTION),
       parameter_count_(0),
       specials_count_(1),
@@ -9622,7 +9628,6 @@
                            Zone* zone)
     : closure_(closure),
       values_(arguments, zone),
-      assigned_variables_(0, zone),
       frame_type_(frame_type),
       parameter_count_(arguments),
       local_count_(0),
@@ -9651,7 +9656,7 @@
 void HEnvironment::Initialize(const HEnvironment* other) {
   closure_ = other->closure();
   values_.AddAll(other->values_, zone());
-  assigned_variables_.AddAll(other->assigned_variables_, zone());
+  assigned_variables_.Union(other->assigned_variables_, zone());
   frame_type_ = other->frame_type_;
   parameter_count_ = other->parameter_count_;
   local_count_ = other->local_count_;
@@ -9695,9 +9700,7 @@
 
 void HEnvironment::Bind(int index, HValue* value) {
   ASSERT(value != NULL);
-  if (!assigned_variables_.Contains(index)) {
-    assigned_variables_.Add(index, zone());
-  }
+  assigned_variables_.Add(index, zone());
   values_[index] = value;
 }
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 0837bf9..eb5ec52 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -450,7 +450,7 @@
   // Simple accessors.
   Handle<JSFunction> closure() const { return closure_; }
   const ZoneList<HValue*>* values() const { return &values_; }
-  const ZoneList<int>* assigned_variables() const {
+  const GrowableBitVector* assigned_variables() const {
     return &assigned_variables_;
   }
   FrameType frame_type() const { return frame_type_; }
@@ -557,7 +557,7 @@
   void ClearHistory() {
     pop_count_ = 0;
     push_count_ = 0;
-    assigned_variables_.Rewind(0);
+    assigned_variables_.Clear();
   }
 
   void SetValueAt(int index, HValue* value) {
@@ -606,7 +606,7 @@
   Handle<JSFunction> closure_;
   // Value array [parameters] [specials] [locals] [temporaries].
   ZoneList<HValue*> values_;
-  ZoneList<int> assigned_variables_;
+  GrowableBitVector assigned_variables_;
   FrameType frame_type_;
   int parameter_count_;
   int specials_count_;
diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h
index f838592..56d88b0 100644
--- a/src/ia32/assembler-ia32-inl.h
+++ b/src/ia32/assembler-ia32-inl.h
@@ -300,7 +300,7 @@
 
 Immediate::Immediate(int x)  {
   x_ = x;
-  rmode_ = RelocInfo::NONE;
+  rmode_ = RelocInfo::NONE32;
 }
 
 
@@ -326,20 +326,20 @@
   } else {
     // no relocation needed
     x_ =  reinterpret_cast<intptr_t>(obj);
-    rmode_ = RelocInfo::NONE;
+    rmode_ = RelocInfo::NONE32;
   }
 }
 
 
 Immediate::Immediate(Smi* value) {
   x_ = reinterpret_cast<intptr_t>(value);
-  rmode_ = RelocInfo::NONE;
+  rmode_ = RelocInfo::NONE32;
 }
 
 
 Immediate::Immediate(Address addr) {
   x_ = reinterpret_cast<int32_t>(addr);
-  rmode_ = RelocInfo::NONE;
+  rmode_ = RelocInfo::NONE32;
 }
 
 
@@ -396,7 +396,7 @@
 
 
 void Assembler::emit_w(const Immediate& x) {
-  ASSERT(x.rmode_ == RelocInfo::NONE);
+  ASSERT(RelocInfo::IsNone(x.rmode_));
   uint16_t value = static_cast<uint16_t>(x.x_);
   reinterpret_cast<uint16_t*>(pc_)[0] = value;
   pc_ += sizeof(uint16_t);
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index 750746c..fd53bbf 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -236,7 +236,7 @@
 #endif
 
   // Patch the code.
-  patcher.masm()->call(target, RelocInfo::NONE);
+  patcher.masm()->call(target, RelocInfo::NONE32);
 
   // Check that the size of the code generated is as expected.
   ASSERT_EQ(kCallCodeSize,
@@ -255,11 +255,11 @@
 
 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
   // [base + disp/r]
-  if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) {
+  if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
     // [base]
     set_modrm(0, base);
     if (base.is(esp)) set_sib(times_1, esp, base);
-  } else if (is_int8(disp) && rmode == RelocInfo::NONE) {
+  } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
     // [base + disp8]
     set_modrm(1, base);
     if (base.is(esp)) set_sib(times_1, esp, base);
@@ -280,11 +280,11 @@
                  RelocInfo::Mode rmode) {
   ASSERT(!index.is(esp));  // illegal addressing mode
   // [base + index*scale + disp/r]
-  if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) {
+  if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
     // [base + index*scale]
     set_modrm(0, esp);
     set_sib(scale, index, base);
-  } else if (is_int8(disp) && rmode == RelocInfo::NONE) {
+  } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
     // [base + index*scale + disp8]
     set_modrm(1, esp);
     set_sib(scale, index, base);
@@ -1180,7 +1180,7 @@
   EnsureSpace ensure_space(this);
   // Only use test against byte for registers that have a byte
   // variant: eax, ebx, ecx, and edx.
-  if (imm.rmode_ == RelocInfo::NONE &&
+  if (RelocInfo::IsNone(imm.rmode_) &&
       is_uint8(imm.x_) &&
       reg.is_byte_register()) {
     uint8_t imm8 = imm.x_;
@@ -2614,7 +2614,7 @@
   pc_ += length;
 
   // Emit relocation information if necessary.
-  if (length >= sizeof(int32_t) && adr.rmode_ != RelocInfo::NONE) {
+  if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
     pc_ -= sizeof(int32_t);  // pc_ must be *at* disp32
     RecordRelocInfo(adr.rmode_);
     pc_ += sizeof(int32_t);
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 28e8339..ca785e9 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -337,12 +337,12 @@
     return Immediate(label);
   }
 
-  bool is_zero() const { return x_ == 0 && rmode_ == RelocInfo::NONE; }
+  bool is_zero() const { return x_ == 0 && RelocInfo::IsNone(rmode_); }
   bool is_int8() const {
-    return -128 <= x_ && x_ < 128 && rmode_ == RelocInfo::NONE;
+    return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
   }
   bool is_int16() const {
-    return -32768 <= x_ && x_ < 32768 && rmode_ == RelocInfo::NONE;
+    return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
   }
 
  private:
@@ -382,20 +382,20 @@
 
   // [base + disp/r]
   explicit Operand(Register base, int32_t disp,
-                   RelocInfo::Mode rmode = RelocInfo::NONE);
+                   RelocInfo::Mode rmode = RelocInfo::NONE32);
 
   // [base + index*scale + disp/r]
   explicit Operand(Register base,
                    Register index,
                    ScaleFactor scale,
                    int32_t disp,
-                   RelocInfo::Mode rmode = RelocInfo::NONE);
+                   RelocInfo::Mode rmode = RelocInfo::NONE32);
 
   // [index*scale + disp/r]
   explicit Operand(Register index,
                    ScaleFactor scale,
                    int32_t disp,
-                   RelocInfo::Mode rmode = RelocInfo::NONE);
+                   RelocInfo::Mode rmode = RelocInfo::NONE32);
 
   static Operand StaticVariable(const ExternalReference& ext) {
     return Operand(reinterpret_cast<int32_t>(ext.address()),
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index da9f13e..c689afb 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -575,7 +575,7 @@
 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
 
 
-void Builtins::Generate_NotifyICMiss(MacroAssembler* masm) {
+void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
   // Enter an internal frame.
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
@@ -584,7 +584,7 @@
     // stubs that tail call the runtime on deopts passing their parameters in
     // registers.
     __ pushad();
-    __ CallRuntime(Runtime::kNotifyICMiss, 0);
+    __ CallRuntime(Runtime::kNotifyStubFailure, 0);
     __ popad();
     // Tear down internal frame.
   }
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 92f55b8..28663ab 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -48,7 +48,7 @@
   descriptor->register_param_count_ = 2;
   descriptor->register_params_ = registers;
   descriptor->deoptimization_handler_ =
-      isolate->builtins()->KeyedLoadIC_Miss();
+      FUNCTION_ADDR(KeyedLoadIC_Miss);
 }
 
 
@@ -323,6 +323,7 @@
     MacroAssembler* masm,
     int length,
     FastCloneShallowArrayStub::Mode mode,
+    AllocationSiteInfoMode allocation_site_info_mode,
     Label* fail) {
   // Registers on entry:
   //
@@ -336,7 +337,12 @@
         ? FixedDoubleArray::SizeFor(length)
         : FixedArray::SizeFor(length);
   }
-  int size = JSArray::kSize + elements_size;
+  int size = JSArray::kSize;
+  int allocation_info_start = size;
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    size += AllocationSiteInfo::kSize;
+  }
+  size += elements_size;
 
   // Allocate both the JS array and the elements array in one big
   // allocation. This avoids multiple limit checks.
@@ -346,6 +352,13 @@
   }
   __ AllocateInNewSpace(size, eax, ebx, edx, fail, flags);
 
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    __ mov(FieldOperand(eax, allocation_info_start),
+           Immediate(Handle<Map>(masm->isolate()->heap()->
+                                 allocation_site_info_map())));
+    __ mov(FieldOperand(eax, allocation_info_start + kPointerSize), ecx);
+  }
+
   // Copy the JS array part.
   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
     if ((i != JSArray::kElementsOffset) || (length == 0)) {
@@ -358,7 +371,11 @@
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
     __ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset));
-    __ lea(edx, Operand(eax, JSArray::kSize));
+    if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+      __ lea(edx, Operand(eax, JSArray::kSize + AllocationSiteInfo::kSize));
+    } else {
+      __ lea(edx, Operand(eax, JSArray::kSize));
+    }
     __ mov(FieldOperand(eax, JSArray::kElementsOffset), edx);
 
     // Copy the elements array.
@@ -408,20 +425,31 @@
 
   FastCloneShallowArrayStub::Mode mode = mode_;
   // ecx is boilerplate object.
+  AllocationSiteInfoMode allocation_site_info_mode =
+      DONT_TRACK_ALLOCATION_SITE_INFO;
+  if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
+    mode = CLONE_ANY_ELEMENTS;
+    allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
+  }
+
   if (mode == CLONE_ANY_ELEMENTS) {
     Label double_elements, check_fast_elements;
     __ mov(ebx, FieldOperand(ecx, JSArray::kElementsOffset));
     __ CheckMap(ebx, factory->fixed_cow_array_map(),
                 &check_fast_elements, DONT_DO_SMI_CHECK);
     GenerateFastCloneShallowArrayCommon(masm, 0,
-                                        COPY_ON_WRITE_ELEMENTS, &slow_case);
+                                        COPY_ON_WRITE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     __ ret(3 * kPointerSize);
 
     __ bind(&check_fast_elements);
     __ CheckMap(ebx, factory->fixed_array_map(),
                 &double_elements, DONT_DO_SMI_CHECK);
     GenerateFastCloneShallowArrayCommon(masm, length_,
-                                        CLONE_ELEMENTS, &slow_case);
+                                        CLONE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     __ ret(3 * kPointerSize);
 
     __ bind(&double_elements);
@@ -450,7 +478,8 @@
     __ pop(ecx);
   }
 
-  GenerateFastCloneShallowArrayCommon(masm, length_, mode, &slow_case);
+  GenerateFastCloneShallowArrayCommon(masm, length_, mode,
+                                      allocation_site_info_mode, &slow_case);
   // Return and remove the on-stack parameters.
   __ ret(3 * kPointerSize);
 
@@ -4849,6 +4878,19 @@
 }
 
 
+static void JumpIfOOM(MacroAssembler* masm,
+                      Register value,
+                      Register scratch,
+                      Label* oom_label) {
+  __ mov(scratch, value);
+  STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3);
+  STATIC_ASSERT(kFailureTag == 3);
+  __ and_(scratch, 0xf);
+  __ cmp(scratch, 0xf);
+  __ j(equal, oom_label);
+}
+
+
 void CEntryStub::GenerateCore(MacroAssembler* masm,
                               Label* throw_normal_exception,
                               Label* throw_termination_exception,
@@ -4946,8 +4988,7 @@
   __ j(zero, &retry, Label::kNear);
 
   // Special handling of out of memory exceptions.
-  __ cmp(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException()));
-  __ j(equal, throw_out_of_memory_exception);
+  JumpIfOOM(masm, eax, ecx, throw_out_of_memory_exception);
 
   // Retrieve the pending exception and clear the variable.
   __ mov(eax, Operand::StaticVariable(pending_exception_address));
@@ -5029,7 +5070,10 @@
   // Set pending exception and eax to out of memory exception.
   ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
                                       isolate);
-  __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException()));
+  Label already_have_failure;
+  JumpIfOOM(masm, eax, ecx, &already_have_failure);
+  __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException(0x1)));
+  __ bind(&already_have_failure);
   __ mov(Operand::StaticVariable(pending_exception), eax);
   // Fall through to the next label.
 
@@ -5472,10 +5516,10 @@
   // Fast case of Heap::LookupSingleCharacterStringFromCode.
   STATIC_ASSERT(kSmiTag == 0);
   STATIC_ASSERT(kSmiShiftSize == 0);
-  ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
+  ASSERT(IsPowerOf2(String::kMaxOneByteCharCode + 1));
   __ test(code_,
           Immediate(kSmiTagMask |
-                    ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
+                    ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
   __ j(not_zero, &slow_case_);
 
   Factory* factory = masm->isolate()->factory();
@@ -6434,7 +6478,12 @@
   // Compare lengths -  strings up to min-length are equal.
   __ bind(&compare_lengths);
   __ test(length_delta, length_delta);
+#ifndef ENABLE_LATIN_1
   __ j(not_zero, &result_not_equal, Label::kNear);
+#else
+  Label length_not_equal;
+  __ j(not_zero, &length_not_equal, Label::kNear);
+#endif
 
   // Result is EQUAL.
   STATIC_ASSERT(EQUAL == 0);
@@ -6443,8 +6492,19 @@
   __ ret(0);
 
   Label result_greater;
-  __ bind(&result_not_equal);
+#ifdef ENABLE_LATIN_1
+  Label result_less;
+  __ bind(&length_not_equal);
   __ j(greater, &result_greater, Label::kNear);
+  __ jmp(&result_less, Label::kNear);
+#endif
+  __ bind(&result_not_equal);
+#ifndef ENABLE_LATIN_1
+  __ j(greater, &result_greater, Label::kNear);
+#else
+  __ j(above, &result_greater, Label::kNear);
+  __ bind(&result_less);
+#endif
 
   // Result is LESS.
   __ Set(eax, Immediate(Smi::FromInt(LESS)));
@@ -7470,7 +7530,7 @@
 
   // Call the entry hook.
   int32_t hook_location = reinterpret_cast<int32_t>(&entry_hook_);
-  __ call(Operand(hook_location, RelocInfo::NONE));
+  __ call(Operand(hook_location, RelocInfo::NONE32));
   __ add(esp, Immediate(2 * kPointerSize));
 
   // Restore ecx.
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 45a968d..cb2fa26 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -388,6 +388,7 @@
 
 #define __ ACCESS_MASM(masm)
 
+
 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
     MacroAssembler* masm) {
   // ----------- S t a t e -------------
@@ -420,6 +421,10 @@
   // -----------------------------------
   Label loop, entry, convert_hole, gc_required, only_change_map;
 
+  if (FLAG_track_allocation_sites) {
+    masm->TestJSArrayForAllocationSiteInfo(edx, edi, fail);
+  }
+
   // Check for empty arrays, which only require a map transition and no changes
   // to the backing store.
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
@@ -938,7 +943,7 @@
   } else {
     Code* stub = GetCodeAgeStub(age, parity);
     CodePatcher patcher(sequence, young_length);
-    patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE);
+    patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32);
   }
 }
 
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 3233c27..72a8592 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -158,7 +158,7 @@
     Address call_address = code_start_address + deopt_data->Pc(i)->value();
     CodePatcher patcher(call_address, patch_size());
     Address deopt_entry = GetDeoptimizationEntry(i, LAZY);
-    patcher.masm()->call(deopt_entry, RelocInfo::NONE);
+    patcher.masm()->call(deopt_entry, RelocInfo::NONE32);
     // We use RUNTIME_ENTRY for deoptimization bailouts.
     RelocInfo rinfo(call_address + 1,  // 1 after the call opcode.
                     RelocInfo::RUNTIME_ENTRY,
@@ -565,35 +565,41 @@
   //               FROM                                  TO             <-ebp
   //    |          ....           |          |          ....           |
   //    +-------------------------+          +-------------------------+
-  //    | JSFunction continuation |          | JSFunction continuation |
+  //    | JSFunction continuation |          |       parameter 1       |
+  //    +-------------------------+          +-------------------------+
+  // |  |   saved frame (ebp)     |          |          ....           |
+  // |  +=========================+<-ebp     +-------------------------+
+  // |  |   JSFunction context    |          |       parameter n       |
+  // v  +-------------------------+          +-------------------------|
+  //    |   COMPILED_STUB marker  |          | JSFunction continuation |
   //    +-------------------------+          +-------------------------+<-esp
-  // |  |   saved frame (ebp)     |
-  // |  +=========================+<-ebp
-  // |  |   JSFunction context    |
-  // v  +-------------------------+
-  //    |   COMPILED_STUB marker  |          ebp = saved frame
-  //    +-------------------------+          esi = JSFunction context
-  //    |                         |
-  //    | ...                     |
-  //    |                         |
-  //    +-------------------------+<-esp
+  //    |                         |          eax = number of parameters
+  //    | ...                     |          ebx = failure handler address
+  //    |                         |          ebp = saved frame
+  //    +-------------------------+<-esp     esi = JSFunction context
   //
   //
-  int output_frame_size = 1 * kPointerSize;
-  FrameDescription* output_frame =
-      new(output_frame_size) FrameDescription(output_frame_size, 0);
-  Code* notify_miss =
-      isolate_->builtins()->builtin(Builtins::kNotifyICMiss);
-  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
-  output_frame->SetContinuation(
-      reinterpret_cast<uint32_t>(notify_miss->entry()));
 
   ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
   int major_key = compiled_code_->major_key();
   CodeStubInterfaceDescriptor* descriptor =
       isolate_->code_stub_interface_descriptor(major_key);
-  Handle<Code> miss_ic(descriptor->deoptimization_handler_);
-  output_frame->SetPc(reinterpret_cast<intptr_t>(miss_ic->instruction_start()));
+
+  int output_frame_size =
+      (1 + descriptor->register_param_count_) * kPointerSize;
+  FrameDescription* output_frame =
+      new(output_frame_size) FrameDescription(output_frame_size, 0);
+  Code* notify_failure =
+      isolate_->builtins()->builtin(Builtins::kNotifyStubFailure);
+  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
+  output_frame->SetContinuation(
+      reinterpret_cast<uint32_t>(notify_failure->entry()));
+
+  Code* code;
+  SaveFPRegsMode mode =
+      CpuFeatures::IsSupported(SSE2) ? kSaveFPRegs : kDontSaveFPRegs;
+  CEntryStub(1, mode).FindCodeInCache(&code, isolate_);
+  output_frame->SetPc(reinterpret_cast<intptr_t>(code->instruction_start()));
   unsigned input_frame_size = input_->GetFrameSize();
   intptr_t value = input_->GetFrameSlot(input_frame_size - kPointerSize);
   output_frame->SetFrameSlot(0, value);
@@ -603,20 +609,22 @@
   value = input_->GetFrameSlot(input_frame_size - 3 * kPointerSize);
   output_frame->SetRegister(esi.code(), value);
 
-  Translation::Opcode opcode =
-      static_cast<Translation::Opcode>(iterator->Next());
-  ASSERT(opcode == Translation::REGISTER);
-  USE(opcode);
-  int input_reg = iterator->Next();
-  intptr_t input_value = input_->GetRegister(input_reg);
-  output_frame->SetRegister(edx.code(), input_value);
+  int parameter_offset = kPointerSize * descriptor->register_param_count_;
+  for (int i = 0; i < descriptor->register_param_count_; ++i) {
+    Translation::Opcode opcode =
+        static_cast<Translation::Opcode>(iterator->Next());
+    ASSERT(opcode == Translation::REGISTER);
+    USE(opcode);
+    int input_reg = iterator->Next();
+    intptr_t reg_value = input_->GetRegister(input_reg);
+    output_frame->SetFrameSlot(parameter_offset, reg_value);
+    parameter_offset -= kPointerSize;
+  }
 
-  int32_t next = iterator->Next();
-  opcode = static_cast<Translation::Opcode>(next);
-  ASSERT(opcode == Translation::REGISTER);
-  input_reg = iterator->Next();
-  input_value = input_->GetRegister(input_reg);
-  output_frame->SetRegister(ecx.code(), input_value);
+  intptr_t handler =
+      reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_);
+  output_frame->SetRegister(eax.code(), descriptor->register_param_count_);
+  output_frame->SetRegister(ebx.code(), handler);
 
   ASSERT(frame_index == 0);
   output_[frame_index] = output_frame;
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 95e95d4..7cb6558 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -127,7 +127,7 @@
 
 #ifdef DEBUG
   if (strlen(FLAG_stop_at) > 0 &&
-      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+      info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
     __ int3();
   }
 #endif
@@ -1678,6 +1678,15 @@
     FastCloneShallowArrayStub::Mode mode = has_constant_fast_elements
         ? FastCloneShallowArrayStub::CLONE_ELEMENTS
         : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+
+    // Tracking allocation info allows us to pre-transition later if it makes
+    // sense.
+    if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
+        FLAG_track_allocation_sites) {
+      mode = FastCloneShallowArrayStub::
+          CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+    }
+
     FastCloneShallowArrayStub stub(mode, length);
     __ CallStub(&stub);
   }
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index ac5af2b..eb69658 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -647,7 +647,7 @@
   char_at_generator.GenerateSlow(masm, call_helper);
 
   __ bind(&miss);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -689,7 +689,7 @@
   __ TailCallExternalReference(ref, 2, 1);
 
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -714,7 +714,7 @@
   __ mov(eax, unmapped_location);
   __ Ret();
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -743,7 +743,7 @@
   __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs);
   __ Ret();
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -1385,7 +1385,7 @@
 }
 
 
-void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ----------- S t a t e -------------
   //  -- ecx    : key
   //  -- edx    : receiver
@@ -1400,7 +1400,7 @@
   __ push(ebx);  // return address
 
   // Perform tail call to the entry.
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
       ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric),
                           masm->isolate())
       : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
@@ -1598,7 +1598,7 @@
 }
 
 
-void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ----------- S t a t e -------------
   //  -- eax    : value
   //  -- ecx    : key
@@ -1613,7 +1613,7 @@
   __ push(ebx);
 
   // Do tail-call to runtime routine.
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
       ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
                           masm->isolate())
       : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 761f516..e9d7509 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -135,7 +135,7 @@
 
 #ifdef DEBUG
     if (strlen(FLAG_stop_at) > 0 &&
-        info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+        info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
       __ int3();
     }
 #endif
@@ -2411,7 +2411,7 @@
   ASSERT(!temp.is(temp2));
   __ JumpIfSmi(input, is_false);
 
-  if (class_name->IsEqualTo(CStrVector("Function"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) {
     // Assuming the following assertions, we can use the same compares to test
     // for both being a function type and being in the object type range.
     STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
@@ -2441,7 +2441,7 @@
   __ mov(temp, FieldOperand(temp, Map::kConstructorOffset));
   // Objects with a non-function constructor have class 'Object'.
   __ CmpObjectType(temp, JS_FUNCTION_TYPE, temp2);
-  if (class_name->IsEqualTo(CStrVector("Object"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) {
     __ j(not_equal, is_true);
   } else {
     __ j(not_equal, is_false);
@@ -4432,7 +4432,7 @@
   Register result = ToRegister(instr->result());
   ASSERT(!char_code.is(result));
 
-  __ cmp(char_code, String::kMaxAsciiCharCode);
+  __ cmp(char_code, String::kMaxOneByteCharCode);
   __ j(above, deferred->entry());
   __ Set(result, Immediate(factory()->single_character_string_cache()));
   __ mov(result, FieldOperand(result,
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index e5b580b..d5013d7 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -170,7 +170,7 @@
   Label done;
   cmp(src, Immediate(0));
   movdbl(scratch,
-         Operand(reinterpret_cast<int32_t>(&kUint32Bias), RelocInfo::NONE));
+         Operand(reinterpret_cast<int32_t>(&kUint32Bias), RelocInfo::NONE32));
   cvtsi2sd(dst, src);
   j(not_sign, &done, Label::kNear);
   addsd(dst, scratch);
@@ -3051,6 +3051,30 @@
   j(not_equal, &next);
 }
 
+
+void MacroAssembler::TestJSArrayForAllocationSiteInfo(
+    Register receiver_reg,
+    Register scratch_reg,
+    Label* allocation_info_present) {
+  Label no_info_available;
+  ExternalReference new_space_start =
+      ExternalReference::new_space_start(isolate());
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address(isolate());
+
+  lea(scratch_reg, Operand(receiver_reg,
+                           JSArray::kSize + AllocationSiteInfo::kSize));
+  cmp(scratch_reg, Immediate(new_space_start));
+  j(less, &no_info_available);
+  cmp(scratch_reg, Operand::StaticVariable(new_space_allocation_top));
+  j(greater_equal, &no_info_available);
+  cmp(MemOperand(scratch_reg, 0),
+      Immediate(Handle<Map>(isolate()->heap()->allocation_site_info_map())));
+  j(equal, allocation_info_present);
+  bind(&no_info_available);
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_IA32
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index cc7ef29..ac1a100 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -859,6 +859,16 @@
   // in eax.  Assumes that any other register can be used as a scratch.
   void CheckEnumCache(Label* call_runtime);
 
+  // AllocationSiteInfo support. Arrays may have an associated
+  // AllocationSiteInfo object that can be checked for in order to pretransition
+  // to another type.
+  // On entry, receiver_reg should point to the array object.
+  // scratch_reg gets clobbered.
+  // If allocation info is present, jump to allocation_info_present
+  void TestJSArrayForAllocationSiteInfo(Register receiver_reg,
+                                        Register scratch_reg,
+                                        Label* allocation_info_present);
+
  private:
   bool generating_stub_;
   bool allow_stub_calls_;
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index af6a9e4..49c75e1 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -217,7 +217,7 @@
   // If input is ASCII, don't even bother calling here if the string to
   // match contains a non-ASCII character.
   if (mode_ == ASCII) {
-    ASSERT(String::IsAscii(str.start(), str.length()));
+    ASSERT(String::IsOneByte(str.start(), str.length()));
   }
 #endif
   int byte_length = str.length() * char_size();
@@ -344,7 +344,19 @@
     __ or_(eax, 0x20);  // Convert match character to lower-case.
     __ lea(ecx, Operand(eax, -'a'));
     __ cmp(ecx, static_cast<int32_t>('z' - 'a'));  // Is eax a lowercase letter?
-    __ j(above, &fail);
+#ifndef ENABLE_LATIN_1
+    __ j(above, &fail);  // Weren't letters anyway.
+#else
+    Label convert_capture;
+    __ j(below_equal, &convert_capture);  // In range 'a'-'z'.
+    // Latin-1: Check for values in range [224,254] but not 247.
+    __ sub(ecx, Immediate(224 - 'a'));
+    __ cmp(ecx, Immediate(254 - 224));
+    __ j(above, &fail);  // Weren't Latin-1 letters.
+    __ cmp(ecx, Immediate(247 - 224));  // Check for 247.
+    __ j(equal, &fail);
+    __ bind(&convert_capture);
+#endif
     // Also convert capture character.
     __ movzx_b(ecx, Operand(edx, 0));
     __ or_(ecx, 0x20);
@@ -569,7 +581,7 @@
     Label* on_bit_set) {
   __ mov(eax, Immediate(table));
   Register index = current_character();
-  if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) {
+  if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) {
     __ mov(ebx, kTableSize - 1);
     __ and_(ebx, current_character());
     index = ebx;
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 7834627..2129be3 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -2947,7 +2947,7 @@
   __ jmp(miss_ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3440,7 +3440,7 @@
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
diff --git a/src/ic.cc b/src/ic.cc
index 3633036..0db9aa5 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -43,9 +43,10 @@
 char IC::TransitionMarkFromState(IC::State state) {
   switch (state) {
     case UNINITIALIZED: return '0';
-    case PREMONOMORPHIC: return 'P';
+    case PREMONOMORPHIC: return '.';
     case MONOMORPHIC: return '1';
     case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
+    case POLYMORPHIC: return 'P';
     case MEGAMORPHIC: return IsGeneric() ? 'G' : 'N';
 
     // We never see the debugger states here, because the state is
@@ -273,7 +274,7 @@
     if (info->pc() == addr) return info->rmode();
   }
   UNREACHABLE();
-  return RelocInfo::NONE;
+  return RelocInfo::NONE32;
 }
 
 
@@ -712,7 +713,6 @@
 
   // Compute the number of arguments.
   int argc = target()->arguments_count();
-  bool had_proto_failure = false;
   Handle<Code> code;
   if (state == UNINITIALIZED) {
     // This is the first time we execute this inline cache.
@@ -729,7 +729,7 @@
                TryRemoveInvalidPrototypeDependentStub(target(),
                                                       *object,
                                                       *name)) {
-      had_proto_failure = true;
+      state = MONOMORPHIC_PROTOTYPE_FAILURE;
       code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
                                     object, name);
     } else {
@@ -745,22 +745,39 @@
   if (code.is_null()) return;
 
   // Patch the call site depending on the state of the cache.
-  if (state == UNINITIALIZED ||
-      state == PREMONOMORPHIC ||
-      state == MONOMORPHIC ||
-      state == MONOMORPHIC_PROTOTYPE_FAILURE) {
-    set_target(*code);
-  } else if (state == MEGAMORPHIC) {
-    // Cache code holding map should be consistent with
-    // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
-    Handle<JSObject> cache_object = object->IsJSObject()
-        ? Handle<JSObject>::cast(object)
-        : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
-    // Update the stub cache.
-    isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
+  switch (state) {
+    case UNINITIALIZED:
+    case MONOMORPHIC_PROTOTYPE_FAILURE:
+    case PREMONOMORPHIC:
+      set_target(*code);
+      break;
+    case MONOMORPHIC:
+      if (code->ic_state() != MONOMORPHIC) {
+        Map* map = target()->FindFirstMap();
+        if (map != NULL) {
+          isolate()->stub_cache()->Set(*name, map, target());
+        }
+      }
+      set_target(*code);
+      break;
+    case MEGAMORPHIC: {
+      // Cache code holding map should be consistent with
+      // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
+      Handle<JSObject> cache_object = object->IsJSObject()
+          ? Handle<JSObject>::cast(object)
+          : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
+      // Update the stub cache.
+      isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
+      break;
+    }
+    case DEBUG_BREAK:
+    case DEBUG_PREPARE_STEP_IN:
+      break;
+    case POLYMORPHIC:
+      UNREACHABLE();
+      break;
   }
 
-  if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
   TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
            name, state, target());
 }
@@ -1024,25 +1041,37 @@
   }
 
   // Patch the call site depending on the state of the cache.
-  if (state == UNINITIALIZED ||
-      state == PREMONOMORPHIC ||
-      state == MONOMORPHIC_PROTOTYPE_FAILURE) {
-    set_target(*code);
-  } else if (state == MONOMORPHIC) {
-    // We are transitioning from monomorphic to megamorphic case.
-    // Place the current monomorphic stub and stub compiled for
-    // the receiver into stub cache.
-    Map* map = target()->FindFirstMap();
-    if (map != NULL) {
-      isolate()->stub_cache()->Set(*name, map, target());
-    }
-    isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+  switch (state) {
+    case UNINITIALIZED:
+    case PREMONOMORPHIC:
+    case MONOMORPHIC_PROTOTYPE_FAILURE:
+      set_target(*code);
+      break;
+    case MONOMORPHIC:
+      if (target() != *code) {
+        // We are transitioning from monomorphic to megamorphic case.
+        // Place the current monomorphic stub and stub compiled for
+        // the receiver into stub cache.
+        Map* map = target()->FindFirstMap();
+        if (map != NULL) {
+          isolate()->stub_cache()->Set(*name, map, target());
+        }
+        isolate()->stub_cache()->Set(*name, receiver->map(), *code);
 
-    set_target(*megamorphic_stub());
-  } else if (state == MEGAMORPHIC) {
-    // Cache code holding map should be consistent with
-    // GenerateMonomorphicCacheProbe.
-    isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+        set_target(*megamorphic_stub());
+      }
+      break;
+    case MEGAMORPHIC:
+      // Cache code holding map should be consistent with
+      // GenerateMonomorphicCacheProbe.
+      isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+      break;
+    case DEBUG_BREAK:
+    case DEBUG_PREPARE_STEP_IN:
+      break;
+    case POLYMORPHIC:
+      UNREACHABLE();
+      break;
   }
 
   TRACE_IC("LoadIC", name, state, target());
@@ -1080,7 +1109,7 @@
       receiver_maps, &handler_ics);
   isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
   PROFILE(isolate(),
-          CodeCreateEvent(Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, *code, 0));
+          CodeCreateEvent(Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG, *code, 0));
   return code;
 }
 
@@ -1108,7 +1137,7 @@
 MaybeObject* KeyedLoadIC::Load(State state,
                                Handle<Object> object,
                                Handle<Object> key,
-                               bool force_generic_stub) {
+                               ICMissMode miss_mode) {
   // Check for values that can be converted into a symbol directly or
   // is representable as a smi.
   key = TryConvertKey(key, isolate());
@@ -1209,7 +1238,7 @@
 
   if (use_ic) {
     Handle<Code> stub = generic_stub();
-    if (!force_generic_stub) {
+    if (miss_mode != MISS_FORCE_GENERIC) {
       if (object->IsString() && key->IsNumber()) {
         if (state == UNINITIALIZED) {
           stub = string_stub();
@@ -1296,13 +1325,26 @@
     }
   }
 
-  // Patch the call site depending on the state of the cache.  Make
-  // sure to always rewrite from monomorphic to megamorphic.
-  ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
-  if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
-    set_target(*code);
-  } else if (state == MONOMORPHIC) {
-    set_target(*megamorphic_stub());
+  // Patch the call site depending on the state of the cache.
+  switch (state) {
+    case UNINITIALIZED:
+    case PREMONOMORPHIC:
+    case POLYMORPHIC:
+      set_target(*code);
+      break;
+    case MONOMORPHIC:
+      // Only move to megamorphic if the target changes.
+      if (target() != *code) {
+        set_target(*megamorphic_stub());
+      }
+      break;
+    case MEGAMORPHIC:
+    case DEBUG_BREAK:
+    case DEBUG_PREPARE_STEP_IN:
+      break;
+    case MONOMORPHIC_PROTOTYPE_FAILURE:
+      UNREACHABLE();
+      break;
   }
 
   TRACE_IC("KeyedLoadIC", name, state, target());
@@ -1547,18 +1589,38 @@
   }
 
   // Patch the call site depending on the state of the cache.
-  if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
-    set_target(*code);
-  } else if (state == MONOMORPHIC) {
-    // Only move to megamorphic if the target changes.
-    if (target() != *code) {
-      set_target((strict_mode == kStrictMode)
-                   ? megamorphic_stub_strict()
-                   : megamorphic_stub());
-    }
-  } else if (state == MEGAMORPHIC) {
-    // Update the stub cache.
-    isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+  switch (state) {
+    case UNINITIALIZED:
+    case PREMONOMORPHIC:
+    case MONOMORPHIC_PROTOTYPE_FAILURE:
+      set_target(*code);
+      break;
+    case MONOMORPHIC:
+      // Only move to megamorphic if the target changes.
+      if (target() != *code) {
+        // We are transitioning from monomorphic to megamorphic case.
+        // Place the current monomorphic stub and stub compiled for
+        // the receiver into stub cache.
+        Map* map = target()->FindFirstMap();
+        if (map != NULL) {
+          isolate()->stub_cache()->Set(*name, map, target());
+        }
+        isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+        set_target((strict_mode == kStrictMode)
+                     ? megamorphic_stub_strict()
+                     : megamorphic_stub());
+      }
+      break;
+    case MEGAMORPHIC:
+      // Update the stub cache.
+      isolate()->stub_cache()->Set(*name, receiver->map(), *code);
+      break;
+    case DEBUG_BREAK:
+    case DEBUG_PREPARE_STEP_IN:
+      break;
+    case POLYMORPHIC:
+      UNREACHABLE();
+      break;
   }
 
   TRACE_IC("StoreIC", name, state, target());
@@ -1585,18 +1647,30 @@
   if (!string_stub().is_null() && stub.is_identical_to(string_stub())) {
     return result->Add(isolate()->factory()->string_map());
   } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
-    if (stub->ic_state() == MONOMORPHIC) {
-      result->Add(Handle<Map>(stub->FindFirstMap()));
-    } else {
-      ASSERT(stub->ic_state() == MEGAMORPHIC);
-      AssertNoAllocation no_allocation;
-      int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
-      for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
-        RelocInfo* info = it.rinfo();
-        Handle<Object> object(info->target_object());
-        ASSERT(object->IsMap());
-        AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
+    switch (stub->ic_state()) {
+      case MONOMORPHIC:
+        result->Add(Handle<Map>(stub->FindFirstMap()));
+        break;
+      case POLYMORPHIC: {
+        AssertNoAllocation no_allocation;
+        int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+        for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
+          RelocInfo* info = it.rinfo();
+          Handle<Object> object(info->target_object());
+          ASSERT(object->IsMap());
+          AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
+        }
+        break;
       }
+      case MEGAMORPHIC:
+        break;
+      case UNINITIALIZED:
+      case PREMONOMORPHIC:
+      case MONOMORPHIC_PROTOTYPE_FAILURE:
+      case DEBUG_BREAK:
+      case DEBUG_PREPARE_STEP_IN:
+        UNREACHABLE();
+        break;
     }
   }
 }
@@ -1686,7 +1760,7 @@
       isolate()->factory()->polymorphic_code_cache();
   Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode,
                                                              strict_mode);
-  Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, extra_state);
+  Code::Flags flags = Code::ComputeFlags(kind(), POLYMORPHIC, extra_state);
   Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags);
   if (probe->IsCode()) return Handle<Code>::cast(probe);
 
@@ -1804,7 +1878,7 @@
       receiver_maps, &handler_ics, &transitioned_maps);
   isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
   PROFILE(isolate(),
-          CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0));
+          CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0));
   return code;
 }
 
@@ -1880,7 +1954,7 @@
                                  Handle<Object> object,
                                  Handle<Object> key,
                                  Handle<Object> value,
-                                 bool force_generic) {
+                                 ICMissMode miss_mode) {
   // Check for values that can be converted into a symbol directly or
   // is representable as a smi.
   key = TryConvertKey(key, isolate());
@@ -1942,7 +2016,7 @@
       if (receiver->elements()->map() ==
           isolate()->heap()->non_strict_arguments_elements_map()) {
         stub = non_strict_arguments_stub();
-      } else if (!force_generic) {
+      } else if (miss_mode != MISS_FORCE_GENERIC) {
         if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
           StubKind stub_kind = GetStubKind(receiver, key, value);
           stub = ComputeStub(receiver, stub_kind, strict_mode, stub);
@@ -2024,15 +2098,28 @@
 
   ASSERT(!code.is_null());
 
-  // Patch the call site depending on the state of the cache.  Make
-  // sure to always rewrite from monomorphic to megamorphic.
-  ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
-  if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
-    set_target(*code);
-  } else if (state == MONOMORPHIC) {
-    set_target((strict_mode == kStrictMode)
-                 ? *megamorphic_stub_strict()
-                 : *megamorphic_stub());
+  // Patch the call site depending on the state of the cache.
+  switch (state) {
+    case UNINITIALIZED:
+    case PREMONOMORPHIC:
+    case POLYMORPHIC:
+      set_target(*code);
+      break;
+    case MONOMORPHIC:
+      // Only move to megamorphic if the target changes.
+      if (target() != *code) {
+        set_target((strict_mode == kStrictMode)
+                     ? *megamorphic_stub_strict()
+                     : *megamorphic_stub());
+      }
+      break;
+    case MEGAMORPHIC:
+    case DEBUG_BREAK:
+    case DEBUG_PREPARE_STEP_IN:
+      break;
+    case MONOMORPHIC_PROTOTYPE_FAILURE:
+      UNREACHABLE();
+      break;
   }
 
   TRACE_IC("KeyedStoreIC", name, state, target());
@@ -2057,13 +2144,12 @@
                                               extra_ic_state,
                                               args.at<Object>(0),
                                               args.at<String>(1));
-  // Result could be a function or a failure.
-  JSFunction* raw_function = NULL;
+  JSFunction* raw_function;
   if (!maybe_result->To(&raw_function)) return maybe_result;
 
   // The first time the inline cache is updated may be the first time the
-  // function it references gets called.  If the function is lazily compiled
-  // then the first call will trigger a compilation.  We check for this case
+  // function it references gets called. If the function is lazily compiled
+  // then the first call will trigger a compilation. We check for this case
   // and we do the compilation immediately, instead of waiting for the stub
   // currently attached to the JSFunction object to trigger compilation.
   if (raw_function->is_compiled()) return raw_function;
@@ -2110,7 +2196,7 @@
   ASSERT(args.length() == 2);
   KeyedLoadIC ic(isolate);
   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
-  return ic.Load(state, args.at<Object>(0), args.at<Object>(1), false);
+  return ic.Load(state, args.at<Object>(0), args.at<Object>(1), MISS);
 }
 
 
@@ -2119,7 +2205,10 @@
   ASSERT(args.length() == 2);
   KeyedLoadIC ic(isolate);
   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
-  return ic.Load(state, args.at<Object>(0), args.at<Object>(1), true);
+  return ic.Load(state,
+                 args.at<Object>(0),
+                 args.at<Object>(1),
+                 MISS_FORCE_GENERIC);
 }
 
 
@@ -2211,7 +2300,7 @@
                   args.at<Object>(0),
                   args.at<Object>(1),
                   args.at<Object>(2),
-                  false);
+                  MISS);
 }
 
 
@@ -2244,7 +2333,7 @@
                   args.at<Object>(0),
                   args.at<Object>(1),
                   args.at<Object>(2),
-                  true);
+                  MISS_FORCE_GENERIC);
 }
 
 
diff --git a/src/ic.h b/src/ic.h
index bfccd10..dd81ab4 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -476,6 +476,12 @@
 };
 
 
+enum ICMissMode {
+  MISS_FORCE_GENERIC,
+  MISS
+};
+
+
 class KeyedLoadIC: public KeyedIC {
  public:
   explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) {
@@ -485,16 +491,16 @@
   MUST_USE_RESULT MaybeObject* Load(State state,
                                     Handle<Object> object,
                                     Handle<Object> key,
-                                    bool force_generic_stub);
+                                    ICMissMode force_generic);
 
   // Code generator routines.
-  static void GenerateMiss(MacroAssembler* masm, bool force_generic);
+  static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic);
   static void GenerateRuntimeGetProperty(MacroAssembler* masm);
   static void GenerateInitialize(MacroAssembler* masm) {
-    GenerateMiss(masm, false);
+    GenerateMiss(masm, MISS);
   }
   static void GeneratePreMonomorphic(MacroAssembler* masm) {
-    GenerateMiss(masm, false);
+    GenerateMiss(masm, MISS);
   }
   static void GenerateGeneric(MacroAssembler* masm);
   static void GenerateString(MacroAssembler* masm);
@@ -654,13 +660,13 @@
                                      Handle<Object> object,
                                      Handle<Object> name,
                                      Handle<Object> value,
-                                     bool force_generic);
+                                     ICMissMode force_generic);
 
   // Code generators for stub routines.  Only called once at startup.
   static void GenerateInitialize(MacroAssembler* masm) {
-    GenerateMiss(masm, false);
+    GenerateMiss(masm, MISS);
   }
-  static void GenerateMiss(MacroAssembler* masm, bool force_generic);
+  static void GenerateMiss(MacroAssembler* masm, ICMissMode force_generic);
   static void GenerateSlow(MacroAssembler* masm);
   static void GenerateRuntimeSetProperty(MacroAssembler* masm,
                                          StrictModeFlag strict_mode);
@@ -686,7 +692,7 @@
                                               StrictModeFlag strict_mode,
                                               KeyedAccessGrowMode grow_mode);
 
-  private:
+ private:
   // Update the inline cache.
   void UpdateCaches(LookupResult* lookup,
                     State state,
@@ -848,6 +854,8 @@
 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
 
+DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss);
+
 } }  // namespace v8::internal
 
 #endif  // V8_IC_H_
diff --git a/src/interpreter-irregexp.cc b/src/interpreter-irregexp.cc
index 3a92b84..5abeb5a 100644
--- a/src/interpreter-irregexp.cc
+++ b/src/interpreter-irregexp.cc
@@ -68,7 +68,7 @@
                                  int from,
                                  int current,
                                  int len,
-                                 Vector<const char> subject) {
+                                 Vector<const uint8_t> subject) {
   for (int i = 0; i < len; i++) {
     unsigned int old_char = subject[from++];
     unsigned int new_char = subject[current++];
@@ -617,7 +617,7 @@
   uc16 previous_char = '\n';
   String::FlatContent subject_content = subject->GetFlatContent();
   if (subject_content.IsAscii()) {
-    Vector<const char> subject_vector = subject_content.ToAsciiVector();
+    Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
     if (start_position != 0) previous_char = subject_vector[start_position - 1];
     return RawMatch(isolate,
                     code_base,
diff --git a/src/isolate.cc b/src/isolate.cc
index 60e3379..c136069 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -536,14 +536,15 @@
                                    unsigned int magic2) {
   const int kMaxStackTraceSize = 8192;
   Handle<String> trace = StackTraceString();
-  char buffer[kMaxStackTraceSize];
+  uint8_t buffer[kMaxStackTraceSize];
   int length = Min(kMaxStackTraceSize - 1, trace->length());
   String::WriteToFlat(*trace, buffer, 0, length);
   buffer[length] = '\0';
+  // TODO(dcarney): convert buffer to utf8?
   OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n",
                  magic, magic2,
                  static_cast<void*>(object), static_cast<void*>(map),
-                 buffer);
+                 reinterpret_cast<char*>(buffer));
   OS::Abort();
 }
 
@@ -1344,7 +1345,7 @@
   // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
   // set it.
   HandleScope scope;
-  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
+  if (thread_local_top_.pending_exception_->IsOutOfMemory()) {
     context()->mark_out_of_memory();
   } else if (thread_local_top_.pending_exception_ ==
              heap()->termination_exception()) {
@@ -1375,7 +1376,7 @@
 MessageLocation Isolate::GetMessageLocation() {
   ASSERT(has_pending_exception());
 
-  if (thread_local_top_.pending_exception_ != Failure::OutOfMemoryException() &&
+  if (!thread_local_top_.pending_exception_->IsOutOfMemory() &&
       thread_local_top_.pending_exception_ != heap()->termination_exception() &&
       thread_local_top_.has_pending_message_ &&
       !thread_local_top_.pending_message_obj_->IsTheHole() &&
@@ -1889,7 +1890,7 @@
 
   if (!external_caught) return;
 
-  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
+  if (thread_local_top_.pending_exception_->IsOutOfMemory()) {
     // Do not propagate OOM exception: we should kill VM asap.
   } else if (thread_local_top_.pending_exception_ ==
              heap()->termination_exception()) {
diff --git a/src/isolate.h b/src/isolate.h
index b3cfb43..8d0575c 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -615,7 +615,7 @@
   bool IsExternallyCaught();
 
   bool is_catchable_by_javascript(MaybeObject* exception) {
-    return (exception != Failure::OutOfMemoryException()) &&
+    return (!exception->IsOutOfMemory()) &&
         (exception != heap()->termination_exception());
   }
 
diff --git a/src/json-parser.h b/src/json-parser.h
index f6140f1..ccb3286 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -441,21 +441,21 @@
   int length = position_ - beg_pos;
   double number;
   if (seq_ascii) {
-    Vector<const char> chars(seq_source_->GetChars() +  beg_pos, length);
+    Vector<const uint8_t> chars(seq_source_->GetChars() +  beg_pos, length);
     number = StringToDouble(isolate()->unicode_cache(),
-                             chars,
+                             Vector<const char>::cast(chars),
                              NO_FLAGS,  // Hex, octal or trailing junk.
                              OS::nan_value());
   } else {
-    Vector<char> buffer = Vector<char>::New(length);
+    Vector<uint8_t> buffer = Vector<uint8_t>::New(length);
     String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
-    Vector<const char> result =
-        Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
-        length);
+    Vector<const uint8_t> result =
+        Vector<const uint8_t>(buffer.start(), length);
     number = StringToDouble(isolate()->unicode_cache(),
-                             result,
-                             NO_FLAGS,  // Hex, octal or trailing junk.
-                             0.0);
+                            // TODO(dcarney): Convert StringToDouble to uint_t.
+                            Vector<const char>::cast(result),
+                            NO_FLAGS,  // Hex, octal or trailing junk.
+                            0.0);
     buffer.Dispose();
   }
   SkipWhitespace();
@@ -526,7 +526,7 @@
       // in the ASCII sink.
       if (sizeof(SinkChar) == kUC16Size ||
           seq_ascii ||
-          c0_ <= kMaxAsciiCharCode) {
+          c0_ <= String::kMaxOneByteCharCode) {
         SeqStringSet(seq_str, count++, c0_);
         Advance();
       } else {
@@ -566,7 +566,8 @@
             }
             value = value * 16 + digit;
           }
-          if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) {
+          if (sizeof(SinkChar) == kUC16Size ||
+              value <= String::kMaxOneByteCharCode) {
             SeqStringSet(seq_str, count++, value);
             break;
           } else {
@@ -626,9 +627,9 @@
         c0_ = c0;
         int beg_pos = position_;
         position_ = position;
-        return SlowScanJsonString<SeqOneByteString, char>(source_,
-                                                        beg_pos,
-                                                        position_);
+        return SlowScanJsonString<SeqOneByteString, uint8_t>(source_,
+                                                            beg_pos,
+                                                            position_);
       }
       if (c0 < 0x20) return Handle<String>::null();
       if (static_cast<uint32_t>(c0) >
@@ -649,7 +650,7 @@
     int length = position - position_;
     uint32_t hash = (length <= String::kMaxHashCalcLength)
         ? StringHasher::GetHashCore(running_hash) : length;
-    Vector<const char> string_vector(
+    Vector<const uint8_t> string_vector(
         seq_source_->GetChars() + position_, length);
     SymbolTable* symbol_table = isolate()->heap()->symbol_table();
     uint32_t capacity = symbol_table->Capacity();
@@ -662,7 +663,7 @@
         break;
       }
       if (element != isolate()->heap()->the_hole_value() &&
-          String::cast(element)->IsAsciiEqualTo(string_vector)) {
+          String::cast(element)->IsOneByteEqualTo(string_vector)) {
         // Lookup success, update the current position.
         position_ = position;
         // Advance past the last '"'.
@@ -679,7 +680,7 @@
     // Check for control character (0x00-0x1f) or unterminated string (<0).
     if (c0_ < 0x20) return Handle<String>::null();
     if (c0_ != '\\') {
-      if (seq_ascii || c0_ <= kMaxAsciiCharCode) {
+      if (seq_ascii || c0_ <= String::kMaxOneByteCharCode) {
         Advance();
       } else {
         return SlowScanJsonString<SeqTwoByteString, uc16>(source_,
@@ -687,9 +688,9 @@
                                                           position_);
       }
     } else {
-      return SlowScanJsonString<SeqOneByteString, char>(source_,
-                                                      beg_pos,
-                                                      position_);
+      return SlowScanJsonString<SeqOneByteString, uint8_t>(source_,
+                                                           beg_pos,
+                                                           position_);
     }
   } while (c0_ != '"');
   int length = position_ - beg_pos;
@@ -698,7 +699,7 @@
     result = factory()->LookupOneByteSymbol(seq_source_, beg_pos, length);
   } else {
     result = factory()->NewRawOneByteString(length, pretenure_);
-    char* dest = SeqOneByteString::cast(*result)->GetChars();
+    uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
     String::WriteToFlat(*source_, dest, beg_pos, position_);
   }
   ASSERT_EQ('"', c0_);
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index 426a370..cec9844 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -60,7 +60,7 @@
   template <bool is_ascii, typename Char>
   INLINE(void Append_(const Char* chars));
 
-  INLINE(void Append(char c)) {
+  INLINE(void Append(uint8_t c)) {
     if (is_ascii_) {
       Append_<true>(c);
     } else {
@@ -68,11 +68,11 @@
     }
   }
 
-  INLINE(void Append(const char* chars)) {
+  INLINE(void AppendAscii(const char* chars)) {
     if (is_ascii_) {
-      Append_<true>(chars);
+      Append_<true>(reinterpret_cast<const uint8_t*>(chars));
     } else {
-      Append_<false>(chars);
+      Append_<false>(reinterpret_cast<const uint8_t*>(chars));
     }
   }
 
@@ -327,15 +327,15 @@
       switch (Oddball::cast(*object)->kind()) {
         case Oddball::kFalse:
           if (deferred_string_key) SerializeDeferredKey(comma, key);
-          Append("false");
+          AppendAscii("false");
           return SUCCESS;
         case Oddball::kTrue:
           if (deferred_string_key) SerializeDeferredKey(comma, key);
-          Append("true");
+          AppendAscii("true");
           return SUCCESS;
         case Oddball::kNull:
           if (deferred_string_key) SerializeDeferredKey(comma, key);
-          Append("null");
+          AppendAscii("null");
           return SUCCESS;
         default:
           return UNCHANGED;
@@ -412,7 +412,7 @@
     ASSERT(class_name == isolate_->heap()->Boolean_symbol());
     Object* value = JSValue::cast(*object)->value();
     ASSERT(value->IsBoolean());
-    Append(value->IsTrue() ? "true" : "false");
+    AppendAscii(value->IsTrue() ? "true" : "false");
   }
   return SUCCESS;
 }
@@ -422,7 +422,7 @@
   static const int kBufferSize = 100;
   char chars[kBufferSize];
   Vector<char> buffer(chars, kBufferSize);
-  Append(IntToCString(object->value(), buffer));
+  AppendAscii(IntToCString(object->value(), buffer));
   return SUCCESS;
 }
 
@@ -430,13 +430,13 @@
 BasicJsonStringifier::Result BasicJsonStringifier::SerializeDouble(
     double number) {
   if (isinf(number) || isnan(number)) {
-    Append("null");
+    AppendAscii("null");
     return SUCCESS;
   }
   static const int kBufferSize = 100;
   char chars[kBufferSize];
   Vector<char> buffer(chars, kBufferSize);
-  Append(DoubleToCString(number, buffer));
+  AppendAscii(DoubleToCString(number, buffer));
   return SUCCESS;
 }
 
@@ -476,7 +476,7 @@
             SerializeElement(Handle<Object>(elements->get(i), isolate_), i);
         if (result == SUCCESS) continue;
         if (result == UNCHANGED) {
-          Append("null");
+          AppendAscii("null");
         } else {
           return result;
         }
@@ -505,12 +505,12 @@
     if (i > 0) Append(',');
     Handle<Object> element = Object::GetElement(object, i);
     if (element->IsUndefined()) {
-      Append("null");
+      AppendAscii("null");
     } else {
       Result result = SerializeElement(element, i);
       if (result == SUCCESS) continue;
       if (result == UNCHANGED) {
-        Append("null");
+        AppendAscii("null");
       } else {
         return result;
       }
@@ -682,8 +682,9 @@
       if (DoNotEscape(c)) {
         Append_<is_ascii, Char>(c);
       } else {
-        Append_<is_ascii, char>(
-            &JsonEscapeTable[c * kJsonEscapeTableEntrySize]);
+        Append_<is_ascii, uint8_t>(
+            reinterpret_cast<const uint8_t*>(
+                &JsonEscapeTable[c * kJsonEscapeTableEntrySize]));
       }
       // If GC moved the string, we need to refresh the vector.
       if (*string != string_location) {
@@ -693,27 +694,22 @@
     }
   }
 
-  Append_<is_ascii, char>('"');
+  Append_<is_ascii, uint8_t>('"');
 }
 
 
-template <>
-bool BasicJsonStringifier::DoNotEscape(char c) {
-  return c >= '#' && c <= '~' && c != '\\';
-}
-
-
-template <>
-bool BasicJsonStringifier::DoNotEscape(uc16 c) {
+template <typename Char>
+bool BasicJsonStringifier::DoNotEscape(Char c) {
   return (c >= 0x80) || (c >= '#' && c <= '~' && c != '\\');
 }
 
 
 template <>
-Vector<const char> BasicJsonStringifier::GetCharVector(Handle<String> string) {
+Vector<const uint8_t> BasicJsonStringifier::GetCharVector(
+    Handle<String> string) {
   String::FlatContent flat = string->GetFlatContent();
   ASSERT(flat.IsAscii());
-  return flat.ToAsciiVector();
+  return flat.ToOneByteVector();
 }
 
 
@@ -730,14 +726,14 @@
   String::FlatContent flat = object->GetFlatContent();
   if (is_ascii_) {
     if (flat.IsAscii()) {
-      SerializeString_<true, char>(object);
+      SerializeString_<true, uint8_t>(object);
     } else {
       ChangeEncoding();
       SerializeString(object);
     }
   } else {
     if (flat.IsAscii()) {
-      SerializeString_<false, char>(object);
+      SerializeString_<false, uint8_t>(object);
     } else {
       SerializeString_<false, uc16>(object);
     }
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 813208c..a3efb85 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -309,16 +309,16 @@
     index = (needle_content.IsAscii()
              ? (subject_content.IsAscii()
                 ? SearchString(isolate,
-                               subject_content.ToAsciiVector(),
-                               needle_content.ToAsciiVector(),
+                               subject_content.ToOneByteVector(),
+                               needle_content.ToOneByteVector(),
                                index)
                 : SearchString(isolate,
                                subject_content.ToUC16Vector(),
-                               needle_content.ToAsciiVector(),
+                               needle_content.ToOneByteVector(),
                                index))
              : (subject_content.IsAscii()
                 ? SearchString(isolate,
-                               subject_content.ToAsciiVector(),
+                               subject_content.ToOneByteVector(),
                                needle_content.ToUC16Vector(),
                                index)
                 : SearchString(isolate,
@@ -1681,7 +1681,7 @@
     letters[0] = character;
     length = 1;
   }
-  if (!ascii_subject || character <= String::kMaxAsciiCharCode) {
+  if (!ascii_subject || character <= String::kMaxOneByteCharCode) {
     return length;
   }
   // The standard requires that non-ASCII characters cannot have ASCII
@@ -1732,7 +1732,7 @@
   bool checked = false;
   // We handle the length > 1 case in a later pass.
   if (length == 1) {
-    if (ascii && c > String::kMaxAsciiCharCodeU) {
+    if (ascii && c > String::kMaxOneByteCharCodeU) {
       // Can't match - see above.
       return false;  // Bounds not checked.
     }
@@ -1753,7 +1753,7 @@
                                       Label* on_failure) {
   uc16 char_mask;
   if (ascii) {
-    char_mask = String::kMaxAsciiCharCode;
+    char_mask = String::kMaxOneByteCharCode;
   } else {
     char_mask = String::kMaxUtf16CodeUnit;
   }
@@ -2007,7 +2007,7 @@
   // range with a single not-taken branch, speeding up this important
   // character range (even non-ASCII charset-based text has spaces and
   // punctuation).
-  if (*border - 1 > String::kMaxAsciiCharCode &&  // ASCII case.
+  if (*border - 1 > String::kMaxOneByteCharCode &&  // ASCII case.
       end_index - start_index > (*new_start_index - start_index) * 2 &&
       last - first > kSize * 2 &&
       binary_chop_index > *new_start_index &&
@@ -2211,7 +2211,7 @@
 
   int max_char;
   if (ascii) {
-    max_char = String::kMaxAsciiCharCode;
+    max_char = String::kMaxOneByteCharCode;
   } else {
     max_char = String::kMaxUtf16CodeUnit;
   }
@@ -2513,7 +2513,7 @@
   bool found_useful_op = false;
   uint32_t char_mask;
   if (asc) {
-    char_mask = String::kMaxAsciiCharCode;
+    char_mask = String::kMaxOneByteCharCode;
   } else {
     char_mask = String::kMaxUtf16CodeUnit;
   }
@@ -2522,7 +2522,7 @@
   int char_shift = 0;
   for (int i = 0; i < characters_; i++) {
     Position* pos = &positions_[i];
-    if ((pos->mask & String::kMaxAsciiCharCode) != 0) {
+    if ((pos->mask & String::kMaxOneByteCharCode) != 0) {
       found_useful_op = true;
     }
     mask_ |= (pos->mask & char_mask) << char_shift;
@@ -2565,7 +2565,7 @@
     // load so the value is already masked down.
     uint32_t char_mask;
     if (compiler->ascii()) {
-      char_mask = String::kMaxAsciiCharCode;
+      char_mask = String::kMaxOneByteCharCode;
     } else {
       char_mask = String::kMaxUtf16CodeUnit;
     }
@@ -2575,7 +2575,11 @@
     // For 2-character preloads in ASCII mode or 1-character preloads in
     // TWO_BYTE mode we also use a 16 bit load with zero extend.
     if (details->characters() == 2 && compiler->ascii()) {
-      if ((mask & 0x7f7f) == 0x7f7f) need_mask = false;
+#ifndef ENABLE_LATIN_1
+      if ((mask & 0x7f7f) == 0xffff) need_mask = false;
+#else
+      if ((mask & 0xffff) == 0xffff) need_mask = false;
+#endif
     } else if (details->characters() == 1 && !compiler->ascii()) {
       if ((mask & 0xffff) == 0xffff) need_mask = false;
     } else {
@@ -2617,7 +2621,7 @@
   int characters = details->characters();
   int char_mask;
   if (compiler->ascii()) {
-    char_mask = String::kMaxAsciiCharCode;
+    char_mask = String::kMaxOneByteCharCode;
   } else {
     char_mask = String::kMaxUtf16CodeUnit;
   }
@@ -2834,24 +2838,24 @@
 };
 
 
-RegExpNode* SeqRegExpNode::FilterASCII(int depth) {
+RegExpNode* SeqRegExpNode::FilterASCII(int depth, bool ignore_case) {
   if (info()->replacement_calculated) return replacement();
   if (depth < 0) return this;
   ASSERT(!info()->visited);
   VisitMarker marker(info());
-  return FilterSuccessor(depth - 1);
+  return FilterSuccessor(depth - 1, ignore_case);
 }
 
 
-RegExpNode* SeqRegExpNode::FilterSuccessor(int depth) {
-  RegExpNode* next = on_success_->FilterASCII(depth - 1);
+RegExpNode* SeqRegExpNode::FilterSuccessor(int depth, bool ignore_case) {
+  RegExpNode* next = on_success_->FilterASCII(depth - 1, ignore_case);
   if (next == NULL) return set_replacement(NULL);
   on_success_ = next;
   return set_replacement(this);
 }
 
 
-RegExpNode* TextNode::FilterASCII(int depth) {
+RegExpNode* TextNode::FilterASCII(int depth, bool ignore_case) {
   if (info()->replacement_calculated) return replacement();
   if (depth < 0) return this;
   ASSERT(!info()->visited);
@@ -2862,15 +2866,40 @@
     if (elm.type == TextElement::ATOM) {
       Vector<const uc16> quarks = elm.data.u_atom->data();
       for (int j = 0; j < quarks.length(); j++) {
-        // We don't need special handling for case independence
-        // because of the rule that case independence cannot make
-        // a non-ASCII character match an ASCII character.
-        if (quarks[j] > String::kMaxAsciiCharCode) {
+#ifndef ENABLE_LATIN_1
+        if (quarks[j] > String::kMaxOneByteCharCode) {
           return set_replacement(NULL);
         }
+#else
+        if (quarks[j] <= String::kMaxOneByteCharCode) continue;
+        if (!ignore_case) return set_replacement(NULL);
+        // Here, we need to check for characters whose upper and lower cases
+        // are outside the Latin-1 range.
+        // TODO(dcarney): Replace this code with a simple
+        // table lookup in unibrow::Latin-1.
+        // TODO(dcarney): Test cases!.
+        unibrow::uchar result;
+        int chars;
+        chars = unibrow::ToLowercase::Convert(quarks[j], 0, &result, NULL);
+        if (chars > 1 ||
+            (chars == 1 && result <= String::kMaxOneByteCharCodeU)) {
+          continue;
+        }
+        chars = unibrow::ToUppercase::Convert(quarks[j], 0, &result, NULL);
+        if (chars > 1 ||
+            (chars == 1 && result <= String::kMaxOneByteCharCodeU)) {
+          continue;
+        }
+        // This character is definitely not in the Latin-1 range.
+        return set_replacement(NULL);
+#endif
       }
     } else {
       ASSERT(elm.type == TextElement::CHAR_CLASS);
+#ifdef ENABLE_LATIN_1
+      // TODO(dcarney): Can this be improved?
+      if (ignore_case) continue;
+#endif
       RegExpCharacterClass* cc = elm.data.u_char_class;
       ZoneList<CharacterRange>* ranges = cc->ranges(zone());
       if (!CharacterRange::IsCanonical(ranges)) {
@@ -2881,39 +2910,40 @@
       if (cc->is_negated()) {
         if (range_count != 0 &&
             ranges->at(0).from() == 0 &&
-            ranges->at(0).to() >= String::kMaxAsciiCharCode) {
+            ranges->at(0).to() >= String::kMaxOneByteCharCode) {
           return set_replacement(NULL);
         }
       } else {
         if (range_count == 0 ||
-            ranges->at(0).from() > String::kMaxAsciiCharCode) {
+            ranges->at(0).from() > String::kMaxOneByteCharCode) {
           return set_replacement(NULL);
         }
       }
     }
   }
-  return FilterSuccessor(depth - 1);
+  return FilterSuccessor(depth - 1, ignore_case);
 }
 
 
-RegExpNode* LoopChoiceNode::FilterASCII(int depth) {
+RegExpNode* LoopChoiceNode::FilterASCII(int depth, bool ignore_case) {
   if (info()->replacement_calculated) return replacement();
   if (depth < 0) return this;
   if (info()->visited) return this;
   {
     VisitMarker marker(info());
 
-    RegExpNode* continue_replacement = continue_node_->FilterASCII(depth - 1);
+    RegExpNode* continue_replacement =
+        continue_node_->FilterASCII(depth - 1, ignore_case);
     // If we can't continue after the loop then there is no sense in doing the
     // loop.
     if (continue_replacement == NULL) return set_replacement(NULL);
   }
 
-  return ChoiceNode::FilterASCII(depth - 1);
+  return ChoiceNode::FilterASCII(depth - 1, ignore_case);
 }
 
 
-RegExpNode* ChoiceNode::FilterASCII(int depth) {
+RegExpNode* ChoiceNode::FilterASCII(int depth, bool ignore_case) {
   if (info()->replacement_calculated) return replacement();
   if (depth < 0) return this;
   if (info()->visited) return this;
@@ -2932,7 +2962,8 @@
   RegExpNode* survivor = NULL;
   for (int i = 0; i < choice_count; i++) {
     GuardedAlternative alternative = alternatives_->at(i);
-    RegExpNode* replacement = alternative.node()->FilterASCII(depth - 1);
+    RegExpNode* replacement =
+        alternative.node()->FilterASCII(depth - 1, ignore_case);
     ASSERT(replacement != this);  // No missing EMPTY_MATCH_CHECK.
     if (replacement != NULL) {
       alternatives_->at(i).set_node(replacement);
@@ -2952,7 +2983,7 @@
       new(zone()) ZoneList<GuardedAlternative>(surviving, zone());
   for (int i = 0; i < choice_count; i++) {
     RegExpNode* replacement =
-        alternatives_->at(i).node()->FilterASCII(depth - 1);
+        alternatives_->at(i).node()->FilterASCII(depth - 1, ignore_case);
     if (replacement != NULL) {
       alternatives_->at(i).set_node(replacement);
       new_alternatives->Add(alternatives_->at(i), zone());
@@ -2963,7 +2994,8 @@
 }
 
 
-RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth) {
+RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth,
+                                                     bool ignore_case) {
   if (info()->replacement_calculated) return replacement();
   if (depth < 0) return this;
   if (info()->visited) return this;
@@ -2971,12 +3003,12 @@
   // Alternative 0 is the negative lookahead, alternative 1 is what comes
   // afterwards.
   RegExpNode* node = alternatives_->at(1).node();
-  RegExpNode* replacement = node->FilterASCII(depth - 1);
+  RegExpNode* replacement = node->FilterASCII(depth - 1, ignore_case);
   if (replacement == NULL) return set_replacement(NULL);
   alternatives_->at(1).set_node(replacement);
 
   RegExpNode* neg_node = alternatives_->at(0).node();
-  RegExpNode* neg_replacement = neg_node->FilterASCII(depth - 1);
+  RegExpNode* neg_replacement = neg_node->FilterASCII(depth - 1, ignore_case);
   // If the negative lookahead is always going to fail then
   // we don't need to check it.
   if (neg_replacement == NULL) return set_replacement(replacement);
@@ -3299,7 +3331,7 @@
         switch (pass) {
           case NON_ASCII_MATCH:
             ASSERT(ascii);
-            if (quarks[j] > String::kMaxAsciiCharCode) {
+            if (quarks[j] > String::kMaxOneByteCharCode) {
               assembler->GoTo(backtrack);
               return;
             }
@@ -3498,7 +3530,7 @@
   if (ranges->length() != 1) return NULL;
   uint32_t max_char;
   if (compiler->ascii()) {
-    max_char = String::kMaxAsciiCharCode;
+    max_char = String::kMaxOneByteCharCode;
   } else {
     max_char = String::kMaxUtf16CodeUnit;
   }
@@ -3698,7 +3730,7 @@
     : length_(length),
       compiler_(compiler) {
   if (compiler->ascii()) {
-    max_char_ = String::kMaxAsciiCharCode;
+    max_char_ = String::kMaxOneByteCharCode;
   } else {
     max_char_ = String::kMaxUtf16CodeUnit;
   }
@@ -5337,8 +5369,8 @@
   uc16 bottom = from();
   uc16 top = to();
   if (is_ascii) {
-    if (bottom > String::kMaxAsciiCharCode) return;
-    if (top > String::kMaxAsciiCharCode) top = String::kMaxAsciiCharCode;
+    if (bottom > String::kMaxOneByteCharCode) return;
+    if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode;
   }
   unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
   if (top == bottom) {
@@ -5885,7 +5917,7 @@
           int length = GetCaseIndependentLetters(
               ISOLATE,
               character,
-              bm->max_char() == String::kMaxAsciiCharCode,
+              bm->max_char() == String::kMaxOneByteCharCode,
               chars);
           for (int j = 0; j < length; j++) {
             bm->Set(offset, chars[j]);
@@ -6099,10 +6131,12 @@
     }
   }
   if (is_ascii) {
-    node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
+    node = node->FilterASCII(RegExpCompiler::kMaxRecursion, ignore_case);
     // Do it again to propagate the new nodes to places where they were not
     // put because they had not been calculated yet.
-    if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
+    if (node != NULL) {
+      node = node->FilterASCII(RegExpCompiler::kMaxRecursion, ignore_case);
+    }
   }
 
   if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone);
diff --git a/src/jsregexp.h b/src/jsregexp.h
index 96825ce..7e83d42 100644
--- a/src/jsregexp.h
+++ b/src/jsregexp.h
@@ -628,7 +628,7 @@
   // If we know that the input is ASCII then there are some nodes that can
   // never match.  This method returns a node that can be substituted for
   // itself, or NULL if the node can never match.
-  virtual RegExpNode* FilterASCII(int depth) { return this; }
+  virtual RegExpNode* FilterASCII(int depth, bool ignore_case) { return this; }
   // Helper for FilterASCII.
   RegExpNode* replacement() {
     ASSERT(info()->replacement_calculated);
@@ -723,7 +723,7 @@
       : RegExpNode(on_success->zone()), on_success_(on_success) { }
   RegExpNode* on_success() { return on_success_; }
   void set_on_success(RegExpNode* node) { on_success_ = node; }
-  virtual RegExpNode* FilterASCII(int depth);
+  virtual RegExpNode* FilterASCII(int depth, bool ignore_case);
   virtual void FillInBMInfo(int offset,
                             int recursion_depth,
                             int budget,
@@ -735,7 +735,7 @@
   }
 
  protected:
-  RegExpNode* FilterSuccessor(int depth);
+  RegExpNode* FilterSuccessor(int depth, bool ignore_case);
 
  private:
   RegExpNode* on_success_;
@@ -861,7 +861,7 @@
                             BoyerMooreLookahead* bm,
                             bool not_at_start);
   void CalculateOffsets();
-  virtual RegExpNode* FilterASCII(int depth);
+  virtual RegExpNode* FilterASCII(int depth, bool ignore_case);
 
  private:
   enum TextEmitPassType {
@@ -1097,7 +1097,7 @@
   void set_not_at_start() { not_at_start_ = true; }
   void set_being_calculated(bool b) { being_calculated_ = b; }
   virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; }
-  virtual RegExpNode* FilterASCII(int depth);
+  virtual RegExpNode* FilterASCII(int depth, bool ignore_case);
 
  protected:
   int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative);
@@ -1155,7 +1155,7 @@
   // characters, but on a negative lookahead the negative branch did not take
   // part in that calculation (EatsAtLeast) so the assumptions don't hold.
   virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; }
-  virtual RegExpNode* FilterASCII(int depth);
+  virtual RegExpNode* FilterASCII(int depth, bool ignore_case);
 };
 
 
@@ -1185,7 +1185,7 @@
   RegExpNode* continue_node() { return continue_node_; }
   bool body_can_be_zero_length() { return body_can_be_zero_length_; }
   virtual void Accept(NodeVisitor* visitor);
-  virtual RegExpNode* FilterASCII(int depth);
+  virtual RegExpNode* FilterASCII(int depth, bool ignore_case);
 
  private:
   // AddAlternative is made private for loop nodes because alternatives
diff --git a/src/lithium-allocator.h b/src/lithium-allocator.h
index 0dd192d..9ea6641 100644
--- a/src/lithium-allocator.h
+++ b/src/lithium-allocator.h
@@ -399,40 +399,6 @@
 };
 
 
-class GrowableBitVector BASE_EMBEDDED {
- public:
-  GrowableBitVector() : bits_(NULL) { }
-
-  bool Contains(int value) const {
-    if (!InBitsRange(value)) return false;
-    return bits_->Contains(value);
-  }
-
-  void Add(int value, Zone* zone) {
-    EnsureCapacity(value, zone);
-    bits_->Add(value);
-  }
-
- private:
-  static const int kInitialLength = 1024;
-
-  bool InBitsRange(int value) const {
-    return bits_ != NULL && bits_->length() > value;
-  }
-
-  void EnsureCapacity(int value, Zone* zone) {
-    if (InBitsRange(value)) return;
-    int new_length = bits_ == NULL ? kInitialLength : bits_->length();
-    while (new_length <= value) new_length *= 2;
-    BitVector* new_bits = new(zone) BitVector(new_length, zone);
-    if (bits_ != NULL) new_bits->CopyFrom(*bits_);
-    bits_ = new_bits;
-  }
-
-  BitVector* bits_;
-};
-
-
 class LAllocator BASE_EMBEDDED {
  public:
   LAllocator(int first_virtual_register, HGraph* graph);
diff --git a/src/log.cc b/src/log.cc
index 88527ca..efbb8f7 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -384,7 +384,10 @@
     if (str == NULL) return;
     if (str->HasOnlyAsciiChars()) {
       int utf8_length = Min(str->length(), kUtf8BufferSize - utf8_pos_);
-      String::WriteToFlat(str, utf8_buffer_ + utf8_pos_, 0, utf8_length);
+      String::WriteToFlat(str,
+                          reinterpret_cast<uint8_t*>(utf8_buffer_ + utf8_pos_),
+                          0,
+                          utf8_length);
       utf8_pos_ += utf8_length;
       return;
     }
@@ -393,7 +396,7 @@
     int previous = unibrow::Utf16::kNoPreviousCharacter;
     for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
       uc16 c = utf16_buffer[i];
-      if (c <= String::kMaxAsciiCharCodeU) {
+      if (c <= unibrow::Utf8::kMaxOneByteChar) {
         utf8_buffer_[utf8_pos_++] = static_cast<char>(c);
       } else {
         int char_length = unibrow::Utf8::Length(c, previous);
diff --git a/src/log.h b/src/log.h
index eced605..b5b6817 100644
--- a/src/log.h
+++ b/src/log.h
@@ -127,10 +127,10 @@
   V(EVAL_TAG,                       "Eval")                             \
   V(FUNCTION_TAG,                   "Function")                         \
   V(KEYED_LOAD_IC_TAG,              "KeyedLoadIC")                      \
-  V(KEYED_LOAD_MEGAMORPHIC_IC_TAG,  "KeyedLoadMegamorphicIC")           \
+  V(KEYED_LOAD_POLYMORPHIC_IC_TAG,  "KeyedLoadPolymorphicIC")           \
   V(KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG, "KeyedExternalArrayLoadIC")       \
   V(KEYED_STORE_IC_TAG,             "KeyedStoreIC")                     \
-  V(KEYED_STORE_MEGAMORPHIC_IC_TAG, "KeyedStoreMegamorphicIC")          \
+  V(KEYED_STORE_POLYMORPHIC_IC_TAG, "KeyedStorePolymorphicIC")          \
   V(KEYED_EXTERNAL_ARRAY_STORE_IC_TAG, "KeyedExternalArrayStoreIC")     \
   V(LAZY_COMPILE_TAG,               "LazyCompile")                      \
   V(LOAD_IC_TAG,                    "LoadIC")                           \
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 8ca14db..3ebdb1e 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1689,10 +1689,10 @@
   for (;
        cell_index < last_cell_index;
        cell_index++, cell_base += 32 * kPointerSize) {
-    ASSERT((unsigned)cell_index ==
-        Bitmap::IndexToCell(
-            Bitmap::CellAlignIndex(
-                p->AddressToMarkbitIndex(cell_base))));
+    ASSERT(static_cast<unsigned>(cell_index) ==
+           Bitmap::IndexToCell(
+               Bitmap::CellAlignIndex(
+                   p->AddressToMarkbitIndex(cell_base))));
 
     const MarkBit::CellType current_cell = cells[cell_index];
     if (current_cell == 0) continue;
@@ -2589,10 +2589,10 @@
   for (;
        cell_index < last_cell_index;
        cell_index++, cell_base += 32 * kPointerSize) {
-    ASSERT((unsigned)cell_index ==
-        Bitmap::IndexToCell(
-            Bitmap::CellAlignIndex(
-                p->AddressToMarkbitIndex(cell_base))));
+    ASSERT(static_cast<unsigned>(cell_index) ==
+           Bitmap::IndexToCell(
+               Bitmap::CellAlignIndex(
+                   p->AddressToMarkbitIndex(cell_base))));
     if (cells[cell_index] == 0) continue;
 
     int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets);
@@ -2762,10 +2762,10 @@
   for (;
        cell_index < last_cell_index;
        cell_index++, object_address += 32 * kPointerSize) {
-    ASSERT((unsigned)cell_index ==
-        Bitmap::IndexToCell(
-            Bitmap::CellAlignIndex(
-                p->AddressToMarkbitIndex(object_address))));
+    ASSERT(static_cast<unsigned>(cell_index) ==
+           Bitmap::IndexToCell(
+               Bitmap::CellAlignIndex(
+                   p->AddressToMarkbitIndex(object_address))));
     int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets);
     int live_index = 0;
     for ( ; live_objects != 0; live_objects--) {
@@ -3442,10 +3442,10 @@
   for ( ;
        cell_index < last_cell_index;
        cell_index++, block_address += 32 * kPointerSize) {
-    ASSERT((unsigned)cell_index ==
-        Bitmap::IndexToCell(
-            Bitmap::CellAlignIndex(
-                p->AddressToMarkbitIndex(block_address))));
+    ASSERT(static_cast<unsigned>(cell_index) ==
+           Bitmap::IndexToCell(
+               Bitmap::CellAlignIndex(
+                   p->AddressToMarkbitIndex(block_address))));
     uint32_t cell = cells[cell_index];
     if (cell != 0) {
       // We have a live object.  Check approximately whether it is more than 32
diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h
index caf544f..38a7cf0 100644
--- a/src/mips/assembler-mips-inl.h
+++ b/src/mips/assembler-mips-inl.h
@@ -66,7 +66,7 @@
 Operand::Operand(Smi* value) {
   rm_ = no_reg;
   imm32_ =  reinterpret_cast<intptr_t>(value);
-  rmode_ = RelocInfo::NONE;
+  rmode_ = RelocInfo::NONE32;
 }
 
 
@@ -80,9 +80,36 @@
 }
 
 
+int Register::NumAllocatableRegisters() {
+  if (CpuFeatures::IsSupported(FPU)) {
+    return kMaxNumAllocatableRegisters;
+  } else {
+    return kMaxNumAllocatableRegisters - kGPRsPerNonFPUDouble;
+  }
+}
+
+
+int DoubleRegister::NumRegisters() {
+  if (CpuFeatures::IsSupported(FPU)) {
+    return FPURegister::kNumRegisters;
+  } else {
+    return 1;
+  }
+}
+
+
+int DoubleRegister::NumAllocatableRegisters() {
+  if (CpuFeatures::IsSupported(FPU)) {
+    return FPURegister::kMaxNumAllocatableRegisters;
+  } else {
+    return 1;
+  }
+}
+
+
 int FPURegister::ToAllocationIndex(FPURegister reg) {
   ASSERT(reg.code() % 2 == 0);
-  ASSERT(reg.code() / 2 < kNumAllocatableRegisters);
+  ASSERT(reg.code() / 2 < kMaxNumAllocatableRegisters);
   ASSERT(reg.is_valid());
   ASSERT(!reg.is(kDoubleRegZero));
   ASSERT(!reg.is(kLithiumScratchDouble));
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index de97bc3..1ca4d52 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -73,6 +73,33 @@
 }
 
 
+const char* DoubleRegister::AllocationIndexToString(int index) {
+  if (CpuFeatures::IsSupported(FPU)) {
+    ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "f0",
+      "f2",
+      "f4",
+      "f6",
+      "f8",
+      "f10",
+      "f12",
+      "f14",
+      "f16",
+      "f18",
+      "f20",
+      "f22",
+      "f24",
+      "f26"
+    };
+    return names[index];
+  } else {
+    ASSERT(index == 0);
+    return "sfpd0";
+  }
+}
+
+
 void CpuFeatures::Probe() {
   unsigned standard_features = (OS::CpuFeaturesImpliedByPlatform() |
                                 CpuFeaturesImpliedByCompiler());
@@ -221,7 +248,7 @@
   } else {
     // No relocation needed.
     imm32_ = reinterpret_cast<intptr_t>(obj);
-    rmode_ = RelocInfo::NONE;
+    rmode_ = RelocInfo::NONE32;
   }
 }
 
@@ -556,7 +583,7 @@
 
 int32_t Assembler::GetBranchOffset(Instr instr) {
   ASSERT(IsBranch(instr));
-  return ((int16_t)(instr & kImm16Mask)) << 2;
+  return (static_cast<int16_t>(instr & kImm16Mask)) << 2;
 }
 
 
@@ -689,7 +716,7 @@
     Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
     Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
     ASSERT(IsOri(instr_ori));
-    uint32_t imm = (uint32_t)buffer_ + target_pos;
+    uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
     ASSERT((imm & 3) == 0);
 
     instr_lui &= ~kImm16Mask;
@@ -700,7 +727,7 @@
     instr_at_put(pos + 1 * Assembler::kInstrSize,
                  instr_ori | (imm & kImm16Mask));
   } else {
-    uint32_t imm28 = (uint32_t)buffer_ + target_pos;
+    uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos;
     imm28 &= kImm28Mask;
     ASSERT((imm28 & 3) == 0);
 
@@ -849,6 +876,20 @@
 
 
 void Assembler::GenInstrRegister(Opcode opcode,
+                                 FPURegister fr,
+                                 FPURegister ft,
+                                 FPURegister fs,
+                                 FPURegister fd,
+                                 SecondaryField func) {
+  ASSERT(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
+  ASSERT(CpuFeatures::IsEnabled(FPU));
+  Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift)
+      | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
+  emit(instr);
+}
+
+
+void Assembler::GenInstrRegister(Opcode opcode,
                                  SecondaryField fmt,
                                  Register rt,
                                  FPURegister fs,
@@ -952,7 +993,7 @@
     }
   }
 
-  uint32_t imm = (uint32_t)buffer_ + target_pos;
+  uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
   ASSERT((imm & 3) == 0);
 
   return imm;
@@ -1087,7 +1128,8 @@
 #if DEBUG
   // Get pc of delay slot.
   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
-  bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0;
+  bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
+                  (kImm26Bits + kImmFieldShift)) == 0;
   ASSERT(in_range && ((target & 3) == 0));
 #endif
   GenInstrJump(J, target >> 2);
@@ -1108,7 +1150,8 @@
 #ifdef DEBUG
   // Get pc of delay slot.
   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
-  bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0;
+  bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
+                  (kImm26Bits + kImmFieldShift)) == 0;
   ASSERT(in_range && ((target & 3) == 0));
 #endif
   positions_recorder()->WriteRecordedPositions();
@@ -1127,8 +1170,8 @@
 void Assembler::j_or_jr(int32_t target, Register rs) {
   // Get pc of delay slot.
   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
-  bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0;
-
+  bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
+                  (kImm26Bits + kImmFieldShift)) == 0;
   if (in_range) {
       j(target);
   } else {
@@ -1140,8 +1183,8 @@
 void Assembler::jal_or_jalr(int32_t target, Register rs) {
   // Get pc of delay slot.
   uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize);
-  bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0;
-
+  bool in_range = (ipc ^ static_cast<uint32_t>(target) >>
+                  (kImm26Bits+kImmFieldShift)) == 0;
   if (in_range) {
       jal(target);
   } else {
@@ -1651,6 +1694,12 @@
 }
 
 
+void Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
+    FPURegister ft) {
+  GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D);
+}
+
+
 void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
 }
@@ -1900,7 +1949,7 @@
     return 2;  // Number of instructions patched.
   } else {
     uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
-    if ((int32_t)imm28 == kEndOfJumpChain) {
+    if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
       return 0;  // Number of instructions patched.
     }
     imm28 += pc_delta;
@@ -2150,9 +2199,10 @@
 
   Instr instr3 = instr_at(pc + 2 * kInstrSize);
   uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize);
-  bool in_range =
-             ((uint32_t)(ipc ^ itarget) >> (kImm26Bits + kImmFieldShift)) == 0;
-  uint32_t target_field = (uint32_t)(itarget & kJumpAddrMask) >> kImmFieldShift;
+  bool in_range = (ipc ^ static_cast<uint32_t>(itarget) >>
+                  (kImm26Bits + kImmFieldShift)) == 0;
+  uint32_t target_field =
+      static_cast<uint32_t>(itarget & kJumpAddrMask) >>kImmFieldShift;
   bool patched_jump = false;
 
 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index 75d110a..1bde0b6 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -72,20 +72,23 @@
 // Core register.
 struct Register {
   static const int kNumRegisters = v8::internal::kNumRegisters;
-  static const int kNumAllocatableRegisters = 14;  // v0 through t7.
+  static const int kMaxNumAllocatableRegisters = 14;  // v0 through t7.
   static const int kSizeInBytes = 4;
+  static const int kGPRsPerNonFPUDouble = 2;
+
+  inline static int NumAllocatableRegisters();
 
   static int ToAllocationIndex(Register reg) {
     return reg.code() - 2;  // zero_reg and 'at' are skipped.
   }
 
   static Register FromAllocationIndex(int index) {
-    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
+    ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
     return from_code(index + 2);  // zero_reg and 'at' are skipped.
   }
 
   static const char* AllocationIndexToString(int index) {
-    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
+    ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
     const char* const names[] = {
       "v0",
       "v1",
@@ -197,38 +200,19 @@
   //  f28: 0.0
   //  f30: scratch register.
   static const int kNumReservedRegisters = 2;
-  static const int kNumAllocatableRegisters = kNumRegisters / 2 -
+  static const int kMaxNumAllocatableRegisters = kNumRegisters / 2 -
       kNumReservedRegisters;
 
-
+  inline static int NumRegisters();
+  inline static int NumAllocatableRegisters();
   inline static int ToAllocationIndex(FPURegister reg);
+  static const char* AllocationIndexToString(int index);
 
   static FPURegister FromAllocationIndex(int index) {
-    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
+    ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
     return from_code(index * 2);
   }
 
-  static const char* AllocationIndexToString(int index) {
-    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
-    const char* const names[] = {
-      "f0",
-      "f2",
-      "f4",
-      "f6",
-      "f8",
-      "f10",
-      "f12",
-      "f14",
-      "f16",
-      "f18",
-      "f20",
-      "f22",
-      "f24",
-      "f26"
-    };
-    return names[index];
-  }
-
   static FPURegister from_code(int code) {
     FPURegister r = { code };
     return r;
@@ -316,6 +300,9 @@
 const FPURegister f30 = { 30 };
 const FPURegister f31 = { 31 };
 
+const Register sfpd_lo  = { kRegister_t6_Code };
+const Register sfpd_hi  = { kRegister_t7_Code };
+
 // Register aliases.
 // cp is assumed to be a callee saved register.
 // Defined using #define instead of "static const Register&" because Clang
@@ -361,7 +348,7 @@
  public:
   // Immediate.
   INLINE(explicit Operand(int32_t immediate,
-         RelocInfo::Mode rmode = RelocInfo::NONE));
+         RelocInfo::Mode rmode = RelocInfo::NONE32));
   INLINE(explicit Operand(const ExternalReference& f));
   INLINE(explicit Operand(const char* s));
   INLINE(explicit Operand(Object** opp));
@@ -818,6 +805,7 @@
   void add_d(FPURegister fd, FPURegister fs, FPURegister ft);
   void sub_d(FPURegister fd, FPURegister fs, FPURegister ft);
   void mul_d(FPURegister fd, FPURegister fs, FPURegister ft);
+  void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
   void div_d(FPURegister fd, FPURegister fs, FPURegister ft);
   void abs_d(FPURegister fd, FPURegister fs);
   void mov_d(FPURegister fd, FPURegister fs);
@@ -1159,6 +1147,13 @@
                         SecondaryField func = NULLSF);
 
   void GenInstrRegister(Opcode opcode,
+                        FPURegister fr,
+                        FPURegister ft,
+                        FPURegister fs,
+                        FPURegister fd,
+                        SecondaryField func = NULLSF);
+
+  void GenInstrRegister(Opcode opcode,
                         SecondaryField fmt,
                         Register rt,
                         FPURegister fs,
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index b2348fc..793968e 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -1297,6 +1297,26 @@
 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
 
 
+void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Preserve registers across notification, this is important for compiled
+    // stubs that tail call the runtime on deopts passing their parameters in
+    // registers.
+    __ MultiPush(kJSCallerSaved | kCalleeSaved);
+    // Pass the function and deoptimization type to the runtime system.
+    __ CallRuntime(Runtime::kNotifyStubFailure, 0);
+    __ MultiPop(kJSCallerSaved | kCalleeSaved);
+  }
+
+  __ mov(at, ra);  // Stash the miss continuation
+  __ Addu(sp, sp, Operand(kPointerSize));  // Ignore state
+  __ pop(ra);  // Restore RA to continuation in JSFunction
+  __ Jump(at);  // Jump to miss handler
+}
+
+
 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
                                              Deoptimizer::BailoutType type) {
   {
@@ -1413,7 +1433,7 @@
   // a0: actual number of arguments
   // a1: function
   Label shift_arguments;
-  __ li(t0, Operand(0, RelocInfo::NONE));  // Indicate regular JS_FUNCTION.
+  __ li(t0, Operand(0, RelocInfo::NONE32));  // Indicate regular JS_FUNCTION.
   { Label convert_to_object, use_global_receiver, patch_receiver;
     // Change context eagerly in case we need the global receiver.
     __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
@@ -1467,7 +1487,7 @@
     __ sll(at, a0, kPointerSizeLog2);
     __ addu(at, sp, at);
     __ lw(a1, MemOperand(at));
-    __ li(t0, Operand(0, RelocInfo::NONE));
+    __ li(t0, Operand(0, RelocInfo::NONE32));
     __ Branch(&patch_receiver);
 
     // Use the global receiver object from the called function as the
@@ -1490,11 +1510,11 @@
 
   // 3b. Check for function proxy.
   __ bind(&slow);
-  __ li(t0, Operand(1, RelocInfo::NONE));  // Indicate function proxy.
+  __ li(t0, Operand(1, RelocInfo::NONE32));  // Indicate function proxy.
   __ Branch(&shift_arguments, eq, a2, Operand(JS_FUNCTION_PROXY_TYPE));
 
   __ bind(&non_function);
-  __ li(t0, Operand(2, RelocInfo::NONE));  // Indicate non-function.
+  __ li(t0, Operand(2, RelocInfo::NONE32));  // Indicate non-function.
 
   // 3c. Patch the first argument when calling a non-function.  The
   //     CALL_NON_FUNCTION builtin expects the non-function callee as
@@ -1725,7 +1745,7 @@
     __ bind(&call_proxy);
     __ push(a1);  // Add function proxy as last argument.
     __ Addu(a0, a0, Operand(1));
-    __ li(a2, Operand(0, RelocInfo::NONE));
+    __ li(a2, Operand(0, RelocInfo::NONE32));
     __ SetCallKind(t1, CALL_AS_METHOD);
     __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
     __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index a05cee8..3d01be6 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -38,6 +38,17 @@
 namespace internal {
 
 
+void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  static Register registers[] = { a1, a0 };
+  descriptor->register_param_count_ = 2;
+  descriptor->register_params_ = registers;
+  descriptor->deoptimization_handler_ =
+      FUNCTION_ADDR(KeyedLoadIC_Miss);
+}
+
+
 #define __ ACCESS_MASM(masm)
 
 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
@@ -332,6 +343,7 @@
     MacroAssembler* masm,
     int length,
     FastCloneShallowArrayStub::Mode mode,
+    AllocationSiteInfoMode allocation_site_info_mode,
     Label* fail) {
   // Registers on entry:
   // a3: boilerplate literal array.
@@ -344,7 +356,12 @@
         ? FixedDoubleArray::SizeFor(length)
         : FixedArray::SizeFor(length);
   }
-  int size = JSArray::kSize + elements_size;
+  int size = JSArray::kSize;
+  int allocation_info_start = size;
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    size += AllocationSiteInfo::kSize;
+  }
+  size += elements_size;
 
   // Allocate both the JS array and the elements array in one big
   // allocation. This avoids multiple limit checks.
@@ -355,6 +372,13 @@
                         fail,
                         TAG_OBJECT);
 
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    __ li(a2, Operand(Handle<Map>(masm->isolate()->heap()->
+                                   allocation_site_info_map())));
+    __ sw(a2, FieldMemOperand(v0, allocation_info_start));
+    __ sw(a3, FieldMemOperand(v0, allocation_info_start + kPointerSize));
+  }
+
   // Copy the JS array part.
   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
     if ((i != JSArray::kElementsOffset) || (length == 0)) {
@@ -367,7 +391,11 @@
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
     __ lw(a3, FieldMemOperand(a3, JSArray::kElementsOffset));
-    __ Addu(a2, v0, Operand(JSArray::kSize));
+    if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+      __ Addu(a2, v0, Operand(JSArray::kSize + AllocationSiteInfo::kSize));
+    } else {
+      __ Addu(a2, v0, Operand(JSArray::kSize));
+    }
     __ sw(a2, FieldMemOperand(v0, JSArray::kElementsOffset));
 
     // Copy the elements array.
@@ -396,6 +424,12 @@
   __ Branch(&slow_case, eq, a3, Operand(t1));
 
   FastCloneShallowArrayStub::Mode mode = mode_;
+  AllocationSiteInfoMode allocation_site_info_mode =
+      DONT_TRACK_ALLOCATION_SITE_INFO;
+  if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
+    mode = CLONE_ANY_ELEMENTS;
+    allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
+  }
   if (mode == CLONE_ANY_ELEMENTS) {
     Label double_elements, check_fast_elements;
     __ lw(v0, FieldMemOperand(a3, JSArray::kElementsOffset));
@@ -403,7 +437,9 @@
     __ LoadRoot(t1, Heap::kFixedCOWArrayMapRootIndex);
     __ Branch(&check_fast_elements, ne, v0, Operand(t1));
     GenerateFastCloneShallowArrayCommon(masm, 0,
-                                        COPY_ON_WRITE_ELEMENTS, &slow_case);
+                                        COPY_ON_WRITE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     // Return and remove the on-stack parameters.
     __ DropAndRet(3);
 
@@ -411,7 +447,9 @@
     __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex);
     __ Branch(&double_elements, ne, v0, Operand(t1));
     GenerateFastCloneShallowArrayCommon(masm, length_,
-                                        CLONE_ELEMENTS, &slow_case);
+                                        CLONE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     // Return and remove the on-stack parameters.
     __ DropAndRet(3);
 
@@ -442,7 +480,8 @@
     __ pop(a3);
   }
 
-  GenerateFastCloneShallowArrayCommon(masm, length_, mode, &slow_case);
+  GenerateFastCloneShallowArrayCommon(masm, length_, mode,
+                                      allocation_site_info_mode, &slow_case);
 
   // Return and remove the on-stack parameters.
   __ DropAndRet(3);
@@ -500,7 +539,7 @@
 // 52 fraction bits (20 in the first word, 32 in the second).  Zeros is a
 // scratch register.  Destroys the source register.  No GC occurs during this
 // stub so you don't have to set up the frame.
-class ConvertToDoubleStub : public CodeStub {
+class ConvertToDoubleStub : public PlatformCodeStub {
  public:
   ConvertToDoubleStub(Register result_reg_1,
                       Register result_reg_2,
@@ -3893,12 +3932,29 @@
 
 
 void CodeStub::GenerateFPStubs() {
-  CEntryStub save_doubles(1, kSaveFPRegs);
-  Handle<Code> code = save_doubles.GetCode();
-  code->set_is_pregenerated(true);
-  StoreBufferOverflowStub stub(kSaveFPRegs);
-  stub.GetCode()->set_is_pregenerated(true);
-  code->GetIsolate()->set_fp_stubs_generated(true);
+  SaveFPRegsMode mode = CpuFeatures::IsSupported(FPU)
+      ? kSaveFPRegs
+      : kDontSaveFPRegs;
+  CEntryStub save_doubles(1, mode);
+  StoreBufferOverflowStub stub(mode);
+  // These stubs might already be in the snapshot, detect that and don't
+  // regenerate, which would lead to code stub initialization state being messed
+  // up.
+  Code* save_doubles_code = NULL;
+  Code* store_buffer_overflow_code = NULL;
+  if (!save_doubles.FindCodeInCache(&save_doubles_code, ISOLATE)) {
+    if (CpuFeatures::IsSupported(FPU)) {
+      CpuFeatures::Scope scope2(FPU);
+      save_doubles_code = *save_doubles.GetCode();
+      store_buffer_overflow_code = *stub.GetCode();
+    } else {
+      save_doubles_code = *save_doubles.GetCode();
+      store_buffer_overflow_code = *stub.GetCode();
+    }
+    save_doubles_code->set_is_pregenerated(true);
+    store_buffer_overflow_code->set_is_pregenerated(true);
+  }
+  ISOLATE->set_fp_stubs_generated(true);
 }
 
 
@@ -4109,7 +4165,7 @@
   Isolate* isolate = masm->isolate();
   ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress,
                                     isolate);
-  __ li(a0, Operand(false, RelocInfo::NONE));
+  __ li(a0, Operand(false, RelocInfo::NONE32));
   __ li(a2, Operand(external_caught));
   __ sw(a0, MemOperand(a2));
 
@@ -5538,8 +5594,8 @@
   // Check for function proxy.
   __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE));
   __ push(a1);  // Put proxy as additional argument.
-  __ li(a0, Operand(argc_ + 1, RelocInfo::NONE));
-  __ li(a2, Operand(0, RelocInfo::NONE));
+  __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32));
+  __ li(a2, Operand(0, RelocInfo::NONE32));
   __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
   __ SetCallKind(t1, CALL_AS_METHOD);
   {
@@ -5596,7 +5652,7 @@
   __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
   __ bind(&do_call);
   // Set expected number of arguments to zero (not changing r0).
-  __ li(a2, Operand(0, RelocInfo::NONE));
+  __ li(a2, Operand(0, RelocInfo::NONE32));
   __ SetCallKind(t1, CALL_AS_METHOD);
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
@@ -5713,11 +5769,11 @@
 
   STATIC_ASSERT(kSmiTag == 0);
   STATIC_ASSERT(kSmiShiftSize == 0);
-  ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
+  ASSERT(IsPowerOf2(String::kMaxOneByteCharCode + 1));
   __ And(t0,
          code_,
          Operand(kSmiTagMask |
-                 ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
+                 ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
   __ Branch(&slow_case_, ne, t0, Operand(zero_reg));
 
   __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index b560c63..356cc87 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -37,7 +37,7 @@
 
 // Compute a transcendental math function natively, or call the
 // TranscendentalCache runtime function.
-class TranscendentalCacheStub: public CodeStub {
+class TranscendentalCacheStub: public PlatformCodeStub {
  public:
   enum ArgumentType {
     TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits,
@@ -59,7 +59,7 @@
 };
 
 
-class StoreBufferOverflowStub: public CodeStub {
+class StoreBufferOverflowStub: public PlatformCodeStub {
  public:
   explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
       : save_doubles_(save_fp) { }
@@ -78,7 +78,7 @@
 };
 
 
-class UnaryOpStub: public CodeStub {
+class UnaryOpStub: public PlatformCodeStub {
  public:
   UnaryOpStub(Token::Value op,
               UnaryOverwriteMode mode,
@@ -220,7 +220,7 @@
 };
 
 
-class StringAddStub: public CodeStub {
+class StringAddStub: public PlatformCodeStub {
  public:
   explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
 
@@ -243,7 +243,7 @@
 };
 
 
-class SubStringStub: public CodeStub {
+class SubStringStub: public PlatformCodeStub {
  public:
   SubStringStub() {}
 
@@ -255,7 +255,7 @@
 };
 
 
-class StringCompareStub: public CodeStub {
+class StringCompareStub: public PlatformCodeStub {
  public:
   StringCompareStub() { }
 
@@ -296,7 +296,7 @@
 // This stub can convert a signed int32 to a heap number (double).  It does
 // not work for int32s that are in Smi range!  No GC occurs during this stub
 // so you don't have to set up the frame.
-class WriteInt32ToHeapNumberStub : public CodeStub {
+class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
  public:
   WriteInt32ToHeapNumberStub(Register the_int,
                              Register the_heap_number,
@@ -340,7 +340,7 @@
 };
 
 
-class NumberToStringStub: public CodeStub {
+class NumberToStringStub: public PlatformCodeStub {
  public:
   NumberToStringStub() { }
 
@@ -366,7 +366,7 @@
 };
 
 
-class RecordWriteStub: public CodeStub {
+class RecordWriteStub: public PlatformCodeStub {
  public:
   RecordWriteStub(Register object,
                   Register value,
@@ -512,7 +512,7 @@
     Register GetRegThatIsNotOneOf(Register r1,
                                   Register r2,
                                   Register r3) {
-      for (int i = 0; i < Register::kNumAllocatableRegisters; i++) {
+      for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
         Register candidate = Register::FromAllocationIndex(i);
         if (candidate.is(r1)) continue;
         if (candidate.is(r2)) continue;
@@ -571,7 +571,7 @@
 // Enter C code from generated RegExp code in a way that allows
 // the C code to fix the return address in case of a GC.
 // Currently only needed on ARM and MIPS.
-class RegExpCEntryStub: public CodeStub {
+class RegExpCEntryStub: public PlatformCodeStub {
  public:
   RegExpCEntryStub() {}
   virtual ~RegExpCEntryStub() {}
@@ -589,7 +589,7 @@
 // keep the code which called into native pinned in the memory. Currently the
 // simplest approach is to generate such stub early enough so it can never be
 // moved by GC
-class DirectCEntryStub: public CodeStub {
+class DirectCEntryStub: public PlatformCodeStub {
  public:
   DirectCEntryStub() {}
   void Generate(MacroAssembler* masm);
@@ -739,7 +739,7 @@
 };
 
 
-class StringDictionaryLookupStub: public CodeStub {
+class StringDictionaryLookupStub: public PlatformCodeStub {
  public:
   enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
 
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 1da8089..27835af 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -180,6 +180,10 @@
 
   Register scratch = t6;
 
+  if (FLAG_track_allocation_sites) {
+    masm->TestJSArrayForAllocationSiteInfo(a2, t0, fail);
+  }
+
   // Check for empty arrays, which only require a map transition and no changes
   // to the backing store.
   __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset));
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index 13b0b43..d429443 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -46,6 +46,10 @@
 
 class CodeGenerator: public AstVisitor {
  public:
+  CodeGenerator() {
+    InitializeAstVisitor();
+  }
+
   static bool MakeCode(CompilationInfo* info);
 
   // Printing of AST, etc. as requested by flags.
@@ -70,7 +74,7 @@
                               int pos,
                               bool right_here = false);
 
-  DEFINE_AST_VISITOR_SUBCLASS_METHODS();
+  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
diff --git a/src/mips/constants-mips.cc b/src/mips/constants-mips.cc
index 7d654f6..ddfa891 100644
--- a/src/mips/constants-mips.cc
+++ b/src/mips/constants-mips.cc
@@ -302,6 +302,8 @@
           return kRegisterType;
       };
       break;
+    case COP1X:
+      return kRegisterType;
     // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
     case REGIMM:
     case BEQ:
diff --git a/src/mips/constants-mips.h b/src/mips/constants-mips.h
index 3d58571..e7c55f5 100644
--- a/src/mips/constants-mips.h
+++ b/src/mips/constants-mips.h
@@ -99,7 +99,7 @@
 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
 const int kFCSRRegister = 31;
 const int kInvalidFPUControlRegister = -1;
-const uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1;
+const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
 
 // FCSR constants.
 const uint32_t kFCSRInexactFlagBit = 2;
@@ -216,6 +216,8 @@
 // and are therefore shifted by 2.
 const int kImmFieldShift = 2;
 
+const int kFrBits        = 5;
+const int kFrShift       = 21;
 const int kFsShift       = 11;
 const int kFsBits        = 5;
 const int kFtShift       = 16;
@@ -295,7 +297,9 @@
   LDC1      =   ((6 << 3) + 5) << kOpcodeShift,
 
   SWC1      =   ((7 << 3) + 1) << kOpcodeShift,
-  SDC1      =   ((7 << 3) + 5) << kOpcodeShift
+  SDC1      =   ((7 << 3) + 5) << kOpcodeShift,
+
+  COP1X     =   ((1 << 4) + 3) << kOpcodeShift
 };
 
 enum SecondaryField {
@@ -416,6 +420,8 @@
   CVT_S_L   =   ((4 << 3) + 0),
   CVT_D_L   =   ((4 << 3) + 1),
   // COP1 Encoding of Function Field When rs=PS.
+  // COP1X Encoding of Function Field.
+  MADD_D    =   ((4 << 3) + 1),
 
   NULLSF    =   0
 };
@@ -677,6 +683,10 @@
     return Bits(kFtShift + kFtBits - 1, kFtShift);
   }
 
+  inline int FrValue() const {
+    return Bits(kFrShift + kFrBits -1, kFrShift);
+  }
+
   // Float Compare condition code instruction bits.
   inline int FCccValue() const {
     return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc
index a134f59..634aecd 100644
--- a/src/mips/deoptimizer-mips.cc
+++ b/src/mips/deoptimizer-mips.cc
@@ -75,12 +75,12 @@
     Address call_address = code_start_address + deopt_data->Pc(i)->value();
     Address deopt_entry = GetDeoptimizationEntry(i, LAZY);
     int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry,
-                                                      RelocInfo::NONE);
+                                                      RelocInfo::NONE32);
     int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize;
     ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0);
     ASSERT(call_size_in_bytes <= patch_size());
     CodePatcher patcher(call_address, call_size_in_words);
-    patcher.masm()->Call(deopt_entry, RelocInfo::NONE);
+    patcher.masm()->Call(deopt_entry, RelocInfo::NONE32);
     ASSERT(prev_call_address == NULL ||
            call_address >= prev_call_address + patch_size());
     ASSERT(call_address + patch_size() <= code->instruction_end());
@@ -206,7 +206,7 @@
 
 void Deoptimizer::DoComputeOsrOutputFrame() {
   DeoptimizationInputData* data = DeoptimizationInputData::cast(
-      optimized_code_->deoptimization_data());
+      compiled_code_->deoptimization_data());
   unsigned ast_id = data->OsrAstId()->value();
 
   int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
@@ -240,7 +240,7 @@
   unsigned input_frame_size = input_->GetFrameSize();
   ASSERT(fixed_size + height_in_bytes == input_frame_size);
 
-  unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize;
+  unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
   unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
   unsigned outgoing_size = outgoing_height * kPointerSize;
   unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
@@ -332,7 +332,7 @@
 
     unsigned pc_offset = data->OsrPcOffset()->value();
     uint32_t pc = reinterpret_cast<uint32_t>(
-        optimized_code_->entry() + pc_offset);
+        compiled_code_->entry() + pc_offset);
     output_[0]->SetPc(pc);
   }
   Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
@@ -445,6 +445,79 @@
 }
 
 
+void Deoptimizer::DoCompiledStubFrame(TranslationIterator* iterator,
+                                      int frame_index) {
+  //
+  //               FROM                                  TO             <-fp
+  //    |          ....           |          |          ....           |
+  //    +-------------------------+          +-------------------------+
+  //    | JSFunction continuation |          |       parameter 1       |
+  //    +-------------------------+          +-------------------------+
+  // |  |   saved frame (fp)      |          |          ....           |
+  // |  +=========================+<-fp      +-------------------------+
+  // |  |   JSFunction context    |          |       parameter n       |
+  // v  +-------------------------+          +-------------------------|
+  //    |   COMPILED_STUB marker  |          | JSFunction continuation |
+  //    +-------------------------+          +-------------------------+<-sp
+  //    |                         |          a0 = number of parameters
+  //    | ...                     |          a1 = failure handler address
+  //    |                         |          fp = saved frame
+  //    +-------------------------+<-sp      cp = JSFunction context
+  //
+  //
+
+  ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
+  int major_key = compiled_code_->major_key();
+  CodeStubInterfaceDescriptor* descriptor =
+      isolate_->code_stub_interface_descriptor(major_key);
+
+  int output_frame_size =
+      (1 + descriptor->register_param_count_) * kPointerSize;
+  FrameDescription* output_frame =
+      new(output_frame_size) FrameDescription(output_frame_size, 0);
+  Code* notify_failure =
+      isolate_->builtins()->builtin(Builtins::kNotifyStubFailure);
+  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
+  output_frame->SetContinuation(
+      reinterpret_cast<uint32_t>(notify_failure->entry()));
+
+  Code* code;
+  CEntryStub(1, kSaveFPRegs).FindCodeInCache(&code, isolate_);
+  output_frame->SetPc(reinterpret_cast<intptr_t>(code->instruction_start()));
+  unsigned input_frame_size = input_->GetFrameSize();
+  intptr_t value = input_->GetFrameSlot(input_frame_size - kPointerSize);
+  output_frame->SetFrameSlot(0, value);
+  value = input_->GetFrameSlot(input_frame_size - 2 * kPointerSize);
+  output_frame->SetRegister(fp.code(), value);
+  output_frame->SetFp(value);
+  value = input_->GetFrameSlot(input_frame_size - 3 * kPointerSize);
+  output_frame->SetRegister(cp.code(), value);
+
+  int parameter_offset = kPointerSize * descriptor->register_param_count_;
+  for (int i = 0; i < descriptor->register_param_count_; ++i) {
+    Translation::Opcode opcode =
+        static_cast<Translation::Opcode>(iterator->Next());
+    ASSERT(opcode == Translation::REGISTER);
+    USE(opcode);
+    int input_reg = iterator->Next();
+    intptr_t reg_value = input_->GetRegister(input_reg);
+    output_frame->SetFrameSlot(parameter_offset, reg_value);
+    parameter_offset -= kPointerSize;
+  }
+
+  ApiFunction function(descriptor->deoptimization_handler_);
+  ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
+  intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
+  output_frame->SetRegister(s0.code(), descriptor->register_param_count_);
+  output_frame->SetRegister(s1.code(),
+      (descriptor->register_param_count_ - 1) * kPointerSize);
+  output_frame->SetRegister(s2.code(), handler);
+
+  ASSERT(frame_index == 0);
+  output_[frame_index] = output_frame;
+}
+
+
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
   Builtins* builtins = isolate_->builtins();
@@ -868,7 +941,7 @@
   }
   input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
   input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
-  for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) {
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
     input_->SetDoubleRegister(i, 0.0);
   }
 
@@ -889,7 +962,6 @@
 
   Isolate* isolate = masm()->isolate();
 
-  CpuFeatures::Scope scope(FPU);
   // Unlike on ARM we don't save all the registers, just the useful ones.
   // For the rest, there are gaps on the stack, so the offsets remain the same.
   const int kNumberOfRegisters = Register::kNumRegisters;
@@ -898,14 +970,19 @@
   RegList saved_regs = restored_regs | sp.bit() | ra.bit();
 
   const int kDoubleRegsSize =
-      kDoubleSize * FPURegister::kNumAllocatableRegisters;
+      kDoubleSize * FPURegister::kMaxNumAllocatableRegisters;
 
-  // Save all FPU registers before messing with them.
-  __ Subu(sp, sp, Operand(kDoubleRegsSize));
-  for (int i = 0; i < FPURegister::kNumAllocatableRegisters; ++i) {
-    FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
-    int offset = i * kDoubleSize;
-    __ sdc1(fpu_reg, MemOperand(sp, offset));
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    // Save all FPU registers before messing with them.
+    __ Subu(sp, sp, Operand(kDoubleRegsSize));
+    for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) {
+      FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
+      int offset = i * kDoubleSize;
+      __ sdc1(fpu_reg, MemOperand(sp, offset));
+    }
+  } else {
+    __ Subu(sp, sp, Operand(kDoubleRegsSize));
   }
 
   // Push saved_regs (needed to populate FrameDescription::registers_).
@@ -977,14 +1054,17 @@
     }
   }
 
-  // Copy FPU registers to
-  // double_registers_[DoubleRegister::kNumAllocatableRegisters]
-  int double_regs_offset = FrameDescription::double_registers_offset();
-  for (int i = 0; i < FPURegister::kNumAllocatableRegisters; ++i) {
-    int dst_offset = i * kDoubleSize + double_regs_offset;
-    int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
-    __ ldc1(f0, MemOperand(sp, src_offset));
-    __ sdc1(f0, MemOperand(a1, dst_offset));
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    // Copy FPU registers to
+    // double_registers_[DoubleRegister::kNumAllocatableRegisters]
+    int double_regs_offset = FrameDescription::double_registers_offset();
+    for (int i = 0; i < FPURegister::NumAllocatableRegisters(); ++i) {
+      int dst_offset = i * kDoubleSize + double_regs_offset;
+      int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
+      __ ldc1(f0, MemOperand(sp, src_offset));
+      __ sdc1(f0, MemOperand(a1, dst_offset));
+    }
   }
 
   // Remove the bailout id, eventually return address, and the saved registers
@@ -1005,11 +1085,14 @@
   // frame description.
   __ Addu(a3, a1, Operand(FrameDescription::frame_content_offset()));
   Label pop_loop;
+  Label pop_loop_header;
+  __ Branch(&pop_loop_header);
   __ bind(&pop_loop);
   __ pop(t0);
   __ sw(t0, MemOperand(a3, 0));
-  __ Branch(USE_DELAY_SLOT, &pop_loop, ne, a2, Operand(sp));
-  __ addiu(a3, a3, sizeof(uint32_t));  // In delay slot.
+  __ addiu(a3, a3, sizeof(uint32_t));
+  __ bind(&pop_loop_header);
+  __ Branch(&pop_loop, ne, a2, Operand(sp));
 
   // Compute the output frame in the deoptimizer.
   __ push(a0);  // Preserve deoptimizer object across call.
@@ -1024,25 +1107,30 @@
   __ pop(a0);  // Restore deoptimizer object (class Deoptimizer).
 
   // Replace the current (input) frame with the output frames.
-  Label outer_push_loop, inner_push_loop;
+  Label outer_push_loop, inner_push_loop,
+      outer_loop_header, inner_loop_header;
   // Outer loop state: a0 = current "FrameDescription** output_",
   // a1 = one past the last FrameDescription**.
   __ lw(a1, MemOperand(a0, Deoptimizer::output_count_offset()));
   __ lw(a0, MemOperand(a0, Deoptimizer::output_offset()));  // a0 is output_.
   __ sll(a1, a1, kPointerSizeLog2);  // Count to offset.
   __ addu(a1, a0, a1);  // a1 = one past the last FrameDescription**.
+  __ jmp(&outer_loop_header);
   __ bind(&outer_push_loop);
   // Inner loop state: a2 = current FrameDescription*, a3 = loop index.
   __ lw(a2, MemOperand(a0, 0));  // output_[ix]
   __ lw(a3, MemOperand(a2, FrameDescription::frame_size_offset()));
+  __ jmp(&inner_loop_header);
   __ bind(&inner_push_loop);
   __ Subu(a3, a3, Operand(sizeof(uint32_t)));
   __ Addu(t2, a2, Operand(a3));
   __ lw(t3, MemOperand(t2, FrameDescription::frame_content_offset()));
   __ push(t3);
+  __ bind(&inner_loop_header);
   __ Branch(&inner_push_loop, ne, a3, Operand(zero_reg));
 
   __ Addu(a0, a0, Operand(kPointerSize));
+  __ bind(&outer_loop_header);
   __ Branch(&outer_push_loop, lt, a0, Operand(a1));
 
 
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
index 1d40c2c..0eca71f 100644
--- a/src/mips/disasm-mips.cc
+++ b/src/mips/disasm-mips.cc
@@ -350,6 +350,10 @@
     int reg = instr->FdValue();
     PrintFPURegister(reg);
     return 2;
+  } else if (format[1] == 'r') {  // 'fr: fr register.
+    int reg = instr->FrValue();
+    PrintFPURegister(reg);
+    return 2;
   }
   UNREACHABLE();
   return -1;
@@ -618,6 +622,15 @@
           UNREACHABLE();
       }
       break;
+    case COP1X:
+      switch (instr->FunctionFieldRaw()) {
+        case MADD_D:
+          Format(instr, "madd.d  'fd, 'fr, 'fs, 'ft");
+          break;
+        default:
+          UNREACHABLE();
+      };
+      break;
     case SPECIAL:
       switch (instr->FunctionFieldRaw()) {
         case JR:
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 5bc5162..d4390b2 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -147,7 +147,7 @@
 
 #ifdef DEBUG
   if (strlen(FLAG_stop_at) > 0 &&
-      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+      info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
     __ stop("stop-at");
   }
 #endif
@@ -675,7 +675,7 @@
                                Label* fall_through) {
   if (CpuFeatures::IsSupported(FPU)) {
     ToBooleanStub stub(result_register());
-    __ CallStub(&stub);
+    __ CallStub(&stub, condition->test_id());
     __ mov(at, zero_reg);
   } else {
     // Call the runtime to find the boolean value of the source and then
@@ -1744,6 +1744,15 @@
     FastCloneShallowArrayStub::Mode mode = has_fast_elements
       ? FastCloneShallowArrayStub::CLONE_ELEMENTS
       : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+
+    // Tracking allocation info allows us to pre-transition later if it makes
+    // sense.
+    if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
+        FLAG_track_allocation_sites) {
+      mode = FastCloneShallowArrayStub::
+          CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+    }
+
     FastCloneShallowArrayStub stub(mode, length);
     __ CallStub(&stub);
   }
@@ -2353,7 +2362,7 @@
 
   CallFunctionStub stub(arg_count, flags);
   __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
-  __ CallStub(&stub);
+  __ CallStub(&stub, expr->CallFeedbackId());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index 4ac92af..0f9d687 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -858,7 +858,7 @@
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, a2);
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -893,7 +893,7 @@
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, a0);  // (In delay slot) return the value stored in v0.
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -926,7 +926,7 @@
 Object* KeyedLoadIC_Miss(Arguments args);
 
 
-void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ---------- S t a t e --------------
   //  -- ra     : return address
   //  -- a0     : key
@@ -939,7 +939,7 @@
   __ Push(a1, a0);
 
   // Perform tail call to the entry.
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
       ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric), isolate)
       : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
 
@@ -1166,7 +1166,7 @@
   char_at_generator.GenerateSlow(masm, call_helper);
 
   __ bind(&miss);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -1452,11 +1452,11 @@
        IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1);
 
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
-void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ---------- S t a t e --------------
   //  -- a0     : value
   //  -- a1     : key
@@ -1467,7 +1467,7 @@
   // Push receiver, key and value for runtime call.
   __ Push(a2, a1, a0);
 
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
       ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
                           masm->isolate())
       : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
@@ -1703,7 +1703,7 @@
   // was inlined.
   Instr instr = Assembler::instr_at(andi_instruction_address);
   return Assembler::IsAndImmediate(instr) &&
-      Assembler::GetRt(instr) == (uint32_t)zero_reg.code();
+      Assembler::GetRt(instr) == static_cast<uint32_t>(zero_reg.code());
 }
 
 
@@ -1715,7 +1715,7 @@
   // was inlined.
   Instr instr = Assembler::instr_at(andi_instruction_address);
   if (!(Assembler::IsAndImmediate(instr) &&
-        Assembler::GetRt(instr) == (uint32_t)zero_reg.code())) {
+        Assembler::GetRt(instr) == static_cast<uint32_t>(zero_reg.code()))) {
     return;
   }
 
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index fd7af9f..02ca145 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -77,6 +77,7 @@
   return GeneratePrologue() &&
       GenerateBody() &&
       GenerateDeferredCode() &&
+      GenerateDeoptJumpTable() &&
       GenerateSafepointTable();
 }
 
@@ -116,42 +117,48 @@
 bool LCodeGen::GeneratePrologue() {
   ASSERT(is_generating());
 
-  ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+  if (info()->IsOptimizing()) {
+    ProfileEntryHookStub::MaybeCallEntryHook(masm_);
 
 #ifdef DEBUG
-  if (strlen(FLAG_stop_at) > 0 &&
-      info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
-    __ stop("stop_at");
-  }
+    if (strlen(FLAG_stop_at) > 0 &&
+        info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
+      __ stop("stop_at");
+    }
 #endif
 
-  // a1: Callee's JS function.
-  // cp: Callee's context.
-  // fp: Caller's frame pointer.
-  // lr: Caller's pc.
+    // a1: Callee's JS function.
+    // cp: Callee's context.
+    // fp: Caller's frame pointer.
+    // lr: Caller's pc.
 
-  // Strict mode functions and builtins need to replace the receiver
-  // with undefined when called as functions (without an explicit
-  // receiver object). r5 is zero for method calls and non-zero for
-  // function calls.
-  if (!info_->is_classic_mode() || info_->is_native()) {
-    Label ok;
-    __ Branch(&ok, eq, t1, Operand(zero_reg));
+    // Strict mode functions and builtins need to replace the receiver
+    // with undefined when called as functions (without an explicit
+    // receiver object). r5 is zero for method calls and non-zero for
+    // function calls.
+    if (!info_->is_classic_mode() || info_->is_native()) {
+      Label ok;
+      __ Branch(&ok, eq, t1, Operand(zero_reg));
 
-    int receiver_offset = scope()->num_parameters() * kPointerSize;
-    __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
-    __ sw(a2, MemOperand(sp, receiver_offset));
-    __ bind(&ok);
+      int receiver_offset = scope()->num_parameters() * kPointerSize;
+      __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
+      __ sw(a2, MemOperand(sp, receiver_offset));
+      __ bind(&ok);
+    }
   }
 
   info()->set_prologue_offset(masm_->pc_offset());
-  // The following three instructions must remain together and unmodified for
-  // code aging to work properly.
-  __ Push(ra, fp, cp, a1);
-  // Add unused load of ip to ensure prologue sequence is identical for
-  // full-codegen and lithium-codegen.
-  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  __ Addu(fp, sp, Operand(2 * kPointerSize));  // Adj. FP to point to saved FP.
+  if (NeedsEagerFrame()) {
+    // The following three instructions must remain together and unmodified for
+    // code aging to work properly.
+    __ Push(ra, fp, cp, a1);
+    // Add unused load of ip to ensure prologue sequence is identical for
+    // full-codegen and lithium-codegen.
+    __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
+    // Adj. FP to point to saved FP.
+    __ Addu(fp, sp, Operand(2 * kPointerSize));
+    frame_is_built_ = true;
+  }
 
   // Reserve space for the stack slots needed by the code.
   int slots = GetStackSlotCount();
@@ -170,7 +177,7 @@
   }
 
   // Possibly allocate a local context.
-  int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   if (heap_slots > 0) {
     Comment(";;; Allocate local context");
     // Argument to NewContext is the function, which is in a1.
@@ -206,7 +213,7 @@
   }
 
   // Trace the call.
-  if (FLAG_trace) {
+  if (FLAG_trace && info()->IsOptimizing()) {
     __ CallRuntime(Runtime::kTraceEnter, 0);
   }
   EnsureSpaceForLazyDeopt();
@@ -264,10 +271,31 @@
     for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
       LDeferredCode* code = deferred_[i];
       __ bind(code->entry());
+      if (NeedsDeferredFrame()) {
+        Comment(";;; Deferred build frame",
+                code->instruction_index(),
+                code->instr()->Mnemonic());
+        ASSERT(!frame_is_built_);
+        ASSERT(info()->IsStub());
+        frame_is_built_ = true;
+        __ MultiPush(cp.bit() | fp.bit() | ra.bit());
+        __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
+        __ push(scratch0());
+        __ Addu(fp, sp, Operand(2 * kPointerSize));
+      }
       Comment(";;; Deferred code @%d: %s.",
               code->instruction_index(),
               code->instr()->Mnemonic());
       code->Generate();
+      if (NeedsDeferredFrame()) {
+        Comment(";;; Deferred destroy frame",
+                code->instruction_index(),
+                code->instr()->Mnemonic());
+        ASSERT(frame_is_built_);
+        __ pop(at);
+        __ MultiPop(cp.bit() | fp.bit() | ra.bit());
+        frame_is_built_ = false;
+      }
       __ jmp(code->exit());
     }
   }
@@ -279,10 +307,72 @@
 
 
 bool LCodeGen::GenerateDeoptJumpTable() {
-  // TODO(plind): not clear that this will have advantage for MIPS.
-  // Skipping it for now. Raised issue #100 for this.
-  Abort("Unimplemented: GenerateDeoptJumpTable");
-  return false;
+  // Check that the jump table is accessible from everywhere in the function
+  // code, i.e. that offsets to the table can be encoded in the 16bit signed
+  // immediate of a branch instruction.
+  // To simplify we consider the code size from the first instruction to the
+  // end of the jump table.
+  if (!is_int16((masm()->pc_offset() / Assembler::kInstrSize) +
+      deopt_jump_table_.length() * 12)) {
+    Abort("Generated code is too large");
+  }
+
+  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
+  __ RecordComment("[ Deoptimization jump table");
+  Label table_start;
+  __ bind(&table_start);
+  Label needs_frame_not_call;
+  Label needs_frame_is_call;
+  for (int i = 0; i < deopt_jump_table_.length(); i++) {
+    __ bind(&deopt_jump_table_[i].label);
+    Address entry = deopt_jump_table_[i].address;
+    __ li(t9, Operand(ExternalReference::ForDeoptEntry(entry)));
+    if (deopt_jump_table_[i].needs_frame) {
+      if (deopt_jump_table_[i].is_lazy_deopt) {
+        if (needs_frame_is_call.is_bound()) {
+          __ Branch(&needs_frame_is_call);
+        } else {
+          __ bind(&needs_frame_is_call);
+          __ MultiPush(cp.bit() | fp.bit() | ra.bit());
+          // This variant of deopt can only be used with stubs. Since we don't
+          // have a function pointer to install in the stack frame that we're
+          // building, install a special marker there instead.
+          ASSERT(info()->IsStub());
+          __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
+          __ push(scratch0());
+          __ Addu(fp, sp, Operand(2 * kPointerSize));
+          __ Call(t9);
+        }
+      } else {
+        if (needs_frame_not_call.is_bound()) {
+          __ Branch(&needs_frame_not_call);
+        } else {
+          __ bind(&needs_frame_not_call);
+          __ MultiPush(cp.bit() | fp.bit() | ra.bit());
+          // This variant of deopt can only be used with stubs. Since we don't
+          // have a function pointer to install in the stack frame that we're
+          // building, install a special marker there instead.
+          ASSERT(info()->IsStub());
+          __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
+          __ push(scratch0());
+          __ Addu(fp, sp, Operand(2 * kPointerSize));
+          __ Jump(t9);
+        }
+      }
+    } else {
+      if (deopt_jump_table_[i].is_lazy_deopt) {
+        __ Call(t9);
+      } else {
+        __ Jump(t9);
+      }
+    }
+  }
+  __ RecordComment("]");
+
+  // The deoptimization jump table is the last part of the instruction
+  // sequence. Mark the generated code as done unless we bailed out.
+  if (!is_aborted()) status_ = DONE;
+  return !is_aborted();
 }
 
 
@@ -482,7 +572,9 @@
                    translation,
                    arguments_index,
                    arguments_count);
-  int closure_id = *info()->closure() != *environment->closure()
+  bool has_closure_id = !info()->closure().is_null() &&
+      *info()->closure() != *environment->closure();
+  int closure_id = has_closure_id
       ? DefineDeoptimizationLiteral(environment->closure())
       : Translation::kSelfLiteralId;
 
@@ -503,6 +595,9 @@
       ASSERT(height == 0);
       translation->BeginSetterStubFrame(closure_id);
       break;
+    case STUB:
+      translation->BeginCompiledStubFrame();
+      break;
     case ARGUMENTS_ADAPTOR:
       translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
       break;
@@ -689,7 +784,11 @@
   RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
   ASSERT(environment->HasBeenRegistered());
   int id = environment->deoptimization_index();
-  Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER);
+
+  Deoptimizer::BailoutType bailout_type = info()->IsStub()
+      ? Deoptimizer::LAZY
+      : Deoptimizer::EAGER;
+  Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
   if (entry == NULL) {
     Abort("bailout was not prepared");
     return;
@@ -712,9 +811,22 @@
     __ bind(&skip);
   }
 
-  // TODO(plind): The Arm port is a little different here, due to their
-  // DeOpt jump table, which is not used for Mips yet.
-  __ Jump(entry, RelocInfo::RUNTIME_ENTRY, cc, src1, src2);
+  bool needs_lazy_deopt = info()->IsStub();
+  ASSERT(info()->IsStub() || frame_is_built_);
+  if (cc == al && !needs_lazy_deopt) {
+    __ Jump(entry, RelocInfo::RUNTIME_ENTRY, cc, src1, src2);
+  } else {
+    // We often have several deopts to the same entry, reuse the last
+    // jump entry if this is the case.
+    if (deopt_jump_table_.is_empty() ||
+        (deopt_jump_table_.last().address != entry) ||
+        (deopt_jump_table_.last().is_lazy_deopt != needs_lazy_deopt) ||
+        (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
+      JumpTableEntry table_entry(entry, !frame_is_built_, needs_lazy_deopt);
+      deopt_jump_table_.Add(table_entry, zone());
+    }
+    __ Branch(&deopt_jump_table_.last().label, cc, src1, src2);
+  }
 }
 
 
@@ -976,6 +1088,14 @@
       DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
     }
 
+    // Check for (kMinInt % -1).
+    if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+      Label left_not_min_int;
+      __ Branch(&left_not_min_int, ne, left, Operand(kMinInt));
+      DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
+      __ bind(&left_not_min_int);
+    }
+
     __ Branch(USE_DELAY_SLOT, &done, ge, left, Operand(zero_reg));
     __ mfhi(result);
 
@@ -1009,7 +1129,7 @@
     __ bind(&left_not_zero);
   }
 
-  // Check for (-kMinInt / -1).
+  // Check for (kMinInt / -1).
   if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
     Label left_not_min_int;
     __ Branch(&left_not_min_int, ne, left, Operand(kMinInt));
@@ -1023,6 +1143,18 @@
 }
 
 
+void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
+  DoubleRegister addend = ToDoubleRegister(instr->addend());
+  DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
+  DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
+
+  // This is computed in-place.
+  ASSERT(addend.is(ToDoubleRegister(instr->result())));
+
+  __ madd_d(addend, addend, multiplier, multiplicand);
+}
+
+
 void LCodeGen::DoMulI(LMulI* instr) {
   Register scratch = scratch0();
   Register result = ToRegister(instr->result());
@@ -1281,6 +1413,7 @@
 void LCodeGen::DoConstantD(LConstantD* instr) {
   ASSERT(instr->result()->IsDoubleRegister());
   DoubleRegister result = ToDoubleRegister(instr->result());
+  CpuFeatures::Scope scope(FPU);
   double v = instr->value();
   __ Move(result, v);
 }
@@ -1478,6 +1611,7 @@
     __ bind(&done);
   } else {
     ASSERT(instr->hydrogen()->representation().IsDouble());
+    CpuFeatures::Scope scope(FPU);
     FPURegister left_reg = ToDoubleRegister(left);
     FPURegister right_reg = ToDoubleRegister(right);
     FPURegister result_reg = ToDoubleRegister(instr->result());
@@ -1518,6 +1652,7 @@
 
 
 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
+  CpuFeatures::Scope scope(FPU);
   DoubleRegister left = ToDoubleRegister(instr->left());
   DoubleRegister right = ToDoubleRegister(instr->right());
   DoubleRegister result = ToDoubleRegister(instr->result());
@@ -1627,6 +1762,7 @@
     Register reg = ToRegister(instr->value());
     EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
   } else if (r.IsDouble()) {
+    CpuFeatures::Scope scope(FPU);
     DoubleRegister reg = ToDoubleRegister(instr->value());
     // Test the double value. Zero and NaN are false.
     EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero);
@@ -1704,6 +1840,7 @@
       }
 
       if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
+        CpuFeatures::Scope scope(FPU);
         // heap number -> false iff +0, -0, or NaN.
         DoubleRegister dbl_scratch = double_scratch0();
         Label not_heap_number;
@@ -1783,6 +1920,7 @@
     EmitGoto(next_block);
   } else {
     if (instr->is_double()) {
+      CpuFeatures::Scope scope(FPU);
       // Compare left and right as doubles and load the
       // resulting flags into the normal status register.
       FPURegister left_reg = ToDoubleRegister(left);
@@ -2088,7 +2226,7 @@
 
   __ JumpIfSmi(input, is_false);
 
-  if (class_name->IsEqualTo(CStrVector("Function"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) {
     // Assuming the following assertions, we can use the same compares to test
     // for both being a function type and being in the object type range.
     STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
@@ -2117,7 +2255,7 @@
 
   // Objects with a non-function constructor have class 'Object'.
   __ GetObjectType(temp, temp2, temp2);
-  if (class_name->IsEqualTo(CStrVector("Object"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) {
     __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE));
   } else {
     __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE));
@@ -2330,16 +2468,18 @@
 
 
 void LCodeGen::DoReturn(LReturn* instr) {
-  if (FLAG_trace) {
+  if (FLAG_trace && info()->IsOptimizing()) {
     // Push the return value on the stack as the parameter.
     // Runtime::TraceExit returns its parameter in v0.
     __ push(v0);
     __ CallRuntime(Runtime::kTraceExit, 1);
   }
-  int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize;
-  __ mov(sp, fp);
-  __ Pop(ra, fp);
-  __ Addu(sp, sp, Operand(sp_delta));
+  if (NeedsEagerFrame()) {
+    int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize;
+    __ mov(sp, fp);
+    __ Pop(ra, fp);
+    __ Addu(sp, sp, Operand(sp_delta));
+  }
   __ Jump(ra);
 }
 
@@ -2698,12 +2838,61 @@
       __ sll(scratch0(), key, shift_size);
       __ Addu(scratch0(), scratch0(), external_pointer);
     }
+    if (CpuFeatures::IsSupported(FPU)) {
+      CpuFeatures::Scope scope(FPU);
+      if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
+        __ lwc1(result, MemOperand(scratch0(), additional_offset));
+        __ cvt_d_s(result, result);
+      } else  {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
+        __ ldc1(result, MemOperand(scratch0(), additional_offset));
+      }
+    } else {
+      if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
+        Register value = external_pointer;
+        __ lw(value, MemOperand(scratch0(), additional_offset));
+        __ And(sfpd_lo, value, Operand(kBinary32MantissaMask));
 
-    if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
-      __ lwc1(result, MemOperand(scratch0(), additional_offset));
-      __ cvt_d_s(result, result);
-    } else  {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
-      __ ldc1(result, MemOperand(scratch0(), additional_offset));
+        __ srl(scratch0(), value, kBinary32MantissaBits);
+        __ And(scratch0(), scratch0(),
+                Operand(kBinary32ExponentMask >> kBinary32MantissaBits));
+
+        Label exponent_rebiased;
+        __ Xor(at, scratch0(), Operand(0x00));
+        __ Branch(&exponent_rebiased, eq, at, Operand(zero_reg));
+
+        __ Xor(at, scratch0(), Operand(0xff));
+        Label skip;
+        __ Branch(&skip, ne, at, Operand(zero_reg));
+        __ li(scratch0(), Operand(0x7ff));
+        __ bind(&skip);
+        __ Branch(&exponent_rebiased, eq, at, Operand(zero_reg));
+
+        // Rebias exponent.
+        __ Addu(scratch0(),
+                scratch0(),
+                Operand(-kBinary32ExponentBias + HeapNumber::kExponentBias));
+
+        __ bind(&exponent_rebiased);
+        __ And(sfpd_hi, value, Operand(kBinary32SignMask));
+        __ sll(at, scratch0(), HeapNumber::kMantissaBitsInTopWord);
+        __ Or(sfpd_hi, sfpd_hi, at);
+
+        // Shift mantissa.
+        static const int kMantissaShiftForHiWord =
+            kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
+
+        static const int kMantissaShiftForLoWord =
+            kBitsPerInt - kMantissaShiftForHiWord;
+
+        __ srl(at, sfpd_lo, kMantissaShiftForHiWord);
+        __ Or(sfpd_hi, sfpd_hi, at);
+        __ sll(sfpd_lo, sfpd_lo, kMantissaShiftForLoWord);
+
+      } else {
+        __ lw(sfpd_lo, MemOperand(scratch0(), additional_offset));
+        __ lw(sfpd_hi, MemOperand(scratch0(),
+                                   additional_offset + kPointerSize));
+      }
     }
   } else {
     Register result = ToRegister(instr->result());
@@ -2772,25 +2961,28 @@
     key = ToRegister(instr->key());
   }
 
-  if (key_is_constant) {
-    __ Addu(elements, elements,
-        Operand(((constant_key + instr->additional_index()) <<
-                 element_size_shift) +
-                FixedDoubleArray::kHeaderSize - kHeapObjectTag));
-  } else {
+  int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
+      ((constant_key + instr->additional_index()) << element_size_shift);
+  if (!key_is_constant) {
     __ sll(scratch, key, shift_size);
-    __ Addu(elements, elements, Operand(scratch));
-    __ Addu(elements, elements,
-            Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
-                    (instr->additional_index() << element_size_shift)));
+    __ Addu(elements, elements, scratch);
   }
-
-  if (instr->hydrogen()->RequiresHoleCheck()) {
-    __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
-    DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    __ Addu(elements, elements, Operand(base_offset));
+    __ ldc1(result, MemOperand(elements));
+    if (instr->hydrogen()->RequiresHoleCheck()) {
+      __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
+      DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
+    }
+  } else {
+      __ lw(sfpd_hi, MemOperand(elements, base_offset + kPointerSize));
+      __ lw(sfpd_lo, MemOperand(elements, base_offset));
+    if (instr->hydrogen()->RequiresHoleCheck()) {
+      ASSERT(kPointerSize == sizeof(kHoleNanLower32));
+      DeoptimizeIf(eq, instr->environment(), sfpd_hi, Operand(kHoleNanUpper32));
+    }
   }
-
-  __ ldc1(result, MemOperand(elements));
 }
 
 
@@ -3233,6 +3425,7 @@
 
 
 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
+  CpuFeatures::Scope scope(FPU);
   // Class for deferred case.
   class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
    public:
@@ -3269,6 +3462,7 @@
 
 
 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
+  CpuFeatures::Scope scope(FPU);
   DoubleRegister input = ToDoubleRegister(instr->value());
   Register result = ToRegister(instr->result());
   Register scratch1 = scratch0();
@@ -3297,6 +3491,7 @@
 
 
 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
+  CpuFeatures::Scope scope(FPU);
   DoubleRegister input = ToDoubleRegister(instr->value());
   Register result = ToRegister(instr->result());
   DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
@@ -3373,6 +3568,7 @@
 
 
 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
+  CpuFeatures::Scope scope(FPU);
   DoubleRegister input = ToDoubleRegister(instr->value());
   DoubleRegister result = ToDoubleRegister(instr->result());
   __ sqrt_d(result, input);
@@ -3380,6 +3576,7 @@
 
 
 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
+  CpuFeatures::Scope scope(FPU);
   DoubleRegister input = ToDoubleRegister(instr->value());
   DoubleRegister result = ToDoubleRegister(instr->result());
   DoubleRegister temp = ToDoubleRegister(instr->temp());
@@ -3404,6 +3601,7 @@
 
 
 void LCodeGen::DoPower(LPower* instr) {
+  CpuFeatures::Scope scope(FPU);
   Representation exponent_type = instr->hydrogen()->right()->representation();
   // Having marked this as a call, we can use any registers.
   // Just make sure that the input/output registers are the expected ones.
@@ -3434,6 +3632,7 @@
 
 
 void LCodeGen::DoRandom(LRandom* instr) {
+  CpuFeatures::Scope scope(FPU);
   class DeferredDoRandom: public LDeferredCode {
    public:
     DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
@@ -3510,6 +3709,7 @@
 
 
 void LCodeGen::DoMathExp(LMathExp* instr) {
+  CpuFeatures::Scope scope(FPU);
   DoubleRegister input = ToDoubleRegister(instr->value());
   DoubleRegister result = ToDoubleRegister(instr->result());
   DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
@@ -3805,6 +4005,7 @@
 
 
 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
+  CpuFeatures::Scope scope(FPU);
   Register external_pointer = ToRegister(instr->elements());
   Register key = no_reg;
   ElementsKind elements_kind = instr->elements_kind();
@@ -3878,6 +4079,7 @@
 
 
 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
+  CpuFeatures::Scope scope(FPU);
   DoubleRegister value = ToDoubleRegister(instr->value());
   Register elements = ToRegister(instr->elements());
   Register key = no_reg;
@@ -4125,7 +4327,7 @@
   ASSERT(!char_code.is(result));
 
   __ Branch(deferred->entry(), hi,
-            char_code, Operand(String::kMaxAsciiCharCode));
+            char_code, Operand(String::kMaxOneByteCharCode));
   __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
   __ sll(scratch, char_code, kPointerSizeLog2);
   __ Addu(result, result, scratch);
@@ -4161,6 +4363,7 @@
 
 
 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
+  CpuFeatures::Scope scope(FPU);
   LOperand* input = instr->value();
   ASSERT(input->IsRegister() || input->IsStackSlot());
   LOperand* output = instr->result();
@@ -4178,6 +4381,7 @@
 
 
 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
+  CpuFeatures::Scope scope(FPU);
   LOperand* input = instr->value();
   LOperand* output = instr->result();
 
@@ -4239,13 +4443,51 @@
 }
 
 
+// Convert unsigned integer with specified number of leading zeroes in binary
+// representation to IEEE 754 double.
+// Integer to convert is passed in register hiword.
+// Resulting double is returned in registers hiword:loword.
+// This functions does not work correctly for 0.
+static void GenerateUInt2Double(MacroAssembler* masm,
+                                Register hiword,
+                                Register loword,
+                                Register scratch,
+                                int leading_zeroes) {
+  const int meaningful_bits = kBitsPerInt - leading_zeroes - 1;
+  const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits;
+
+  const int mantissa_shift_for_hi_word =
+      meaningful_bits - HeapNumber::kMantissaBitsInTopWord;
+  const int mantissa_shift_for_lo_word =
+      kBitsPerInt - mantissa_shift_for_hi_word;
+  masm->li(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
+  if (mantissa_shift_for_hi_word > 0) {
+    masm->sll(loword, hiword, mantissa_shift_for_lo_word);
+    masm->srl(hiword, hiword, mantissa_shift_for_hi_word);
+    masm->Or(hiword, scratch, hiword);
+  } else {
+    masm->mov(loword, zero_reg);
+    masm->sll(hiword, hiword, mantissa_shift_for_hi_word);
+    masm->Or(hiword, scratch, hiword);
+  }
+
+  // If least significant bit of biased exponent was not 1 it was corrupted
+  // by most significant bit of mantissa so we should fix that.
+  if (!(biased_exponent & 1)) {
+    masm->li(scratch, 1 << HeapNumber::kExponentShift);
+    masm->nor(scratch, scratch, scratch);
+    masm->and_(hiword, hiword, scratch);
+  }
+}
+
+
 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
                                     LOperand* value,
                                     IntegerSignedness signedness) {
   Label slow;
   Register src = ToRegister(value);
   Register dst = ToRegister(instr->result());
-  FPURegister dbl_scratch = double_scratch0();
+  DoubleRegister dbl_scratch = double_scratch0();
 
   // Preserve the value of all registers.
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
@@ -4259,16 +4501,40 @@
       __ SmiUntag(src, dst);
       __ Xor(src, src, Operand(0x80000000));
     }
-    __ mtc1(src, dbl_scratch);
-    __ cvt_d_w(dbl_scratch, dbl_scratch);
+    if (CpuFeatures::IsSupported(FPU)) {
+      CpuFeatures::Scope scope(FPU);
+      __ mtc1(src, dbl_scratch);
+      __ cvt_d_w(dbl_scratch, dbl_scratch);
+    } else {
+      FloatingPointHelper::Destination dest =
+          FloatingPointHelper::kCoreRegisters;
+      FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0,
+                                              sfpd_lo, sfpd_hi,
+                                              scratch0(), f2);
+    }
   } else {
-    __ mtc1(src, dbl_scratch);
-    __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
+    if (CpuFeatures::IsSupported(FPU)) {
+      CpuFeatures::Scope scope(FPU);
+      __ mtc1(src, dbl_scratch);
+      __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
+    } else {
+      Label no_leading_zero, done;
+      __ And(at, src, Operand(0x80000000));
+      __ Branch(&no_leading_zero, ne, at, Operand(zero_reg));
+
+      // Integer has one leading zeros.
+      GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 1);
+      __ Branch(&done);
+
+      __ bind(&no_leading_zero);
+      GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 0);
+      __ Branch(&done);
+    }
   }
 
   if (FLAG_inline_new) {
-    __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(t1, a3, t0, t2, &slow, DONT_TAG_RESULT);
+    __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex);
+    __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT);
     __ Move(dst, t1);
     __ Branch(&done);
   }
@@ -4287,7 +4553,13 @@
   // Done. Put the value in dbl_scratch into the value of the allocated heap
   // number.
   __ bind(&done);
-  __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset));
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset));
+  } else {
+    __ sw(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset));
+    __ sw(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset));
+  }
   __ Addu(dst, dst, kHeapObjectTag);
   __ StoreToSafepointRegisterSlot(dst, dst);
 }
@@ -4320,7 +4592,13 @@
     __ Branch(deferred->entry());
   }
   __ bind(deferred->exit());
-  __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset));
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset));
+  } else {
+    __ sw(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset));
+    __ sw(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize));
+  }
   // Now that we have finished with the object's real address tag it
   __ Addu(reg, reg, kHeapObjectTag);
 }
@@ -4368,6 +4646,7 @@
                                 bool deoptimize_on_minus_zero,
                                 LEnvironment* env) {
   Register scratch = scratch0();
+  CpuFeatures::Scope scope(FPU);
 
   Label load_smi, heap_number, done;
 
@@ -4432,6 +4711,7 @@
   // of the if.
 
   if (instr->truncating()) {
+    CpuFeatures::Scope scope(FPU);
     Register scratch3 = ToRegister(instr->temp2());
     FPURegister single_scratch = double_scratch.low();
     ASSERT(!scratch3.is(input_reg) &&
@@ -4637,37 +4917,38 @@
 }
 
 
-void LCodeGen::DoCheckMapCommon(Register reg,
-                                Register scratch,
+void LCodeGen::DoCheckMapCommon(Register map_reg,
                                 Handle<Map> map,
                                 CompareMapMode mode,
                                 LEnvironment* env) {
   Label success;
-  __ CompareMapAndBranch(reg, scratch, map, &success, eq, &success, mode);
+  __ CompareMapAndBranch(map_reg, map, &success, eq, &success, mode);
   DeoptimizeIf(al, env);
   __ bind(&success);
 }
 
 
 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
-  Register scratch = scratch0();
+  Register map_reg = scratch0();
   LOperand* input = instr->value();
   ASSERT(input->IsRegister());
   Register reg = ToRegister(input);
   Label success;
   SmallMapList* map_set = instr->hydrogen()->map_set();
+  __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
   for (int i = 0; i < map_set->length() - 1; i++) {
     Handle<Map> map = map_set->at(i);
     __ CompareMapAndBranch(
-        reg, scratch, map, &success, eq, &success, REQUIRE_EXACT_MAP);
+        map_reg, map, &success, eq, &success, REQUIRE_EXACT_MAP);
   }
   Handle<Map> map = map_set->last();
-  DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment());
+  DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment());
   __ bind(&success);
 }
 
 
 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
+  CpuFeatures::Scope vfp_scope(FPU);
   DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
   Register result_reg = ToRegister(instr->result());
   DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
@@ -4676,6 +4957,7 @@
 
 
 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
+  CpuFeatures::Scope vfp_scope(FPU);
   Register unclamped_reg = ToRegister(instr->unclamped());
   Register result_reg = ToRegister(instr->result());
   __ ClampUint8(result_reg, unclamped_reg);
@@ -4683,6 +4965,7 @@
 
 
 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
+  CpuFeatures::Scope vfp_scope(FPU);
   Register scratch = scratch0();
   Register input_reg = ToRegister(instr->unclamped());
   Register result_reg = ToRegister(instr->result());
@@ -4719,28 +5002,30 @@
 
 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
   ASSERT(instr->temp()->Equals(instr->result()));
-  Register temp1 = ToRegister(instr->temp());
-  Register temp2 = ToRegister(instr->temp2());
+  Register prototype_reg = ToRegister(instr->temp());
+  Register map_reg = ToRegister(instr->temp2());
 
   Handle<JSObject> holder = instr->holder();
   Handle<JSObject> current_prototype = instr->prototype();
 
   // Load prototype object.
-  __ LoadHeapObject(temp1, current_prototype);
+  __ LoadHeapObject(prototype_reg, current_prototype);
 
   // Check prototype maps up to the holder.
   while (!current_prototype.is_identical_to(holder)) {
-    DoCheckMapCommon(temp1, temp2,
+    __ lw(map_reg, FieldMemOperand(prototype_reg, HeapObject::kMapOffset));
+    DoCheckMapCommon(map_reg,
                      Handle<Map>(current_prototype->map()),
                      ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
     current_prototype =
         Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
     // Load next prototype object.
-    __ LoadHeapObject(temp1, current_prototype);
+    __ LoadHeapObject(prototype_reg, current_prototype);
   }
 
   // Check the holder map.
-  DoCheckMapCommon(temp1, temp2,
+  __ lw(map_reg, FieldMemOperand(prototype_reg, HeapObject::kMapOffset));
+  DoCheckMapCommon(map_reg,
                    Handle<Map>(current_prototype->map()),
                    ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
 }
@@ -5304,6 +5589,7 @@
 
 
 void LCodeGen::EnsureSpaceForLazyDeopt() {
+  if (info()->IsStub()) return;
   // Ensure that we have enough space after the previous lazy-bailout
   // instruction for patching the code here.
   int current_pc = masm()->pc_offset();
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index 7363eb8..443a20a 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -61,6 +61,7 @@
         deferred_(8, info->zone()),
         osr_pc_offset_(-1),
         last_lazy_deopt_pc_(0),
+        frame_is_built_(false),
         safepoints_(info->zone()),
         resolver_(this),
         expected_safepoint_kind_(Safepoint::kSimple) {
@@ -76,6 +77,15 @@
   Heap* heap() const { return isolate()->heap(); }
   Zone* zone() const { return zone_; }
 
+  bool NeedsEagerFrame() const {
+    return GetStackSlotCount() > 0 ||
+        info()->is_non_deferred_calling() ||
+        !info()->IsStub();
+  }
+  bool NeedsDeferredFrame() const {
+    return !NeedsEagerFrame() && info()->is_deferred_calling();
+  }
+
   // Support for converting LOperands to assembler types.
   // LOperand must be a register.
   Register ToRegister(LOperand* op) const;
@@ -126,7 +136,7 @@
   void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                                        Label* map_check);
 
-  void DoCheckMapCommon(Register reg, Register scratch, Handle<Map> map,
+  void DoCheckMapCommon(Register map_reg, Handle<Map> map,
                         CompareMapMode mode, LEnvironment* env);
 
   // Parallel move support.
@@ -189,7 +199,7 @@
                        Register temporary2);
 
   int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
-  int GetParameterCount() const { return scope()->num_parameters(); }
+  int GetParameterCount() const { return info()->num_parameters(); }
 
   void Abort(const char* reason);
   void Comment(const char* format, ...);
@@ -368,11 +378,15 @@
                     int* offset);
 
   struct JumpTableEntry {
-    explicit inline JumpTableEntry(Address entry)
+    inline JumpTableEntry(Address entry, bool frame, bool is_lazy)
         : label(),
-          address(entry) { }
+          address(entry),
+          needs_frame(frame),
+          is_lazy_deopt(is_lazy) { }
     Label label;
     Address address;
+    bool needs_frame;
+    bool is_lazy_deopt;
   };
 
   void EnsureSpaceForLazyDeopt();
@@ -401,6 +415,7 @@
   ZoneList<LDeferredCode*> deferred_;
   int osr_pc_offset_;
   int last_lazy_deopt_pc_;
+  bool frame_is_built_;
 
   // Builder that keeps track of safepoints in the code. The table
   // itself is emitted at the end of the generated code.
@@ -416,6 +431,7 @@
     PushSafepointRegistersScope(LCodeGen* codegen,
                                 Safepoint::Kind kind)
         : codegen_(codegen) {
+      ASSERT(codegen_->info()->is_calling());
       ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
       codegen_->expected_safepoint_kind_ = kind;
 
diff --git a/src/mips/lithium-gap-resolver-mips.cc b/src/mips/lithium-gap-resolver-mips.cc
index 87efae5..a4a4411 100644
--- a/src/mips/lithium-gap-resolver-mips.cc
+++ b/src/mips/lithium-gap-resolver-mips.cc
@@ -172,8 +172,10 @@
   } else if (source->IsStackSlot()) {
     __ lw(kLithiumScratchReg, cgen_->ToMemOperand(source));
   } else if (source->IsDoubleRegister()) {
+    CpuFeatures::Scope scope(FPU);
     __ mov_d(kLithiumScratchDouble, cgen_->ToDoubleRegister(source));
   } else if (source->IsDoubleStackSlot()) {
+    CpuFeatures::Scope scope(FPU);
     __ ldc1(kLithiumScratchDouble, cgen_->ToMemOperand(source));
   } else {
     UNREACHABLE();
@@ -193,9 +195,11 @@
   } else if (saved_destination_->IsStackSlot()) {
     __ sw(kLithiumScratchReg, cgen_->ToMemOperand(saved_destination_));
   } else if (saved_destination_->IsDoubleRegister()) {
+    CpuFeatures::Scope scope(FPU);
     __ mov_d(cgen_->ToDoubleRegister(saved_destination_),
             kLithiumScratchDouble);
   } else if (saved_destination_->IsDoubleStackSlot()) {
+    CpuFeatures::Scope scope(FPU);
     __ sdc1(kLithiumScratchDouble,
             cgen_->ToMemOperand(saved_destination_));
   } else {
@@ -232,6 +236,7 @@
       MemOperand destination_operand = cgen_->ToMemOperand(destination);
       if (in_cycle_) {
         if (!destination_operand.OffsetIsInt16Encodable()) {
+          CpuFeatures::Scope scope(FPU);
           // 'at' is overwritten while saving the value to the destination.
           // Therefore we can't use 'at'.  It is OK if the read from the source
           // destroys 'at', since that happens before the value is read.
@@ -271,6 +276,7 @@
     }
 
   } else if (source->IsDoubleRegister()) {
+    CpuFeatures::Scope scope(FPU);
     DoubleRegister source_register = cgen_->ToDoubleRegister(source);
     if (destination->IsDoubleRegister()) {
       __ mov_d(cgen_->ToDoubleRegister(destination), source_register);
@@ -281,6 +287,7 @@
     }
 
   } else if (source->IsDoubleStackSlot()) {
+    CpuFeatures::Scope scope(FPU);
     MemOperand source_operand = cgen_->ToMemOperand(source);
     if (destination->IsDoubleRegister()) {
       __ ldc1(cgen_->ToDoubleRegister(destination), source_operand);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 0e58eb5..8ce576d 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -42,10 +42,10 @@
 #undef DEFINE_COMPILE
 
 LOsrEntry::LOsrEntry() {
-  for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) {
+  for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) {
     register_spills_[i] = NULL;
   }
-  for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
     double_register_spills_[i] = NULL;
   }
 }
@@ -616,6 +616,7 @@
 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
                                         HInstruction* hinstr,
                                         CanDeoptimize can_deoptimize) {
+  info()->MarkAsNonDeferredCalling();
 #ifdef DEBUG
   instr->VerifyCall();
 #endif
@@ -1001,7 +1002,14 @@
 
 
 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
-  return instr->HasNoUses() ? NULL : DefineAsRegister(new(zone()) LContext);
+  // If there is a non-return use, the context must be allocated in a register.
+  for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+    if (!it.value()->IsReturn()) {
+      return DefineAsRegister(new(zone()) LContext);
+    }
+  }
+
+  return NULL;
 }
 
 
@@ -1275,8 +1283,22 @@
     return DefineAsRegister(mul);
 
   } else if (instr->representation().IsDouble()) {
+    if (kArchVariant == kMips32r2) {
+      if (instr->UseCount() == 1 && instr->uses().value()->IsAdd()) {
+        HAdd* add = HAdd::cast(instr->uses().value());
+        if (instr == add->left()) {
+          // This mul is the lhs of an add. The add and mul will be folded
+          // into a multiply-add.
+          return NULL;
+        }
+        if (instr == add->right() && !add->left()->IsMul()) {
+          // This mul is the rhs of an add, where the lhs is not another mul.
+          // The add and mul will be folded into a multiply-add.
+          return NULL;
+        }
+      }
+    }
     return DoArithmeticD(Token::MUL, instr);
-
   } else {
     return DoArithmeticT(Token::MUL, instr);
   }
@@ -1303,6 +1325,15 @@
 }
 
 
+LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) {
+  LOperand* multiplier_op = UseRegisterAtStart(mul->left());
+  LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
+  LOperand* addend_op = UseRegisterAtStart(addend);
+  return DefineSameAsFirst(new(zone()) LMultiplyAddD(addend_op, multiplier_op,
+                                                     multiplicand_op));
+}
+
+
 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
   if (instr->representation().IsInteger32()) {
     ASSERT(instr->left()->representation().IsInteger32());
@@ -1316,6 +1347,15 @@
     }
     return result;
   } else if (instr->representation().IsDouble()) {
+    if (kArchVariant == kMips32r2) {
+      if (instr->left()->IsMul())
+        return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
+
+      if (instr->right()->IsMul()) {
+        ASSERT(!instr->left()->IsMul());
+        return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
+      }
+    }
     return DoArithmeticD(Token::ADD, instr);
   } else {
     ASSERT(instr->representation().IsTagged());
@@ -1583,6 +1623,7 @@
   Representation to = instr->to();
   if (from.IsTagged()) {
     if (to.IsDouble()) {
+      info()->MarkAsDeferredCalling();
       LOperand* value = UseRegister(instr->value());
       LNumberUntagD* res = new(zone()) LNumberUntagD(value);
       return AssignEnvironment(DefineAsRegister(res));
@@ -1607,6 +1648,7 @@
     }
   } else if (from.IsDouble()) {
     if (to.IsTagged()) {
+      info()->MarkAsDeferredCalling();
       LOperand* value = UseRegister(instr->value());
       LOperand* temp1 = TempRegister();
       LOperand* temp2 = TempRegister();
@@ -1626,6 +1668,7 @@
       return AssignEnvironment(DefineAsRegister(res));
     }
   } else if (from.IsInteger32()) {
+    info()->MarkAsDeferredCalling();
     if (to.IsTagged()) {
       HValue* val = instr->value();
       LOperand* value = UseRegisterAtStart(val);
@@ -1864,7 +1907,16 @@
         (instr->representation().IsDouble() &&
          ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
           (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
-    LOperand* external_pointer = UseRegister(instr->elements());
+    // float->double conversion on non-VFP2 requires an extra scratch
+    // register. For convenience, just mark the elements register as "UseTemp"
+    // so that it can be used as a temp during the float->double conversion
+    // after it's no longer needed after the float load.
+    bool needs_temp =
+        !CpuFeatures::IsSupported(FPU) &&
+        (elements_kind == EXTERNAL_FLOAT_ELEMENTS);
+    LOperand* external_pointer = needs_temp
+        ? UseTempRegister(instr->elements())
+        : UseRegister(instr->elements());
     result = new(zone()) LLoadKeyed(external_pointer, key);
   }
 
@@ -2083,8 +2135,17 @@
 
 
 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
-  int spill_index = chunk()->GetParameterStackSlot(instr->index());
-  return DefineAsSpilled(new(zone()) LParameter, spill_index);
+  LParameter* result = new(zone()) LParameter;
+  if (info()->IsOptimizing()) {
+    int spill_index = chunk()->GetParameterStackSlot(instr->index());
+    return DefineAsSpilled(result, spill_index);
+  } else {
+    ASSERT(info()->IsStub());
+    CodeStubInterfaceDescriptor* descriptor =
+        info()->code_stub()->GetInterfaceDescriptor(info()->isolate());
+    Register reg = descriptor->register_params_[instr->index()];
+    return DefineFixed(result, reg);
+  }
 }
 
 
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index b2ed72a..7f87b02 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -135,6 +135,7 @@
   V(MathMinMax)                                 \
   V(ModI)                                       \
   V(MulI)                                       \
+  V(MultiplyAddD)                               \
   V(NumberTagD)                                 \
   V(NumberTagI)                                 \
   V(NumberTagU)                                 \
@@ -252,6 +253,11 @@
   void MarkAsCall() { is_call_ = true; }
 
   // Interface to the register allocator and iterators.
+  bool ClobbersTemps() const { return is_call_; }
+  bool ClobbersRegisters() const { return is_call_; }
+  bool ClobbersDoubleRegisters() const { return is_call_; }
+
+  // Interface to the register allocator and iterators.
   bool IsMarkedAsCall() const { return is_call_; }
 
   virtual bool HasResult() const = 0;
@@ -603,6 +609,24 @@
 };
 
 
+// Instruction for computing multiplier * multiplicand + addend.
+class LMultiplyAddD: public LTemplateInstruction<1, 3, 0> {
+ public:
+  LMultiplyAddD(LOperand* addend, LOperand* multiplier,
+                LOperand* multiplicand) {
+    inputs_[0] = addend;
+    inputs_[1] = multiplier;
+    inputs_[2] = multiplicand;
+  }
+
+  LOperand* addend() { return inputs_[0]; }
+  LOperand* multiplier() { return inputs_[1]; }
+  LOperand* multiplicand() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d")
+};
+
+
 class LCmpIDAndBranch: public LControlInstruction<2, 0> {
  public:
   LCmpIDAndBranch(LOperand* left, LOperand* right) {
@@ -2304,8 +2328,9 @@
   // slot, i.e., that must also be restored to the spill slot on OSR entry.
   // NULL if the register has no assigned spill slot.  Indexed by allocation
   // index.
-  LOperand* register_spills_[Register::kNumAllocatableRegisters];
-  LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
+  LOperand* register_spills_[Register::kMaxNumAllocatableRegisters];
+  LOperand* double_register_spills_[
+      DoubleRegister::kMaxNumAllocatableRegisters];
 };
 
 
@@ -2427,6 +2452,8 @@
   HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
 #undef DECLARE_DO
 
+  LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend);
+
  private:
   enum Status {
     UNUSED,
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 9249917..e0c5787 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -118,8 +118,8 @@
 
 void MacroAssembler::PushSafepointRegistersAndDoubles() {
   PushSafepointRegisters();
-  Subu(sp, sp, Operand(FPURegister::kNumAllocatableRegisters * kDoubleSize));
-  for (int i = 0; i < FPURegister::kNumAllocatableRegisters; i+=2) {
+  Subu(sp, sp, Operand(FPURegister::NumAllocatableRegisters() * kDoubleSize));
+  for (int i = 0; i < FPURegister::NumAllocatableRegisters(); i+=2) {
     FPURegister reg = FPURegister::FromAllocationIndex(i);
     sdc1(reg, MemOperand(sp, i * kDoubleSize));
   }
@@ -127,11 +127,11 @@
 
 
 void MacroAssembler::PopSafepointRegistersAndDoubles() {
-  for (int i = 0; i < FPURegister::kNumAllocatableRegisters; i+=2) {
+  for (int i = 0; i < FPURegister::NumAllocatableRegisters(); i+=2) {
     FPURegister reg = FPURegister::FromAllocationIndex(i);
     ldc1(reg, MemOperand(sp, i * kDoubleSize));
   }
-  Addu(sp, sp, Operand(FPURegister::kNumAllocatableRegisters * kDoubleSize));
+  Addu(sp, sp, Operand(FPURegister::NumAllocatableRegisters() * kDoubleSize));
   PopSafepointRegisters();
 }
 
@@ -167,7 +167,7 @@
 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
   UNIMPLEMENTED_MIPS();
   // General purpose registers are pushed last on the stack.
-  int doubles_size = FPURegister::kNumAllocatableRegisters * kDoubleSize;
+  int doubles_size = FPURegister::NumAllocatableRegisters() * kDoubleSize;
   int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
   return MemOperand(sp, doubles_size + register_offset);
 }
@@ -3935,12 +3935,13 @@
 // Runtime calls.
 
 void MacroAssembler::CallStub(CodeStub* stub,
+                              TypeFeedbackId ast_id,
                               Condition cond,
                               Register r1,
                               const Operand& r2,
                               BranchDelaySlot bd) {
   ASSERT(AllowThisStubCall(stub));  // Stub calls are not allowed in some stubs.
-  Call(stub->GetCode(), RelocInfo::CODE_TARGET, TypeFeedbackId::None(),
+  Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id,
        cond, r1, r2, bd);
 }
 
@@ -4249,7 +4250,10 @@
   const Runtime::Function* function = Runtime::FunctionForId(id);
   PrepareCEntryArgs(function->nargs);
   PrepareCEntryFunction(ExternalReference(function, isolate()));
-  CEntryStub stub(1, kSaveFPRegs);
+  SaveFPRegsMode mode = CpuFeatures::IsSupported(FPU)
+      ? kSaveFPRegs
+      : kDontSaveFPRegs;
+  CEntryStub stub(1, mode);
   CallStub(&stub);
 }
 
@@ -4266,7 +4270,7 @@
   PrepareCEntryFunction(ext);
 
   CEntryStub stub(1);
-  CallStub(&stub, al, zero_reg, Operand(zero_reg), bd);
+  CallStub(&stub, TypeFeedbackId::None(), al, zero_reg, Operand(zero_reg), bd);
 }
 
 
@@ -5445,6 +5449,27 @@
 }
 
 
+void MacroAssembler::TestJSArrayForAllocationSiteInfo(
+    Register receiver_reg,
+    Register scratch_reg,
+    Label* allocation_info_present) {
+  Label no_info_available;
+  ExternalReference new_space_start =
+      ExternalReference::new_space_start(isolate());
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address(isolate());
+  lw(scratch_reg, FieldMemOperand(receiver_reg,
+                                  JSArray::kSize + AllocationSiteInfo::kSize));
+  Branch(&no_info_available, lt, scratch_reg, Operand(new_space_start));
+  Branch(&no_info_available, hs, scratch_reg,
+      Operand(new_space_allocation_top));
+  lw(scratch_reg, MemOperand(scratch_reg));
+  Branch(allocation_info_present, eq, scratch_reg,
+      Operand(Handle<Map>(isolate()->heap()->allocation_site_info_map())));
+  bind(&no_info_available);
+}
+
+
 bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
   if (r1.is(r2)) return true;
   if (r1.is(r3)) return true;
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 474772e..1a37aca 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -1141,6 +1141,7 @@
 
   // Call a code stub.
   void CallStub(CodeStub* stub,
+                TypeFeedbackId ast_id = TypeFeedbackId::None(),
                 Condition cond = cc_always,
                 Register r1 = zero_reg,
                 const Operand& r2 = Operand(zero_reg),
@@ -1439,6 +1440,16 @@
   // in a0.  Assumes that any other register can be used as a scratch.
   void CheckEnumCache(Register null_value, Label* call_runtime);
 
+  // AllocationSiteInfo support. Arrays may have an associated
+  // AllocationSiteInfo object that can be checked for in order to pretransition
+  // to another type.
+  // On entry, receiver_reg should point to the array object.
+  // scratch_reg gets clobbered.
+  // If allocation info is present, jump to allocation_info_present
+  void TestJSArrayForAllocationSiteInfo(Register receiver_reg,
+                                        Register scratch_reg,
+                                        Label* allocation_info_present);
+
  private:
   void CallCFunctionHelper(Register function,
                            int num_reg_arguments,
@@ -1513,9 +1524,9 @@
   // This handle will be patched with the code object on installation.
   Handle<Object> code_object_;
 
-  // Needs access to SafepointRegisterStackIndex for optimized frame
+  // Needs access to SafepointRegisterStackIndex for compiled frame
   // traversal.
-  friend class OptimizedFrame;
+  friend class StandardFrame;
 };
 
 
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index 0dd72de..6ace471 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -262,7 +262,7 @@
     if (mode_ == ASCII) {
       __ lbu(a1, MemOperand(a0, 0));
       __ addiu(a0, a0, char_size());
-      ASSERT(str[i] <= String::kMaxAsciiCharCode);
+      ASSERT(str[i] <= String::kMaxOneByteCharCode);
       BranchOrBacktrack(on_failure, ne, a1, Operand(str[i]));
     } else {
       __ lhu(a1, MemOperand(a0, 0));
@@ -511,7 +511,7 @@
     Handle<ByteArray> table,
     Label* on_bit_set) {
   __ li(a0, Operand(table));
-  if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) {
+  if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) {
     __ And(a1, current_character(), Operand(kTableSize - 1));
     __ Addu(a0, a0, a1);
   } else {
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index ea359ea..be9f369 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -1545,7 +1545,7 @@
                FUNCTION_ADDR(target), arg1);
       }
       v8::Handle<v8::Value> result = target(arg1);
-      *(reinterpret_cast<int*>(arg0)) = (int32_t) *result;
+      *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
       set_register(v0, arg0);
     } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
       // See DirectCEntryStub::GenerateCall for explanation of register usage.
@@ -1556,7 +1556,7 @@
                FUNCTION_ADDR(target), arg1, arg2);
       }
       v8::Handle<v8::Value> result = target(arg1, arg2);
-      *(reinterpret_cast<int*>(arg0)) = (int32_t) *result;
+      *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
       set_register(v0, arg0);
     } else {
       SimulatorRuntimeCall target =
@@ -1760,6 +1760,8 @@
           UNIMPLEMENTED_MIPS();
       };
       break;
+    case COP1X:
+      break;
     case SPECIAL:
       switch (instr->FunctionFieldRaw()) {
         case JR:
@@ -1949,6 +1951,7 @@
   const uint32_t rt_u   = static_cast<uint32_t>(rt);
   const int32_t  rd_reg = instr->RdValue();
 
+  const int32_t  fr_reg = instr->FrValue();
   const int32_t  fs_reg = instr->FsValue();
   const int32_t  ft_reg = instr->FtValue();
   const int32_t  fd_reg = instr->FdValue();
@@ -2193,8 +2196,8 @@
           case CVT_D_L:  // Mips32r2 instruction.
             // Watch the signs here, we want 2 32-bit vals
             // to make a sign-64.
-            i64 = (uint32_t) get_fpu_register(fs_reg);
-            i64 |= ((int64_t) get_fpu_register(fs_reg + 1) << 32);
+            i64 = static_cast<uint32_t>(get_fpu_register(fs_reg));
+            i64 |= static_cast<int64_t>(get_fpu_register(fs_reg + 1)) << 32;
             set_fpu_register_double(fd_reg, static_cast<double>(i64));
             break;
             case CVT_S_L:
@@ -2210,6 +2213,19 @@
           UNREACHABLE();
       };
       break;
+    case COP1X:
+      switch (instr->FunctionFieldRaw()) {
+        case MADD_D:
+          double fr, ft, fs;
+          fr = get_fpu_register_double(fr_reg);
+          fs = get_fpu_register_double(fs_reg);
+          ft = get_fpu_register_double(ft_reg);
+          set_fpu_register_double(fd_reg, fs * ft + fr);
+          break;
+        default:
+          UNREACHABLE();
+      };
+      break;
     case SPECIAL:
       switch (instr->FunctionFieldRaw()) {
         case JR: {
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 323933b..0313826 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -1054,46 +1054,6 @@
 }
 
 
-// Convert unsigned integer with specified number of leading zeroes in binary
-// representation to IEEE 754 double.
-// Integer to convert is passed in register hiword.
-// Resulting double is returned in registers hiword:loword.
-// This functions does not work correctly for 0.
-static void GenerateUInt2Double(MacroAssembler* masm,
-                                Register hiword,
-                                Register loword,
-                                Register scratch,
-                                int leading_zeroes) {
-  const int meaningful_bits = kBitsPerInt - leading_zeroes - 1;
-  const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits;
-
-  const int mantissa_shift_for_hi_word =
-      meaningful_bits - HeapNumber::kMantissaBitsInTopWord;
-
-  const int mantissa_shift_for_lo_word =
-      kBitsPerInt - mantissa_shift_for_hi_word;
-
-  __ li(scratch, biased_exponent << HeapNumber::kExponentShift);
-  if (mantissa_shift_for_hi_word > 0) {
-    __ sll(loword, hiword, mantissa_shift_for_lo_word);
-    __ srl(hiword, hiword, mantissa_shift_for_hi_word);
-    __ or_(hiword, scratch, hiword);
-  } else {
-    __ mov(loword, zero_reg);
-    __ sll(hiword, hiword, mantissa_shift_for_hi_word);
-    __ or_(hiword, scratch, hiword);
-  }
-
-  // If least significant bit of biased exponent was not 1 it was corrupted
-  // by most significant bit of mantissa so we should fix that.
-  if (!(biased_exponent & 1)) {
-    __ li(scratch, 1 << HeapNumber::kExponentShift);
-    __ nor(scratch, scratch, scratch);
-    __ and_(hiword, hiword, scratch);
-  }
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm())
 
@@ -3316,9 +3276,17 @@
   //  -- a1    : receiver
   // -----------------------------------
   ElementsKind elements_kind = receiver_map->elements_kind();
-  Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode();
-
-  __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
+  if (receiver_map->has_fast_elements() ||
+      receiver_map->has_external_array_elements()) {
+    Handle<Code> stub = KeyedLoadFastElementStub(
+        receiver_map->instance_type() == JS_ARRAY_TYPE,
+        elements_kind).GetCode();
+    __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
+  } else {
+    Handle<Code> stub =
+        KeyedLoadDictionaryElementStub().GetCode();
+    __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
+  }
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
@@ -3351,7 +3319,7 @@
   __ Jump(miss_ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3454,7 +3422,7 @@
   __ Jump(miss_ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3730,355 +3698,6 @@
 }
 
 
-void KeyedLoadStubCompiler::GenerateLoadExternalArray(
-    MacroAssembler* masm,
-    ElementsKind elements_kind) {
-  // ---------- S t a t e --------------
-  //  -- ra     : return address
-  //  -- a0     : key
-  //  -- a1     : receiver
-  // -----------------------------------
-  Label miss_force_generic, slow, failed_allocation;
-
-  Register key = a0;
-  Register receiver = a1;
-
-  // This stub is meant to be tail-jumped to, the receiver must already
-  // have been verified by the caller to not be a smi.
-
-  // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, key, t0, t1, f2, f4, &miss_force_generic);
-
-  __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
-  // a3: elements array
-
-  // Check that the index is in range.
-  __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset));
-  __ sra(t2, key, kSmiTagSize);
-  // Unsigned comparison catches both negative and too-large values.
-  __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1));
-
-  __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
-  // a3: base pointer of external storage
-
-  // We are not untagging smi key and instead work with it
-  // as if it was premultiplied by 2.
-  STATIC_ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
-
-  Register value = a2;
-  switch (elements_kind) {
-    case EXTERNAL_BYTE_ELEMENTS:
-      __ srl(t2, key, 1);
-      __ addu(t3, a3, t2);
-      __ lb(value, MemOperand(t3, 0));
-      break;
-    case EXTERNAL_PIXEL_ELEMENTS:
-    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
-      __ srl(t2, key, 1);
-      __ addu(t3, a3, t2);
-      __ lbu(value, MemOperand(t3, 0));
-      break;
-    case EXTERNAL_SHORT_ELEMENTS:
-      __ addu(t3, a3, key);
-      __ lh(value, MemOperand(t3, 0));
-      break;
-    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-      __ addu(t3, a3, key);
-      __ lhu(value, MemOperand(t3, 0));
-      break;
-    case EXTERNAL_INT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
-      __ sll(t2, key, 1);
-      __ addu(t3, a3, t2);
-      __ lw(value, MemOperand(t3, 0));
-      break;
-    case EXTERNAL_FLOAT_ELEMENTS:
-      __ sll(t3, t2, 2);
-      __ addu(t3, a3, t3);
-      if (CpuFeatures::IsSupported(FPU)) {
-        CpuFeatures::Scope scope(FPU);
-        __ lwc1(f0, MemOperand(t3, 0));
-      } else {
-        __ lw(value, MemOperand(t3, 0));
-      }
-      break;
-    case EXTERNAL_DOUBLE_ELEMENTS:
-      __ sll(t2, key, 2);
-      __ addu(t3, a3, t2);
-      if (CpuFeatures::IsSupported(FPU)) {
-        CpuFeatures::Scope scope(FPU);
-        __ ldc1(f0, MemOperand(t3, 0));
-      } else {
-        // t3: pointer to the beginning of the double we want to load.
-        __ lw(a2, MemOperand(t3, 0));
-        __ lw(a3, MemOperand(t3, Register::kSizeInBytes));
-      }
-      break;
-    case FAST_ELEMENTS:
-    case FAST_SMI_ELEMENTS:
-    case FAST_DOUBLE_ELEMENTS:
-    case FAST_HOLEY_ELEMENTS:
-    case FAST_HOLEY_SMI_ELEMENTS:
-    case FAST_HOLEY_DOUBLE_ELEMENTS:
-    case DICTIONARY_ELEMENTS:
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
-      UNREACHABLE();
-      break;
-  }
-
-  // For integer array types:
-  // a2: value
-  // For float array type:
-  // f0: value (if FPU is supported)
-  // a2: value (if FPU is not supported)
-  // For double array type:
-  // f0: value (if FPU is supported)
-  // a2/a3: value (if FPU is not supported)
-
-  if (elements_kind == EXTERNAL_INT_ELEMENTS) {
-    // For the Int and UnsignedInt array types, we need to see whether
-    // the value can be represented in a Smi. If not, we need to convert
-    // it to a HeapNumber.
-    Label box_int;
-    __ Subu(t3, value, Operand(0xC0000000));  // Non-smi value gives neg result.
-    __ Branch(&box_int, lt, t3, Operand(zero_reg));
-    // Tag integer as smi and return it.
-    __ sll(v0, value, kSmiTagSize);
-    __ Ret();
-
-    __ bind(&box_int);
-
-    if (CpuFeatures::IsSupported(FPU)) {
-      CpuFeatures::Scope scope(FPU);
-      // Allocate a HeapNumber for the result and perform int-to-double
-      // conversion.
-      // The arm version uses a temporary here to save r0, but we don't need to
-      // (a0 is not modified).
-      __ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(v0, a3, t0, t1, &slow, DONT_TAG_RESULT);
-      __ mtc1(value, f0);
-      __ cvt_d_w(f0, f0);
-      __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
-      __ Addu(v0, v0, kHeapObjectTag);
-      __ Ret();
-    } else {
-      // Allocate a HeapNumber for the result and perform int-to-double
-      // conversion.
-      // The arm version uses a temporary here to save r0, but we don't need to
-      // (a0 is not modified).
-      __ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(v0, a3, t0, t1, &slow, TAG_RESULT);
-      Register dst_mantissa = t2;
-      Register dst_exponent = t3;
-      FloatingPointHelper::Destination dest =
-          FloatingPointHelper::kCoreRegisters;
-      FloatingPointHelper::ConvertIntToDouble(masm,
-                                              value,
-                                              dest,
-                                              f0,
-                                              dst_mantissa,
-                                              dst_exponent,
-                                              t1,
-                                              f2);
-      __ sw(dst_mantissa, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
-      __ sw(dst_exponent, FieldMemOperand(v0, HeapNumber::kExponentOffset));
-      __ Ret();
-    }
-  } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
-    // The test is different for unsigned int values. Since we need
-    // the value to be in the range of a positive smi, we can't
-    // handle either of the top two bits being set in the value.
-    if (CpuFeatures::IsSupported(FPU)) {
-      CpuFeatures::Scope scope(FPU);
-      Label pl_box_int;
-      __ And(t2, value, Operand(0xC0000000));
-      __ Branch(&pl_box_int, ne, t2, Operand(zero_reg));
-
-      // It can fit in an Smi.
-      // Tag integer as smi and return it.
-      __ sll(v0, value, kSmiTagSize);
-      __ Ret();
-
-      __ bind(&pl_box_int);
-      // Allocate a HeapNumber for the result and perform int-to-double
-      // conversion. Don't use a0 and a1 as AllocateHeapNumber clobbers all
-      // registers - also when jumping due to exhausted young space.
-      __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(v0, t2, t3, t6, &slow, DONT_TAG_RESULT);
-
-      // This is replaced by a macro:
-      // __ mtc1(value, f0);     // LS 32-bits.
-      // __ mtc1(zero_reg, f1);  // MS 32-bits are all zero.
-      // __ cvt_d_l(f0, f0); // Use 64 bit conv to get correct unsigned 32-bit.
-
-      __ Cvt_d_uw(f0, value, f22);
-
-      __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
-
-      __ Addu(v0, v0, kHeapObjectTag);
-      __ Ret();
-    } else {
-      // Check whether unsigned integer fits into smi.
-      Label box_int_0, box_int_1, done;
-      __ And(t2, value, Operand(0x80000000));
-      __ Branch(&box_int_0, ne, t2, Operand(zero_reg));
-      __ And(t2, value, Operand(0x40000000));
-      __ Branch(&box_int_1, ne, t2, Operand(zero_reg));
-
-      // Tag integer as smi and return it.
-      __ sll(v0, value, kSmiTagSize);
-      __ Ret();
-
-      Register hiword = value;  // a2.
-      Register loword = a3;
-
-      __ bind(&box_int_0);
-      // Integer does not have leading zeros.
-      GenerateUInt2Double(masm, hiword, loword, t0, 0);
-      __ Branch(&done);
-
-      __ bind(&box_int_1);
-      // Integer has one leading zero.
-      GenerateUInt2Double(masm, hiword, loword, t0, 1);
-
-
-      __ bind(&done);
-      // Integer was converted to double in registers hiword:loword.
-      // Wrap it into a HeapNumber. Don't use a0 and a1 as AllocateHeapNumber
-      // clobbers all registers - also when jumping due to exhausted young
-      // space.
-      __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(t2, t3, t5, t6, &slow, TAG_RESULT);
-
-      __ sw(hiword, FieldMemOperand(t2, HeapNumber::kExponentOffset));
-      __ sw(loword, FieldMemOperand(t2, HeapNumber::kMantissaOffset));
-
-      __ mov(v0, t2);
-      __ Ret();
-    }
-  } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
-    // For the floating-point array type, we need to always allocate a
-    // HeapNumber.
-    if (CpuFeatures::IsSupported(FPU)) {
-      CpuFeatures::Scope scope(FPU);
-      // Allocate a HeapNumber for the result. Don't use a0 and a1 as
-      // AllocateHeapNumber clobbers all registers - also when jumping due to
-      // exhausted young space.
-      __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(v0, t3, t5, t6, &slow, DONT_TAG_RESULT);
-      // The float (single) value is already in fpu reg f0 (if we use float).
-      __ cvt_d_s(f0, f0);
-      __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
-
-      __ Addu(v0, v0, kHeapObjectTag);
-      __ Ret();
-    } else {
-      // Allocate a HeapNumber for the result. Don't use a0 and a1 as
-      // AllocateHeapNumber clobbers all registers - also when jumping due to
-      // exhausted young space.
-      __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(v0, t3, t5, t6, &slow, TAG_RESULT);
-      // FPU is not available, do manual single to double conversion.
-
-      // a2: floating point value (binary32).
-      // v0: heap number for result
-
-      // Extract mantissa to t4.
-      __ And(t4, value, Operand(kBinary32MantissaMask));
-
-      // Extract exponent to t5.
-      __ srl(t5, value, kBinary32MantissaBits);
-      __ And(t5, t5, Operand(kBinary32ExponentMask >> kBinary32MantissaBits));
-
-      Label exponent_rebiased;
-      __ Branch(&exponent_rebiased, eq, t5, Operand(zero_reg));
-
-      __ li(t0, 0x7ff);
-      __ Xor(t1, t5, Operand(0xFF));
-      __ Movz(t5, t0, t1);  // Set t5 to 0x7ff only if t5 is equal to 0xff.
-      __ Branch(&exponent_rebiased, eq, t1, Operand(zero_reg));
-
-      // Rebias exponent.
-      __ Addu(t5,
-              t5,
-              Operand(-kBinary32ExponentBias + HeapNumber::kExponentBias));
-
-      __ bind(&exponent_rebiased);
-      __ And(a2, value, Operand(kBinary32SignMask));
-      value = no_reg;
-      __ sll(t0, t5, HeapNumber::kMantissaBitsInTopWord);
-      __ or_(a2, a2, t0);
-
-      // Shift mantissa.
-      static const int kMantissaShiftForHiWord =
-          kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
-
-      static const int kMantissaShiftForLoWord =
-          kBitsPerInt - kMantissaShiftForHiWord;
-
-      __ srl(t0, t4, kMantissaShiftForHiWord);
-      __ or_(a2, a2, t0);
-      __ sll(a0, t4, kMantissaShiftForLoWord);
-
-      __ sw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
-      __ sw(a0, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
-      __ Ret();
-    }
-
-  } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
-    if (CpuFeatures::IsSupported(FPU)) {
-      CpuFeatures::Scope scope(FPU);
-      // Allocate a HeapNumber for the result. Don't use a0 and a1 as
-      // AllocateHeapNumber clobbers all registers - also when jumping due to
-      // exhausted young space.
-      __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(v0, t3, t5, t6, &slow, DONT_TAG_RESULT);
-      // The double value is already in f0
-      __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
-
-      __ Addu(v0, v0, kHeapObjectTag);
-      __ Ret();
-    } else {
-      // Allocate a HeapNumber for the result. Don't use a0 and a1 as
-      // AllocateHeapNumber clobbers all registers - also when jumping due to
-      // exhausted young space.
-      __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
-      __ AllocateHeapNumber(v0, t3, t5, t6, &slow, TAG_RESULT);
-
-      __ sw(a2, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
-      __ sw(a3, FieldMemOperand(v0, HeapNumber::kExponentOffset));
-      __ Ret();
-    }
-
-  } else {
-    // Tag integer as smi and return it.
-    __ sll(v0, value, kSmiTagSize);
-    __ Ret();
-  }
-
-  // Slow case, key and receiver still in a0 and a1.
-  __ bind(&slow);
-  __ IncrementCounter(
-      masm->isolate()->counters()->keyed_load_external_array_slow(),
-      1, a2, a3);
-
-  // ---------- S t a t e --------------
-  //  -- ra     : return address
-  //  -- a0     : key
-  //  -- a1     : receiver
-  // -----------------------------------
-
-  __ Push(a1, a0);
-
-  __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
-
-  __ bind(&miss_force_generic);
-  Handle<Code> stub =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ Jump(stub, RelocInfo::CODE_TARGET);
-}
-
-
 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
     MacroAssembler* masm,
     ElementsKind elements_kind) {
@@ -4478,115 +4097,6 @@
 }
 
 
-void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- ra    : return address
-  //  -- a0    : key
-  //  -- a1    : receiver
-  // -----------------------------------
-  Label miss_force_generic;
-
-  // This stub is meant to be tail-jumped to, the receiver must already
-  // have been verified by the caller to not be a smi.
-
-  // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, a0, t0, t1, f2, f4, &miss_force_generic);
-
-  // Get the elements array.
-  __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset));
-  __ AssertFastElements(a2);
-
-  // Check that the key is within bounds.
-  __ lw(a3, FieldMemOperand(a2, FixedArray::kLengthOffset));
-  __ Branch(USE_DELAY_SLOT, &miss_force_generic, hs, a0, Operand(a3));
-
-  // Load the result and make sure it's not the hole.
-  __ Addu(a3, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
-  __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize);
-  __ Addu(t0, t0, a3);
-  __ lw(t0, MemOperand(t0));
-  __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
-  __ Branch(&miss_force_generic, eq, t0, Operand(t1));
-  __ Ret(USE_DELAY_SLOT);
-  __ mov(v0, t0);
-
-  __ bind(&miss_force_generic);
-  Handle<Code> stub =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ Jump(stub, RelocInfo::CODE_TARGET);
-}
-
-
-void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
-    MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- ra    : return address
-  //  -- a0    : key
-  //  -- a1    : receiver
-  // -----------------------------------
-  Label miss_force_generic, slow_allocate_heapnumber;
-
-  Register key_reg = a0;
-  Register receiver_reg = a1;
-  Register elements_reg = a2;
-  Register heap_number_reg = a2;
-  Register indexed_double_offset = a3;
-  Register scratch = t0;
-  Register scratch2 = t1;
-  Register scratch3 = t2;
-  Register heap_number_map = t3;
-
-  // This stub is meant to be tail-jumped to, the receiver must already
-  // have been verified by the caller to not be a smi.
-
-  // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic);
-
-  // Get the elements array.
-  __ lw(elements_reg,
-        FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
-
-  // Check that the key is within bounds.
-  __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
-  __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch));
-
-  // Load the upper word of the double in the fixed array and test for NaN.
-  __ sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize);
-  __ Addu(indexed_double_offset, elements_reg, Operand(scratch2));
-  uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32);
-  __ lw(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset));
-  __ Branch(&miss_force_generic, eq, scratch, Operand(kHoleNanUpper32));
-
-  // Non-NaN. Allocate a new heap number and copy the double value into it.
-  __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
-  __ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
-                        heap_number_map, &slow_allocate_heapnumber, TAG_RESULT);
-
-  // Don't need to reload the upper 32 bits of the double, it's already in
-  // scratch.
-  __ sw(scratch, FieldMemOperand(heap_number_reg,
-                                 HeapNumber::kExponentOffset));
-  __ lw(scratch, FieldMemOperand(indexed_double_offset,
-                                 FixedArray::kHeaderSize));
-  __ sw(scratch, FieldMemOperand(heap_number_reg,
-                                 HeapNumber::kMantissaOffset));
-
-  __ mov(v0, heap_number_reg);
-  __ Ret();
-
-  __ bind(&slow_allocate_heapnumber);
-  Handle<Code> slow_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_Slow();
-  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
-
-  __ bind(&miss_force_generic);
-  Handle<Code> miss_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
-}
-
-
 void KeyedStoreStubCompiler::GenerateStoreFastElement(
     MacroAssembler* masm,
     bool is_js_array,
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 5045e1e..e99c45b 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -473,7 +473,9 @@
 
 
 void SeqOneByteString::SeqOneByteStringVerify() {
-  CHECK(String::IsAscii(GetChars(), length()));
+#ifndef ENABLE_LATIN_1
+  CHECK(!HasOnlyAsciiChars() || String::IsAscii(GetChars(), length()));
+#endif
 }
 
 
@@ -774,6 +776,13 @@
 }
 
 
+void AllocationSiteInfo::AllocationSiteInfoVerify() {
+  CHECK(IsAllocationSiteInfo());
+  VerifyHeapPointer(payload());
+  CHECK(payload()->IsObject());
+}
+
+
 void Script::ScriptVerify() {
   CHECK(IsScript());
   VerifyPointer(source());
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 89623bd..658214a 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -345,6 +345,11 @@
 }
 
 
+bool String::IsOneByteConvertible() {
+  return HasOnlyAsciiChars() || IsOneByteRepresentation();
+}
+
+
 bool StringShape::IsCons() {
   return (type_ & kStringRepresentationMask) == kConsStringTag;
 }
@@ -1038,8 +1043,8 @@
 }
 
 
-Failure* Failure::OutOfMemoryException() {
-  return Construct(OUT_OF_MEMORY_EXCEPTION);
+Failure* Failure::OutOfMemoryException(intptr_t value) {
+  return Construct(OUT_OF_MEMORY_EXCEPTION, value);
 }
 
 
@@ -1734,7 +1739,7 @@
   if (!js_value->value()->IsString()) return false;
 
   String* str = String::cast(js_value->value());
-  if (index >= (uint32_t)str->length()) return false;
+  if (index >= static_cast<uint32_t>(str->length())) return false;
 
   return true;
 }
@@ -2546,31 +2551,26 @@
     switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
       case kSeqStringTag | kOneByteStringTag:
         visitor.VisitOneByteString(
-            reinterpret_cast<const uint8_t*>(
-                SeqOneByteString::cast(string)->GetChars()) + slice_offset,
-                length - offset);
+            SeqOneByteString::cast(string)->GetChars() + slice_offset,
+            length - offset);
         return;
 
       case kSeqStringTag | kTwoByteStringTag:
         visitor.VisitTwoByteString(
-            reinterpret_cast<const uint16_t*>(
-                SeqTwoByteString::cast(string)->GetChars()) + slice_offset,
-                length - offset);
+            SeqTwoByteString::cast(string)->GetChars() + slice_offset,
+            length - offset);
         return;
 
       case kExternalStringTag | kOneByteStringTag:
         visitor.VisitOneByteString(
-            reinterpret_cast<const uint8_t*>(
-                ExternalAsciiString::cast(string)->GetChars()) + slice_offset,
-                length - offset);
+            ExternalAsciiString::cast(string)->GetChars() + slice_offset,
+            length - offset);
         return;
 
       case kExternalStringTag | kTwoByteStringTag:
         visitor.VisitTwoByteString(
-            reinterpret_cast<const uint16_t*>(
-                ExternalTwoByteString::cast(string)->GetChars())
-                    + slice_offset,
-                length - offset);
+            ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
+            length - offset);
         return;
 
       case kSlicedStringTag | kOneByteStringTag:
@@ -2605,7 +2605,7 @@
 
 
 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
-  ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
+  ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
                    static_cast<byte>(value));
 }
@@ -2616,8 +2616,8 @@
 }
 
 
-char* SeqOneByteString::GetChars() {
-  return reinterpret_cast<char*>(GetCharsAddress());
+uint8_t* SeqOneByteString::GetChars() {
+  return reinterpret_cast<uint8_t*>(GetCharsAddress());
 }
 
 
@@ -2727,8 +2727,8 @@
 }
 
 
-const char* ExternalAsciiString::GetChars() {
-  return resource()->data();
+const uint8_t* ExternalAsciiString::GetChars() {
+  return reinterpret_cast<const uint8_t*>(resource()->data());
 }
 
 
@@ -4064,6 +4064,8 @@
 
 ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
 
+ACCESSORS(AllocationSiteInfo, payload, Object, kPayloadOffset)
+
 ACCESSORS(Script, source, Object, kSourceOffset)
 ACCESSORS(Script, name, Object, kNameOffset)
 ACCESSORS(Script, id, Object, kIdOffset)
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 9a1a58e..c88de21 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -1002,6 +1002,22 @@
 }
 
 
+void AllocationSiteInfo::AllocationSiteInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "AllocationSiteInfo");
+  PrintF(out, " - payload: ");
+  if (payload()->IsJSArray()) {
+    PrintF(out, "Array literal ");
+    payload()->ShortPrint(out);
+    PrintF(out, "\n");
+    return;
+  }
+
+  PrintF(out, "unknown payload ");
+  payload()->ShortPrint(out);
+  PrintF(out, "\n");
+}
+
+
 void Script::ScriptPrint(FILE* out) {
   HeapObject::PrintHeader(out, "Script");
   PrintF(out, "\n - source: ");
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
index 925b256..309cddf 100644
--- a/src/objects-visiting-inl.h
+++ b/src/objects-visiting-inl.h
@@ -211,7 +211,8 @@
   // when they might be keeping a Context alive, or when the heap is about
   // to be serialized.
   if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
-      && (target->ic_state() == MEGAMORPHIC || heap->flush_monomorphic_ics() ||
+      && (target->ic_state() == MEGAMORPHIC ||
+          target->ic_state() == POLYMORPHIC || heap->flush_monomorphic_ics() ||
           Serializer::enabled() || target->ic_age() != heap->global_ic_age())) {
     IC::Clear(rinfo->pc());
     target = Code::GetCodeFromTargetAddress(rinfo->target_address());
diff --git a/src/objects.cc b/src/objects.cc
index a97590a..2d8626b 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -903,7 +903,7 @@
         result = String::cast(object);
         String* first = cs->first();
         int first_length = first->length();
-        char* dest = SeqOneByteString::cast(result)->GetChars();
+        uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
         WriteToFlat(first, dest, 0, first_length);
         String* second = cs->second();
         WriteToFlat(second,
@@ -6561,13 +6561,13 @@
            shape.representation_tag() != kSlicedStringTag);
   }
   if (shape.encoding_tag() == kOneByteStringTag) {
-    const char* start;
+    const uint8_t* start;
     if (shape.representation_tag() == kSeqStringTag) {
       start = SeqOneByteString::cast(string)->GetChars();
     } else {
       start = ExternalAsciiString::cast(string)->GetChars();
     }
-    return FlatContent(Vector<const char>(start + offset, length));
+    return FlatContent(Vector<const uint8_t>(start + offset, length));
   } else {
     ASSERT(shape.encoding_tag() == kTwoByteStringTag);
     const uc16* start;
@@ -6770,7 +6770,7 @@
   ASSERT(content.IsFlat());
   is_ascii_ = content.IsAscii();
   if (is_ascii_) {
-    start_ = content.ToAsciiVector().start();
+    start_ = content.ToOneByteVector().start();
   } else {
     start_ = content.ToUC16Vector().start();
   }
@@ -6878,7 +6878,7 @@
     if ((type & kStringRepresentationMask) != kConsStringTag) {
       // Pop stack so next iteration is in correct place.
       Pop();
-      unsigned length = (unsigned) string->length();
+      unsigned length = static_cast<unsigned>(string->length());
       // Could be a flattened ConsString.
       if (length == 0) continue;
       *length_out = length;
@@ -6896,7 +6896,7 @@
       type = string->map()->instance_type();
       if ((type & kStringRepresentationMask) != kConsStringTag) {
         AdjustMaximumDepth();
-        unsigned length = (unsigned) string->length();
+        unsigned length = static_cast<unsigned>(string->length());
         ASSERT(length != 0);
         *length_out = length;
         *type_out = type;
@@ -7254,8 +7254,8 @@
   // TODO(dcarney): Compare all types of flat strings with a Visitor.
   if (StringShape(lhs).IsSequentialAscii() &&
       StringShape(rhs).IsSequentialAscii()) {
-    const char* str1 = SeqOneByteString::cast(lhs)->GetChars();
-    const char* str2 = SeqOneByteString::cast(rhs)->GetChars();
+    const uint8_t* str1 = SeqOneByteString::cast(lhs)->GetChars();
+    const uint8_t* str2 = SeqOneByteString::cast(rhs)->GetChars();
     return CompareRawStringContents(str1, str2, len);
   }
 
@@ -7284,7 +7284,7 @@
 }
 
 
-bool String::IsEqualTo(Vector<const char> str) {
+bool String::IsUtf8EqualTo(Vector<const char> str) {
   int slen = length();
   // Can't check exact length equality, but we can check bounds.
   int str_len = str.length();
@@ -7313,12 +7313,12 @@
 }
 
 
-bool String::IsAsciiEqualTo(Vector<const char> str) {
+bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
   int slen = length();
   if (str.length() != slen) return false;
   FlatContent content = GetFlatContent();
   if (content.IsAscii()) {
-    return CompareChars(content.ToAsciiVector().start(),
+    return CompareChars(content.ToOneByteVector().start(),
                         str.start(), slen) == 0;
   }
   for (int i = 0; i < slen; i++) {
@@ -7483,6 +7483,31 @@
 }
 
 
+AllocationSiteInfo* AllocationSiteInfo::FindForJSObject(JSObject* object) {
+  // Currently, AllocationSiteInfo objects are only allocated immediately
+  // after JSArrays in NewSpace, and detecting whether a JSArray has one
+  // involves carefully checking the object immediately after the JSArray
+  // (if there is one) to see if it's an AllocationSiteInfo.
+  if (FLAG_track_allocation_sites && object->GetHeap()->InNewSpace(object)) {
+    Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) +
+        object->Size();
+    if ((ptr_end + AllocationSiteInfo::kSize) <=
+        object->GetHeap()->NewSpaceTop()) {
+      // There is room in newspace for allocation info. Do we have some?
+      Map** possible_allocation_site_info_map =
+          reinterpret_cast<Map**>(ptr_end);
+      if (*possible_allocation_site_info_map ==
+          object->GetHeap()->allocation_site_info_map()) {
+        AllocationSiteInfo* info = AllocationSiteInfo::cast(
+            reinterpret_cast<Object*>(ptr_end + 1));
+        return info;
+      }
+    }
+  }
+  return NULL;
+}
+
+
 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
   // For array indexes mix the length into the hash as an array index could
   // be zero.
@@ -9009,6 +9034,7 @@
     case PREMONOMORPHIC: return "PREMONOMORPHIC";
     case MONOMORPHIC: return "MONOMORPHIC";
     case MONOMORPHIC_PROTOTYPE_FAILURE: return "MONOMORPHIC_PROTOTYPE_FAILURE";
+    case POLYMORPHIC: return "POLYMORPHIC";
     case MEGAMORPHIC: return "MEGAMORPHIC";
     case DEBUG_BREAK: return "DEBUG_BREAK";
     case DEBUG_PREPARE_STEP_IN: return "DEBUG_PREPARE_STEP_IN";
@@ -9829,6 +9855,14 @@
   }
   // Convert to fast double elements if appropriate.
   if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) {
+    // Consider fixing the boilerplate as well if we have one.
+    ElementsKind to_kind = IsHoleyElementsKind(elements_kind)
+        ? FAST_HOLEY_DOUBLE_ELEMENTS
+        : FAST_DOUBLE_ELEMENTS;
+
+    MaybeObject* trans = PossiblyTransitionArrayBoilerplate(to_kind);
+    if (trans->IsFailure()) return trans;
+
     MaybeObject* maybe =
         SetFastDoubleElementsCapacityAndLength(new_capacity, array_length);
     if (maybe->IsFailure()) return maybe;
@@ -10370,6 +10404,25 @@
 }
 
 
+MaybeObject* JSObject::PossiblyTransitionArrayBoilerplate(
+    ElementsKind to_kind) {
+  MaybeObject* ret = NULL;
+  if (IsJSArray()) {
+    AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this);
+    if (info != NULL) {
+      JSObject* payload = JSObject::cast(info->payload());
+      if (payload->GetElementsKind() != to_kind) {
+        if (IsMoreGeneralElementsKindTransition(payload->GetElementsKind(),
+                                                to_kind)) {
+          ret = payload->TransitionElementsKind(to_kind);
+        }
+      }
+    }
+  }
+  return ret;
+}
+
+
 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
   ASSERT(!map()->is_observed());
   ElementsKind from_kind = map()->elements_kind();
@@ -10380,6 +10433,9 @@
 
   if (from_kind == to_kind) return this;
 
+  MaybeObject* trans = PossiblyTransitionArrayBoilerplate(to_kind);
+  if (trans->IsFailure()) return trans;
+
   Isolate* isolate = GetIsolate();
   if (elements() == isolate->heap()->empty_fixed_array() ||
       (IsFastSmiOrObjectElementsKind(from_kind) &&
@@ -11387,7 +11443,7 @@
       : string_(string), hash_field_(0), seed_(seed) { }
 
   bool IsMatch(Object* string) {
-    return String::cast(string)->IsEqualTo(string_);
+    return String::cast(string)->IsUtf8EqualTo(string_);
   }
 
   uint32_t Hash() {
@@ -11404,7 +11460,7 @@
 
   MaybeObject* AsObject() {
     if (hash_field_ == 0) Hash();
-    return Isolate::Current()->heap()->AllocateSymbol(
+    return Isolate::Current()->heap()->AllocateSymbolFromUtf8(
         string_, chars_, hash_field_);
   }
 
@@ -11443,25 +11499,25 @@
 
 
 
-class AsciiSymbolKey : public SequentialSymbolKey<char> {
+class OneByteSymbolKey : public SequentialSymbolKey<uint8_t> {
  public:
-  AsciiSymbolKey(Vector<const char> str, uint32_t seed)
-      : SequentialSymbolKey<char>(str, seed) { }
+  OneByteSymbolKey(Vector<const uint8_t> str, uint32_t seed)
+      : SequentialSymbolKey<uint8_t>(str, seed) { }
 
   bool IsMatch(Object* string) {
-    return String::cast(string)->IsAsciiEqualTo(string_);
+    return String::cast(string)->IsOneByteEqualTo(string_);
   }
 
   MaybeObject* AsObject() {
     if (hash_field_ == 0) Hash();
-    return HEAP->AllocateAsciiSymbol(string_, hash_field_);
+    return HEAP->AllocateOneByteSymbol(string_, hash_field_);
   }
 };
 
 
-class SubStringAsciiSymbolKey : public HashTableKey {
+class SubStringOneByteSymbolKey : public HashTableKey {
  public:
-  explicit SubStringAsciiSymbolKey(Handle<SeqOneByteString> string,
+  explicit SubStringOneByteSymbolKey(Handle<SeqOneByteString> string,
                                    int from,
                                    int length)
       : string_(string), from_(from), length_(length) { }
@@ -11469,7 +11525,7 @@
   uint32_t Hash() {
     ASSERT(length_ >= 0);
     ASSERT(from_ + length_ <= string_->length());
-    char* chars = string_->GetChars() + from_;
+    uint8_t* chars = string_->GetChars() + from_;
     hash_field_ = StringHasher::HashSequentialString(
         chars, length_, string_->GetHeap()->HashSeed());
     uint32_t result = hash_field_ >> String::kHashShift;
@@ -11483,14 +11539,14 @@
   }
 
   bool IsMatch(Object* string) {
-    Vector<const char> chars(string_->GetChars() + from_, length_);
-    return String::cast(string)->IsAsciiEqualTo(chars);
+    Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
+    return String::cast(string)->IsOneByteEqualTo(chars);
   }
 
   MaybeObject* AsObject() {
     if (hash_field_ == 0) Hash();
-    Vector<const char> chars(string_->GetChars() + from_, length_);
-    return HEAP->AllocateAsciiSymbol(chars, hash_field_);
+    Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
+    return HEAP->AllocateOneByteSymbol(chars, hash_field_);
   }
 
  private:
@@ -11582,7 +11638,7 @@
                      ? at_least_space_for
                      : ComputeCapacity(at_least_space_for);
   if (capacity > HashTable::kMaxCapacity) {
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x10);
   }
 
   Object* obj;
@@ -11896,8 +11952,9 @@
       ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
       Object* value = dict->ValueAt(i);
       PropertyDetails details = dict->DetailsAt(i);
-      if (details.type() == CALLBACKS) {
+      if (details.type() == CALLBACKS || details.IsReadOnly()) {
         // Bail out and do the sorting of undefineds and array holes in JS.
+        // Also bail out if the element is not supposed to be moved.
         return Smi::FromInt(-1);
       }
       uint32_t key = NumberToUint32(k);
@@ -12410,9 +12467,9 @@
 }
 
 
-MaybeObject* SymbolTable::LookupOneByteSymbol(Vector<const char> str,
+MaybeObject* SymbolTable::LookupOneByteSymbol(Vector<const uint8_t> str,
                                               Object** s) {
-  AsciiSymbolKey key(str, GetHeap()->HashSeed());
+  OneByteSymbolKey key(str, GetHeap()->HashSeed());
   return LookupKey(&key, s);
 }
 
@@ -12422,7 +12479,7 @@
     int from,
     int length,
     Object** s) {
-  SubStringAsciiSymbolKey key(str, from, length);
+  SubStringOneByteSymbolKey key(str, from, length);
   return LookupKey(&key, s);
 }
 
diff --git a/src/objects.h b/src/objects.h
index f1fa27a..79f1f1d 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -291,6 +291,7 @@
   V(OBJECT_TEMPLATE_INFO_TYPE)                                                 \
   V(SIGNATURE_INFO_TYPE)                                                       \
   V(TYPE_SWITCH_INFO_TYPE)                                                     \
+  V(ALLOCATION_SITE_INFO_TYPE)                                                 \
   V(SCRIPT_TYPE)                                                               \
   V(CODE_CACHE_TYPE)                                                           \
   V(POLYMORPHIC_CODE_CACHE_TYPE)                                               \
@@ -444,6 +445,7 @@
   V(SIGNATURE_INFO, SignatureInfo, signature_info)                             \
   V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info)                        \
   V(SCRIPT, Script, script)                                                    \
+  V(ALLOCATION_SITE_INFO, AllocationSiteInfo, allocation_site_info)            \
   V(CODE_CACHE, CodeCache, code_cache)                                         \
   V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache)      \
   V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info)                  \
@@ -606,6 +608,7 @@
   OBJECT_TEMPLATE_INFO_TYPE,
   SIGNATURE_INFO_TYPE,
   TYPE_SWITCH_INFO_TYPE,
+  ALLOCATION_SITE_INFO_TYPE,
   SCRIPT_TYPE,
   CODE_CACHE_TYPE,
   POLYMORPHIC_CODE_CACHE_TYPE,
@@ -1141,7 +1144,9 @@
   static inline Failure* RetryAfterGC();  // NEW_SPACE
   static inline Failure* Exception();
   static inline Failure* InternalError();
-  static inline Failure* OutOfMemoryException();
+  // TODO(jkummerow): The value is temporary instrumentation. Remove it
+  // when it has served its purpose.
+  static inline Failure* OutOfMemoryException(intptr_t value);
   // Casting.
   static inline Failure* cast(MaybeObject* object);
 
@@ -2012,6 +2017,8 @@
                                                ElementsKind to_kind);
 
   MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
+  MUST_USE_RESULT MaybeObject* PossiblyTransitionArrayBoilerplate(
+      ElementsKind to_kind);
 
   // Replaces an existing transition with a transition to a map with a FIELD.
   MUST_USE_RESULT MaybeObject* ConvertTransitionToMapTransition(
@@ -3028,7 +3035,7 @@
   // pointer *s is set to the symbol found.
   MUST_USE_RESULT MaybeObject* LookupUtf8Symbol(Vector<const char> str,
                                                 Object** s);
-  MUST_USE_RESULT MaybeObject* LookupOneByteSymbol(Vector<const char> str,
+  MUST_USE_RESULT MaybeObject* LookupOneByteSymbol(Vector<const uint8_t> str,
                                                    Object** s);
   MUST_USE_RESULT MaybeObject* LookupSubStringOneByteSymbol(
       Handle<SeqOneByteString> str,
@@ -6897,6 +6904,32 @@
 };
 
 
+enum AllocationSiteInfoMode {
+  DONT_TRACK_ALLOCATION_SITE_INFO,
+  TRACK_ALLOCATION_SITE_INFO
+};
+
+
+class AllocationSiteInfo: public Struct {
+ public:
+  DECL_ACCESSORS(payload, Object)
+
+  static inline AllocationSiteInfo* cast(Object* obj);
+
+  DECLARE_PRINTER(AllocationSiteInfo)
+  DECLARE_VERIFIER(AllocationSiteInfo)
+
+  // Returns NULL if no AllocationSiteInfo is available for object.
+  static AllocationSiteInfo* FindForJSObject(JSObject* object);
+
+  static const int kPayloadOffset = HeapObject::kHeaderSize;
+  static const int kSize = kPayloadOffset + kPointerSize;
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSiteInfo);
+};
+
+
 // Representation of a slow alias as part of a non-strict arguments objects.
 // For fast aliases (if HasNonStrictArgumentsElements()):
 // - the parameter map contains an index into the context
@@ -7057,11 +7090,11 @@
     // Returns true if the structure contains two-byte content.
     bool IsTwoByte() { return state_ == TWO_BYTE; }
 
-    // Return the ASCII content of the string. Only use if IsAscii() returns
+    // Return the one byte content of the string. Only use if IsAscii() returns
     // true.
-    Vector<const char> ToAsciiVector() {
+    Vector<const uint8_t> ToOneByteVector() {
       ASSERT_EQ(ASCII, state_);
-      return Vector<const char>::cast(buffer_);
+      return buffer_;
     }
     // Return the two-byte content of the string. Only use if IsTwoByte()
     // returns true.
@@ -7074,15 +7107,15 @@
     enum State { NON_FLAT, ASCII, TWO_BYTE };
 
     // Constructors only used by String::GetFlatContent().
-    explicit FlatContent(Vector<const char> chars)
-        : buffer_(Vector<const byte>::cast(chars)),
+    explicit FlatContent(Vector<const uint8_t> chars)
+        : buffer_(chars),
           state_(ASCII) { }
     explicit FlatContent(Vector<const uc16> chars)
         : buffer_(Vector<const byte>::cast(chars)),
           state_(TWO_BYTE) { }
     FlatContent() : buffer_(), state_(NON_FLAT) { }
 
-    Vector<const byte> buffer_;
+    Vector<const uint8_t> buffer_;
     State state_;
 
     friend class String;
@@ -7113,6 +7146,8 @@
   // possible.
   inline bool HasOnlyAsciiChars();
 
+  inline bool IsOneByteConvertible();
+
   // Get and set individual two byte chars in the string.
   inline void Set(int index, uint16_t value);
   // Get individual two byte char in the string.  Repeated calls
@@ -7163,8 +7198,8 @@
 
   // String equality operations.
   inline bool Equals(String* other);
-  bool IsEqualTo(Vector<const char> str);
-  bool IsAsciiEqualTo(Vector<const char> str);
+  bool IsUtf8EqualTo(Vector<const char> str);
+  bool IsOneByteEqualTo(Vector<const uint8_t> str);
   bool IsTwoByteEqualTo(Vector<const uc16> str);
 
   // Return a UTF8 representation of the string.  The string is null
@@ -7240,9 +7275,9 @@
   // value into an array index.
   static const int kMaxArrayIndexSize = 10;
 
-  // Max ASCII char code.
-  static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar;
-  static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar;
+  // Max char codes.
+  static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
+  static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
   static const int kMaxUtf16CodeUnit = 0xffff;
 
   // Mask constant for checking if a string has a computed hash code
@@ -7327,7 +7362,7 @@
     const char* start = chars;
     const char* limit = chars + length;
 #ifdef V8_HOST_CAN_READ_UNALIGNED
-    ASSERT(kMaxAsciiCharCode == 0x7F);
+    ASSERT(unibrow::Utf8::kMaxOneByteChar == 0x7F);
     const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
     while (chars + sizeof(uintptr_t) <= limit) {
       if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
@@ -7337,7 +7372,7 @@
     }
 #endif
     while (chars < limit) {
-      if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) {
+      if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
         return static_cast<int>(chars - start);
       }
       ++chars;
@@ -7349,18 +7384,23 @@
     return NonAsciiStart(chars, length) >= length;
   }
 
-  static inline int NonAsciiStart(const uc16* chars, int length) {
+  static inline bool IsAscii(const uint8_t* chars, int length) {
+    return
+        NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
+  }
+
+  static inline int NonOneByteStart(const uc16* chars, int length) {
     const uc16* limit = chars + length;
     const uc16* start = chars;
     while (chars < limit) {
-      if (*chars > kMaxAsciiCharCodeU) return static_cast<int>(chars - start);
+      if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
       ++chars;
     }
     return static_cast<int>(chars - start);
   }
 
-  static inline bool IsAscii(const uc16* chars, int length) {
-    return NonAsciiStart(chars, length) >= length;
+  static inline bool IsOneByte(const uc16* chars, int length) {
+    return NonOneByteStart(chars, length) >= length;
   }
 
   template<class Visitor, class ConsOp>
@@ -7425,7 +7465,7 @@
   // Get the address of the characters in this string.
   inline Address GetCharsAddress();
 
-  inline char* GetChars();
+  inline uint8_t* GetChars();
 
   // Casting
   static inline SeqOneByteString* cast(Object* obj);
@@ -7638,7 +7678,7 @@
   // which the pointer cache has to be refreshed.
   inline void update_data_cache();
 
-  inline const char* GetChars();
+  inline const uint8_t* GetChars();
 
   // Dispatched behavior.
   inline uint16_t ExternalAsciiStringGet(int index);
diff --git a/src/parser.cc b/src/parser.cc
index 6365e41..f6f8462 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -255,7 +255,7 @@
       >= static_cast<unsigned>(symbol_cache_.length())) {
     if (scanner().is_literal_ascii()) {
       return isolate()->factory()->LookupOneByteSymbol(
-          scanner().literal_ascii_string());
+          Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
     } else {
       return isolate()->factory()->LookupTwoByteSymbol(
           scanner().literal_utf16_string());
@@ -276,7 +276,7 @@
   if (result.is_null()) {
     if (scanner().is_literal_ascii()) {
       result = isolate()->factory()->LookupOneByteSymbol(
-          scanner().literal_ascii_string());
+          Vector<const uint8_t>::cast(scanner().literal_ascii_string()));
     } else {
       result = isolate()->factory()->LookupTwoByteSymbol(
           scanner().literal_utf16_string());
@@ -1429,7 +1429,7 @@
     case Token::IDENTIFIER: {
       Handle<String> name = ParseIdentifier(CHECK_OK);
       // Handle 'module' as a context-sensitive keyword.
-      if (!name->IsEqualTo(CStrVector("module"))) {
+      if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) {
         names.Add(name, zone());
         while (peek() == Token::COMMA) {
           Consume(Token::COMMA);
@@ -4711,7 +4711,7 @@
   if (!*ok) return;
   Handle<String> symbol = GetSymbol(ok);
   if (!*ok) return;
-  if (!symbol->IsEqualTo(CStrVector(keyword))) {
+  if (!symbol->IsUtf8EqualTo(CStrVector(keyword))) {
     *ok = false;
     ReportUnexpectedToken(scanner().current_token());
   }
diff --git a/src/regexp-macro-assembler.cc b/src/regexp-macro-assembler.cc
index ee9347a..f73726a 100644
--- a/src/regexp-macro-assembler.cc
+++ b/src/regexp-macro-assembler.cc
@@ -80,11 +80,11 @@
   if (subject->IsOneByteRepresentation()) {
     const byte* address;
     if (StringShape(subject).IsExternal()) {
-      const char* data = ExternalAsciiString::cast(subject)->GetChars();
+      const uint8_t* data = ExternalAsciiString::cast(subject)->GetChars();
       address = reinterpret_cast<const byte*>(data);
     } else {
       ASSERT(subject->IsSeqOneByteString());
-      char* data = SeqOneByteString::cast(subject)->GetChars();
+      const uint8_t* data = SeqOneByteString::cast(subject)->GetChars();
       address = reinterpret_cast<const byte*>(data);
     }
     return address + start_index;
diff --git a/src/runtime.cc b/src/runtime.cc
index f6051ac..0b63056 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1804,25 +1804,27 @@
   result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_symbol(),
                                                     source,
                                                     final);
-  ASSERT(!result->IsFailure());
+  // TODO(jkummerow): Turn these back into ASSERTs when we can be certain
+  // that it never fires in Release mode in the wild.
+  CHECK(!result->IsFailure());
   result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_symbol(),
                                                     global,
                                                     final);
-  ASSERT(!result->IsFailure());
+  CHECK(!result->IsFailure());
   result =
       regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_symbol(),
                                                ignoreCase,
                                                final);
-  ASSERT(!result->IsFailure());
+  CHECK(!result->IsFailure());
   result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_symbol(),
                                                     multiline,
                                                     final);
-  ASSERT(!result->IsFailure());
+  CHECK(!result->IsFailure());
   result =
       regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_symbol(),
                                                Smi::FromInt(0),
                                                writable);
-  ASSERT(!result->IsFailure());
+  CHECK(!result->IsFailure());
   USE(result);
   return regexp;
 }
@@ -2405,7 +2407,7 @@
     if (is_ascii_) {
       Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_);
       AssertNoAllocation no_alloc;
-      char* char_buffer = seq->GetChars();
+      uint8_t* char_buffer = seq->GetChars();
       StringBuilderConcatHelper(*subject_,
                                 char_buffer,
                                 *array_builder_.array(),
@@ -2662,7 +2664,7 @@
     bool simple = false;
     if (content.IsAscii()) {
       simple = ParseReplacementPattern(&parts_,
-                                       content.ToAsciiVector(),
+                                       content.ToOneByteVector(),
                                        capture_count,
                                        subject_length,
                                        zone());
@@ -2738,7 +2740,7 @@
 }
 
 
-void FindAsciiStringIndices(Vector<const char> subject,
+void FindAsciiStringIndices(Vector<const uint8_t> subject,
                             char pattern,
                             ZoneList<int>* indices,
                             unsigned int limit,
@@ -2746,11 +2748,11 @@
   ASSERT(limit > 0);
   // Collect indices of pattern in subject using memchr.
   // Stop after finding at most limit values.
-  const char* subject_start = reinterpret_cast<const char*>(subject.start());
-  const char* subject_end = subject_start + subject.length();
-  const char* pos = subject_start;
+  const uint8_t* subject_start = subject.start();
+  const uint8_t* subject_end = subject_start + subject.length();
+  const uint8_t* pos = subject_start;
   while (limit > 0) {
-    pos = reinterpret_cast<const char*>(
+    pos = reinterpret_cast<const uint8_t*>(
         memchr(pos, pattern, subject_end - pos));
     if (pos == NULL) return;
     indices->Add(static_cast<int>(pos - subject_start), zone);
@@ -2813,9 +2815,10 @@
     ASSERT(subject_content.IsFlat());
     ASSERT(pattern_content.IsFlat());
     if (subject_content.IsAscii()) {
-      Vector<const char> subject_vector = subject_content.ToAsciiVector();
+      Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
       if (pattern_content.IsAscii()) {
-        Vector<const char> pattern_vector = pattern_content.ToAsciiVector();
+        Vector<const uint8_t> pattern_vector =
+            pattern_content.ToOneByteVector();
         if (pattern_vector.length() == 1) {
           FindAsciiStringIndices(subject_vector,
                                  pattern_vector[0],
@@ -2841,7 +2844,8 @@
     } else {
       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
       if (pattern_content.IsAscii()) {
-        Vector<const char> pattern_vector = pattern_content.ToAsciiVector();
+        Vector<const uint8_t> pattern_vector =
+            pattern_content.ToOneByteVector();
         if (pattern_vector.length() == 1) {
           FindTwoByteStringIndices(subject_vector,
                                    pattern_vector[0],
@@ -2913,7 +2917,7 @@
        static_cast<int64_t>(pattern_len)) *
       static_cast<int64_t>(matches) +
       static_cast<int64_t>(subject_len);
-  if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException();
+  if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11);
   int result_len = static_cast<int>(result_len_64);
 
   int subject_pos = 0;
@@ -2990,7 +2994,8 @@
   if (is_global &&
       regexp->TypeTag() == JSRegExp::ATOM &&
       simple_replace) {
-    if (subject->HasOnlyAsciiChars() && replacement->HasOnlyAsciiChars()) {
+    if (subject->IsOneByteConvertible() &&
+        replacement->IsOneByteConvertible()) {
       return StringReplaceAtomRegExpWithString<SeqOneByteString>(
           isolate, subject, regexp, replacement, last_match_info);
     } else {
@@ -3081,7 +3086,7 @@
   if (is_global &&
       regexp->TypeTag() == JSRegExp::ATOM) {
     Handle<String> empty_string = isolate->factory()->empty_string();
-    if (subject->HasOnlyAsciiChars()) {
+    if (subject->IsOneByteRepresentation()) {
       return StringReplaceAtomRegExpWithString<SeqOneByteString>(
           isolate,
           subject,
@@ -3210,7 +3215,7 @@
   ASSERT(last_match_info->HasFastObjectElements());
 
   if (replacement->length() == 0) {
-    if (subject->HasOnlyAsciiChars()) {
+    if (subject->IsOneByteConvertible()) {
       return StringReplaceRegExpWithEmptyString<SeqOneByteString>(
           isolate, subject, regexp, last_match_info);
     } else {
@@ -3322,10 +3327,10 @@
 
   // dispatch on type of strings
   if (seq_pat.IsAscii()) {
-    Vector<const char> pat_vector = seq_pat.ToAsciiVector();
+    Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
     if (seq_sub.IsAscii()) {
       return SearchString(isolate,
-                          seq_sub.ToAsciiVector(),
+                          seq_sub.ToOneByteVector(),
                           pat_vector,
                           start_index);
     }
@@ -3337,7 +3342,7 @@
   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
   if (seq_sub.IsAscii()) {
     return SearchString(isolate,
-                        seq_sub.ToAsciiVector(),
+                        seq_sub.ToOneByteVector(),
                         pat_vector,
                         start_index);
   }
@@ -3377,7 +3382,7 @@
   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
     for (int i = 0; i < pattern_length; i++) {
       uc16 c = pattern[i];
-      if (c > String::kMaxAsciiCharCode) {
+      if (c > String::kMaxOneByteCharCode) {
         return -1;
       }
     }
@@ -3432,9 +3437,9 @@
   String::FlatContent pat_content = pat->GetFlatContent();
 
   if (pat_content.IsAscii()) {
-    Vector<const char> pat_vector = pat_content.ToAsciiVector();
+    Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
     if (sub_content.IsAscii()) {
-      position = StringMatchBackwards(sub_content.ToAsciiVector(),
+      position = StringMatchBackwards(sub_content.ToOneByteVector(),
                                       pat_vector,
                                       start_index);
     } else {
@@ -3445,7 +3450,7 @@
   } else {
     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
     if (sub_content.IsAscii()) {
-      position = StringMatchBackwards(sub_content.ToAsciiVector(),
+      position = StringMatchBackwards(sub_content.ToOneByteVector(),
                                       pat_vector,
                                       start_index);
     } else {
@@ -4999,7 +5004,7 @@
 }
 
 
-static bool AreDigits(const char*s, int from, int to) {
+static bool AreDigits(const uint8_t*s, int from, int to) {
   for (int i = from; i < to; i++) {
     if (s[i] < '0' || s[i] > '9') return false;
   }
@@ -5008,7 +5013,7 @@
 }
 
 
-static int ParseDecimalInteger(const char*s, int from, int to) {
+static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
   ASSERT(to - from < 10);  // Overflow is not possible.
   ASSERT(from < to);
   int d = s[from] - '0';
@@ -5032,7 +5037,7 @@
   if (subject->IsSeqOneByteString()) {
     if (len == 0) return Smi::FromInt(0);
 
-    char const* data = SeqOneByteString::cast(subject)->GetChars();
+    uint8_t const* data = SeqOneByteString::cast(subject)->GetChars();
     bool minus = (data[0] == '-');
     int start_pos = (minus ? 1 : 0);
 
@@ -5159,7 +5164,7 @@
       ASSERT(String::kMaxLength < 0x7fffffff - 6);  // Cannot overflow.
       if (escaped_length > String::kMaxLength) {
         isolate->context()->mark_out_of_memory();
-        return Failure::OutOfMemoryException();
+        return Failure::OutOfMemoryException(0x12);
       }
     }
   }
@@ -5258,14 +5263,14 @@
 
   source->TryFlatten();
 
-  bool ascii = true;
+  bool one_byte = true;
   int length = source->length();
 
   int unescaped_length = 0;
   for (int i = 0; i < length; unescaped_length++) {
     int step;
-    if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) {
-      ascii = false;
+    if (Unescape(source, i, length, &step) > String::kMaxOneByteCharCode) {
+      one_byte = false;
     }
     i += step;
   }
@@ -5276,7 +5281,7 @@
 
   Object* o;
   { MaybeObject* maybe_o =
-        ascii ?
+        one_byte ?
         isolate->heap()->AllocateRawOneByteString(unescaped_length) :
         isolate->heap()->AllocateRawTwoByteString(unescaped_length);
     if (!maybe_o->ToObject(&o)) return maybe_o;
@@ -5527,8 +5532,9 @@
     return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate,
                                                           flat.ToUC16Vector());
   } else {
-    return QuoteJsonString<char, SeqOneByteString, false>(isolate,
-                                                        flat.ToAsciiVector());
+    return QuoteJsonString<uint8_t, SeqOneByteString, false>(
+        isolate,
+        flat.ToOneByteVector());
   }
 }
 
@@ -5550,8 +5556,9 @@
     return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
                                                          flat.ToUC16Vector());
   } else {
-    return QuoteJsonString<char, SeqOneByteString, true>(isolate,
-                                                       flat.ToAsciiVector());
+    return QuoteJsonString<uint8_t, SeqOneByteString, true>(
+        isolate,
+        flat.ToOneByteVector());
   }
 }
 
@@ -5592,9 +5599,10 @@
                                                       write_cursor,
                                                       content.ToUC16Vector());
     } else {
-      write_cursor = WriteQuoteJsonString<Char, char>(isolate,
-                                                      write_cursor,
-                                                      content.ToAsciiVector());
+      write_cursor =
+          WriteQuoteJsonString<Char, uint8_t>(isolate,
+                                              write_cursor,
+                                              content.ToOneByteVector());
     }
   }
   *(write_cursor++) = ']';
@@ -5766,7 +5774,7 @@
         current_length += char_length;
         if (current_length > Smi::kMaxValue) {
           isolate->context()->mark_out_of_memory();
-          return Failure::OutOfMemoryException();
+          return Failure::OutOfMemoryException(0x13);
         }
       }
       // Try again with the real length.
@@ -5933,6 +5941,7 @@
   // Assume that the string is not empty; we need this assumption later
   if (length == 0) return s;
 
+#ifndef ENABLE_LATIN_1
   // Simpler handling of ASCII strings.
   //
   // NOTE: This assumes that the upper/lower case of an ASCII
@@ -5946,9 +5955,12 @@
     }
     SeqOneByteString* result = SeqOneByteString::cast(o);
     bool has_changed_character = ConvertTraits::AsciiConverter::Convert(
-        result->GetChars(), SeqOneByteString::cast(s)->GetChars(), length);
+        reinterpret_cast<char*>(result->GetChars()),
+        reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
+        length);
     return has_changed_character ? result : s;
   }
+#endif
 
   Object* answer;
   { MaybeObject* maybe_answer =
@@ -6107,7 +6119,7 @@
 // not in the cache and fills the remainder with smi zeros. Returns
 // the length of the successfully copied prefix.
 static int CopyCachedAsciiCharsToArray(Heap* heap,
-                                       const char* chars,
+                                       const uint8_t* chars,
                                        FixedArray* elements,
                                        int length) {
   AssertNoAllocation no_gc;
@@ -6158,7 +6170,7 @@
     elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
     String::FlatContent content = s->GetFlatContent();
     if (content.IsAscii()) {
-      Vector<const char> chars = content.ToAsciiVector();
+      Vector<const uint8_t> chars = content.ToOneByteVector();
       // Note, this will initialize all elements (not only the prefix)
       // to prevent GC from seeing partially initialized array.
       position = CopyCachedAsciiCharsToArray(isolate->heap(),
@@ -6434,7 +6446,7 @@
   CONVERT_ARG_CHECKED(JSArray, array, 0);
   if (!args[1]->IsSmi()) {
     isolate->context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x14);
   }
   int array_length = args.smi_at(1);
   CONVERT_ARG_CHECKED(String, special, 2);
@@ -6461,7 +6473,7 @@
     if (first->IsString()) return first;
   }
 
-  bool ascii = special->HasOnlyAsciiChars();
+  bool one_byte = special->IsOneByteConvertible();
   int position = 0;
   for (int i = 0; i < array_length; i++) {
     int increment = 0;
@@ -6502,8 +6514,8 @@
       String* element = String::cast(elt);
       int element_length = element->length();
       increment = element_length;
-      if (ascii && !element->HasOnlyAsciiChars()) {
-        ascii = false;
+      if (one_byte && !element->IsOneByteConvertible()) {
+        one_byte = false;
       }
     } else {
       ASSERT(!elt->IsTheHole());
@@ -6511,7 +6523,7 @@
     }
     if (increment > String::kMaxLength - position) {
       isolate->context()->mark_out_of_memory();
-      return Failure::OutOfMemoryException();
+      return Failure::OutOfMemoryException(0x15);
     }
     position += increment;
   }
@@ -6519,7 +6531,7 @@
   int length = position;
   Object* object;
 
-  if (ascii) {
+  if (one_byte) {
     { MaybeObject* maybe_object =
           isolate->heap()->AllocateRawOneByteString(length);
       if (!maybe_object->ToObject(&object)) return maybe_object;
@@ -6551,7 +6563,7 @@
   CONVERT_ARG_CHECKED(JSArray, array, 0);
   if (!args[1]->IsSmi()) {
     isolate->context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException();
+    return Failure::OutOfMemoryException(0x16);
   }
   int array_length = args.smi_at(1);
   CONVERT_ARG_CHECKED(String, separator, 2);
@@ -6576,7 +6588,7 @@
       (String::kMaxLength + separator_length - 1) / separator_length;
   if (max_nof_separators < (array_length - 1)) {
       isolate->context()->mark_out_of_memory();
-      return Failure::OutOfMemoryException();
+      return Failure::OutOfMemoryException(0x17);
   }
   int length = (array_length - 1) * separator_length;
   for (int i = 0; i < array_length; i++) {
@@ -6589,7 +6601,7 @@
     int increment = element->length();
     if (increment > String::kMaxLength - length) {
       isolate->context()->mark_out_of_memory();
-      return Failure::OutOfMemoryException();
+      return Failure::OutOfMemoryException(0x18);
     }
     length += increment;
   }
@@ -6624,7 +6636,8 @@
   }
   ASSERT(sink == end);
 
-  ASSERT(!answer->HasOnlyAsciiChars());  // Use %_FastAsciiArrayJoin instead.
+  // Use %_FastAsciiArrayJoin instead.
+  ASSERT(!answer->IsOneByteRepresentation());
   return answer;
 }
 
@@ -6740,12 +6753,13 @@
     if (result_allocation->IsFailure()) return result_allocation;
     SeqOneByteString* result_string =
         SeqOneByteString::cast(result_allocation->ToObjectUnchecked());
-    JoinSparseArrayWithSeparator<char>(elements,
-                                       elements_length,
-                                       array_length,
-                                       separator,
-                                       Vector<char>(result_string->GetChars(),
-                                                    string_length));
+    JoinSparseArrayWithSeparator<uint8_t>(elements,
+                                          elements_length,
+                                          array_length,
+                                          separator,
+                                          Vector<uint8_t>(
+                                              result_string->GetChars(),
+                                              string_length));
     return result_string;
   } else {
     MaybeObject* result_allocation =
@@ -6993,9 +7007,9 @@
   String::FlatContent x_content = x->GetFlatContent();
   String::FlatContent y_content = y->GetFlatContent();
   if (x_content.IsAscii()) {
-    Vector<const char> x_chars = x_content.ToAsciiVector();
+    Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
     if (y_content.IsAscii()) {
-      Vector<const char> y_chars = y_content.ToAsciiVector();
+      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
     } else {
       Vector<const uc16> y_chars = y_content.ToUC16Vector();
@@ -7004,7 +7018,7 @@
   } else {
     Vector<const uc16> x_chars = x_content.ToUC16Vector();
     if (y_content.IsAscii()) {
-      Vector<const char> y_chars = y_content.ToAsciiVector();
+      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
     } else {
       Vector<const uc16> y_chars = y_content.ToUC16Vector();
@@ -7889,7 +7903,7 @@
 };
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyICMiss) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 0);
   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
@@ -8016,7 +8030,7 @@
   if (args.length() == 2 &&
       unoptimized->kind() == Code::FUNCTION) {
     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
-    CHECK(type->IsEqualTo(CStrVector("osr")));
+    CHECK(type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr")));
     isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
     unoptimized->set_allow_osr_at_loop_nesting_level(
         Code::kMaxLoopNestingMarker);
@@ -8954,7 +8968,7 @@
   bool result;
   String::FlatContent str_content = str->GetFlatContent();
   if (str_content.IsAscii()) {
-    result = DateParser::Parse(str_content.ToAsciiVector(),
+    result = DateParser::Parse(str_content.ToOneByteVector(),
                                output_array,
                                isolate->unicode_cache());
   } else {
@@ -13242,6 +13256,15 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
+  FlattenString(str);
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
   // This is only called from codegen, so checks might be more lax.
   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
@@ -13403,8 +13426,8 @@
   CONVERT_ARG_CHECKED(JSArray, elms, 1);
   String::FlatContent format_content = format->GetFlatContent();
   RUNTIME_ASSERT(format_content.IsAscii());
-  Vector<const char> chars = format_content.ToAsciiVector();
-  LOGGER->LogRuntime(chars, elms);
+  Vector<const uint8_t> chars = format_content.ToOneByteVector();
+  LOGGER->LogRuntime(Vector<const char>::cast(chars), elms);
   return isolate->heap()->undefined_value();
 }
 
diff --git a/src/runtime.h b/src/runtime.h
index 47102a0..b72813d 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -89,7 +89,7 @@
   F(ForceParallelRecompile, 1, 1) \
   F(InstallRecompiledCode, 1, 1) \
   F(NotifyDeoptimized, 1, 1) \
-  F(NotifyICMiss, 0, 1) \
+  F(NotifyStubFailure, 0, 1) \
   F(NotifyOSR, 0, 1) \
   F(DeoptimizeFunction, 1, 1) \
   F(ClearFunctionTypeFeedback, 1, 1) \
@@ -104,6 +104,7 @@
   F(StoreArrayLiteralElement, 5, 1) \
   F(DebugCallbackSupportsStepping, 1, 1) \
   F(DebugPrepareStepInIfStepping, 1, 1) \
+  F(FlattenString, 1, 1) \
   \
   /* Array join support */ \
   F(PushIfAbsent, 2, 1) \
diff --git a/src/scanner.h b/src/scanner.h
index 0a560e3..a454750 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -183,9 +183,9 @@
   INLINE(void AddChar(uint32_t code_unit)) {
     if (position_ >= backing_store_.length()) ExpandBuffer();
     if (is_ascii_) {
-      if (code_unit < kMaxAsciiCharCodeU) {
+      if (code_unit <= unibrow::Latin1::kMaxChar) {
         backing_store_[position_] = static_cast<byte>(code_unit);
-        position_ += kASCIISize;
+        position_ += kOneByteSize;
         return;
       }
       ConvertToUtf16();
@@ -250,7 +250,7 @@
     } else {
       new_store = backing_store_;
     }
-    char* src = reinterpret_cast<char*>(backing_store_.start());
+    uint8_t* src = backing_store_.start();
     uc16* dst = reinterpret_cast<uc16*>(new_store.start());
     for (int i = position_ - 1; i >= 0; i--) {
       dst[i] = src[i];
diff --git a/src/string-search.h b/src/string-search.h
index 8c3456a..86237f3 100644
--- a/src/string-search.h
+++ b/src/string-search.h
@@ -53,7 +53,11 @@
   // a potentially less efficient searching, but is a safe approximation.
   // For needles using only characters in the same Unicode 256-code point page,
   // there is no search speed degradation.
+#ifndef ENABLE_LATIN_1
   static const int kAsciiAlphabetSize = 128;
+#else
+  static const int kAsciiAlphabetSize = 256;
+#endif
   static const int kUC16AlphabetSize = Isolate::kUC16AlphabetSize;
 
   // Bad-char shift table stored in the state. It's length is the alphabet size.
@@ -61,12 +65,12 @@
   // to compensate for the algorithmic overhead compared to simple brute force.
   static const int kBMMinPatternLength = 7;
 
-  static inline bool IsAsciiString(Vector<const char>) {
+  static inline bool IsOneByteString(Vector<const uint8_t> string) {
     return true;
   }
 
-  static inline bool IsAsciiString(Vector<const uc16> string) {
-    return String::IsAscii(string.start(), string.length());
+  static inline bool IsOneByteString(Vector<const uc16> string) {
+    return String::IsOneByte(string.start(), string.length());
   }
 
   friend class Isolate;
@@ -81,7 +85,7 @@
         pattern_(pattern),
         start_(Max(0, pattern.length() - kBMMaxShift)) {
     if (sizeof(PatternChar) > sizeof(SubjectChar)) {
-      if (!IsAsciiString(pattern_)) {
+      if (!IsOneByteString(pattern_)) {
         strategy_ = &FailSearch;
         return;
       }
@@ -150,13 +154,25 @@
 
   void PopulateBoyerMooreTable();
 
+  static inline bool exceedsOneByte(uint8_t c) {
+#ifdef ENABLE_LATIN_1
+    return false;
+#else
+    return c > String::kMaxOneByteCharCodeU;
+#endif
+  }
+
+  static inline bool exceedsOneByte(uint16_t c) {
+    return c > String::kMaxOneByteCharCodeU;
+  }
+
   static inline int CharOccurrence(int* bad_char_occurrence,
                                    SubjectChar char_code) {
     if (sizeof(SubjectChar) == 1) {
       return bad_char_occurrence[static_cast<int>(char_code)];
     }
     if (sizeof(PatternChar) == 1) {
-      if (static_cast<unsigned int>(char_code) > String::kMaxAsciiCharCodeU) {
+      if (exceedsOneByte(char_code)) {
         return -1;
       }
       return bad_char_occurrence[static_cast<unsigned int>(char_code)];
@@ -223,7 +239,7 @@
     return static_cast<int>(pos - subject.start());
   } else {
     if (sizeof(PatternChar) > sizeof(SubjectChar)) {
-      if (static_cast<uc16>(pattern_first_char) > String::kMaxAsciiCharCodeU) {
+      if (exceedsOneByte(pattern_first_char)) {
         return -1;
       }
     }
diff --git a/src/string.js b/src/string.js
index d9ca035..60a5abe 100644
--- a/src/string.js
+++ b/src/string.js
@@ -825,6 +825,7 @@
     var code = %_Arguments(i);
     if (!%_IsSmi(code)) code = ToNumber(code) & 0xffff;
     if (code < 0) code = code & 0xffff;
+    // TODO(dcarney): Fix for Latin-1.
     if (code > 0x7f) break;
     %_OneByteSeqStringSetChar(one_byte, i, code);
   }
diff --git a/src/type-info.cc b/src/type-info.cc
index 7a9a5de..00e8ee8 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -111,14 +111,11 @@
 }
 
 
-bool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) {
+bool TypeFeedbackOracle::LoadIsPolymorphic(Property* expr) {
   Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
-    Builtins* builtins = isolate_->builtins();
-    return code->is_keyed_load_stub() &&
-        *code != builtins->builtin(Builtins::kKeyedLoadIC_Generic) &&
-        code->ic_state() == MEGAMORPHIC;
+    return code->is_keyed_load_stub() && code->ic_state() == POLYMORPHIC;
   }
   return false;
 }
@@ -145,19 +142,15 @@
 }
 
 
-bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(TypeFeedbackId ast_id) {
+bool TypeFeedbackOracle::StoreIsPolymorphic(TypeFeedbackId ast_id) {
   Handle<Object> map_or_code = GetInfo(ast_id);
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
-    Builtins* builtins = isolate_->builtins();
     bool allow_growth =
         Code::GetKeyedAccessGrowMode(code->extra_ic_state()) ==
         ALLOW_JSARRAY_GROWTH;
-    return code->is_keyed_store_stub() &&
-        !allow_growth &&
-        *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic) &&
-        *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic_Strict) &&
-        code->ic_state() == MEGAMORPHIC;
+    return code->is_keyed_store_stub() && !allow_growth &&
+        code->ic_state() == POLYMORPHIC;
   }
   return false;
 }
@@ -667,7 +660,7 @@
       case Code::KEYED_LOAD_IC:
       case Code::KEYED_STORE_IC:
         if (target->ic_state() == MONOMORPHIC ||
-            target->ic_state() == MEGAMORPHIC) {
+            target->ic_state() == POLYMORPHIC) {
           SetInfo(ast_id, target);
         }
         break;
diff --git a/src/type-info.h b/src/type-info.h
index 8b2ec49..330ecd3 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -242,9 +242,9 @@
 
   bool LoadIsMonomorphicNormal(Property* expr);
   bool LoadIsUninitialized(Property* expr);
-  bool LoadIsMegamorphicWithTypeInfo(Property* expr);
+  bool LoadIsPolymorphic(Property* expr);
   bool StoreIsMonomorphicNormal(TypeFeedbackId ast_id);
-  bool StoreIsMegamorphicWithTypeInfo(TypeFeedbackId ast_id);
+  bool StoreIsPolymorphic(TypeFeedbackId ast_id);
   bool CallIsMonomorphic(Call* expr);
   bool CallNewIsMonomorphic(CallNew* expr);
   bool ObjectLiteralStoreIsMonomorphic(ObjectLiteral::Property* prop);
diff --git a/src/unicode.h b/src/unicode.h
index 626d988..61dbab4 100644
--- a/src/unicode.h
+++ b/src/unicode.h
@@ -133,6 +133,14 @@
   }
 };
 
+class Latin1 {
+ public:
+#ifndef ENABLE_LATIN_1
+  static const unsigned kMaxChar = 0x7f;
+#else
+  static const unsigned kMaxChar = 0xff;
+#endif
+};
 
 class Utf8 {
  public:
diff --git a/src/utils.h b/src/utils.h
index d964983..9080bd6 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -304,7 +304,7 @@
   hash = hash ^ (hash >> 11);
   hash = hash + (hash << 6);
   hash = hash ^ (hash >> 22);
-  return (uint32_t) hash;
+  return static_cast<uint32_t>(hash);
 }
 
 
@@ -523,12 +523,21 @@
 };
 
 #define STATIC_ASCII_VECTOR(x)                        \
-  v8::internal::Vector<const char>(x, ARRAY_SIZE(x)-1)
+  v8::internal::Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(x), \
+                                      ARRAY_SIZE(x)-1)
 
 inline Vector<const char> CStrVector(const char* data) {
   return Vector<const char>(data, StrLength(data));
 }
 
+inline Vector<const uint8_t> OneByteVector(const char* data, int length) {
+  return Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), length);
+}
+
+inline Vector<const uint8_t> OneByteVector(const char* data) {
+  return OneByteVector(data, StrLength(data));
+}
+
 inline Vector<char> MutableCStrVector(char* data) {
   return Vector<char>(data, StrLength(data));
 }
@@ -767,7 +776,9 @@
 
 // Compare ASCII/16bit chars to ASCII/16bit chars.
 template <typename lchar, typename rchar>
-inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
+inline int CompareCharsUnsigned(const lchar* lhs,
+                                const rchar* rhs,
+                                int chars) {
   const lchar* limit = lhs + chars;
 #ifdef V8_HOST_CAN_READ_UNALIGNED
   if (sizeof(*lhs) == sizeof(*rhs)) {
@@ -792,6 +803,33 @@
   return 0;
 }
 
+template<typename lchar, typename rchar>
+inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
+  ASSERT(sizeof(lchar) <= 2);
+  ASSERT(sizeof(rchar) <= 2);
+  if (sizeof(lchar) == 1) {
+    if (sizeof(rchar) == 1) {
+      return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs),
+                                  reinterpret_cast<const uint8_t*>(rhs),
+                                  chars);
+    } else {
+      return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs),
+                                  reinterpret_cast<const uint16_t*>(rhs),
+                                  chars);
+    }
+  } else {
+    if (sizeof(rchar) == 1) {
+      return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs),
+                                  reinterpret_cast<const uint8_t*>(rhs),
+                                  chars);
+    } else {
+      return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs),
+                                  reinterpret_cast<const uint16_t*>(rhs),
+                                  chars);
+    }
+  }
+}
+
 
 // Calculate 10^exponent.
 inline int TenToThe(int exponent) {
diff --git a/src/v8conversions.cc b/src/v8conversions.cc
index 26a4868..900b62d 100644
--- a/src/v8conversions.cc
+++ b/src/v8conversions.cc
@@ -85,8 +85,8 @@
   StringShape shape(str);
   // TODO(dcarney): Use a Visitor here.
   if (shape.IsSequentialAscii()) {
-    const char* begin = SeqOneByteString::cast(str)->GetChars();
-    const char* end = begin + str->length();
+    const uint8_t* begin = SeqOneByteString::cast(str)->GetChars();
+    const uint8_t* end = begin + str->length();
     return InternalStringToDouble(unicode_cache, begin, end, flags,
                                   empty_string_val);
   } else if (shape.IsSequentialTwoByte()) {
@@ -112,8 +112,8 @@
   StringShape shape(str);
   // TODO(dcarney): Use a Visitor here.
   if (shape.IsSequentialAscii()) {
-    const char* begin = SeqOneByteString::cast(str)->GetChars();
-    const char* end = begin + str->length();
+    const uint8_t* begin = SeqOneByteString::cast(str)->GetChars();
+    const uint8_t* end = begin + str->length();
     return InternalStringToInt(unicode_cache, begin, end, radix);
   } else if (shape.IsSequentialTwoByte()) {
     const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
diff --git a/src/v8globals.h b/src/v8globals.h
index 5920d33..085d67b 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -260,6 +260,8 @@
   // Like MONOMORPHIC but check failed due to prototype.
   MONOMORPHIC_PROTOTYPE_FAILURE,
   // Multiple receiver types have been seen.
+  POLYMORPHIC,
+  // Many receiver types have been seen.
   MEGAMORPHIC,
   // Special states for debug break or step in prepare stubs.
   DEBUG_BREAK,
diff --git a/src/v8utils.h b/src/v8utils.h
index 9072b4e..2064c5a 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -202,13 +202,44 @@
                             bool verbose = true);
 
 
+template <typename sourcechar, typename sinkchar>
+INLINE(static void CopyCharsUnsigned(sinkchar* dest,
+                                     const sourcechar* src,
+                                     int chars));
+
 // Copy from ASCII/16bit chars to ASCII/16bit chars.
 template <typename sourcechar, typename sinkchar>
 INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
 
+template<typename sourcechar, typename sinkchar>
+void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
+  ASSERT(sizeof(sourcechar) <= 2);
+  ASSERT(sizeof(sinkchar) <= 2);
+  if (sizeof(sinkchar) == 1) {
+    if (sizeof(sourcechar) == 1) {
+      CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
+                        reinterpret_cast<const uint8_t*>(src),
+                        chars);
+    } else {
+      CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
+                        reinterpret_cast<const uint16_t*>(src),
+                        chars);
+    }
+  } else {
+    if (sizeof(sourcechar) == 1) {
+      CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
+                        reinterpret_cast<const uint8_t*>(src),
+                        chars);
+    } else {
+      CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
+                        reinterpret_cast<const uint16_t*>(src),
+                        chars);
+    }
+  }
+}
 
 template <typename sourcechar, typename sinkchar>
-void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
+void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
   sinkchar* limit = dest + chars;
 #ifdef V8_HOST_CAN_READ_UNALIGNED
   if (sizeof(*dest) == sizeof(*src)) {
diff --git a/src/version.cc b/src/version.cc
index f203b64..25854d2 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     16
-#define BUILD_NUMBER      2
+#define BUILD_NUMBER      3
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index e156dfd..52c81e2 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -646,7 +646,7 @@
 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
 
 
-void Builtins::Generate_NotifyICMiss(MacroAssembler* masm) {
+void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
   // Enter an internal frame.
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
@@ -655,7 +655,7 @@
     // stubs that tail call the runtime on deopts passing their parameters in
     // registers.
     __ Pushad();
-    __ CallRuntime(Runtime::kNotifyICMiss, 0);
+    __ CallRuntime(Runtime::kNotifyStubFailure, 0);
     __ Popad();
     // Tear down internal frame.
   }
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 650cf5d..3f17d03 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -44,7 +44,7 @@
   descriptor->register_param_count_ = 2;
   descriptor->register_params_ = registers;
   descriptor->deoptimization_handler_ =
-      isolate->builtins()->KeyedLoadIC_Miss();
+      FUNCTION_ADDR(KeyedLoadIC_Miss);
 }
 
 
@@ -316,6 +316,7 @@
     MacroAssembler* masm,
     int length,
     FastCloneShallowArrayStub::Mode mode,
+    AllocationSiteInfoMode allocation_site_info_mode,
     Label* fail) {
   // Registers on entry:
   //
@@ -329,7 +330,12 @@
         ? FixedDoubleArray::SizeFor(length)
         : FixedArray::SizeFor(length);
   }
-  int size = JSArray::kSize + elements_size;
+  int size = JSArray::kSize;
+  int allocation_info_start = size;
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    size += AllocationSiteInfo::kSize;
+  }
+  size += elements_size;
 
   // Allocate both the JS array and the elements array in one big
   // allocation. This avoids multiple limit checks.
@@ -339,6 +345,12 @@
   }
   __ AllocateInNewSpace(size, rax, rbx, rdx, fail, flags);
 
+  if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+    __ LoadRoot(kScratchRegister, Heap::kAllocationSiteInfoMapRootIndex);
+    __ movq(FieldOperand(rax, allocation_info_start), kScratchRegister);
+    __ movq(FieldOperand(rax, allocation_info_start + kPointerSize), rcx);
+  }
+
   // Copy the JS array part.
   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
     if ((i != JSArray::kElementsOffset) || (length == 0)) {
@@ -351,7 +363,11 @@
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
     __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
-    __ lea(rdx, Operand(rax, JSArray::kSize));
+    if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+      __ lea(rdx, Operand(rax, JSArray::kSize + AllocationSiteInfo::kSize));
+    } else {
+      __ lea(rdx, Operand(rax, JSArray::kSize));
+    }
     __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx);
 
     // Copy the elements array.
@@ -398,6 +414,13 @@
   FastCloneShallowArrayStub::Mode mode = mode_;
   // rcx is boilerplate object.
   Factory* factory = masm->isolate()->factory();
+  AllocationSiteInfoMode allocation_site_info_mode =
+      DONT_TRACK_ALLOCATION_SITE_INFO;
+  if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
+    mode = CLONE_ANY_ELEMENTS;
+    allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
+  }
+
   if (mode == CLONE_ANY_ELEMENTS) {
     Label double_elements, check_fast_elements;
     __ movq(rbx, FieldOperand(rcx, JSArray::kElementsOffset));
@@ -405,7 +428,9 @@
            factory->fixed_cow_array_map());
     __ j(not_equal, &check_fast_elements);
     GenerateFastCloneShallowArrayCommon(masm, 0,
-                                        COPY_ON_WRITE_ELEMENTS, &slow_case);
+                                        COPY_ON_WRITE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     __ ret(3 * kPointerSize);
 
     __ bind(&check_fast_elements);
@@ -413,7 +438,9 @@
            factory->fixed_array_map());
     __ j(not_equal, &double_elements);
     GenerateFastCloneShallowArrayCommon(masm, length_,
-                                        CLONE_ELEMENTS, &slow_case);
+                                        CLONE_ELEMENTS,
+                                        allocation_site_info_mode,
+                                        &slow_case);
     __ ret(3 * kPointerSize);
 
     __ bind(&double_elements);
@@ -443,7 +470,8 @@
     __ pop(rcx);
   }
 
-  GenerateFastCloneShallowArrayCommon(masm, length_, mode, &slow_case);
+  GenerateFastCloneShallowArrayCommon(masm, length_, mode,
+                                      allocation_site_info_mode, &slow_case);
   __ ret(3 * kPointerSize);
 
   __ bind(&slow_case);
@@ -3899,6 +3927,19 @@
 }
 
 
+static void JumpIfOOM(MacroAssembler* masm,
+                      Register value,
+                      Register scratch,
+                      Label* oom_label) {
+  __ movq(scratch, value);
+  STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3);
+  STATIC_ASSERT(kFailureTag == 3);
+  __ and_(scratch, Immediate(0xf));
+  __ cmpq(scratch, Immediate(0xf));
+  __ j(equal, oom_label);
+}
+
+
 void CEntryStub::GenerateCore(MacroAssembler* masm,
                               Label* throw_normal_exception,
                               Label* throw_termination_exception,
@@ -4012,9 +4053,7 @@
   __ j(zero, &retry, Label::kNear);
 
   // Special handling of out of memory exceptions.
-  __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE64);
-  __ cmpq(rax, kScratchRegister);
-  __ j(equal, throw_out_of_memory_exception);
+  JumpIfOOM(masm, rax, kScratchRegister, throw_out_of_memory_exception);
 
   // Retrieve the pending exception and clear the variable.
   ExternalReference pending_exception_address(
@@ -4111,7 +4150,10 @@
   // Set pending exception and rax to out of memory exception.
   ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
                                       isolate);
-  __ movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE64);
+  Label already_have_failure;
+  JumpIfOOM(masm, rax, kScratchRegister, &already_have_failure);
+  __ movq(rax, Failure::OutOfMemoryException(0x1), RelocInfo::NONE64);
+  __ bind(&already_have_failure);
   __ Store(pending_exception, rax);
   // Fall through to the next label.
 
@@ -4534,7 +4576,7 @@
 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
   // Fast case of Heap::LookupSingleCharacterStringFromCode.
   __ JumpIfNotSmi(code_, &slow_case_);
-  __ SmiCompare(code_, Smi::FromInt(String::kMaxAsciiCharCode));
+  __ SmiCompare(code_, Smi::FromInt(String::kMaxOneByteCharCode));
   __ j(above, &slow_case_);
 
   __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
@@ -5445,16 +5487,32 @@
   // Compare lengths (precomputed).
   __ bind(&compare_lengths);
   __ SmiTest(length_difference);
+#ifndef ENABLE_LATIN_1
   __ j(not_zero, &result_not_equal, Label::kNear);
+#else
+  Label length_not_equal;
+  __ j(not_zero, &length_not_equal, Label::kNear);
+#endif
 
   // Result is EQUAL.
   __ Move(rax, Smi::FromInt(EQUAL));
   __ ret(0);
 
   Label result_greater;
+#ifdef ENABLE_LATIN_1
+  Label result_less;
+  __ bind(&length_not_equal);
+  __ j(greater, &result_greater, Label::kNear);
+  __ jmp(&result_less, Label::kNear);
+#endif
   __ bind(&result_not_equal);
   // Unequal comparison of left to right, either character or length.
+#ifndef ENABLE_LATIN_1
   __ j(greater, &result_greater, Label::kNear);
+#else
+  __ j(above, &result_greater, Label::kNear);
+  __ bind(&result_less);
+#endif
 
   // Result is LESS.
   __ Move(rax, Smi::FromInt(LESS));
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 63f3ac4..0b2480a 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -283,6 +283,10 @@
   // The fail label is not actually used since we do not allocate.
   Label allocated, new_backing_store, only_change_map, done;
 
+  if (FLAG_track_allocation_sites) {
+    masm->TestJSArrayForAllocationSiteInfo(rdx, rdi, fail);
+  }
+
   // Check for empty arrays, which only require a map transition and no changes
   // to the backing store.
   __ movq(r8, FieldOperand(rdx, JSObject::kElementsOffset));
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index c719bf8..79c8cd1 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -454,35 +454,39 @@
   //               FROM                                  TO             <-rbp
   //    |          ....           |          |          ....           |
   //    +-------------------------+          +-------------------------+
-  //    | JSFunction continuation |          | JSFunction continuation |
+  //    | JSFunction continuation |          |       parameter 1       |
+  //    +-------------------------+          +-------------------------+
+  // |  |   saved frame (rbp)     |          |          ....           |
+  // |  +=========================+<-rbp     +-------------------------+
+  // |  |   JSFunction context    |          |       parameter n       |
+  // v  +-------------------------+          +-------------------------|
+  //    |   COMPILED_STUB marker  |          | JSFunction continuation |
   //    +-------------------------+          +-------------------------+<-rsp
-  // |  |   saved frame (rbp)     |
-  // |  +=========================+<-rbp
-  // |  |   JSFunction context    |
-  // v  +-------------------------+
-  //    |   COMPILED_STUB marker  |          rbp = saved frame
-  //    +-------------------------+          rsi = JSFunction context
-  //    |                         |
-  //    | ...                     |
-  //    |                         |
-  //    +-------------------------+<-rsp
+  //    |                         |          rax = number of parameters
+  //    | ...                     |          rbx = failure handler address
+  //    |                         |          rbp = saved frame
+  //    +-------------------------+<-rsp     rsi = JSFunction context
   //
   //
-  int output_frame_size = 1 * kPointerSize;
-  FrameDescription* output_frame =
-      new(output_frame_size) FrameDescription(output_frame_size, 0);
-  Code* notify_miss =
-      isolate_->builtins()->builtin(Builtins::kNotifyICMiss);
-  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
-  output_frame->SetContinuation(
-      reinterpret_cast<intptr_t>(notify_miss->entry()));
 
   ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
   int major_key = compiled_code_->major_key();
   CodeStubInterfaceDescriptor* descriptor =
       isolate_->code_stub_interface_descriptor(major_key);
-  Handle<Code> miss_ic(descriptor->deoptimization_handler_);
-  output_frame->SetPc(reinterpret_cast<intptr_t>(miss_ic->instruction_start()));
+
+  int output_frame_size =
+      (1 + descriptor->register_param_count_) * kPointerSize;
+  FrameDescription* output_frame =
+      new(output_frame_size) FrameDescription(output_frame_size, 0);
+  Code* notify_failure =
+      isolate_->builtins()->builtin(Builtins::kNotifyStubFailure);
+  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
+  output_frame->SetContinuation(
+      reinterpret_cast<intptr_t>(notify_failure->entry()));
+
+  Code* code;
+  CEntryStub(1, kDontSaveFPRegs).FindCodeInCache(&code, isolate_);
+  output_frame->SetPc(reinterpret_cast<intptr_t>(code->instruction_start()));
   unsigned input_frame_size = input_->GetFrameSize();
   intptr_t value = input_->GetFrameSlot(input_frame_size - kPointerSize);
   output_frame->SetFrameSlot(0, value);
@@ -492,20 +496,22 @@
   value = input_->GetFrameSlot(input_frame_size - 3 * kPointerSize);
   output_frame->SetRegister(rsi.code(), value);
 
-  Translation::Opcode opcode =
-      static_cast<Translation::Opcode>(iterator->Next());
-  ASSERT(opcode == Translation::REGISTER);
-  USE(opcode);
-  int input_reg = iterator->Next();
-  intptr_t input_value = input_->GetRegister(input_reg);
-  output_frame->SetRegister(rdx.code(), input_value);
+  int parameter_offset = kPointerSize * descriptor->register_param_count_;
+  for (int i = 0; i < descriptor->register_param_count_; ++i) {
+    Translation::Opcode opcode =
+        static_cast<Translation::Opcode>(iterator->Next());
+    ASSERT(opcode == Translation::REGISTER);
+    USE(opcode);
+    int input_reg = iterator->Next();
+    intptr_t reg_value = input_->GetRegister(input_reg);
+    output_frame->SetFrameSlot(parameter_offset, reg_value);
+    parameter_offset -= kPointerSize;
+  }
 
-  int32_t next = iterator->Next();
-  opcode = static_cast<Translation::Opcode>(next);
-  ASSERT(opcode == Translation::REGISTER);
-  input_reg = iterator->Next();
-  input_value = input_->GetRegister(input_reg);
-  output_frame->SetRegister(rax.code(), input_value);
+  intptr_t handler =
+      reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_);
+  output_frame->SetRegister(rax.code(), descriptor->register_param_count_);
+  output_frame->SetRegister(rbx.code(), handler);
 
   ASSERT(frame_index == 0);
   output_[frame_index] = output_frame;
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 97ec4b1..6f18c19 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -127,7 +127,7 @@
 
 #ifdef DEBUG
   if (strlen(FLAG_stop_at) > 0 &&
-      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+      info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
     __ int3();
   }
 #endif
@@ -1703,6 +1703,15 @@
     FastCloneShallowArrayStub::Mode mode = has_constant_fast_elements
         ? FastCloneShallowArrayStub::CLONE_ELEMENTS
         : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+
+    // Tracking allocation info allows us to pre-transition later if it makes
+    // sense.
+    if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
+        FLAG_track_allocation_sites) {
+      mode = FastCloneShallowArrayStub::
+          CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+    }
+
     FastCloneShallowArrayStub stub(mode, length);
     __ CallStub(&stub);
   }
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 641e243..f3061af 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -576,7 +576,7 @@
   char_at_generator.GenerateSlow(masm, call_helper);
 
   __ bind(&miss);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -619,7 +619,7 @@
       1);
 
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -1278,7 +1278,7 @@
   __ movq(rax, unmapped_location);
   __ Ret();
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -1317,7 +1317,7 @@
                  INLINE_SMI_CHECK);
   __ Ret();
   __ bind(&slow);
-  GenerateMiss(masm, false);
+  GenerateMiss(masm, MISS);
 }
 
 
@@ -1411,7 +1411,7 @@
 }
 
 
-void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ----------- S t a t e -------------
   //  -- rax    : key
   //  -- rdx    : receiver
@@ -1427,7 +1427,7 @@
   __ push(rbx);  // return address
 
   // Perform tail call to the entry.
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
       ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric),
                           masm->isolate())
       : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
@@ -1638,7 +1638,7 @@
 }
 
 
-void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ----------- S t a t e -------------
   //  -- rax     : value
   //  -- rcx     : key
@@ -1653,7 +1653,7 @@
   __ push(rbx);  // return address
 
   // Do tail-call to runtime routine.
-  ExternalReference ref = force_generic
+  ExternalReference ref = miss_mode == MISS_FORCE_GENERIC
     ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
                         masm->isolate())
     : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index d64d4ff..8c4dafa 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -124,7 +124,7 @@
 
 #ifdef DEBUG
     if (strlen(FLAG_stop_at) > 0 &&
-        info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+        info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
       __ int3();
     }
 #endif
@@ -2224,7 +2224,7 @@
 
   __ JumpIfSmi(input, is_false);
 
-  if (class_name->IsEqualTo(CStrVector("Function"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Function"))) {
     // Assuming the following assertions, we can use the same compares to test
     // for both being a function type and being in the object type range.
     STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
@@ -2255,7 +2255,7 @@
 
   // Objects with a non-function constructor have class 'Object'.
   __ CmpObjectType(temp, JS_FUNCTION_TYPE, kScratchRegister);
-  if (class_name->IsEqualTo(CStrVector("Object"))) {
+  if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) {
     __ j(not_equal, is_true);
   } else {
     __ j(not_equal, is_false);
@@ -4249,7 +4249,7 @@
   Register result = ToRegister(instr->result());
   ASSERT(!char_code.is(result));
 
-  __ cmpl(char_code, Immediate(String::kMaxAsciiCharCode));
+  __ cmpl(char_code, Immediate(String::kMaxOneByteCharCode));
   __ j(above, deferred->entry());
   __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
   __ movq(result, FieldOperand(result,
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 0270a26..6e9e78e 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -4609,6 +4609,29 @@
   j(not_equal, &next);
 }
 
+void MacroAssembler::TestJSArrayForAllocationSiteInfo(
+    Register receiver_reg,
+    Register scratch_reg,
+    Label* allocation_info_present) {
+  Label no_info_available;
+  ExternalReference new_space_start =
+      ExternalReference::new_space_start(isolate());
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address(isolate());
+
+  lea(scratch_reg, Operand(receiver_reg,
+                           JSArray::kSize + AllocationSiteInfo::kSize));
+  movq(kScratchRegister, new_space_start);
+  cmpq(scratch_reg, kScratchRegister);
+  j(less, &no_info_available);
+  cmpq(scratch_reg, ExternalOperand(new_space_allocation_top));
+  j(greater_equal, &no_info_available);
+  CompareRoot(MemOperand(scratch_reg, 0),
+              Heap::kAllocationSiteInfoMapRootIndex);
+  j(equal, allocation_info_present);
+  bind(&no_info_available);
+}
+
 
 } }  // namespace v8::internal
 
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 136f0f6..e615b89 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -1315,6 +1315,16 @@
   void CheckEnumCache(Register null_value,
                       Label* call_runtime);
 
+  // AllocationSiteInfo support. Arrays may have an associated
+  // AllocationSiteInfo object that can be checked for in order to pretransition
+  // to another type.
+  // On entry, receiver_reg should point to the array object.
+  // scratch_reg gets clobbered.
+  // If allocation info is present, jump to allocation_info_present
+  void TestJSArrayForAllocationSiteInfo(Register receiver_reg,
+                                        Register scratch_reg,
+                                        Label* allocation_info_present);
+
  private:
   // Order general registers are pushed by Pushad.
   // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 827ec28..f5b5e95 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -234,7 +234,7 @@
   // If input is ASCII, don't even bother calling here if the string to
   // match contains a non-ASCII character.
   if (mode_ == ASCII) {
-    ASSERT(String::IsAscii(str.start(), str.length()));
+    ASSERT(String::IsOneByte(str.start(), str.length()));
   }
 #endif
   int byte_length = str.length() * char_size();
@@ -393,8 +393,17 @@
     __ j(not_equal, on_no_match);  // Definitely not equal.
     __ subb(rax, Immediate('a'));
     __ cmpb(rax, Immediate('z' - 'a'));
+#ifndef ENABLE_LATIN_1
     __ j(above, on_no_match);  // Weren't letters anyway.
-
+#else
+    __ j(below_equal, &loop_increment);  // In range 'a'-'z'.
+    // Latin-1: Check for values in range [224,254] but not 247.
+    __ subb(rax, Immediate(224 - 'a'));
+    __ cmpb(rax, Immediate(254 - 224));
+    __ j(above, on_no_match);  // Weren't Latin-1 letters.
+    __ cmpb(rax, Immediate(247 - 224));  // Check for 247.
+    __ j(equal, on_no_match);
+#endif
     __ bind(&loop_increment);
     // Increment pointers into match and capture strings.
     __ addq(r11, Immediate(1));
@@ -610,7 +619,7 @@
     Label* on_bit_set) {
   __ Move(rax, table);
   Register index = current_character();
-  if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) {
+  if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) {
     __ movq(rbx, current_character());
     __ and_(rbx, Immediate(kTableMask));
     index = rbx;
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 994b5bc..82727ef 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -2772,7 +2772,7 @@
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3253,7 +3253,7 @@
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
+  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }