Version 3.29.17 (based on bleeding_edge revision r23372)

Performance and stability improvements on all platforms.

git-svn-id: https://v8.googlecode.com/svn/trunk@23377 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/BUILD.gn b/BUILD.gn
index 8512dea..49ae65a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -718,6 +718,8 @@
     "src/ic/access-compiler.h",
     "src/ic/call-optimization.cc",
     "src/ic/call-optimization.h",
+    "src/ic/handler-compiler.cc",
+    "src/ic/handler-compiler.h",
     "src/ic/ic-inl.h",
     "src/ic/ic.cc",
     "src/ic/ic.h",
@@ -934,6 +936,7 @@
       "src/compiler/x64/instruction-selector-x64.cc",
       "src/compiler/x64/linkage-x64.cc",
       "src/ic/x64/access-compiler-x64.cc",
+      "src/ic/x64/handler-compiler-x64.cc",
       "src/ic/x64/ic-x64.cc",
       "src/ic/x64/ic-compiler-x64.cc",
       "src/ic/x64/stub-cache-x64.cc",
@@ -973,6 +976,7 @@
       "src/compiler/arm/instruction-selector-arm.cc",
       "src/compiler/arm/linkage-arm.cc",
       "src/ic/arm/access-compiler-arm.cc",
+      "src/ic/arm/handler-compiler-arm.cc",
       "src/ic/arm/ic-arm.cc",
       "src/ic/arm/ic-compiler-arm.cc",
       "src/ic/arm/stub-cache-arm.cc",
@@ -1023,6 +1027,7 @@
       "src/compiler/arm64/instruction-selector-arm64.cc",
       "src/compiler/arm64/linkage-arm64.cc",
       "src/ic/arm64/access-compiler-arm64.cc",
+      "src/ic/arm64/handler-compiler-arm64.cc",
       "src/ic/arm64/ic-arm64.cc",
       "src/ic/arm64/ic-compiler-arm64.cc",
       "src/ic/arm64/stub-cache-arm64.cc",
@@ -1046,7 +1051,6 @@
       "src/mips/frames-mips.cc",
       "src/mips/frames-mips.h",
       "src/mips/full-codegen-mips.cc",
-      "src/mips/ic-mips.cc",
       "src/mips/lithium-codegen-mips.cc",
       "src/mips/lithium-codegen-mips.h",
       "src/mips/lithium-gap-resolver-mips.cc",
@@ -1058,7 +1062,47 @@
       "src/mips/regexp-macro-assembler-mips.cc",
       "src/mips/regexp-macro-assembler-mips.h",
       "src/mips/simulator-mips.cc",
-      "src/mips/stub-cache-mips.cc",
+      "src/ic/mips/access-compiler-mips.cc",
+      "src/ic/mips/handler-compiler-mips.cc",
+      "src/ic/mips/ic-mips.cc",
+      "src/ic/mips/ic-compiler-mips.cc",
+      "src/ic/mips/stub-cache-mips.cc",
+    ]
+  } else if (v8_target_arch == "mips64") {
+    sources += [
+      "src/mips64/assembler-mips64.cc",
+      "src/mips64/assembler-mips64.h",
+      "src/mips64/assembler-mips64-inl.h",
+      "src/mips64/builtins-mips64.cc",
+      "src/mips64/codegen-mips64.cc",
+      "src/mips64/codegen-mips64.h",
+      "src/mips64/code-stubs-mips64.cc",
+      "src/mips64/code-stubs-mips64.h",
+      "src/mips64/constants-mips64.cc",
+      "src/mips64/constants-mips64.h",
+      "src/mips64/cpu-mips64.cc",
+      "src/mips64/debug-mips64.cc",
+      "src/mips64/deoptimizer-mips64.cc",
+      "src/mips64/disasm-mips64.cc",
+      "src/mips64/frames-mips64.cc",
+      "src/mips64/frames-mips64.h",
+      "src/mips64/full-codegen-mips64.cc",
+      "src/mips64/lithium-codegen-mips64.cc",
+      "src/mips64/lithium-codegen-mips64.h",
+      "src/mips64/lithium-gap-resolver-mips64.cc",
+      "src/mips64/lithium-gap-resolver-mips64.h",
+      "src/mips64/lithium-mips64.cc",
+      "src/mips64/lithium-mips64.h",
+      "src/mips64/macro-assembler-mips64.cc",
+      "src/mips64/macro-assembler-mips64.h",
+      "src/mips64/regexp-macro-assembler-mips64.cc",
+      "src/mips64/regexp-macro-assembler-mips64.h",
+      "src/mips64/simulator-mips64.cc",
+      "src/ic/mips64/access-compiler-mips64.cc",
+      "src/ic/mips64/handler-compiler-mips64.cc",
+      "src/ic/mips64/ic-mips64.cc",
+      "src/ic/mips64/ic-compiler-mips64.cc",
+      "src/ic/mips64/stub-cache-mips64.cc",
     ]
   }
 
diff --git a/ChangeLog b/ChangeLog
index 18bed25..caf6bb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-08-25: Version 3.29.17
+
+        Performance and stability improvements on all platforms.
+
+
 2014-08-24: Version 3.29.16
 
         Fix issue with numeric property names (issue 3507).
diff --git a/build/toolchain.gypi b/build/toolchain.gypi
index 45c1f9d..eddc329 100644
--- a/build/toolchain.gypi
+++ b/build/toolchain.gypi
@@ -91,6 +91,9 @@
     # Allow to suppress the array bounds warning (default is no suppression).
     'wno_array_bounds%': '',
 
+    # Link-Time Optimizations
+    'use_lto%': 0,
+
     'variables': {
       # This is set when building the Android WebView inside the Android build
       # system, using the 'android' gyp backend.
@@ -241,6 +244,15 @@
                   }],
                 ],
               }],
+              # Disable LTO for v8
+              # v8 is optimized for speed, which takes precedence over
+              # size optimization in LTO.
+              ['use_lto==1', {
+                'cflags!': [
+                  '-flto',
+                  '-ffat-lto-objects',
+                ],
+              }],
             ],
           }],  # _toolset=="target"
         ],
diff --git a/include/v8.h b/include/v8.h
index 9407c6c..cbe8edd 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1473,6 +1473,30 @@
   bool IsPromise() const;
 
   /**
+   * Returns true if this value is a Map.
+   * This is an experimental feature.
+   */
+  bool IsMap() const;
+
+  /**
+   * Returns true if this value is a Set.
+   * This is an experimental feature.
+   */
+  bool IsSet() const;
+
+  /**
+   * Returns true if this value is a WeakMap.
+   * This is an experimental feature.
+   */
+  bool IsWeakMap() const;
+
+  /**
+   * Returns true if this value is a WeakSet.
+   * This is an experimental feature.
+   */
+  bool IsWeakSet() const;
+
+  /**
    * Returns true if this value is an ArrayBuffer.
    * This is an experimental feature.
    */
@@ -5669,7 +5693,7 @@
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptyStringRootIndex = 162;
+  static const int kEmptyStringRootIndex = 164;
 
   // The external allocation limit should be below 256 MB on all architectures
   // to avoid that resource-constrained embedders run low on memory.
diff --git a/src/accessors.cc b/src/accessors.cc
index c2361b3..9a2431b 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -156,6 +156,46 @@
 
 
 //
+// Accessors::ArgumentsIterator
+//
+
+
+void Accessors::ArgumentsIteratorGetter(
+    v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* result = isolate->native_context()->array_values_iterator();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
+}
+
+
+void Accessors::ArgumentsIteratorSetter(
+    v8::Local<v8::Name> name, v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<JSObject> object = Utils::OpenHandle(*info.This());
+  Handle<Object> value = Utils::OpenHandle(*val);
+
+  if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
+
+  LookupIterator it(object, Utils::OpenHandle(*name));
+  CHECK(it.HasProperty());
+  DCHECK(it.HolderIsReceiverOrHiddenPrototype());
+  Object::SetDataProperty(&it, value);
+}
+
+
+Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
+    Isolate* isolate, PropertyAttributes attributes) {
+  Handle<Name> name(isolate->native_context()->iterator_symbol(), isolate);
+  return MakeAccessor(isolate, name, &ArgumentsIteratorGetter,
+                      &ArgumentsIteratorSetter, attributes);
+}
+
+
+//
 // Accessors::ArrayLength
 //
 
diff --git a/src/accessors.h b/src/accessors.h
index 75099a0..8fc1f84 100644
--- a/src/accessors.h
+++ b/src/accessors.h
@@ -13,27 +13,28 @@
 
 // The list of accessor descriptors. This is a second-order macro
 // taking a macro to be applied to all accessor descriptor names.
-#define ACCESSOR_INFO_LIST(V)       \
-  V(ArrayLength)                    \
-  V(FunctionArguments)              \
-  V(FunctionCaller)                 \
-  V(FunctionName)                   \
-  V(FunctionLength)                 \
-  V(FunctionPrototype)              \
-  V(ScriptColumnOffset)             \
-  V(ScriptCompilationType)          \
-  V(ScriptContextData)              \
-  V(ScriptEvalFromScript)           \
-  V(ScriptEvalFromScriptPosition)   \
-  V(ScriptEvalFromFunctionName)     \
-  V(ScriptId)                       \
-  V(ScriptLineEnds)                 \
-  V(ScriptLineOffset)               \
-  V(ScriptName)                     \
-  V(ScriptSource)                   \
-  V(ScriptType)                     \
-  V(ScriptSourceUrl)                \
-  V(ScriptSourceMappingUrl)         \
+#define ACCESSOR_INFO_LIST(V)     \
+  V(ArgumentsIterator)            \
+  V(ArrayLength)                  \
+  V(FunctionArguments)            \
+  V(FunctionCaller)               \
+  V(FunctionName)                 \
+  V(FunctionLength)               \
+  V(FunctionPrototype)            \
+  V(ScriptColumnOffset)           \
+  V(ScriptCompilationType)        \
+  V(ScriptContextData)            \
+  V(ScriptEvalFromScript)         \
+  V(ScriptEvalFromScriptPosition) \
+  V(ScriptEvalFromFunctionName)   \
+  V(ScriptId)                     \
+  V(ScriptLineEnds)               \
+  V(ScriptLineOffset)             \
+  V(ScriptName)                   \
+  V(ScriptSource)                 \
+  V(ScriptType)                   \
+  V(ScriptSourceUrl)              \
+  V(ScriptSourceMappingUrl)       \
   V(StringLength)
 
 // Accessors contains all predefined proxy accessors.
diff --git a/src/api.cc b/src/api.cc
index b23ec0e..45efd68 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2412,12 +2412,26 @@
 }
 
 
-bool Value::IsArgumentsObject() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (!obj->IsHeapObject()) return false;
-  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
-  return obj->HasSpecificClassOf(isolate->heap()->Arguments_string());
-}
+#define VALUE_IS_SPECIFIC_TYPE(Type, Class)                            \
+  bool Value::Is##Type() const {                                       \
+    i::Handle<i::Object> obj = Utils::OpenHandle(this);                \
+    if (!obj->IsHeapObject()) return false;                            \
+    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();     \
+    return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
+  }
+
+VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
+VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
+VALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
+VALUE_IS_SPECIFIC_TYPE(StringObject, String)
+VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
+VALUE_IS_SPECIFIC_TYPE(Date, Date)
+VALUE_IS_SPECIFIC_TYPE(Map, Map)
+VALUE_IS_SPECIFIC_TYPE(Set, Set)
+VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
+VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
+
+#undef VALUE_IS_SPECIFIC_TYPE
 
 
 bool Value::IsBoolean() const {
@@ -2454,38 +2468,6 @@
 }
 
 
-bool Value::IsDate() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (!obj->IsHeapObject()) return false;
-  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
-  return obj->HasSpecificClassOf(isolate->heap()->Date_string());
-}
-
-
-bool Value::IsStringObject() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (!obj->IsHeapObject()) return false;
-  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
-  return obj->HasSpecificClassOf(isolate->heap()->String_string());
-}
-
-
-bool Value::IsSymbolObject() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (!obj->IsHeapObject()) return false;
-  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
-  return obj->HasSpecificClassOf(isolate->heap()->Symbol_string());
-}
-
-
-bool Value::IsNumberObject() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (!obj->IsHeapObject()) return false;
-  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
-  return obj->HasSpecificClassOf(isolate->heap()->Number_string());
-}
-
-
 static bool CheckConstructor(i::Isolate* isolate,
                              i::Handle<i::JSObject> obj,
                              const char* class_name) {
@@ -2517,14 +2499,6 @@
 }
 
 
-bool Value::IsBooleanObject() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (!obj->IsHeapObject()) return false;
-  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
-  return obj->HasSpecificClassOf(isolate->heap()->Boolean_string());
-}
-
-
 bool Value::IsRegExp() const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   return obj->IsJSRegExp();
@@ -3636,7 +3610,7 @@
   i::PrototypeIterator iter(isolate, self_obj);
   if (iter.IsAtEnd()) return Local<Value>();
   i::LookupIterator it(i::PrototypeIterator::GetCurrent(iter), key_obj,
-                       i::LookupIterator::CHECK_DERIVED_PROPERTY);
+                       i::LookupIterator::PROTOTYPE_CHAIN_PROPERTY);
   return GetPropertyByLookup(&it);
 }
 
@@ -3649,7 +3623,7 @@
   i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::LookupIterator it(self_obj, key_obj,
-                       i::LookupIterator::CHECK_DERIVED_PROPERTY);
+                       i::LookupIterator::PROTOTYPE_CHAIN_PROPERTY);
   return GetPropertyByLookup(&it);
 }
 
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index a04bb86..d96560f 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -9,7 +9,7 @@
 #include "src/bootstrapper.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
-#include "src/ic/ic-compiler.h"
+#include "src/ic/handler-compiler.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -425,7 +425,7 @@
   class OpBits: public BitField<Token::Value, 2, 14> {};
 
   Major MajorKey() const { return ConvertToDouble; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     // Encode the parameters in a unique 16 bit value.
     return  result1_.code() +
            (result2_.code() << 4) +
@@ -1392,7 +1392,7 @@
 
   // Enter the exit frame that transitions from JavaScript to C++.
   FrameScope scope(masm, StackFrame::MANUAL);
-  __ EnterExitFrame(save_doubles_);
+  __ EnterExitFrame(save_doubles());
 
   // Store a copy of argc in callee-saved registers for later.
   __ mov(r4, Operand(r0));
@@ -1476,7 +1476,7 @@
   // sp: stack pointer
   // fp: frame pointer
   // Callee-saved register r4 still holds argc.
-  __ LeaveExitFrame(save_doubles_, r4, true);
+  __ LeaveExitFrame(save_doubles(), r4, true);
   __ mov(pc, lr);
 
   // Handling of exception.
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index 08efecb..64a0c18 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -28,7 +28,7 @@
   SaveFPRegsMode save_doubles_;
 
   Major MajorKey() const { return StoreBufferOverflow; }
-  int MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
+  uint32_t MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
 };
 
 
@@ -69,7 +69,7 @@
 
  private:
   Major MajorKey() const { return SubString; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -100,7 +100,7 @@
 
  private:
   virtual Major MajorKey() const { return StringCompare; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
   virtual void Generate(MacroAssembler* masm);
 
   static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
@@ -140,7 +140,7 @@
   class ScratchRegisterBits: public BitField<int, 8, 4> {};
 
   Major MajorKey() const { return WriteInt32ToHeapNumber; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     // Encode the parameters in a unique 16 bit value.
     return IntRegisterBits::encode(the_int_.code())
            | HeapNumberRegisterBits::encode(the_heap_number_.code())
@@ -307,7 +307,7 @@
 
   Major MajorKey() const { return RecordWrite; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return ObjectBits::encode(object_.code()) |
         ValueBits::encode(value_.code()) |
         AddressBits::encode(address_.code()) |
@@ -348,7 +348,7 @@
 
  private:
   Major MajorKey() const { return DirectCEntry; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   bool NeedsImmovableCode() { return true; }
 };
@@ -395,7 +395,7 @@
 
   Major MajorKey() const { return NameDictionaryLookup; }
 
-  int MinorKey() const { return LookupModeBits::encode(mode_); }
+  uint32_t MinorKey() const { return LookupModeBits::encode(mode_); }
 
   class LookupModeBits: public BitField<LookupMode, 0, 1> {};
 
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index e2658f3..cb0277e 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -931,7 +931,7 @@
   int length = deoptimizations_.length();
   if (length == 0) return;
   Handle<DeoptimizationInputData> data =
-      DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+      DeoptimizationInputData::New(isolate(), length, TENURED);
 
   Handle<ByteArray> translations =
       translations_.CreateByteArray(isolate()->factory());
@@ -2990,6 +2990,19 @@
 }
 
 
+template <class T>
+void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
+  DCHECK(FLAG_vector_ics);
+  Register vector = ToRegister(instr->temp_vector());
+  DCHECK(vector.is(LoadIC::VectorRegister()));
+  __ Move(vector, instr->hydrogen()->feedback_vector());
+  // No need to allocate this register.
+  DCHECK(LoadIC::SlotRegister().is(r0));
+  __ mov(LoadIC::SlotRegister(),
+         Operand(Smi::FromInt(instr->hydrogen()->slot())));
+}
+
+
 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
   DCHECK(ToRegister(instr->context()).is(cp));
   DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
@@ -2997,13 +3010,7 @@
 
   __ mov(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Move(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(r0));
-    __ mov(LoadIC::SlotRegister(),
-           Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
@@ -3126,13 +3133,7 @@
   // Name is always in r2.
   __ mov(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Move(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(r0));
-    __ mov(LoadIC::SlotRegister(),
-           Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
   CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
@@ -3422,13 +3423,7 @@
   DCHECK(ToRegister(instr->key()).is(LoadIC::NameRegister()));
 
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Move(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(r0));
-    __ mov(LoadIC::SlotRegister(),
-           Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index ee5f4e9..0094755 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -332,6 +332,9 @@
   void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
   void DoStoreKeyedFixedArray(LStoreKeyed* instr);
 
+  template <class T>
+  void EmitVectorLoadICRegisters(T* instr);
+
   ZoneList<LEnvironment*> deoptimizations_;
   ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
   ZoneList<Handle<Object> > deoptimization_literals_;
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc
index 23a5737..c00b572 100644
--- a/src/arm64/code-stubs-arm64.cc
+++ b/src/arm64/code-stubs-arm64.cc
@@ -9,7 +9,7 @@
 #include "src/bootstrapper.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
-#include "src/ic/ic-compiler.h"
+#include "src/ic/handler-compiler.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -1377,7 +1377,7 @@
   // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved
   // registers.
   FrameScope scope(masm, StackFrame::MANUAL);
-  __ EnterExitFrame(save_doubles_, x10, 3);
+  __ EnterExitFrame(save_doubles(), x10, 3);
   DCHECK(csp.Is(__ StackPointer()));
 
   // Poke callee-saved registers into reserved space.
@@ -1474,7 +1474,7 @@
   __ Peek(argc, 2 * kPointerSize);
   __ Peek(target, 3 * kPointerSize);
 
-  __ LeaveExitFrame(save_doubles_, x10, true);
+  __ LeaveExitFrame(save_doubles(), x10, true);
   DCHECK(jssp.Is(__ StackPointer()));
   // Pop or drop the remaining stack slots and return from the stub.
   //         jssp[24]:    Arguments array (of size argc), including receiver.
diff --git a/src/arm64/code-stubs-arm64.h b/src/arm64/code-stubs-arm64.h
index 6ba2f57..cb4738d 100644
--- a/src/arm64/code-stubs-arm64.h
+++ b/src/arm64/code-stubs-arm64.h
@@ -28,7 +28,7 @@
   SaveFPRegsMode save_doubles_;
 
   Major MajorKey() const { return StoreBufferOverflow; }
-  int MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
+  uint32_t MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
 };
 
 
@@ -63,7 +63,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);
  private:
   Major MajorKey() const { return StoreRegistersState; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -77,7 +77,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);
  private:
   Major MajorKey() const { return RestoreRegistersState; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -303,16 +303,14 @@
 
   Major MajorKey() const { return RecordWrite; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return MinorKeyFor(object_, value_, address_, remembered_set_action_,
                        save_fp_regs_mode_);
   }
 
-  static int MinorKeyFor(Register object,
-                         Register value,
-                         Register address,
-                         RememberedSetAction action,
-                         SaveFPRegsMode fp_mode) {
+  static uint32_t MinorKeyFor(Register object, Register value, Register address,
+                              RememberedSetAction action,
+                              SaveFPRegsMode fp_mode) {
     DCHECK(object.Is64Bits());
     DCHECK(value.Is64Bits());
     DCHECK(address.Is64Bits());
@@ -353,7 +351,7 @@
 
  private:
   Major MajorKey() const { return DirectCEntry; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   bool NeedsImmovableCode() { return true; }
 };
@@ -400,7 +398,7 @@
 
   Major MajorKey() const { return NameDictionaryLookup; }
 
-  int MinorKey() const { return LookupModeBits::encode(mode_); }
+  uint32_t MinorKey() const { return LookupModeBits::encode(mode_); }
 
   class LookupModeBits: public BitField<LookupMode, 0, 1> {};
 
@@ -414,7 +412,7 @@
 
  private:
   Major MajorKey() const { return SubString; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -444,7 +442,7 @@
 
  private:
   virtual Major MajorKey() const { return StringCompare; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
   virtual void Generate(MacroAssembler* masm);
 
   static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
index d6c9ef6..b5fef7e 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -937,7 +937,7 @@
   if (length == 0) return;
 
   Handle<DeoptimizationInputData> data =
-      DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+      DeoptimizationInputData::New(isolate(), length, TENURED);
 
   Handle<ByteArray> translations =
       translations_.CreateByteArray(isolate()->factory());
@@ -3344,19 +3344,25 @@
 }
 
 
+template <class T>
+void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
+  DCHECK(FLAG_vector_ics);
+  Register vector = ToRegister(instr->temp_vector());
+  DCHECK(vector.is(LoadIC::VectorRegister()));
+  __ Mov(vector, instr->hydrogen()->feedback_vector());
+  // No need to allocate this register.
+  DCHECK(LoadIC::SlotRegister().is(x0));
+  __ Mov(LoadIC::SlotRegister(), Smi::FromInt(instr->hydrogen()->slot()));
+}
+
+
 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
   DCHECK(ToRegister(instr->context()).is(cp));
   DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
   DCHECK(ToRegister(instr->result()).Is(x0));
   __ Mov(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Mov(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(x0));
-    __ Mov(LoadIC::SlotRegister(),
-           Smi::FromInt(instr->hydrogen()->slot()));
+    EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
@@ -3611,13 +3617,7 @@
   DCHECK(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
   DCHECK(ToRegister(instr->key()).is(LoadIC::NameRegister()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Mov(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(x0));
-    __ Mov(LoadIC::SlotRegister(),
-           Smi::FromInt(instr->hydrogen()->slot()));
+    EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
@@ -3673,13 +3673,7 @@
   DCHECK(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
   __ Mov(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Mov(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(x0));
-    __ Mov(LoadIC::SlotRegister(),
-           Smi::FromInt(instr->hydrogen()->slot()));
+    EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
 
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
diff --git a/src/arm64/lithium-codegen-arm64.h b/src/arm64/lithium-codegen-arm64.h
index 7baa05d..e16d44a 100644
--- a/src/arm64/lithium-codegen-arm64.h
+++ b/src/arm64/lithium-codegen-arm64.h
@@ -196,6 +196,9 @@
                     int* offset,
                     AllocationSiteMode mode);
 
+  template <class T>
+  void EmitVectorLoadICRegisters(T* instr);
+
   // Emits optimized code for %_IsString(x).  Preserves input register.
   // Returns the condition on which a final split to
   // true and false label should be made, to optimize fallthrough.
diff --git a/src/base/bits.h b/src/base/bits.h
index 129bf62..04a0300 100644
--- a/src/base/bits.h
+++ b/src/base/bits.h
@@ -17,8 +17,8 @@
 namespace base {
 namespace bits {
 
-// CountSetBits32(value) returns the number of bits set in |value|.
-inline uint32_t CountSetBits32(uint32_t value) {
+// CountPopulation32(value) returns the number of bits set in |value|.
+inline uint32_t CountPopulation32(uint32_t value) {
 #if V8_HAS_BUILTIN_POPCOUNT
   return __builtin_popcount(value);
 #else
@@ -47,7 +47,7 @@
   value = value | (value >> 4);
   value = value | (value >> 8);
   value = value | (value >> 16);
-  return CountSetBits32(~value);
+  return CountPopulation32(~value);
 #endif
 }
 
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index fc0af00..e0e90b3 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -780,7 +780,7 @@
         name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
 #ifdef DEBUG
     LookupIterator it(prototype, factory()->constructor_string(),
-                      LookupIterator::CHECK_PROPERTY);
+                      LookupIterator::OWN_PROPERTY);
     Handle<Object> value = JSReceiver::GetProperty(&it).ToHandleChecked();
     DCHECK(it.IsFound());
     DCHECK_EQ(*isolate()->object_function(), *value);
@@ -1204,6 +1204,7 @@
                         DONT_ENUM, Representation::Tagged());
       map->AppendDescriptor(&d);
     }
+    // @@iterator method is added later.
 
     map->set_function_with_prototype(true);
     map->set_pre_allocated_property_fields(2);
@@ -1262,6 +1263,7 @@
       CallbacksDescriptor d(factory->caller_string(), caller, attributes);
       map->AppendDescriptor(&d);
     }
+    // @@iterator method is added later.
 
     map->set_function_with_prototype(true);
     map->set_prototype(native_context()->object_function()->prototype());
@@ -1596,6 +1598,7 @@
 
   INSTALL_NATIVE(Symbol, "symbolIterator", iterator_symbol);
   INSTALL_NATIVE(Symbol, "symbolUnscopables", unscopables_symbol);
+  INSTALL_NATIVE(JSFunction, "ArrayValues", array_values_iterator);
 
   INSTALL_NATIVE_MATH(abs)
   INSTALL_NATIVE_MATH(acos)
@@ -2039,6 +2042,34 @@
     native_context()->set_regexp_result_map(*initial_map);
   }
 
+  // Add @@iterator method to the arguments object maps.
+  {
+    PropertyAttributes attribs = DONT_ENUM;
+    Handle<AccessorInfo> arguments_iterator =
+        Accessors::ArgumentsIteratorInfo(isolate(), attribs);
+    {
+      CallbacksDescriptor d(Handle<Name>(native_context()->iterator_symbol()),
+                            arguments_iterator, attribs);
+      Handle<Map> map(native_context()->sloppy_arguments_map());
+      Map::EnsureDescriptorSlack(map, 1);
+      map->AppendDescriptor(&d);
+    }
+    {
+      CallbacksDescriptor d(Handle<Name>(native_context()->iterator_symbol()),
+                            arguments_iterator, attribs);
+      Handle<Map> map(native_context()->aliased_arguments_map());
+      Map::EnsureDescriptorSlack(map, 1);
+      map->AppendDescriptor(&d);
+    }
+    {
+      CallbacksDescriptor d(Handle<Name>(native_context()->iterator_symbol()),
+                            arguments_iterator, attribs);
+      Handle<Map> map(native_context()->strict_arguments_map());
+      Map::EnsureDescriptorSlack(map, 1);
+      map->AppendDescriptor(&d);
+    }
+  }
+
 #ifdef VERIFY_HEAP
   builtins->ObjectVerify();
 #endif
@@ -2449,7 +2480,7 @@
         }
         case CALLBACKS: {
           Handle<Name> key(descs->GetKey(i));
-          LookupIterator it(to, key, LookupIterator::CHECK_PROPERTY);
+          LookupIterator it(to, key, LookupIterator::OWN_PROPERTY);
           // If the property is already there we skip it
           if (it.IsFound() && it.HasProperty()) continue;
           HandleScope inner(isolate());
@@ -2480,7 +2511,7 @@
         DCHECK(raw_key->IsName());
         // If the property is already there we skip it.
         Handle<Name> key(Name::cast(raw_key));
-        LookupIterator it(to, key, LookupIterator::CHECK_PROPERTY);
+        LookupIterator it(to, key, LookupIterator::OWN_PROPERTY);
         if (it.IsFound() && it.HasProperty()) continue;
         // Set the property.
         Handle<Object> value = Handle<Object>(properties->ValueAt(i),
diff --git a/src/builtins.cc b/src/builtins.cc
index 0f7bc20..7c64f65 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -13,8 +13,8 @@
 #include "src/gdb-jit.h"
 #include "src/heap/mark-compact.h"
 #include "src/heap-profiler.h"
+#include "src/ic/handler-compiler.h"
 #include "src/ic/ic.h"
-#include "src/ic/ic-compiler.h"
 #include "src/prototype.h"
 #include "src/vm-state-inl.h"
 
@@ -1298,11 +1298,6 @@
 }
 
 
-static void Generate_StoreIC_Slow(MacroAssembler* masm) {
-  StoreIC::GenerateSlow(masm);
-}
-
-
 static void Generate_StoreIC_Miss(MacroAssembler* masm) {
   StoreIC::GenerateMiss(masm);
 }
@@ -1313,6 +1308,16 @@
 }
 
 
+static void Generate_StoreIC_Slow(MacroAssembler* masm) {
+  NamedStoreHandlerCompiler::GenerateSlow(masm);
+}
+
+
+static void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
+  ElementHandlerCompiler::GenerateStoreSlow(masm);
+}
+
+
 static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
   NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
 }
@@ -1333,11 +1338,6 @@
 }
 
 
-static void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateSlow(masm);
-}
-
-
 static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) {
   KeyedStoreIC::GenerateInitialize(masm);
 }
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index b190321..9b84122 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -9,7 +9,7 @@
 #include "src/cpu-profiler.h"
 #include "src/factory.h"
 #include "src/gdb-jit.h"
-#include "src/ic/ic-compiler.h"
+#include "src/ic/handler-compiler.h"
 #include "src/macro-assembler.h"
 
 namespace v8 {
@@ -380,7 +380,7 @@
 }
 
 
-int ICCompareStub::MinorKey() const {
+uint32_t ICCompareStub::MinorKey() const {
   return OpField::encode(op_ - Token::EQ) |
          LeftStateField::encode(left_) |
          RightStateField::encode(right_) |
@@ -690,7 +690,7 @@
       UNREACHABLE();
       break;
     case DICTIONARY_ELEMENTS:
-      ElementHandlerCompiler::GenerateStoreDictionaryElement(masm);
+      ElementHandlerCompiler::GenerateStoreSlow(masm);
       break;
     case SLOPPY_ARGUMENTS_ELEMENTS:
       UNREACHABLE();
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 4d021c2..9f18772 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -150,7 +150,7 @@
   static Major MajorKeyFromKey(uint32_t key) {
     return static_cast<Major>(MajorKeyBits::decode(key));
   }
-  static int MinorKeyFromKey(uint32_t key) {
+  static uint32_t MinorKeyFromKey(uint32_t key) {
     return MinorKeyBits::decode(key);
   }
 
@@ -163,7 +163,7 @@
 
   static const char* MajorName(Major major_key, bool allow_unknown_keys);
 
-  explicit CodeStub(Isolate* isolate) : isolate_(isolate) { }
+  explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
   virtual ~CodeStub() {}
 
   static void GenerateStubsAheadOfTime(Isolate* isolate);
@@ -182,7 +182,7 @@
 
   // Returns information for computing the number key.
   virtual Major MajorKey() const = 0;
-  virtual int MinorKey() const = 0;
+  virtual uint32_t MinorKey() const { return minor_key_; }
 
   virtual InlineCacheState GetICState() const { return UNINITIALIZED; }
   virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
@@ -215,6 +215,8 @@
     return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey());
   }
 
+  uint32_t minor_key_;
+
  private:
   // Perform bookkeeping required after code generation when stub code is
   // initially generated.
@@ -476,7 +478,7 @@
   class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {};
 
   void GenerateLightweightMiss(MacroAssembler* masm);
-  virtual int MinorKey() const {
+  virtual uint32_t MinorKey() const {
     return IsMissBits::encode(is_uninitialized_) |
         MinorKeyBits::encode(NotMissMinorKey());
   }
@@ -753,7 +755,7 @@
 
  private:
   Major MajorKey() const { return Instanceof; }
-  int MinorKey() const { return static_cast<int>(flags_); }
+  uint32_t MinorKey() const { return static_cast<int>(flags_); }
 
   bool HasArgsInRegisters() const {
     return (flags_ & kArgsInRegisters) != 0;
@@ -794,7 +796,7 @@
   virtual void PrintName(OStream& os) const V8_OVERRIDE;  // NOLINT
 
   virtual CodeStub::Major MajorKey() const { return ArrayConstructor; }
-  virtual int MinorKey() const { return argument_count_; }
+  virtual uint32_t MinorKey() const { return argument_count_; }
 
   ArgumentCountKey argument_count_;
 };
@@ -808,7 +810,7 @@
 
  private:
   virtual CodeStub::Major MajorKey() const { return InternalArrayConstructor; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
 
   void GenerateCase(MacroAssembler* masm, ElementsKind kind);
 };
@@ -824,7 +826,7 @@
 
  private:
   virtual CodeStub::Major MajorKey() const { return MathPow; }
-  virtual int MinorKey() const { return exponent_type_; }
+  virtual uint32_t MinorKey() const { return exponent_type_; }
 
   ExponentType exponent_type_;
 };
@@ -857,7 +859,7 @@
   }
 
  protected:
-  virtual int MinorKey() const { return GetExtraICState(); }
+  virtual uint32_t MinorKey() const { return GetExtraICState(); }
   virtual void PrintState(OStream& os) const V8_OVERRIDE;  // NOLINT
 
   virtual CodeStub::Major MajorKey() const { return CallIC; }
@@ -897,7 +899,7 @@
 
  private:
   virtual CodeStub::Major MajorKey() const { return FunctionPrototype; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
 };
 
 
@@ -1083,7 +1085,7 @@
  private:
   virtual void Generate(MacroAssembler* masm) V8_OVERRIDE;
   virtual Major MajorKey() const V8_OVERRIDE { return CallApiFunction; }
-  virtual int MinorKey() const V8_OVERRIDE { return bit_field_; }
+  virtual uint32_t MinorKey() const V8_OVERRIDE { return bit_field_; }
 
   class IsStoreBits: public BitField<bool, 0, 1> {};
   class CallDataUndefinedBits: public BitField<bool, 1, 1> {};
@@ -1102,7 +1104,7 @@
  private:
   virtual void Generate(MacroAssembler* masm) V8_OVERRIDE;
   virtual Major MajorKey() const V8_OVERRIDE { return CallApiGetter; }
-  virtual int MinorKey() const V8_OVERRIDE { return 0; }
+  virtual uint32_t MinorKey() const V8_OVERRIDE { return 0; }
 
   DISALLOW_COPY_AND_ASSIGN(CallApiGetterStub);
 };
@@ -1196,7 +1198,7 @@
   virtual Major MajorKey() const V8_OVERRIDE {
     return BinaryOpICWithAllocationSite;
   }
-  virtual int MinorKey() const V8_OVERRIDE { return GetExtraICState(); }
+  virtual uint32_t MinorKey() const V8_OVERRIDE { return GetExtraICState(); }
 
  private:
   static void GenerateAheadOfTime(Isolate* isolate,
@@ -1327,7 +1329,7 @@
   class HandlerStateField: public BitField<int, 11, 4> { };
 
   virtual CodeStub::Major MajorKey() const { return CompareIC; }
-  virtual int MinorKey() const;
+  virtual uint32_t MinorKey() const;
 
   virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; }
 
@@ -1460,12 +1462,15 @@
 
 class CEntryStub : public PlatformCodeStub {
  public:
-  CEntryStub(Isolate* isolate,
-             int result_size,
+  CEntryStub(Isolate* isolate, int result_size,
              SaveFPRegsMode save_doubles = kDontSaveFPRegs)
-      : PlatformCodeStub(isolate),
-        result_size_(result_size),
-        save_doubles_(save_doubles) { }
+      : PlatformCodeStub(isolate) {
+    minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs);
+    DCHECK(result_size == 1 || result_size == 2);
+#ifdef _WIN64
+    minor_key_ = ResultSizeBits::update(minor_key_, result_size);
+#endif  // _WIN64
+  }
 
   void Generate(MacroAssembler* masm);
 
@@ -1476,14 +1481,17 @@
   static void GenerateAheadOfTime(Isolate* isolate);
 
  private:
-  // Number of pointers/values returned.
-  const int result_size_;
-  SaveFPRegsMode save_doubles_;
-
   Major MajorKey() const { return CEntry; }
-  int MinorKey() const;
+
+  bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
+#ifdef _WIN64
+  int result_size() const { return ResultSizeBits::decode(minor_key_); }
+#endif  // _WIN64
 
   bool NeedsImmovableCode();
+
+  class SaveDoublesBits : public BitField<bool, 0, 1> {};
+  class ResultSizeBits : public BitField<int, 1, 3> {};
 };
 
 
@@ -1498,7 +1506,7 @@
 
  private:
   Major MajorKey() const { return JSEntry; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   virtual void FinishCode(Handle<Code> code);
 
@@ -1513,7 +1521,7 @@
   void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
 
  private:
-  int MinorKey() const { return 1; }
+  uint32_t MinorKey() const { return 1; }
 
   virtual void PrintName(OStream& os) const V8_OVERRIDE {  // NOLINT
     os << "JSConstructEntryStub";
@@ -1537,7 +1545,7 @@
   Type type_;
 
   Major MajorKey() const { return ArgumentsAccess; }
-  int MinorKey() const { return type_; }
+  uint32_t MinorKey() const { return type_; }
 
   void Generate(MacroAssembler* masm);
   void GenerateReadElement(MacroAssembler* masm);
@@ -1555,7 +1563,7 @@
 
  private:
   Major MajorKey() const { return RegExpExec; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -1615,7 +1623,7 @@
   STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits);
 
   Major MajorKey() const { return CallFunction; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     // Encode the parameters in a unique 32 bit value.
     return FlagBits::encode(flags_) | ArgcBits::encode(argc_);
   }
@@ -1650,7 +1658,7 @@
   virtual void PrintName(OStream& os) const V8_OVERRIDE;  // NOLINT
 
   Major MajorKey() const { return CallConstruct; }
-  int MinorKey() const { return flags_; }
+  uint32_t MinorKey() const { return flags_; }
 
   bool RecordCallTarget() const {
     return (flags_ & RECORD_CONSTRUCTOR_TARGET) != 0;
@@ -1859,7 +1867,7 @@
 
  private:
   Major MajorKey() const { return LoadElement; }
-  int MinorKey() const { return DICTIONARY_ELEMENTS; }
+  uint32_t MinorKey() const { return DICTIONARY_ELEMENTS; }
 
   DISALLOW_COPY_AND_ASSIGN(LoadDictionaryElementPlatformStub);
 };
@@ -1946,7 +1954,7 @@
       public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {};  // NOLINT
 
   Major MajorKey() const { return DoubleToI; }
-  int MinorKey() const { return bit_field_; }
+  uint32_t MinorKey() const { return bit_field_; }
 
   int bit_field_;
 
@@ -2282,7 +2290,7 @@
         store_mode_(store_mode) {}
 
   Major MajorKey() const { return StoreElement; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return ElementsKindBits::encode(elements_kind_) |
         IsJSArrayBits::encode(is_js_array_) |
         StoreModeBits::encode(store_mode_);
@@ -2472,7 +2480,7 @@
 
  private:
   Major MajorKey() const { return StoreArrayLiteralElement; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 
@@ -2492,7 +2500,9 @@
   class FunctionModeField: public BitField<StubFunctionMode,    0, 1> {};
 
   Major MajorKey() const { return StubFailureTrampoline; }
-  int MinorKey() const { return FunctionModeField::encode(function_mode_); }
+  uint32_t MinorKey() const {
+    return FunctionModeField::encode(function_mode_);
+  }
 
   void Generate(MacroAssembler* masm);
 
@@ -2518,7 +2528,7 @@
                                   Isolate* isolate);
 
   Major MajorKey() const { return ProfileEntryHook; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 
diff --git a/src/codegen.cc b/src/codegen.cc
index 8b54ff5..082905a 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -252,16 +252,4 @@
   }
 }
 
-
-int CEntryStub::MinorKey() const {
-  int result = (save_doubles_ == kSaveFPRegs) ? 1 : 0;
-  DCHECK(result_size_ == 1 || result_size_ == 2);
-#ifdef _WIN64
-  return result | ((result_size_ == 1) ? 0 : 2);
-#else
-  return result;
-#endif
-}
-
-
 } }  // namespace v8::internal
diff --git a/src/compiler.cc b/src/compiler.cc
index bddb327..7918920 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -414,7 +414,9 @@
     compiler::Pipeline pipeline(info());
     pipeline.GenerateCode();
     if (!info()->code().is_null()) {
-      info()->context()->native_context()->AddOptimizedCode(*info()->code());
+      if (FLAG_turbo_deoptimization) {
+        info()->context()->native_context()->AddOptimizedCode(*info()->code());
+      }
       return SetLastStatus(SUCCEEDED);
     }
   }
diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc
index 19a7b94..a8678bd 100644
--- a/src/compiler/arm/code-generator-arm.cc
+++ b/src/compiler/arm/code-generator-arm.cc
@@ -377,42 +377,49 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmLoadWord8:
+    case kArmLdrb:
       __ ldrb(i.OutputRegister(), i.InputOffset());
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
-    case kArmStoreWord8: {
+    case kArmLdrsb:
+      __ ldrsb(i.OutputRegister(), i.InputOffset());
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmStrb: {
       int index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ strb(i.InputRegister(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmLoadWord16:
+    case kArmLdrh:
       __ ldrh(i.OutputRegister(), i.InputOffset());
       break;
-    case kArmStoreWord16: {
+    case kArmLdrsh:
+      __ ldrsh(i.OutputRegister(), i.InputOffset());
+      break;
+    case kArmStrh: {
       int index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ strh(i.InputRegister(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmLoadWord32:
+    case kArmLdr:
       __ ldr(i.OutputRegister(), i.InputOffset());
       break;
-    case kArmStoreWord32: {
+    case kArmStr: {
       int index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ str(i.InputRegister(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmFloat64Load:
+    case kArmVldr64:
       __ vldr(i.OutputDoubleRegister(), i.InputOffset());
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
-    case kArmFloat64Store: {
+    case kArmVstr64: {
       int index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ vstr(i.InputDoubleRegister(index), operand);
diff --git a/src/compiler/arm/instruction-codes-arm.h b/src/compiler/arm/instruction-codes-arm.h
index 1d5b5c7..ab86ce4 100644
--- a/src/compiler/arm/instruction-codes-arm.h
+++ b/src/compiler/arm/instruction-codes-arm.h
@@ -50,14 +50,16 @@
   V(ArmVcvtF64U32)                 \
   V(ArmVcvtS32F64)                 \
   V(ArmVcvtU32F64)                 \
-  V(ArmFloat64Load)                \
-  V(ArmFloat64Store)               \
-  V(ArmLoadWord8)                  \
-  V(ArmStoreWord8)                 \
-  V(ArmLoadWord16)                 \
-  V(ArmStoreWord16)                \
-  V(ArmLoadWord32)                 \
-  V(ArmStoreWord32)                \
+  V(ArmVldr64)                     \
+  V(ArmVstr64)                     \
+  V(ArmLdrb)                       \
+  V(ArmLdrsb)                      \
+  V(ArmStrb)                       \
+  V(ArmLdrh)                       \
+  V(ArmLdrsh)                      \
+  V(ArmStrh)                       \
+  V(ArmLdr)                        \
+  V(ArmStr)                        \
   V(ArmStoreWriteBarrier)
 
 
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
index 3bf7e2f..6ec86bd 100644
--- a/src/compiler/arm/instruction-selector-arm.cc
+++ b/src/compiler/arm/instruction-selector-arm.cc
@@ -55,19 +55,21 @@
       case kArmRsb:
         return ImmediateFitsAddrMode1Instruction(value);
 
-      case kArmFloat64Load:
-      case kArmFloat64Store:
+      case kArmVldr64:
+      case kArmVstr64:
         return value >= -1020 && value <= 1020 && (value % 4) == 0;
 
-      case kArmLoadWord8:
-      case kArmStoreWord8:
-      case kArmLoadWord32:
-      case kArmStoreWord32:
+      case kArmLdrb:
+      case kArmLdrsb:
+      case kArmStrb:
+      case kArmLdr:
+      case kArmStr:
       case kArmStoreWriteBarrier:
         return value >= -4095 && value <= 4095;
 
-      case kArmLoadWord16:
-      case kArmStoreWord16:
+      case kArmLdrh:
+      case kArmLdrsh:
+      case kArmStrh:
         return value >= -255 && value <= 255;
 
       case kArchJmp:
@@ -287,6 +289,7 @@
 
 void InstructionSelector::VisitLoad(Node* node) {
   MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
   ArmOperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -296,21 +299,20 @@
                                    : g.DefineAsRegister(node);
 
   ArchOpcode opcode;
-  // TODO(titzer): signed/unsigned small loads
   switch (rep) {
     case kRepFloat64:
-      opcode = kArmFloat64Load;
+      opcode = kArmVldr64;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = kArmLoadWord8;
+      opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb;
       break;
     case kRepWord16:
-      opcode = kArmLoadWord16;
+      opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord32:
-      opcode = kArmLoadWord32;
+      opcode = kArmLdr;
       break;
     default:
       UNREACHABLE();
@@ -320,9 +322,6 @@
   if (g.CanBeImmediate(index, opcode)) {
     Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result,
          g.UseRegister(base), g.UseImmediate(index));
-  } else if (g.CanBeImmediate(base, opcode)) {
-    Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result,
-         g.UseRegister(index), g.UseImmediate(base));
   } else {
     Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), result,
          g.UseRegister(base), g.UseRegister(index));
@@ -356,18 +355,18 @@
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat64:
-      opcode = kArmFloat64Store;
+      opcode = kArmVstr64;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = kArmStoreWord8;
+      opcode = kArmStrb;
       break;
     case kRepWord16:
-      opcode = kArmStoreWord16;
+      opcode = kArmStrh;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord32:
-      opcode = kArmStoreWord32;
+      opcode = kArmStr;
       break;
     default:
       UNREACHABLE();
@@ -377,9 +376,6 @@
   if (g.CanBeImmediate(index, opcode)) {
     Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL,
          g.UseRegister(base), g.UseImmediate(index), val);
-  } else if (g.CanBeImmediate(base, opcode)) {
-    Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL,
-         g.UseRegister(index), g.UseImmediate(base), val);
   } else {
     Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL,
          g.UseRegister(base), g.UseRegister(index), val);
@@ -423,7 +419,7 @@
   }
   if (IsSupported(ARMv7) && m.right().HasValue()) {
     uint32_t value = m.right().Value();
-    uint32_t width = base::bits::CountSetBits32(value);
+    uint32_t width = base::bits::CountPopulation32(value);
     uint32_t msb = base::bits::CountLeadingZeros32(value);
     if (width != 0 && msb + width == 32) {
       DCHECK_EQ(0, base::bits::CountTrailingZeros32(value));
@@ -536,7 +532,7 @@
     Int32BinopMatcher mleft(m.left().node());
     if (mleft.right().HasValue()) {
       uint32_t value = (mleft.right().Value() >> lsb) << lsb;
-      uint32_t width = base::bits::CountSetBits32(value);
+      uint32_t width = base::bits::CountPopulation32(value);
       uint32_t msb = base::bits::CountLeadingZeros32(value);
       if (msb + width + lsb == 32) {
         DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(value));
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc
index ab0236f..baacc85 100644
--- a/src/compiler/arm64/code-generator-arm64.cc
+++ b/src/compiler/arm64/code-generator-arm64.cc
@@ -396,34 +396,40 @@
     case kArm64Uint32ToFloat64:
       __ Ucvtf(i.OutputDoubleRegister(), i.InputRegister32(0));
       break;
-    case kArm64LoadWord8:
+    case kArm64Ldrb:
       __ Ldrb(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kArm64StoreWord8:
+    case kArm64Ldrsb:
+      __ Ldrsb(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kArm64Strb:
       __ Strb(i.InputRegister(2), i.MemoryOperand());
       break;
-    case kArm64LoadWord16:
+    case kArm64Ldrh:
       __ Ldrh(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kArm64StoreWord16:
+    case kArm64Ldrsh:
+      __ Ldrsh(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kArm64Strh:
       __ Strh(i.InputRegister(2), i.MemoryOperand());
       break;
-    case kArm64LoadWord32:
+    case kArm64LdrW:
       __ Ldr(i.OutputRegister32(), i.MemoryOperand());
       break;
-    case kArm64StoreWord32:
+    case kArm64StrW:
       __ Str(i.InputRegister32(2), i.MemoryOperand());
       break;
-    case kArm64LoadWord64:
+    case kArm64Ldr:
       __ Ldr(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kArm64StoreWord64:
+    case kArm64Str:
       __ Str(i.InputRegister(2), i.MemoryOperand());
       break;
-    case kArm64Float64Load:
+    case kArm64LdrD:
       __ Ldr(i.OutputDoubleRegister(), i.MemoryOperand());
       break;
-    case kArm64Float64Store:
+    case kArm64StrD:
       __ Str(i.InputDoubleRegister(2), i.MemoryOperand());
       break;
     case kArm64StoreWriteBarrier: {
diff --git a/src/compiler/arm64/instruction-codes-arm64.h b/src/compiler/arm64/instruction-codes-arm64.h
index cb4d18e..bce47f8 100644
--- a/src/compiler/arm64/instruction-codes-arm64.h
+++ b/src/compiler/arm64/instruction-codes-arm64.h
@@ -68,16 +68,18 @@
   V(Arm64Float64ToUint32)          \
   V(Arm64Int32ToFloat64)           \
   V(Arm64Uint32ToFloat64)          \
-  V(Arm64Float64Load)              \
-  V(Arm64Float64Store)             \
-  V(Arm64LoadWord8)                \
-  V(Arm64StoreWord8)               \
-  V(Arm64LoadWord16)               \
-  V(Arm64StoreWord16)              \
-  V(Arm64LoadWord32)               \
-  V(Arm64StoreWord32)              \
-  V(Arm64LoadWord64)               \
-  V(Arm64StoreWord64)              \
+  V(Arm64LdrD)                     \
+  V(Arm64StrD)                     \
+  V(Arm64Ldrb)                     \
+  V(Arm64Ldrsb)                    \
+  V(Arm64Strb)                     \
+  V(Arm64Ldrh)                     \
+  V(Arm64Ldrsh)                    \
+  V(Arm64Strh)                     \
+  V(Arm64LdrW)                     \
+  V(Arm64StrW)                     \
+  V(Arm64Ldr)                      \
+  V(Arm64Str)                      \
   V(Arm64StoreWriteBarrier)
 
 
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
index dd1857b..410105c 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -143,6 +143,7 @@
 
 void InstructionSelector::VisitLoad(Node* node) {
   MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
   Arm64OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -155,21 +156,21 @@
   // TODO(titzer): signed/unsigned small loads
   switch (rep) {
     case kRepFloat64:
-      opcode = kArm64Float64Load;
+      opcode = kArm64LdrD;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = kArm64LoadWord8;
+      opcode = typ == kTypeInt32 ? kArm64Ldrsb : kArm64Ldrb;
       break;
     case kRepWord16:
-      opcode = kArm64LoadWord16;
+      opcode = typ == kTypeInt32 ? kArm64Ldrsh : kArm64Ldrh;
       break;
     case kRepWord32:
-      opcode = kArm64LoadWord32;
+      opcode = kArm64LdrW;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord64:
-      opcode = kArm64LoadWord64;
+      opcode = kArm64Ldr;
       break;
     default:
       UNREACHABLE();
@@ -178,9 +179,6 @@
   if (g.CanBeImmediate(index, kLoadStoreImm)) {
     Emit(opcode | AddressingModeField::encode(kMode_MRI), result,
          g.UseRegister(base), g.UseImmediate(index));
-  } else if (g.CanBeImmediate(base, kLoadStoreImm)) {
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), result,
-         g.UseRegister(index), g.UseImmediate(base));
   } else {
     Emit(opcode | AddressingModeField::encode(kMode_MRR), result,
          g.UseRegister(base), g.UseRegister(index));
@@ -217,21 +215,21 @@
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat64:
-      opcode = kArm64Float64Store;
+      opcode = kArm64StrD;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = kArm64StoreWord8;
+      opcode = kArm64Strb;
       break;
     case kRepWord16:
-      opcode = kArm64StoreWord16;
+      opcode = kArm64Strh;
       break;
     case kRepWord32:
-      opcode = kArm64StoreWord32;
+      opcode = kArm64StrW;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord64:
-      opcode = kArm64StoreWord64;
+      opcode = kArm64Str;
       break;
     default:
       UNREACHABLE();
@@ -240,9 +238,6 @@
   if (g.CanBeImmediate(index, kLoadStoreImm)) {
     Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
          g.UseRegister(base), g.UseImmediate(index), val);
-  } else if (g.CanBeImmediate(base, kLoadStoreImm)) {
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-         g.UseRegister(index), g.UseImmediate(base), val);
   } else {
     Emit(opcode | AddressingModeField::encode(kMode_MRR), NULL,
          g.UseRegister(base), g.UseRegister(index), val);
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 66a371b..0e642c9 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -744,13 +744,13 @@
         // Bind value and do loop body.
         VisitForInAssignment(stmt->each(), value);
         VisitIterationBody(stmt, &for_loop, 5);
+        for_loop.EndBody();
         // Inc counter and continue.
         Node* index_inc =
             NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
         // TODO(jarin): provide real bailout id.
         PrepareFrameState(index_inc, BailoutId::None());
         environment()->Poke(0, index_inc);
-        for_loop.EndBody();
         for_loop.EndLoop();
         environment()->Drop(5);
         // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc
index 5a5d9f9..1cbb596 100644
--- a/src/compiler/code-generator.cc
+++ b/src/compiler/code-generator.cc
@@ -53,6 +53,7 @@
 
   FinishCode(masm());
 
+  UpdateSafepointsWithDeoptimizationPc();
   safepoints()->Emit(masm(), frame()->GetSpillSlotCount());
 
   // TODO(titzer): what are the right code flags here?
@@ -76,9 +77,10 @@
 }
 
 
-void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
-                                    int arguments,
-                                    Safepoint::DeoptMode deopt_mode) {
+Safepoint::Id CodeGenerator::RecordSafepoint(PointerMap* pointers,
+                                             Safepoint::Kind kind,
+                                             int arguments,
+                                             Safepoint::DeoptMode deopt_mode) {
   const ZoneList<InstructionOperand*>* operands =
       pointers->GetNormalizedOperands();
   Safepoint safepoint =
@@ -92,6 +94,7 @@
       safepoint.DefinePointerRegister(reg, zone());
     }
   }
+  return safepoint.id();
 }
 
 
@@ -172,13 +175,25 @@
 }
 
 
+void CodeGenerator::UpdateSafepointsWithDeoptimizationPc() {
+  int patch_count = static_cast<int>(lazy_deoptimization_entries_.size());
+  for (int i = 0; i < patch_count; ++i) {
+    LazyDeoptimizationEntry entry = lazy_deoptimization_entries_[i];
+    // TODO(jarin) make sure that there is no code (other than nops)
+    // between the call position and the continuation position.
+    safepoints()->SetDeoptimizationPc(entry.safepoint_id(),
+                                      entry.deoptimization()->pos());
+  }
+}
+
+
 void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
   CompilationInfo* info = linkage()->info();
   int deopt_count = code()->GetDeoptimizationEntryCount();
   int patch_count = static_cast<int>(lazy_deoptimization_entries_.size());
   if (patch_count == 0 && deopt_count == 0) return;
-  Handle<DeoptimizationInputData> data = DeoptimizationInputData::New(
-      isolate(), deopt_count, patch_count, TENURED);
+  Handle<DeoptimizationInputData> data =
+      DeoptimizationInputData::New(isolate(), deopt_count, TENURED);
 
   Handle<ByteArray> translation_array =
       translations_.CreateByteArray(isolate()->factory());
@@ -222,13 +237,6 @@
     data->SetPc(i, Smi::FromInt(-1));
   }
 
-  // Populate the return address patcher entries.
-  for (int i = 0; i < patch_count; ++i) {
-    LazyDeoptimizationEntry entry = lazy_deoptimization_entries_[i];
-    data->SetReturnAddressPc(i, Smi::FromInt(entry.position_after_call()));
-    data->SetPatchedAddressPc(i, Smi::FromInt(entry.deoptimization()->pos()));
-  }
-
   code_object->set_deoptimization_data(*data);
 }
 
@@ -238,30 +246,43 @@
       static_cast<CallDescriptor::DeoptimizationSupport>(
           MiscField::decode(instr->opcode()));
 
-  if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) {
-    RecordLazyDeoptimizationEntry(instr);
-  }
-
   bool needs_frame_state = (deopt & CallDescriptor::kNeedsFrameState) != 0;
 
-  RecordSafepoint(
+  Safepoint::Id safepoint_id = RecordSafepoint(
       instr->pointer_map(), Safepoint::kSimple, 0,
       needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt);
 
-  if ((deopt & CallDescriptor::kNeedsFrameState) != 0) {
+  if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) {
+    RecordLazyDeoptimizationEntry(instr, safepoint_id);
+  }
+
+  if (needs_frame_state) {
     // If the frame state is present, it starts at argument 1
     // (just after the code address).
     InstructionOperandConverter converter(this, instr);
     // Argument 1 is deoptimization id.
     int deoptimization_id = converter.ToConstant(instr->InputAt(1)).ToInt32();
     // The actual frame state values start with argument 2.
-    BuildTranslation(instr, 2, deoptimization_id);
+    int first_state_value_offset = 2;
+#if DEBUG
+    // Make sure all the values live in stack slots or they are immediates.
+    // (The values should not live in register because registers are clobbered
+    // by calls.)
+    FrameStateDescriptor* descriptor =
+        code()->GetDeoptimizationEntry(deoptimization_id);
+    for (int i = 0; i < descriptor->size(); i++) {
+      InstructionOperand* op = instr->InputAt(first_state_value_offset + i);
+      CHECK(op->IsStackSlot() || op->IsImmediate());
+    }
+#endif
+    BuildTranslation(instr, first_state_value_offset, deoptimization_id);
     safepoints()->RecordLazyDeoptimizationIndex(deoptimization_id);
   }
 }
 
 
-void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr) {
+void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr,
+                                                  Safepoint::Id safepoint_id) {
   InstructionOperandConverter i(this, instr);
 
   Label after_call;
@@ -276,8 +297,8 @@
   Label* cont_label = code_->GetLabel(cont_block);
   Label* deopt_label = code_->GetLabel(deopt_block);
 
-  lazy_deoptimization_entries_.push_back(
-      LazyDeoptimizationEntry(after_call.pos(), cont_label, deopt_label));
+  lazy_deoptimization_entries_.push_back(LazyDeoptimizationEntry(
+      after_call.pos(), cont_label, deopt_label, safepoint_id));
 }
 
 
diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h
index 8bacdf3..14ee351 100644
--- a/src/compiler/code-generator.h
+++ b/src/compiler/code-generator.h
@@ -46,8 +46,8 @@
   }
 
   // Record a safepoint with the given pointer map.
-  void RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
-                       int arguments, Safepoint::DeoptMode deopt_mode);
+  Safepoint::Id RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
+                                int arguments, Safepoint::DeoptMode deopt_mode);
 
   // Assemble code for the specified instruction.
   void AssembleInstruction(Instruction* instr);
@@ -82,7 +82,9 @@
   // ===========================================================================
   // Deoptimization table construction
   void AddSafepointAndDeopt(Instruction* instr);
-  void RecordLazyDeoptimizationEntry(Instruction* instr);
+  void UpdateSafepointsWithDeoptimizationPc();
+  void RecordLazyDeoptimizationEntry(Instruction* instr,
+                                     Safepoint::Id safepoint_id);
   void PopulateDeoptimizationData(Handle<Code> code);
   int DefineDeoptimizationLiteral(Handle<Object> literal);
   void BuildTranslation(Instruction* instr, int first_argument_index,
@@ -95,19 +97,22 @@
   class LazyDeoptimizationEntry V8_FINAL {
    public:
     LazyDeoptimizationEntry(int position_after_call, Label* continuation,
-                            Label* deoptimization)
+                            Label* deoptimization, Safepoint::Id safepoint_id)
         : position_after_call_(position_after_call),
           continuation_(continuation),
-          deoptimization_(deoptimization) {}
+          deoptimization_(deoptimization),
+          safepoint_id_(safepoint_id) {}
 
     int position_after_call() const { return position_after_call_; }
     Label* continuation() const { return continuation_; }
     Label* deoptimization() const { return deoptimization_; }
+    Safepoint::Id safepoint_id() const { return safepoint_id_; }
 
    private:
     int position_after_call_;
     Label* continuation_;
     Label* deoptimization_;
+    Safepoint::Id safepoint_id_;
   };
 
   struct DeoptimizationState : ZoneObject {
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc
index 6730469..19b4ddf 100644
--- a/src/compiler/ia32/code-generator-ia32.cc
+++ b/src/compiler/ia32/code-generator-ia32.cc
@@ -335,60 +335,60 @@
       // TODO(turbofan): IA32 SSE LoadUint32() should take an operand.
       __ LoadUint32(i.OutputDoubleRegister(), i.InputRegister(0));
       break;
-    case kSSELoad:
-      __ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
+    case kIA32Movsxbl:
+      __ movsx_b(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kSSEStore: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movsd(operand, i.InputDoubleRegister(index));
-      break;
-    }
-    case kIA32LoadWord8:
+    case kIA32Movzxbl:
       __ movzx_b(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kIA32StoreWord8: {
+    case kIA32Movb: {
       int index = 0;
       Operand operand = i.MemoryOperand(&index);
-      __ mov_b(operand, i.InputRegister(index));
+      if (HasImmediateInput(instr, index)) {
+        __ mov_b(operand, i.InputInt8(index));
+      } else {
+        __ mov_b(operand, i.InputRegister(index));
+      }
       break;
     }
-    case kIA32StoreWord8I: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ mov_b(operand, i.InputInt8(index));
+    case kIA32Movsxwl:
+      __ movsx_w(i.OutputRegister(), i.MemoryOperand());
       break;
-    }
-    case kIA32LoadWord16:
+    case kIA32Movzxwl:
       __ movzx_w(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kIA32StoreWord16: {
+    case kIA32Movw: {
       int index = 0;
       Operand operand = i.MemoryOperand(&index);
-      __ mov_w(operand, i.InputRegister(index));
+      if (HasImmediateInput(instr, index)) {
+        __ mov_w(operand, i.InputInt16(index));
+      } else {
+        __ mov_w(operand, i.InputRegister(index));
+      }
       break;
     }
-    case kIA32StoreWord16I: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ mov_w(operand, i.InputInt16(index));
+    case kIA32Movl:
+      if (instr->HasOutput()) {
+        __ mov(i.OutputRegister(), i.MemoryOperand());
+      } else {
+        int index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        if (HasImmediateInput(instr, index)) {
+          __ mov(operand, i.InputImmediate(index));
+        } else {
+          __ mov(operand, i.InputRegister(index));
+        }
+      }
       break;
-    }
-    case kIA32LoadWord32:
-      __ mov(i.OutputRegister(), i.MemoryOperand());
+    case kIA32Movsd:
+      if (instr->HasOutput()) {
+        __ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
+      } else {
+        int index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        __ movsd(operand, i.InputDoubleRegister(index));
+      }
       break;
-    case kIA32StoreWord32: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ mov(operand, i.InputRegister(index));
-      break;
-    }
-    case kIA32StoreWord32I: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ mov(operand, i.InputImmediate(index));
-      break;
-    }
     case kIA32StoreWriteBarrier: {
       Register object = i.InputRegister(0);
       Register index = i.InputRegister(1);
diff --git a/src/compiler/ia32/instruction-codes-ia32.h b/src/compiler/ia32/instruction-codes-ia32.h
index 0b0944e..9ddff37 100644
--- a/src/compiler/ia32/instruction-codes-ia32.h
+++ b/src/compiler/ia32/instruction-codes-ia32.h
@@ -43,17 +43,14 @@
   V(SSEFloat64ToUint32)            \
   V(SSEInt32ToFloat64)             \
   V(SSEUint32ToFloat64)            \
-  V(SSELoad)                       \
-  V(SSEStore)                      \
-  V(IA32LoadWord8)                 \
-  V(IA32StoreWord8)                \
-  V(IA32StoreWord8I)               \
-  V(IA32LoadWord16)                \
-  V(IA32StoreWord16)               \
-  V(IA32StoreWord16I)              \
-  V(IA32LoadWord32)                \
-  V(IA32StoreWord32)               \
-  V(IA32StoreWord32I)              \
+  V(IA32Movsxbl)                   \
+  V(IA32Movzxbl)                   \
+  V(IA32Movb)                      \
+  V(IA32Movsxwl)                   \
+  V(IA32Movzxwl)                   \
+  V(IA32Movw)                      \
+  V(IA32Movl)                      \
+  V(IA32Movsd)                     \
   V(IA32StoreWriteBarrier)
 
 
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc
index ef7d36a..03f35fe 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -42,6 +42,7 @@
 
 void InstructionSelector::VisitLoad(Node* node) {
   MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
   IA32OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -53,18 +54,18 @@
   // TODO(titzer): signed/unsigned small loads
   switch (rep) {
     case kRepFloat64:
-      opcode = kSSELoad;
+      opcode = kIA32Movsd;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = kIA32LoadWord8;
+      opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl;
       break;
     case kRepWord16:
-      opcode = kIA32LoadWord16;
+      opcode = typ == kTypeInt32 ? kIA32Movsxwl : kIA32Movzxwl;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord32:
-      opcode = kIA32LoadWord32;
+      opcode = kIA32Movl;
       break;
     default:
       UNREACHABLE();
@@ -109,13 +110,11 @@
     return;
   }
   DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind);
-  bool is_immediate = false;
   InstructionOperand* val;
   if (rep == kRepFloat64) {
     val = g.UseDoubleRegister(value);
   } else {
-    is_immediate = g.CanBeImmediate(value);
-    if (is_immediate) {
+    if (g.CanBeImmediate(value)) {
       val = g.UseImmediate(value);
     } else if (rep == kRepWord8 || rep == kRepBit) {
       val = g.UseByteRegister(value);
@@ -126,18 +125,18 @@
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat64:
-      opcode = kSSEStore;
+      opcode = kIA32Movsd;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = is_immediate ? kIA32StoreWord8I : kIA32StoreWord8;
+      opcode = kIA32Movb;
       break;
     case kRepWord16:
-      opcode = is_immediate ? kIA32StoreWord16I : kIA32StoreWord16;
+      opcode = kIA32Movw;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord32:
-      opcode = is_immediate ? kIA32StoreWord32I : kIA32StoreWord32;
+      opcode = kIA32Movl;
       break;
     default:
       UNREACHABLE();
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
index 0d014a5..143bd69 100644
--- a/src/compiler/instruction-selector.cc
+++ b/src/compiler/instruction-selector.cc
@@ -284,9 +284,8 @@
     if (buffer->descriptor->ReturnCount() == 1) {
       buffer->output_nodes.push_back(call);
     } else {
+      buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL);
       call->CollectProjections(&buffer->output_nodes);
-      DCHECK(buffer->output_nodes.size() <=
-             static_cast<size_t>(buffer->descriptor->ReturnCount()));
     }
 
     // Filter out the outputs that aren't live because no projection uses them.
@@ -1039,7 +1038,7 @@
     case IrOpcode::kHeapConstant:
       return g->UseImmediate(input);
     default:
-      return g->Use(input);
+      return g->UseUnique(input);
   }
 }
 
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h
index 31f3175..da01351 100644
--- a/src/compiler/instruction.h
+++ b/src/compiler/instruction.h
@@ -405,12 +405,14 @@
 class Instruction : public ZoneObject {
  public:
   size_t OutputCount() const { return OutputCountField::decode(bit_field_); }
-  InstructionOperand* Output() const { return OutputAt(0); }
   InstructionOperand* OutputAt(size_t i) const {
     DCHECK(i < OutputCount());
     return operands_[i];
   }
 
+  bool HasOutput() const { return OutputCount() == 1; }
+  InstructionOperand* Output() const { return OutputAt(0); }
+
   size_t InputCount() const { return InputCountField::decode(bit_field_); }
   InstructionOperand* InputAt(size_t i) const {
     DCHECK(i < InputCount());
diff --git a/src/compiler/machine-type.cc b/src/compiler/machine-type.cc
index 33ac20f..b27727c 100644
--- a/src/compiler/machine-type.cc
+++ b/src/compiler/machine-type.cc
@@ -11,11 +11,12 @@
 
 #define PRINT(bit)         \
   if (type & bit) {        \
-    if (before) os << "+"; \
+    if (before) os << "|"; \
     os << #bit;            \
     before = true;         \
   }
 
+
 OStream& operator<<(OStream& os, const MachineType& type) {
   bool before = false;
   PRINT(kRepBit);
@@ -35,6 +36,10 @@
   PRINT(kTypeAny);
   return os;
 }
-}
-}
-}  // namespace v8::internal::compiler
+
+
+#undef PRINT
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/machine-type.h b/src/compiler/machine-type.h
index a26b644..3b1b9bd 100644
--- a/src/compiler/machine-type.h
+++ b/src/compiler/machine-type.h
@@ -70,6 +70,12 @@
 const MachineType kMachAnyTagged =
     static_cast<MachineType>(kRepTagged | kTypeAny);
 
+// Gets only the type of the given type.
+inline MachineType TypeOf(MachineType machine_type) {
+  int result = machine_type & kTypeMask;
+  return static_cast<MachineType>(result);
+}
+
 // Gets only the representation of the given type.
 inline MachineType RepresentationOf(MachineType machine_type) {
   int result = machine_type & kRepMask;
@@ -97,8 +103,9 @@
       return kPointerSize;
   }
 }
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_MACHINE_TYPE_H_
diff --git a/src/compiler/node.cc b/src/compiler/node.cc
index c60822e..dcb3bfe 100644
--- a/src/compiler/node.cc
+++ b/src/compiler/node.cc
@@ -11,10 +11,16 @@
 namespace compiler {
 
 void Node::CollectProjections(NodeVector* projections) {
+  for (size_t i = 0; i < projections->size(); i++) {
+    (*projections)[i] = NULL;
+  }
   for (UseIter i = uses().begin(); i != uses().end(); ++i) {
     if ((*i)->opcode() != IrOpcode::kProjection) continue;
-    DCHECK_GE(OpParameter<int32_t>(*i), 0);
-    projections->push_back(*i);
+    int32_t index = OpParameter<int32_t>(*i);
+    DCHECK_GE(index, 0);
+    DCHECK_LT(index, static_cast<int32_t>(projections->size()));
+    DCHECK_EQ(NULL, (*projections)[index]);
+    (*projections)[index] = *i;
   }
 }
 
diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc
index 091dd60..9506525 100644
--- a/src/compiler/x64/code-generator-x64.cc
+++ b/src/compiler/x64/code-generator-x64.cc
@@ -391,24 +391,6 @@
     case kX64PushI:
       __ pushq(i.InputImmediate(0));
       break;
-    case kX64Movl: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kRegister) {
-        __ movl(i.OutputRegister(), input.reg);
-      } else {
-        __ movl(i.OutputRegister(), input.operand);
-      }
-      break;
-    }
-    case kX64Movsxlq: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kRegister) {
-        __ movsxlq(i.OutputRegister(), input.reg);
-      } else {
-        __ movsxlq(i.OutputRegister(), input.operand);
-      }
-      break;
-    }
     case kX64CallCodeObject: {
       if (HasImmediateInput(instr, 0)) {
         Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
@@ -532,75 +514,91 @@
       break;
     }
 
-    case kSSELoad:
-      __ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
+    case kX64Movsd:
+      if (instr->HasOutput()) {
+        __ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
+      } else {
+        int index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        __ movsd(operand, i.InputDoubleRegister(index));
+      }
       break;
-    case kSSEStore: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movsd(operand, i.InputDoubleRegister(index));
+    case kX64Movsxbl:
+      __ movsxbl(i.OutputRegister(), i.MemoryOperand());
       break;
-    }
-    case kX64LoadWord8:
+    case kX64Movzxbl:
       __ movzxbl(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kX64StoreWord8: {
+    case kX64Movb: {
       int index = 0;
       Operand operand = i.MemoryOperand(&index);
-      __ movb(operand, i.InputRegister(index));
+      if (HasImmediateInput(instr, index)) {
+        __ movb(operand, Immediate(i.InputInt8(index)));
+      } else {
+        __ movb(operand, i.InputRegister(index));
+      }
       break;
     }
-    case kX64StoreWord8I: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movb(operand, Immediate(i.InputInt8(index)));
+    case kX64Movsxwl:
+      __ movsxwl(i.OutputRegister(), i.MemoryOperand());
       break;
-    }
-    case kX64LoadWord16:
+    case kX64Movzxwl:
       __ movzxwl(i.OutputRegister(), i.MemoryOperand());
       break;
-    case kX64StoreWord16: {
+    case kX64Movw: {
       int index = 0;
       Operand operand = i.MemoryOperand(&index);
-      __ movw(operand, i.InputRegister(index));
+      if (HasImmediateInput(instr, index)) {
+        __ movw(operand, Immediate(i.InputInt16(index)));
+      } else {
+        __ movw(operand, i.InputRegister(index));
+      }
       break;
     }
-    case kX64StoreWord16I: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movw(operand, Immediate(i.InputInt16(index)));
+    case kX64Movl:
+      if (instr->HasOutput()) {
+        if (instr->addressing_mode() == kMode_None) {
+          RegisterOrOperand input = i.InputRegisterOrOperand(0);
+          if (input.type == kRegister) {
+            __ movl(i.OutputRegister(), input.reg);
+          } else {
+            __ movl(i.OutputRegister(), input.operand);
+          }
+        } else {
+          __ movl(i.OutputRegister(), i.MemoryOperand());
+        }
+      } else {
+        int index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        if (HasImmediateInput(instr, index)) {
+          __ movl(operand, i.InputImmediate(index));
+        } else {
+          __ movl(operand, i.InputRegister(index));
+        }
+      }
+      break;
+    case kX64Movsxlq: {
+      RegisterOrOperand input = i.InputRegisterOrOperand(0);
+      if (input.type == kRegister) {
+        __ movsxlq(i.OutputRegister(), input.reg);
+      } else {
+        __ movsxlq(i.OutputRegister(), input.operand);
+      }
       break;
     }
-    case kX64LoadWord32:
-      __ movl(i.OutputRegister(), i.MemoryOperand());
+    case kX64Movq:
+      if (instr->HasOutput()) {
+        __ movq(i.OutputRegister(), i.MemoryOperand());
+      } else {
+        int index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        if (HasImmediateInput(instr, index)) {
+          __ movq(operand, i.InputImmediate(index));
+        } else {
+          __ movq(operand, i.InputRegister(index));
+        }
+      }
       break;
-    case kX64StoreWord32: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movl(operand, i.InputRegister(index));
-      break;
-    }
-    case kX64StoreWord32I: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movl(operand, i.InputImmediate(index));
-      break;
-    }
-    case kX64LoadWord64:
-      __ movq(i.OutputRegister(), i.MemoryOperand());
-      break;
-    case kX64StoreWord64: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movq(operand, i.InputRegister(index));
-      break;
-    }
-    case kX64StoreWord64I: {
-      int index = 0;
-      Operand operand = i.MemoryOperand(&index);
-      __ movq(operand, i.InputImmediate(index));
-      break;
-    }
     case kX64StoreWriteBarrier: {
       Register object = i.InputRegister(0);
       Register index = i.InputRegister(1);
diff --git a/src/compiler/x64/instruction-codes-x64.h b/src/compiler/x64/instruction-codes-x64.h
index 1345ce7..b0a1595 100644
--- a/src/compiler/x64/instruction-codes-x64.h
+++ b/src/compiler/x64/instruction-codes-x64.h
@@ -46,8 +46,6 @@
   V(X64Ror32)                      \
   V(X64Push)                       \
   V(X64PushI)                      \
-  V(X64Movsxlq)                    \
-  V(X64Movl)                       \
   V(X64CallCodeObject)             \
   V(X64CallAddress)                \
   V(PopStack)                      \
@@ -62,20 +60,16 @@
   V(SSEFloat64ToUint32)            \
   V(SSEInt32ToFloat64)             \
   V(SSEUint32ToFloat64)            \
-  V(SSELoad)                       \
-  V(SSEStore)                      \
-  V(X64LoadWord8)                  \
-  V(X64StoreWord8)                 \
-  V(X64StoreWord8I)                \
-  V(X64LoadWord16)                 \
-  V(X64StoreWord16)                \
-  V(X64StoreWord16I)               \
-  V(X64LoadWord32)                 \
-  V(X64StoreWord32)                \
-  V(X64StoreWord32I)               \
-  V(X64LoadWord64)                 \
-  V(X64StoreWord64)                \
-  V(X64StoreWord64I)               \
+  V(X64Movsd)                      \
+  V(X64Movsxbl)                    \
+  V(X64Movzxbl)                    \
+  V(X64Movb)                       \
+  V(X64Movsxwl)                    \
+  V(X64Movzxwl)                    \
+  V(X64Movw)                       \
+  V(X64Movl)                       \
+  V(X64Movsxlq)                    \
+  V(X64Movq)                       \
   V(X64StoreWriteBarrier)
 
 
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc
index 1dad9ee..138a63d 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -57,6 +57,7 @@
 
 void InstructionSelector::VisitLoad(Node* node) {
   MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
   X64OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -68,21 +69,21 @@
   // TODO(titzer): signed/unsigned small loads
   switch (rep) {
     case kRepFloat64:
-      opcode = kSSELoad;
+      opcode = kX64Movsd;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = kX64LoadWord8;
+      opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl;
       break;
     case kRepWord16:
-      opcode = kX64LoadWord16;
+      opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl;
       break;
     case kRepWord32:
-      opcode = kX64LoadWord32;
+      opcode = kX64Movl;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord64:
-      opcode = kX64LoadWord64;
+      opcode = kX64Movq;
       break;
     default:
       UNREACHABLE();
@@ -123,13 +124,11 @@
     return;
   }
   DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind);
-  bool is_immediate = false;
   InstructionOperand* val;
   if (rep == kRepFloat64) {
     val = g.UseDoubleRegister(value);
   } else {
-    is_immediate = g.CanBeImmediate(value);
-    if (is_immediate) {
+    if (g.CanBeImmediate(value)) {
       val = g.UseImmediate(value);
     } else if (rep == kRepWord8 || rep == kRepBit) {
       val = g.UseByteRegister(value);
@@ -140,21 +139,21 @@
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat64:
-      opcode = kSSEStore;
+      opcode = kX64Movsd;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
-      opcode = is_immediate ? kX64StoreWord8I : kX64StoreWord8;
+      opcode = kX64Movb;
       break;
     case kRepWord16:
-      opcode = is_immediate ? kX64StoreWord16I : kX64StoreWord16;
+      opcode = kX64Movw;
       break;
     case kRepWord32:
-      opcode = is_immediate ? kX64StoreWord32I : kX64StoreWord32;
+      opcode = kX64Movl;
       break;
     case kRepTagged:  // Fall through.
     case kRepWord64:
-      opcode = is_immediate ? kX64StoreWord64I : kX64StoreWord64;
+      opcode = kX64Movq;
       break;
     default:
       UNREACHABLE();
diff --git a/src/contexts.h b/src/contexts.h
index 63c9955..e8d2291 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -201,7 +201,8 @@
   V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map)                             \
   V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map)                             \
   V(ITERATOR_SYMBOL_INDEX, Symbol, iterator_symbol)                            \
-  V(UNSCOPABLES_SYMBOL_INDEX, Symbol, unscopables_symbol)
+  V(UNSCOPABLES_SYMBOL_INDEX, Symbol, unscopables_symbol)                      \
+  V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator)
 
 // JSFunctions are pairs (context, function code), sometimes also called
 // closures. A Context object is used to represent function contexts and
@@ -396,6 +397,7 @@
     SET_ITERATOR_MAP_INDEX,
     ITERATOR_SYMBOL_INDEX,
     UNSCOPABLES_SYMBOL_INDEX,
+    ARRAY_VALUES_ITERATOR_INDEX,
 
     // Properties from here are treated as weak references by the full GC.
     // Scavenge treats them as strong references.
diff --git a/src/data-flow.cc b/src/data-flow.cc
index 9494525..bd92ea0 100644
--- a/src/data-flow.cc
+++ b/src/data-flow.cc
@@ -45,7 +45,7 @@
   int count = 0;
   for (int i = 0; i < data_length_; i++) {
     int data = data_[i];
-    if (data != 0) count += base::bits::CountSetBits32(data);
+    if (data != 0) count += base::bits::CountPopulation32(data);
   }
   return count;
 }
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 5209a51..e6415f4 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -442,23 +442,6 @@
 }
 
 
-static int FindPatchAddressForReturnAddress(Code* code, int pc) {
-  DeoptimizationInputData* input_data =
-      DeoptimizationInputData::cast(code->deoptimization_data());
-  int patch_count = input_data->ReturnAddressPatchCount();
-  for (int i = 0; i < patch_count; i++) {
-    int return_pc = input_data->ReturnAddressPc(i)->value();
-    int patch_pc = input_data->PatchedAddressPc(i)->value();
-    // If the supplied pc matches the return pc or if the address
-    // has been already patched, return the patch pc.
-    if (pc == return_pc || pc == patch_pc) {
-      return patch_pc;
-    }
-  }
-  return -1;
-}
-
-
 // For all marked Turbofanned code on stack, change the return address to go
 // to the deoptimization block.
 void Deoptimizer::PatchStackForMarkedCode(Isolate* isolate) {
@@ -474,7 +457,8 @@
         Address* pc_address = it.frame()->pc_address();
         int pc_offset =
             static_cast<int>(*pc_address - code->instruction_start());
-        int new_pc_offset = FindPatchAddressForReturnAddress(code, pc_offset);
+        SafepointEntry safepoint_entry = code->GetSafepointEntry(*pc_address);
+        unsigned new_pc_offset = safepoint_entry.deoptimization_pc();
 
         if (FLAG_trace_deopt) {
           CodeTracer::Scope scope(isolate->GetCodeTracer());
@@ -484,8 +468,8 @@
                  new_pc_offset);
         }
 
-        CHECK_LE(0, new_pc_offset);
-        *pc_address += new_pc_offset - pc_offset;
+        CHECK(new_pc_offset != Safepoint::kNoDeoptimizationPc);
+        *pc_address += static_cast<int>(new_pc_offset) - pc_offset;
       }
     }
   }
diff --git a/src/factory.cc b/src/factory.cc
index 5ecdfcf..70fa986 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -2174,7 +2174,7 @@
   if (prototype->IsTheHole()) {
 #ifdef DEBUG
     LookupIterator it(handle(JSObject::cast(result->prototype())),
-                      constructor_string(), LookupIterator::CHECK_PROPERTY);
+                      constructor_string(), LookupIterator::OWN_PROPERTY);
     MaybeHandle<Object> maybe_prop = Object::GetProperty(&it);
     DCHECK(it.IsFound());
     DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result));
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 03ee2a1..7796700 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -335,7 +335,7 @@
 DEFINE_BOOL(turbo_types, false, "use typed lowering in TurboFan")
 DEFINE_BOOL(turbo_source_positions, false,
             "track source code positions when building TurboFan IR")
-DEFINE_BOOL(context_specialization, true,
+DEFINE_BOOL(context_specialization, false,
             "enable context specialization in TurboFan")
 DEFINE_BOOL(turbo_deoptimization, false, "enable deoptimization in TurboFan")
 DEFINE_BOOL(turbo_inlining, false, "enable inlining in TurboFan")
diff --git a/src/frames.cc b/src/frames.cc
index b22fafd..a4e77ff 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -1579,9 +1579,7 @@
 
 // -------------------------------------------------------------------------
 
-int NumRegs(RegList reglist) {
-  return base::bits::CountSetBits32(reglist);
-}
+int NumRegs(RegList reglist) { return base::bits::CountPopulation32(reglist); }
 
 
 struct JSCallerSavedCodeData {
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 119d150..a3d653d 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -2863,6 +2863,8 @@
   set_elements_transition_symbol(*factory->NewPrivateSymbol());
   set_frozen_symbol(*factory->NewPrivateSymbol());
   set_megamorphic_symbol(*factory->NewPrivateSymbol());
+  set_premonomorphic_symbol(*factory->NewPrivateSymbol());
+  set_generic_symbol(*factory->NewPrivateSymbol());
   set_nonexistent_symbol(*factory->NewPrivateSymbol());
   set_normal_ic_symbol(*factory->NewPrivateSymbol());
   set_observed_symbol(*factory->NewPrivateSymbol());
diff --git a/src/heap/heap.h b/src/heap/heap.h
index 1b56f25..8b4a021 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -183,6 +183,8 @@
   V(Symbol, observed_symbol, ObservedSymbol)                                   \
   V(Symbol, uninitialized_symbol, UninitializedSymbol)                         \
   V(Symbol, megamorphic_symbol, MegamorphicSymbol)                             \
+  V(Symbol, premonomorphic_symbol, PremonomorphicSymbol)                       \
+  V(Symbol, generic_symbol, GenericSymbol)                                     \
   V(Symbol, stack_trace_symbol, StackTraceSymbol)                              \
   V(Symbol, detailed_stack_trace_symbol, DetailedStackTraceSymbol)             \
   V(Symbol, normal_ic_symbol, NormalICSymbol)                                  \
@@ -294,6 +296,10 @@
   V(String_string, "String")                                       \
   V(symbol_string, "symbol")                                       \
   V(Symbol_string, "Symbol")                                       \
+  V(Map_string, "Map")                                             \
+  V(Set_string, "Set")                                             \
+  V(WeakMap_string, "WeakMap")                                     \
+  V(WeakSet_string, "WeakSet")                                     \
   V(for_string, "for")                                             \
   V(for_api_string, "for_api")                                     \
   V(for_intern_string, "for_intern")                               \
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 1ad5d95..16d91c4 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5341,8 +5341,7 @@
       }
 
       Handle<GlobalObject> global(current_info()->global_object());
-      LookupIterator it(global, variable->name(),
-                        LookupIterator::CHECK_PROPERTY);
+      LookupIterator it(global, variable->name(), LookupIterator::OWN_PROPERTY);
       GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD);
 
       if (type == kUseCell &&
@@ -5797,7 +5796,7 @@
         HConstant::cast(checked_object->ActualValue())->handle(isolate()));
 
     if (object->IsJSObject()) {
-      LookupIterator it(object, info->name(), LookupIterator::CHECK_PROPERTY);
+      LookupIterator it(object, info->name(), LookupIterator::OWN_PROPERTY);
       Handle<Object> value = JSObject::GetDataProperty(&it);
       CHECK(it.IsFound());
       return New<HConstant>(value);
@@ -6463,7 +6462,7 @@
     HValue* value,
     BailoutId ast_id) {
   Handle<GlobalObject> global(current_info()->global_object());
-  LookupIterator it(global, var->name(), LookupIterator::CHECK_PROPERTY);
+  LookupIterator it(global, var->name(), LookupIterator::OWN_PROPERTY);
   GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE);
   if (type == kUseCell) {
     Handle<PropertyCell> cell = it.GetPropertyCell();
@@ -9055,7 +9054,7 @@
       // access check is not enabled we assume that the function will not change
       // and generate optimized code for calling the function.
       Handle<GlobalObject> global(current_info()->global_object());
-      LookupIterator it(global, var->name(), LookupIterator::CHECK_PROPERTY);
+      LookupIterator it(global, var->name(), LookupIterator::OWN_PROPERTY);
       GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD);
       if (type == kUseCell &&
           !current_info()->global_object()->IsAccessCheckNeeded()) {
@@ -10699,7 +10698,7 @@
         !current_info()->global_object()->IsAccessCheckNeeded()) {
       Handle<String> name = proxy->name();
       Handle<GlobalObject> global(current_info()->global_object());
-      LookupIterator it(global, name, LookupIterator::CHECK_PROPERTY);
+      LookupIterator it(global, name, LookupIterator::OWN_PROPERTY);
       Handle<Object> value = JSObject::GetDataProperty(&it);
       if (it.IsFound() && value->IsJSFunction()) {
         Handle<JSFunction> candidate = Handle<JSFunction>::cast(value);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 6a5f99e..1714e4a 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -9,7 +9,7 @@
 #include "src/bootstrapper.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
-#include "src/ic/ic-compiler.h"
+#include "src/ic/handler-compiler.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -2557,7 +2557,7 @@
   ProfileEntryHookStub::MaybeCallEntryHook(masm);
 
   // Enter the exit frame that transitions from JavaScript to C++.
-  __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
+  __ EnterExitFrame(save_doubles());
 
   // ebx: pointer to C function  (C callee-saved)
   // ebp: frame pointer  (restored after C call)
@@ -2565,7 +2565,7 @@
   // edi: number of arguments including receiver  (C callee-saved)
   // esi: pointer to the first argument (C callee-saved)
 
-  // Result returned in eax, or eax+edx if result_size_ is 2.
+  // Result returned in eax, or eax+edx if result size is 2.
 
   // Check stack alignment.
   if (FLAG_debug_code) {
@@ -2613,7 +2613,7 @@
   }
 
   // Exit the JavaScript to C++ exit frame.
-  __ LeaveExitFrame(save_doubles_ == kSaveFPRegs);
+  __ LeaveExitFrame(save_doubles());
   __ ret(0);
 
   // Handling of exception.
diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h
index d0d5216..8ee0a92 100644
--- a/src/ia32/code-stubs-ia32.h
+++ b/src/ia32/code-stubs-ia32.h
@@ -30,7 +30,7 @@
   SaveFPRegsMode save_doubles_;
 
   Major MajorKey() const { return StoreBufferOverflow; }
-  int MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
+  uint32_t MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
 };
 
 
@@ -70,7 +70,7 @@
 
  private:
   Major MajorKey() const { return SubString; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -98,7 +98,7 @@
 
  private:
   virtual Major MajorKey() const { return StringCompare; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
   virtual void Generate(MacroAssembler* masm);
 
   static void GenerateAsciiCharsCompareLoop(
@@ -157,7 +157,7 @@
 
   Major MajorKey() const { return NameDictionaryLookup; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return DictionaryBits::encode(dictionary_.code()) |
         ResultBits::encode(result_.code()) |
         IndexBits::encode(index_.code()) |
@@ -406,7 +406,7 @@
 
   Major MajorKey() const { return RecordWrite; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return ObjectBits::encode(object_.code()) |
         ValueBits::encode(value_.code()) |
         AddressBits::encode(address_.code()) |
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 395ae39..9796cf3 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -900,7 +900,7 @@
   int length = deoptimizations_.length();
   if (length == 0) return;
   Handle<DeoptimizationInputData> data =
-      DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+      DeoptimizationInputData::New(isolate(), length, TENURED);
 
   Handle<ByteArray> translations =
       translations_.CreateByteArray(isolate()->factory());
@@ -2828,6 +2828,19 @@
 }
 
 
+template <class T>
+void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
+  DCHECK(FLAG_vector_ics);
+  Register vector = ToRegister(instr->temp_vector());
+  DCHECK(vector.is(LoadIC::VectorRegister()));
+  __ mov(vector, instr->hydrogen()->feedback_vector());
+  // No need to allocate this register.
+  DCHECK(LoadIC::SlotRegister().is(eax));
+  __ mov(LoadIC::SlotRegister(),
+         Immediate(Smi::FromInt(instr->hydrogen()->slot())));
+}
+
+
 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
   DCHECK(ToRegister(instr->context()).is(esi));
   DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
@@ -2835,13 +2848,7 @@
 
   __ mov(LoadIC::NameRegister(), instr->name());
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ mov(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(eax));
-    __ mov(LoadIC::SlotRegister(),
-           Immediate(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
@@ -2978,13 +2985,7 @@
 
   __ mov(LoadIC::NameRegister(), instr->name());
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ mov(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(eax));
-    __ mov(LoadIC::SlotRegister(),
-           Immediate(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3211,13 +3212,7 @@
   DCHECK(ToRegister(instr->key()).is(LoadIC::NameRegister()));
 
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ mov(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(eax));
-    __ mov(LoadIC::SlotRegister(),
-           Immediate(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index d2f85f1..7c5896b 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -319,6 +319,9 @@
   void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
   void DoStoreKeyedFixedArray(LStoreKeyed* instr);
 
+  template <class T>
+  void EmitVectorLoadICRegisters(T* instr);
+
   void EmitReturn(LReturn* instr, bool dynamic_frame_alignment);
 
   // Emits code for pushing either a tagged constant, a (non-double)
diff --git a/src/ic/arm/handler-compiler-arm.cc b/src/ic/arm/handler-compiler-arm.cc
new file mode 100644
index 0000000..7722af6
--- /dev/null
+++ b/src/ic/arm/handler-compiler-arm.cc
@@ -0,0 +1,866 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_ARM
+
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> getter) {
+  // ----------- S t a t e -------------
+  //  -- r0    : receiver
+  //  -- r2    : name
+  //  -- lr    : return address
+  // -----------------------------------
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    if (!getter.is_null()) {
+      // Call the JavaScript getter with the receiver on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ ldr(receiver,
+               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ push(receiver);
+      ParameterCount actual(0);
+      ParameterCount expected(getter);
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // Restore context register.
+    __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
+
+
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> setter) {
+  // ----------- S t a t e -------------
+  //  -- lr    : return address
+  // -----------------------------------
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    // Save value register, so we can restore it later.
+    __ push(value());
+
+    if (!setter.is_null()) {
+      // Call the JavaScript setter with receiver and value on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ ldr(receiver,
+               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver, value());
+      ParameterCount actual(1);
+      ParameterCount expected(setter);
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // We have to return the passed value, not the return value of the setter.
+    __ pop(r0);
+
+    // Restore context register.
+    __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
+
+
+void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
+    MacroAssembler* masm, Label* miss_label, Register receiver,
+    Handle<Name> name, Register scratch0, Register scratch1) {
+  DCHECK(name->IsUniqueName());
+  DCHECK(!receiver.is(scratch0));
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
+  __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+
+  Label done;
+
+  const int kInterceptorOrAccessCheckNeededMask =
+      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
+
+  // Bail out if the receiver has a named interceptor or requires access checks.
+  Register map = scratch1;
+  __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
+  __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
+  __ b(ne, miss_label);
+
+  // Check that receiver is a JSObject.
+  __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
+  __ b(lt, miss_label);
+
+  // Load properties array.
+  Register properties = scratch0;
+  __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+  // Check that the properties array is a dictionary.
+  __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset));
+  Register tmp = properties;
+  __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
+  __ cmp(map, tmp);
+  __ b(ne, miss_label);
+
+  // Restore the temporarily used register.
+  __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+
+
+  NameDictionaryLookupStub::GenerateNegativeLookup(
+      masm, miss_label, &done, receiver, properties, name, scratch1);
+  __ bind(&done);
+  __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
+    MacroAssembler* masm, int index, Register prototype, Label* miss) {
+  Isolate* isolate = masm->isolate();
+  // Get the global function with the given index.
+  Handle<JSFunction> function(
+      JSFunction::cast(isolate->native_context()->get(index)));
+
+  // Check we're still in the same context.
+  Register scratch = prototype;
+  const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
+  __ ldr(scratch, MemOperand(cp, offset));
+  __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
+  __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index)));
+  __ Move(ip, function);
+  __ cmp(ip, scratch);
+  __ b(ne, miss);
+
+  // Load its initial map. The global functions all have initial maps.
+  __ Move(prototype, Handle<Map>(function->initial_map()));
+  // Load the prototype from the initial map.
+  __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
+    MacroAssembler* masm, Register receiver, Register scratch1,
+    Register scratch2, Label* miss_label) {
+  __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
+  __ mov(r0, scratch1);
+  __ Ret();
+}
+
+
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
+void PropertyHandlerCompiler::GenerateCheckPropertyCell(
+    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
+    Register scratch, Label* miss) {
+  Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
+  DCHECK(cell->value()->IsTheHole());
+  __ mov(scratch, Operand(cell));
+  __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
+  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+  __ cmp(scratch, ip);
+  __ b(ne, miss);
+}
+
+
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
+                                     Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
+  __ push(name);
+  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
+  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
+  Register scratch = name;
+  __ mov(scratch, Operand(interceptor));
+  __ push(scratch);
+  __ push(receiver);
+  __ push(holder);
+}
+
+
+static void CompileCallLoadPropertyWithInterceptor(
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
+  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
+  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
+                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
+}
+
+
+// Generate call to api function.
+void PropertyHandlerCompiler::GenerateFastApiCall(
+    MacroAssembler* masm, const CallOptimization& optimization,
+    Handle<Map> receiver_map, Register receiver, Register scratch_in,
+    bool is_store, int argc, Register* values) {
+  DCHECK(!receiver.is(scratch_in));
+  __ push(receiver);
+  // Write the arguments to stack frame.
+  for (int i = 0; i < argc; i++) {
+    Register arg = values[argc - 1 - i];
+    DCHECK(!receiver.is(arg));
+    DCHECK(!scratch_in.is(arg));
+    __ push(arg);
+  }
+  DCHECK(optimization.is_simple_api_call());
+
+  // Abi for CallApiFunctionStub.
+  Register callee = r0;
+  Register call_data = r4;
+  Register holder = r2;
+  Register api_function_address = r1;
+
+  // Put holder in place.
+  CallOptimization::HolderLookup holder_lookup;
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  switch (holder_lookup) {
+    case CallOptimization::kHolderIsReceiver:
+      __ Move(holder, receiver);
+      break;
+    case CallOptimization::kHolderFound:
+      __ Move(holder, api_holder);
+      break;
+    case CallOptimization::kHolderNotFound:
+      UNREACHABLE();
+      break;
+  }
+
+  Isolate* isolate = masm->isolate();
+  Handle<JSFunction> function = optimization.constant_function();
+  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
+  Handle<Object> call_data_obj(api_call_info->data(), isolate);
+
+  // Put callee in place.
+  __ Move(callee, function);
+
+  bool call_data_undefined = false;
+  // Put call_data in place.
+  if (isolate->heap()->InNewSpace(*call_data_obj)) {
+    __ Move(call_data, api_call_info);
+    __ ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
+  } else if (call_data_obj->IsUndefined()) {
+    call_data_undefined = true;
+    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
+  } else {
+    __ Move(call_data, call_data_obj);
+  }
+
+  // Put api_function_address in place.
+  Address function_address = v8::ToCData<Address>(api_call_info->callback());
+  ApiFunction fun(function_address);
+  ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
+  ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
+  __ mov(api_function_address, Operand(ref));
+
+  // Jump to stub.
+  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
+  __ TailCallStub(&stub);
+}
+
+
+void ElementHandlerCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // The return address is in lr.
+  Label slow, miss;
+
+  Register key = LoadIC::NameRegister();
+  Register receiver = LoadIC::ReceiverRegister();
+  DCHECK(receiver.is(r1));
+  DCHECK(key.is(r2));
+
+  __ UntagAndJumpIfNotSmi(r6, key, &miss);
+  __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ LoadFromNumberDictionary(&slow, r4, key, r0, r6, r3, r5);
+  __ Ret();
+
+  __ bind(&slow);
+  __ IncrementCounter(
+      masm->isolate()->counters()->keyed_load_external_array_slow(), 1, r2, r3);
+
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
+
+  // Miss case, call the runtime.
+  __ bind(&miss);
+
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
+                                                    Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ bind(label);
+    __ mov(this->name(), Operand(name));
+  }
+}
+
+
+// Generate StoreTransition code, value is passed in r0 register.
+// When leaving generated code after success, the receiver_reg and name_reg
+// may be clobbered.  Upon branch to miss_label, the receiver and name
+// registers have their original values.
+void NamedStoreHandlerCompiler::GenerateStoreTransition(
+    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
+    Register storage_reg, Register value_reg, Register scratch1,
+    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
+  // r0 : value
+  Label exit;
+
+  int descriptor = transition->LastAdded();
+  DescriptorArray* descriptors = transition->instance_descriptors();
+  PropertyDetails details = descriptors->GetDetails(descriptor);
+  Representation representation = details.representation();
+  DCHECK(!representation.IsNone());
+
+  if (details.type() == CONSTANT) {
+    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
+    __ Move(scratch1, constant);
+    __ cmp(value_reg, scratch1);
+    __ b(ne, miss_label);
+  } else if (representation.IsSmi()) {
+    __ JumpIfNotSmi(value_reg, miss_label);
+  } else if (representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_label);
+    HeapType* field_type = descriptors->GetFieldType(descriptor);
+    HeapType::Iterator<Map> it = field_type->Classes();
+    if (!it.Done()) {
+      __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+      Label do_store;
+      while (true) {
+        __ CompareMap(scratch1, it.Current(), &do_store);
+        it.Advance();
+        if (it.Done()) {
+          __ b(ne, miss_label);
+          break;
+        }
+        __ b(eq, &do_store);
+      }
+      __ bind(&do_store);
+    }
+  } else if (representation.IsDouble()) {
+    Label do_store, heap_number;
+    __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
+    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
+                          TAG_RESULT, MUTABLE);
+
+    __ JumpIfNotSmi(value_reg, &heap_number);
+    __ SmiUntag(scratch1, value_reg);
+    __ vmov(s0, scratch1);
+    __ vcvt_f64_s32(d0, s0);
+    __ jmp(&do_store);
+
+    __ bind(&heap_number);
+    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
+                DONT_DO_SMI_CHECK);
+    __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
+
+    __ bind(&do_store);
+    __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
+  }
+
+  // Stub never generated for objects that require access checks.
+  DCHECK(!transition->is_access_check_needed());
+
+  // Perform map transition for the receiver if necessary.
+  if (details.type() == FIELD &&
+      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
+    // The properties must be extended before we can store the value.
+    // We jump to a runtime call that extends the properties array.
+    __ push(receiver_reg);
+    __ mov(r2, Operand(transition));
+    __ Push(r2, r0);
+    __ TailCallExternalReference(
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
+                          isolate()),
+        3, 1);
+    return;
+  }
+
+  // Update the map of the object.
+  __ mov(scratch1, Operand(transition));
+  __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
+
+  // Update the write barrier for the map field.
+  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
+                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+
+  if (details.type() == CONSTANT) {
+    DCHECK(value_reg.is(r0));
+    __ Ret();
+    return;
+  }
+
+  int index = transition->instance_descriptors()->GetFieldIndex(
+      transition->LastAdded());
+
+  // Adjust for the number of properties stored in the object. Even in the
+  // face of a transition we can use the old map here because the size of the
+  // object and the number of in-object properties is not going to change.
+  index -= transition->inobject_properties();
+
+  // TODO(verwaest): Share this code as a code stub.
+  SmiCheck smi_check =
+      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  if (index < 0) {
+    // Set the property straight into the object.
+    int offset = transition->instance_size() + (index * kPointerSize);
+    if (representation.IsDouble()) {
+      __ str(storage_reg, FieldMemOperand(receiver_reg, offset));
+    } else {
+      __ str(value_reg, FieldMemOperand(receiver_reg, offset));
+    }
+
+    if (!representation.IsSmi()) {
+      // Update the write barrier for the array address.
+      if (!representation.IsDouble()) {
+        __ mov(storage_reg, value_reg);
+      }
+      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
+                          kLRHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
+    }
+  } else {
+    // Write to the properties array.
+    int offset = index * kPointerSize + FixedArray::kHeaderSize;
+    // Get the properties array
+    __ ldr(scratch1,
+           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
+    if (representation.IsDouble()) {
+      __ str(storage_reg, FieldMemOperand(scratch1, offset));
+    } else {
+      __ str(value_reg, FieldMemOperand(scratch1, offset));
+    }
+
+    if (!representation.IsSmi()) {
+      // Update the write barrier for the array address.
+      if (!representation.IsDouble()) {
+        __ mov(storage_reg, value_reg);
+      }
+      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
+                          kLRHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
+    }
+  }
+
+  // Return the value (register r0).
+  DCHECK(value_reg.is(r0));
+  __ bind(&exit);
+  __ Ret();
+}
+
+
+void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
+                                                   Register value_reg,
+                                                   Label* miss_label) {
+  DCHECK(lookup->representation().IsHeapObject());
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
+  __ ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
+  Label do_store;
+  while (true) {
+    __ CompareMap(scratch1(), it.Current(), &do_store);
+    it.Advance();
+    if (it.Done()) {
+      __ b(ne, miss_label);
+      break;
+    }
+    __ b(eq, &do_store);
+  }
+  __ bind(&do_store);
+
+  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
+                      lookup->representation());
+  GenerateTailCall(masm(), stub.GetCode());
+}
+
+
+Register PropertyHandlerCompiler::CheckPrototypes(
+    Register object_reg, Register holder_reg, Register scratch1,
+    Register scratch2, Handle<Name> name, Label* miss,
+    PrototypeCheckType check) {
+  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
+
+  // Make sure there's no overlap between holder and object registers.
+  DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
+  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
+         !scratch2.is(scratch1));
+
+  // Keep track of the current object in register reg.
+  Register reg = object_reg;
+  int depth = 0;
+
+  Handle<JSObject> current = Handle<JSObject>::null();
+  if (type()->IsConstant()) {
+    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
+  }
+  Handle<JSObject> prototype = Handle<JSObject>::null();
+  Handle<Map> current_map = receiver_map;
+  Handle<Map> holder_map(holder()->map());
+  // Traverse the prototype chain and check the maps in the prototype chain for
+  // fast and global objects or do negative lookup for normal objects.
+  while (!current_map.is_identical_to(holder_map)) {
+    ++depth;
+
+    // Only global objects and objects that do not require access
+    // checks are allowed in stubs.
+    DCHECK(current_map->IsJSGlobalProxyMap() ||
+           !current_map->is_access_check_needed());
+
+    prototype = handle(JSObject::cast(current_map->prototype()));
+    if (current_map->is_dictionary_map() &&
+        !current_map->IsJSGlobalObjectMap()) {
+      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
+      if (!name->IsUniqueName()) {
+        DCHECK(name->IsString());
+        name = factory()->InternalizeString(Handle<String>::cast(name));
+      }
+      DCHECK(current.is_null() ||
+             current->property_dictionary()->FindEntry(name) ==
+                 NameDictionary::kNotFound);
+
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
+
+      __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+      __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
+    } else {
+      Register map_reg = scratch1;
+      if (depth != 1 || check == CHECK_ALL_MAPS) {
+        // CheckMap implicitly loads the map of |reg| into |map_reg|.
+        __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
+      } else {
+        __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
+      }
+
+      // Check access rights to the global object.  This has to happen after
+      // the map check so that we know that the object is actually a global
+      // object.
+      // This allows us to install generated handlers for accesses to the
+      // global proxy (as opposed to using slow ICs). See corresponding code
+      // in LookupForRead().
+      if (current_map->IsJSGlobalProxyMap()) {
+        __ CheckAccessGlobalProxy(reg, scratch2, miss);
+      } else if (current_map->IsJSGlobalObjectMap()) {
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
+      }
+
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+
+      // Two possible reasons for loading the prototype from the map:
+      // (1) Can't store references to new space in code.
+      // (2) Handler is shared for all receivers with the same prototype
+      //     map (but not necessarily the same prototype instance).
+      bool load_prototype_from_map =
+          heap()->InNewSpace(*prototype) || depth == 1;
+      if (load_prototype_from_map) {
+        __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
+      } else {
+        __ mov(reg, Operand(prototype));
+      }
+    }
+
+    // Go to the next object in the prototype chain.
+    current = prototype;
+    current_map = handle(current->map());
+  }
+
+  // Log the check depth.
+  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
+
+  if (depth != 0 || check == CHECK_ALL_MAPS) {
+    // Check the holder map.
+    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
+  }
+
+  // Perform security check for access to the global object.
+  DCHECK(current_map->IsJSGlobalProxyMap() ||
+         !current_map->is_access_check_needed());
+  if (current_map->IsJSGlobalProxyMap()) {
+    __ CheckAccessGlobalProxy(reg, scratch1, miss);
+  }
+
+  // Return the register containing the holder.
+  return reg;
+}
+
+
+void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ b(&success);
+    __ bind(miss);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+    __ bind(&success);
+  }
+}
+
+
+void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ b(&success);
+    GenerateRestoreName(miss, name);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+    __ bind(&success);
+  }
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
+  // Return the constant value.
+  __ Move(r0, value);
+  __ Ret();
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadCallback(
+    Register reg, Handle<ExecutableAccessorInfo> callback) {
+  // Build AccessorInfo::args_ list on the stack and push property name below
+  // the exit frame to make GC aware of them and store pointers to them.
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
+  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
+  DCHECK(!scratch2().is(reg));
+  DCHECK(!scratch3().is(reg));
+  DCHECK(!scratch4().is(reg));
+  __ push(receiver());
+  if (heap()->InNewSpace(callback->data())) {
+    __ Move(scratch3(), callback);
+    __ ldr(scratch3(),
+           FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
+  } else {
+    __ Move(scratch3(), Handle<Object>(callback->data(), isolate()));
+  }
+  __ push(scratch3());
+  __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
+  __ mov(scratch4(), scratch3());
+  __ Push(scratch3(), scratch4());
+  __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
+  __ Push(scratch4(), reg);
+  __ mov(scratch2(), sp);  // scratch2 = PropertyAccessorInfo::args_
+  __ push(name());
+
+  // Abi for CallApiGetter
+  Register getter_address_reg = r2;
+
+  Address getter_address = v8::ToCData<Address>(callback->getter());
+  ApiFunction fun(getter_address);
+  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
+  ExternalReference ref = ExternalReference(&fun, type, isolate());
+  __ mov(getter_address_reg, Operand(ref));
+
+  CallApiGetterStub stub(isolate());
+  __ TailCallStub(&stub);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
+    LookupIterator* it, Register holder_reg) {
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+
+  // Compile the interceptor call, followed by inline code to load the
+  // property from further up the prototype chain if the call fails.
+  // Check that the maps haven't changed.
+  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
+
+  // Preserve the receiver register explicitly whenever it is different from the
+  // holder and it is needed should the interceptor return without any result.
+  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
+  // case might cause a miss during the prototype check.
+  bool must_perform_prototype_check =
+      !holder().is_identical_to(it->GetHolder<JSObject>());
+  bool must_preserve_receiver_reg =
+      !receiver().is(holder_reg) &&
+      (it->property_kind() == LookupIterator::ACCESSOR ||
+       must_perform_prototype_check);
+
+  // Save necessary data before invoking an interceptor.
+  // Requires a frame to make GC aware of pushed pointers.
+  {
+    FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
+    if (must_preserve_receiver_reg) {
+      __ Push(receiver(), holder_reg, this->name());
+    } else {
+      __ Push(holder_reg, this->name());
+    }
+    // Invoke an interceptor.  Note: map checks from receiver to
+    // interceptor's holder has been compiled before (see a caller
+    // of this method.)
+    CompileCallLoadPropertyWithInterceptor(
+        masm(), receiver(), holder_reg, this->name(), holder(),
+        IC::kLoadPropertyWithInterceptorOnly);
+
+    // Check if interceptor provided a value for property.  If it's
+    // the case, return immediately.
+    Label interceptor_failed;
+    __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
+    __ cmp(r0, scratch1());
+    __ b(eq, &interceptor_failed);
+    frame_scope.GenerateLeaveFrame();
+    __ Ret();
+
+    __ bind(&interceptor_failed);
+    __ pop(this->name());
+    __ pop(holder_reg);
+    if (must_preserve_receiver_reg) {
+      __ pop(receiver());
+    }
+    // Leave the internal frame.
+  }
+
+  GenerateLoadPostInterceptor(it, holder_reg);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
+  // Call the runtime system to load the interceptor.
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
+                           holder());
+
+  ExternalReference ref = ExternalReference(
+      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(
+      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
+    Handle<JSObject> object, Handle<Name> name,
+    Handle<ExecutableAccessorInfo> callback) {
+  Register holder_reg = Frontend(receiver(), name);
+
+  __ push(receiver());  // receiver
+  __ push(holder_reg);
+  __ mov(ip, Operand(callback));  // callback info
+  __ push(ip);
+  __ mov(ip, Operand(name));
+  __ Push(ip, value());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_callback_property =
+      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
+  __ TailCallExternalReference(store_callback_property, 5, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
+    Handle<Name> name) {
+  __ Push(receiver(), this->name(), value());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_ic_property = ExternalReference(
+      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(store_ic_property, 3, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
+    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
+  Label miss;
+  FrontendHeader(receiver(), name, &miss);
+
+  // Get the value from the cell.
+  Register result = StoreIC::ValueRegister();
+  __ mov(result, Operand(cell));
+  __ ldr(result, FieldMemOperand(result, Cell::kValueOffset));
+
+  // Check for deleted property if property can actually be deleted.
+  if (is_configurable) {
+    __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+    __ cmp(result, ip);
+    __ b(eq, &miss);
+  }
+
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
+  __ Ret();
+
+  FrontendFooter(name, &miss);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, name);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_ARM
diff --git a/src/ic/arm/ic-arm.cc b/src/ic/arm/ic-arm.cc
index 9c6b894..57bd5a4 100644
--- a/src/ic/arm/ic-arm.cc
+++ b/src/ic/arm/ic-arm.cc
@@ -733,30 +733,6 @@
 }
 
 
-void StoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Push receiver, key and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
-void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Push receiver, key and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
 static void KeyedStoreGenerateGenericHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
diff --git a/src/ic/arm/ic-compiler-arm.cc b/src/ic/arm/ic-compiler-arm.cc
index c5b0903..ba038ab 100644
--- a/src/ic/arm/ic-compiler-arm.cc
+++ b/src/ic/arm/ic-compiler-arm.cc
@@ -6,7 +6,6 @@
 
 #if V8_TARGET_ARCH_ARM
 
-#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
@@ -15,198 +14,16 @@
 #define __ ACCESS_MASM(masm)
 
 
-void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
-    MacroAssembler* masm, Label* miss_label, Register receiver,
-    Handle<Name> name, Register scratch0, Register scratch1) {
-  DCHECK(name->IsUniqueName());
-  DCHECK(!receiver.is(scratch0));
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
-  __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
 
-  Label done;
+  __ mov(r0, Operand(Smi::FromInt(strict_mode)));
+  __ Push(r0);
 
-  const int kInterceptorOrAccessCheckNeededMask =
-      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
-
-  // Bail out if the receiver has a named interceptor or requires access checks.
-  Register map = scratch1;
-  __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
-  __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
-  __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
-  __ b(ne, miss_label);
-
-  // Check that receiver is a JSObject.
-  __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
-  __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
-  __ b(lt, miss_label);
-
-  // Load properties array.
-  Register properties = scratch0;
-  __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
-  // Check that the properties array is a dictionary.
-  __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset));
-  Register tmp = properties;
-  __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
-  __ cmp(map, tmp);
-  __ b(ne, miss_label);
-
-  // Restore the temporarily used register.
-  __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
-
-
-  NameDictionaryLookupStub::GenerateNegativeLookup(
-      masm, miss_label, &done, receiver, properties, name, scratch1);
-  __ bind(&done);
-  __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
-  // Check we're still in the same context.
-  Register scratch = prototype;
-  const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ ldr(scratch, MemOperand(cp, offset));
-  __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index)));
-  __ Move(ip, function);
-  __ cmp(ip, scratch);
-  __ b(ne, miss);
-
-  // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Handle<Map>(function->initial_map()));
-  // Load the prototype from the initial map.
-  __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
-    MacroAssembler* masm, Register receiver, Register scratch1,
-    Register scratch2, Label* miss_label) {
-  __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
-  __ mov(r0, scratch1);
-  __ Ret();
-}
-
-
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-void PropertyHandlerCompiler::GenerateCheckPropertyCell(
-    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
-    Register scratch, Label* miss) {
-  Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
-  DCHECK(cell->value()->IsTheHole());
-  __ mov(scratch, Operand(cell));
-  __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
-  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
-  __ cmp(scratch, ip);
-  __ b(ne, miss);
-}
-
-
-static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
-                                     Register holder, Register name,
-                                     Handle<JSObject> holder_obj) {
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
-  __ push(name);
-  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
-  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
-  Register scratch = name;
-  __ mov(scratch, Operand(interceptor));
-  __ push(scratch);
-  __ push(receiver);
-  __ push(holder);
-}
-
-
-static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm, Register receiver, Register holder, Register name,
-    Handle<JSObject> holder_obj, IC::UtilityId id) {
-  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
-                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
-}
-
-
-// Generate call to api function.
-void PropertyHandlerCompiler::GenerateFastApiCall(
-    MacroAssembler* masm, const CallOptimization& optimization,
-    Handle<Map> receiver_map, Register receiver, Register scratch_in,
-    bool is_store, int argc, Register* values) {
-  DCHECK(!receiver.is(scratch_in));
-  __ push(receiver);
-  // Write the arguments to stack frame.
-  for (int i = 0; i < argc; i++) {
-    Register arg = values[argc - 1 - i];
-    DCHECK(!receiver.is(arg));
-    DCHECK(!scratch_in.is(arg));
-    __ push(arg);
-  }
-  DCHECK(optimization.is_simple_api_call());
-
-  // Abi for CallApiFunctionStub.
-  Register callee = r0;
-  Register call_data = r4;
-  Register holder = r2;
-  Register api_function_address = r1;
-
-  // Put holder in place.
-  CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
-  switch (holder_lookup) {
-    case CallOptimization::kHolderIsReceiver:
-      __ Move(holder, receiver);
-      break;
-    case CallOptimization::kHolderFound:
-      __ Move(holder, api_holder);
-      break;
-    case CallOptimization::kHolderNotFound:
-      UNREACHABLE();
-      break;
-  }
-
-  Isolate* isolate = masm->isolate();
-  Handle<JSFunction> function = optimization.constant_function();
-  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
-  Handle<Object> call_data_obj(api_call_info->data(), isolate);
-
-  // Put callee in place.
-  __ Move(callee, function);
-
-  bool call_data_undefined = false;
-  // Put call_data in place.
-  if (isolate->heap()->InNewSpace(*call_data_obj)) {
-    __ Move(call_data, api_call_info);
-    __ ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
-  } else if (call_data_obj->IsUndefined()) {
-    call_data_undefined = true;
-    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
-  } else {
-    __ Move(call_data, call_data_obj);
-  }
-
-  // Put api_function_address in place.
-  Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  ApiFunction fun(function_address);
-  ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
-  ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
-  __ mov(api_function_address, Operand(ref));
-
-  // Jump to stub.
-  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
-  __ TailCallStub(&stub);
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
 }
 
 
@@ -214,613 +31,6 @@
 #define __ ACCESS_MASM(masm())
 
 
-void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
-                                                    Handle<Name> name) {
-  if (!label->is_unused()) {
-    __ bind(label);
-    __ mov(this->name(), Operand(name));
-  }
-}
-
-
-// Generate StoreTransition code, value is passed in r0 register.
-// When leaving generated code after success, the receiver_reg and name_reg
-// may be clobbered.  Upon branch to miss_label, the receiver and name
-// registers have their original values.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
-  // r0 : value
-  Label exit;
-
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ Move(scratch1, constant);
-    __ cmp(value_reg, scratch1);
-    __ b(ne, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
-      Label do_store;
-      while (true) {
-        __ CompareMap(scratch1, it.Current(), &do_store);
-        it.Advance();
-        if (it.Done()) {
-          __ b(ne, miss_label);
-          break;
-        }
-        __ b(eq, &do_store);
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
-                          TAG_RESULT, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiUntag(scratch1, value_reg);
-    __ vmov(s0, scratch1);
-    __ vcvt_f64_s32(d0, s0);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
-                DONT_DO_SMI_CHECK);
-    __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ push(receiver_reg);
-    __ mov(r2, Operand(transition));
-    __ Push(r2, r0);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ mov(scratch1, Operand(transition));
-  __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(r0));
-    __ Ret();
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ str(storage_reg, FieldMemOperand(receiver_reg, offset));
-    } else {
-      __ str(value_reg, FieldMemOperand(receiver_reg, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array
-    __ ldr(scratch1,
-           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ str(storage_reg, FieldMemOperand(scratch1, offset));
-    } else {
-      __ str(value_reg, FieldMemOperand(scratch1, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register r0).
-  DCHECK(value_reg.is(r0));
-  __ bind(&exit);
-  __ Ret();
-}
-
-
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  __ ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
-  Label do_store;
-  while (true) {
-    __ CompareMap(scratch1(), it.Current(), &do_store);
-    it.Advance();
-    if (it.Done()) {
-      __ b(ne, miss_label);
-      break;
-    }
-    __ b(eq, &do_store);
-  }
-  __ bind(&do_store);
-
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
-}
-
-
-Register PropertyHandlerCompiler::CheckPrototypes(
-    Register object_reg, Register holder_reg, Register scratch1,
-    Register scratch2, Handle<Name> name, Label* miss,
-    PrototypeCheckType check) {
-  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
-
-  // Make sure there's no overlap between holder and object registers.
-  DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
-         !scratch2.is(scratch1));
-
-  // Keep track of the current object in register reg.
-  Register reg = object_reg;
-  int depth = 0;
-
-  Handle<JSObject> current = Handle<JSObject>::null();
-  if (type()->IsConstant()) {
-    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
-  }
-  Handle<JSObject> prototype = Handle<JSObject>::null();
-  Handle<Map> current_map = receiver_map;
-  Handle<Map> holder_map(holder()->map());
-  // Traverse the prototype chain and check the maps in the prototype chain for
-  // fast and global objects or do negative lookup for normal objects.
-  while (!current_map.is_identical_to(holder_map)) {
-    ++depth;
-
-    // Only global objects and objects that do not require access
-    // checks are allowed in stubs.
-    DCHECK(current_map->IsJSGlobalProxyMap() ||
-           !current_map->is_access_check_needed());
-
-    prototype = handle(JSObject::cast(current_map->prototype()));
-    if (current_map->is_dictionary_map() &&
-        !current_map->IsJSGlobalObjectMap()) {
-      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
-      if (!name->IsUniqueName()) {
-        DCHECK(name->IsString());
-        name = factory()->InternalizeString(Handle<String>::cast(name));
-      }
-      DCHECK(current.is_null() ||
-             current->property_dictionary()->FindEntry(name) ==
-                 NameDictionary::kNotFound);
-
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
-                                       scratch2);
-
-      __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-      __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
-    } else {
-      Register map_reg = scratch1;
-      if (depth != 1 || check == CHECK_ALL_MAPS) {
-        // CheckMap implicitly loads the map of |reg| into |map_reg|.
-        __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
-      } else {
-        __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
-      }
-
-      // Check access rights to the global object.  This has to happen after
-      // the map check so that we know that the object is actually a global
-      // object.
-      // This allows us to install generated handlers for accesses to the
-      // global proxy (as opposed to using slow ICs). See corresponding code
-      // in LookupForRead().
-      if (current_map->IsJSGlobalProxyMap()) {
-        __ CheckAccessGlobalProxy(reg, scratch2, miss);
-      } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
-                                  name, scratch2, miss);
-      }
-
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map =
-          heap()->InNewSpace(*prototype) || depth == 1;
-      if (load_prototype_from_map) {
-        __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
-      } else {
-        __ mov(reg, Operand(prototype));
-      }
-    }
-
-    // Go to the next object in the prototype chain.
-    current = prototype;
-    current_map = handle(current->map());
-  }
-
-  // Log the check depth.
-  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
-
-  if (depth != 0 || check == CHECK_ALL_MAPS) {
-    // Check the holder map.
-    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
-  }
-
-  // Perform security check for access to the global object.
-  DCHECK(current_map->IsJSGlobalProxyMap() ||
-         !current_map->is_access_check_needed());
-  if (current_map->IsJSGlobalProxyMap()) {
-    __ CheckAccessGlobalProxy(reg, scratch1, miss);
-  }
-
-  // Return the register containing the holder.
-  return reg;
-}
-
-
-void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ b(&success);
-    __ bind(miss);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-    __ bind(&success);
-  }
-}
-
-
-void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ b(&success);
-    GenerateRestoreName(miss, name);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-    __ bind(&success);
-  }
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
-  // Return the constant value.
-  __ Move(r0, value);
-  __ Ret();
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadCallback(
-    Register reg, Handle<ExecutableAccessorInfo> callback) {
-  // Build AccessorInfo::args_ list on the stack and push property name below
-  // the exit frame to make GC aware of them and store pointers to them.
-  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
-  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
-  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
-  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
-  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
-  DCHECK(!scratch2().is(reg));
-  DCHECK(!scratch3().is(reg));
-  DCHECK(!scratch4().is(reg));
-  __ push(receiver());
-  if (heap()->InNewSpace(callback->data())) {
-    __ Move(scratch3(), callback);
-    __ ldr(scratch3(),
-           FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
-  } else {
-    __ Move(scratch3(), Handle<Object>(callback->data(), isolate()));
-  }
-  __ push(scratch3());
-  __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
-  __ mov(scratch4(), scratch3());
-  __ Push(scratch3(), scratch4());
-  __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
-  __ Push(scratch4(), reg);
-  __ mov(scratch2(), sp);  // scratch2 = PropertyAccessorInfo::args_
-  __ push(name());
-
-  // Abi for CallApiGetter
-  Register getter_address_reg = r2;
-
-  Address getter_address = v8::ToCData<Address>(callback->getter());
-  ApiFunction fun(getter_address);
-  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
-  ExternalReference ref = ExternalReference(&fun, type, isolate());
-  __ mov(getter_address_reg, Operand(ref));
-
-  CallApiGetterStub stub(isolate());
-  __ TailCallStub(&stub);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
-    LookupIterator* it, Register holder_reg) {
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-
-  // Compile the interceptor call, followed by inline code to load the
-  // property from further up the prototype chain if the call fails.
-  // Check that the maps haven't changed.
-  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
-
-  // Preserve the receiver register explicitly whenever it is different from the
-  // holder and it is needed should the interceptor return without any result.
-  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
-  // case might cause a miss during the prototype check.
-  bool must_perform_prototype_check =
-      !holder().is_identical_to(it->GetHolder<JSObject>());
-  bool must_preserve_receiver_reg =
-      !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
-
-  // Save necessary data before invoking an interceptor.
-  // Requires a frame to make GC aware of pushed pointers.
-  {
-    FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
-    if (must_preserve_receiver_reg) {
-      __ Push(receiver(), holder_reg, this->name());
-    } else {
-      __ Push(holder_reg, this->name());
-    }
-    // Invoke an interceptor.  Note: map checks from receiver to
-    // interceptor's holder has been compiled before (see a caller
-    // of this method.)
-    CompileCallLoadPropertyWithInterceptor(
-        masm(), receiver(), holder_reg, this->name(), holder(),
-        IC::kLoadPropertyWithInterceptorOnly);
-
-    // Check if interceptor provided a value for property.  If it's
-    // the case, return immediately.
-    Label interceptor_failed;
-    __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
-    __ cmp(r0, scratch1());
-    __ b(eq, &interceptor_failed);
-    frame_scope.GenerateLeaveFrame();
-    __ Ret();
-
-    __ bind(&interceptor_failed);
-    __ pop(this->name());
-    __ pop(holder_reg);
-    if (must_preserve_receiver_reg) {
-      __ pop(receiver());
-    }
-    // Leave the internal frame.
-  }
-
-  GenerateLoadPostInterceptor(it, holder_reg);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
-  // Call the runtime system to load the interceptor.
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
-                           holder());
-
-  ExternalReference ref = ExternalReference(
-      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(
-      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
-}
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
-    Handle<JSObject> object, Handle<Name> name,
-    Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
-
-  __ push(receiver());  // receiver
-  __ push(holder_reg);
-  __ mov(ip, Operand(callback));  // callback info
-  __ push(ip);
-  __ mov(ip, Operand(name));
-  __ Push(ip, value());
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_callback_property =
-      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
-  __ TailCallExternalReference(store_callback_property, 5, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- lr    : return address
-  // -----------------------------------
-  {
-    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
-
-    // Save value register, so we can restore it later.
-    __ push(value());
-
-    if (!setter.is_null()) {
-      // Call the JavaScript setter with receiver and value on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ ldr(receiver,
-               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ Push(receiver, value());
-      ParameterCount actual(1);
-      ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // We have to return the passed value, not the return value of the setter.
-    __ pop(r0);
-
-    // Restore context register.
-    __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
-    Handle<Name> name) {
-  __ Push(receiver(), this->name(), value());
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_ic_property = ExternalReference(
-      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(store_ic_property, 3, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
-  // ----------- S t a t e -------------
-  //  -- r0    : receiver
-  //  -- r2    : name
-  //  -- lr    : return address
-  // -----------------------------------
-  {
-    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
-
-    if (!getter.is_null()) {
-      // Call the JavaScript getter with the receiver on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ ldr(receiver,
-               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ push(receiver);
-      ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // Restore context register.
-    __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
-  Label miss;
-  FrontendHeader(receiver(), name, &miss);
-
-  // Get the value from the cell.
-  Register result = StoreIC::ValueRegister();
-  __ mov(result, Operand(cell));
-  __ ldr(result, FieldMemOperand(result, Cell::kValueOffset));
-
-  // Check for deleted property if property can actually be deleted.
-  if (is_configurable) {
-    __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
-    __ cmp(result, ip);
-    __ b(eq, &miss);
-  }
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
-  __ Ret();
-
-  FrontendFooter(name, &miss);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, name);
-}
-
-
 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
                                                     CodeHandleList* handlers,
                                                     Handle<Name> name,
@@ -909,51 +119,6 @@
 
 
 #undef __
-#define __ ACCESS_MASM(masm)
-
-
-void ElementHandlerCompiler::GenerateLoadDictionaryElement(
-    MacroAssembler* masm) {
-  // The return address is in lr.
-  Label slow, miss;
-
-  Register key = LoadIC::NameRegister();
-  Register receiver = LoadIC::ReceiverRegister();
-  DCHECK(receiver.is(r1));
-  DCHECK(key.is(r2));
-
-  __ UntagAndJumpIfNotSmi(r6, key, &miss);
-  __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
-  __ LoadFromNumberDictionary(&slow, r4, key, r0, r6, r3, r5);
-  __ Ret();
-
-  __ bind(&slow);
-  __ IncrementCounter(
-      masm->isolate()->counters()->keyed_load_external_array_slow(), 1, r2, r3);
-
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
-
-  // Miss case, call the runtime.
-  __ bind(&miss);
-
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
-}
-
-
-void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                                    StrictMode strict_mode) {
-  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
-          StoreIC::ValueRegister());
-
-  __ mov(r0, Operand(Smi::FromInt(strict_mode)));
-  __ Push(r0);
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
-#undef __
 }
 }  // namespace v8::internal
 
diff --git a/src/ic/arm64/handler-compiler-arm64.cc b/src/ic/arm64/handler-compiler-arm64.cc
new file mode 100644
index 0000000..a5d0bb4
--- /dev/null
+++ b/src/ic/arm64/handler-compiler-arm64.cc
@@ -0,0 +1,872 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_ARM64
+
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
+    MacroAssembler* masm, Label* miss_label, Register receiver,
+    Handle<Name> name, Register scratch0, Register scratch1) {
+  DCHECK(!AreAliased(receiver, scratch0, scratch1));
+  DCHECK(name->IsUniqueName());
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
+  __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+
+  Label done;
+
+  const int kInterceptorOrAccessCheckNeededMask =
+      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
+
+  // Bail out if the receiver has a named interceptor or requires access checks.
+  Register map = scratch1;
+  __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ Ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
+  __ Tst(scratch0, kInterceptorOrAccessCheckNeededMask);
+  __ B(ne, miss_label);
+
+  // Check that receiver is a JSObject.
+  __ Ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  __ Cmp(scratch0, FIRST_SPEC_OBJECT_TYPE);
+  __ B(lt, miss_label);
+
+  // Load properties array.
+  Register properties = scratch0;
+  __ Ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+  // Check that the properties array is a dictionary.
+  __ Ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset));
+  __ JumpIfNotRoot(map, Heap::kHashTableMapRootIndex, miss_label);
+
+  NameDictionaryLookupStub::GenerateNegativeLookup(
+      masm, miss_label, &done, receiver, properties, name, scratch1);
+  __ Bind(&done);
+  __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
+    MacroAssembler* masm, int index, Register prototype, Label* miss) {
+  Isolate* isolate = masm->isolate();
+  // Get the global function with the given index.
+  Handle<JSFunction> function(
+      JSFunction::cast(isolate->native_context()->get(index)));
+
+  // Check we're still in the same context.
+  Register scratch = prototype;
+  __ Ldr(scratch, GlobalObjectMemOperand());
+  __ Ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
+  __ Ldr(scratch, ContextMemOperand(scratch, index));
+  __ Cmp(scratch, Operand(function));
+  __ B(ne, miss);
+
+  // Load its initial map. The global functions all have initial maps.
+  __ Mov(prototype, Operand(Handle<Map>(function->initial_map())));
+  // Load the prototype from the initial map.
+  __ Ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
+    MacroAssembler* masm, Register receiver, Register scratch1,
+    Register scratch2, Label* miss_label) {
+  __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
+  // TryGetFunctionPrototype can't put the result directly in x0 because the
+  // 3 inputs registers can't alias and we call this function from
+  // LoadIC::GenerateFunctionPrototype, where receiver is x0. So we explicitly
+  // move the result in x0.
+  __ Mov(x0, scratch1);
+  __ Ret();
+}
+
+
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
+void PropertyHandlerCompiler::GenerateCheckPropertyCell(
+    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
+    Register scratch, Label* miss) {
+  Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
+  DCHECK(cell->value()->IsTheHole());
+  __ Mov(scratch, Operand(cell));
+  __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
+  __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss);
+}
+
+
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
+                                     Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
+
+  __ Push(name);
+  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
+  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
+  Register scratch = name;
+  __ Mov(scratch, Operand(interceptor));
+  __ Push(scratch, receiver, holder);
+}
+
+
+static void CompileCallLoadPropertyWithInterceptor(
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
+  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
+
+  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
+                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
+}
+
+
+// Generate call to api function.
+void PropertyHandlerCompiler::GenerateFastApiCall(
+    MacroAssembler* masm, const CallOptimization& optimization,
+    Handle<Map> receiver_map, Register receiver, Register scratch,
+    bool is_store, int argc, Register* values) {
+  DCHECK(!AreAliased(receiver, scratch));
+
+  MacroAssembler::PushPopQueue queue(masm);
+  queue.Queue(receiver);
+  // Write the arguments to the stack frame.
+  for (int i = 0; i < argc; i++) {
+    Register arg = values[argc - 1 - i];
+    DCHECK(!AreAliased(receiver, scratch, arg));
+    queue.Queue(arg);
+  }
+  queue.PushQueued();
+
+  DCHECK(optimization.is_simple_api_call());
+
+  // Abi for CallApiFunctionStub.
+  Register callee = x0;
+  Register call_data = x4;
+  Register holder = x2;
+  Register api_function_address = x1;
+
+  // Put holder in place.
+  CallOptimization::HolderLookup holder_lookup;
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  switch (holder_lookup) {
+    case CallOptimization::kHolderIsReceiver:
+      __ Mov(holder, receiver);
+      break;
+    case CallOptimization::kHolderFound:
+      __ LoadObject(holder, api_holder);
+      break;
+    case CallOptimization::kHolderNotFound:
+      UNREACHABLE();
+      break;
+  }
+
+  Isolate* isolate = masm->isolate();
+  Handle<JSFunction> function = optimization.constant_function();
+  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
+  Handle<Object> call_data_obj(api_call_info->data(), isolate);
+
+  // Put callee in place.
+  __ LoadObject(callee, function);
+
+  bool call_data_undefined = false;
+  // Put call_data in place.
+  if (isolate->heap()->InNewSpace(*call_data_obj)) {
+    __ LoadObject(call_data, api_call_info);
+    __ Ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
+  } else if (call_data_obj->IsUndefined()) {
+    call_data_undefined = true;
+    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
+  } else {
+    __ LoadObject(call_data, call_data_obj);
+  }
+
+  // Put api_function_address in place.
+  Address function_address = v8::ToCData<Address>(api_call_info->callback());
+  ApiFunction fun(function_address);
+  ExternalReference ref = ExternalReference(
+      &fun, ExternalReference::DIRECT_API_CALL, masm->isolate());
+  __ Mov(api_function_address, ref);
+
+  // Jump to stub.
+  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
+  __ TailCallStub(&stub);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> setter) {
+  // ----------- S t a t e -------------
+  //  -- lr    : return address
+  // -----------------------------------
+  Label miss;
+
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Save value register, so we can restore it later.
+    __ Push(value());
+
+    if (!setter.is_null()) {
+      // Call the JavaScript setter with receiver and value on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ Ldr(receiver,
+               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver, value());
+      ParameterCount actual(1);
+      ParameterCount expected(setter);
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // We have to return the passed value, not the return value of the setter.
+    __ Pop(x0);
+
+    // Restore context register.
+    __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> getter) {
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    if (!getter.is_null()) {
+      // Call the JavaScript getter with the receiver on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ Ldr(receiver,
+               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver);
+      ParameterCount actual(0);
+      ParameterCount expected(getter);
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // Restore context register.
+    __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
+
+
+void ElementHandlerCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // The return address is in lr.
+  Label slow, miss;
+
+  Register result = x0;
+  Register key = LoadIC::NameRegister();
+  Register receiver = LoadIC::ReceiverRegister();
+  DCHECK(receiver.is(x1));
+  DCHECK(key.is(x2));
+
+  __ JumpIfNotSmi(key, &miss);
+  __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6);
+  __ Ret();
+
+  __ Bind(&slow);
+  __ IncrementCounter(
+      masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
+
+  // Miss case, call the runtime.
+  __ Bind(&miss);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
+  // Push receiver, name and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
+  ASM_LOCATION("ElementHandlerCompiler::GenerateStoreSlow");
+
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
+    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
+  Label miss;
+  FrontendHeader(receiver(), name, &miss);
+
+  // Get the value from the cell.
+  Register result = StoreIC::ValueRegister();
+  __ Mov(result, Operand(cell));
+  __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
+
+  // Check for deleted property if property can actually be deleted.
+  if (is_configurable) {
+    __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss);
+  }
+
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
+  __ Ret();
+
+  FrontendFooter(name, &miss);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, name);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
+    Handle<Name> name) {
+  Label miss;
+
+  ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor");
+
+  __ Push(receiver(), this->name(), value());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_ic_property = ExternalReference(
+      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(store_ic_property, 3, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
+
+
+void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
+                                                    Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ Bind(label);
+    __ Mov(this->name(), Operand(name));
+  }
+}
+
+
+// Generate StoreTransition code, value is passed in x0 register.
+// When leaving generated code after success, the receiver_reg and storage_reg
+// may be clobbered. Upon branch to miss_label, the receiver and name registers
+// have their original values.
+void NamedStoreHandlerCompiler::GenerateStoreTransition(
+    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
+    Register storage_reg, Register value_reg, Register scratch1,
+    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
+  Label exit;
+
+  DCHECK(!AreAliased(receiver_reg, storage_reg, value_reg, scratch1, scratch2,
+                     scratch3));
+
+  // We don't need scratch3.
+  scratch3 = NoReg;
+
+  int descriptor = transition->LastAdded();
+  DescriptorArray* descriptors = transition->instance_descriptors();
+  PropertyDetails details = descriptors->GetDetails(descriptor);
+  Representation representation = details.representation();
+  DCHECK(!representation.IsNone());
+
+  if (details.type() == CONSTANT) {
+    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
+    __ LoadObject(scratch1, constant);
+    __ Cmp(value_reg, scratch1);
+    __ B(ne, miss_label);
+  } else if (representation.IsSmi()) {
+    __ JumpIfNotSmi(value_reg, miss_label);
+  } else if (representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_label);
+    HeapType* field_type = descriptors->GetFieldType(descriptor);
+    HeapType::Iterator<Map> it = field_type->Classes();
+    if (!it.Done()) {
+      __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+      Label do_store;
+      while (true) {
+        __ CompareMap(scratch1, it.Current());
+        it.Advance();
+        if (it.Done()) {
+          __ B(ne, miss_label);
+          break;
+        }
+        __ B(eq, &do_store);
+      }
+      __ Bind(&do_store);
+    }
+  } else if (representation.IsDouble()) {
+    UseScratchRegisterScope temps(masm());
+    DoubleRegister temp_double = temps.AcquireD();
+    __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
+
+    Label do_store;
+    __ JumpIfSmi(value_reg, &do_store);
+
+    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
+                DONT_DO_SMI_CHECK);
+    __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
+
+    __ Bind(&do_store);
+    __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double,
+                          NoReg, MUTABLE);
+  }
+
+  // Stub never generated for objects that require access checks.
+  DCHECK(!transition->is_access_check_needed());
+
+  // Perform map transition for the receiver if necessary.
+  if (details.type() == FIELD &&
+      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
+    // The properties must be extended before we can store the value.
+    // We jump to a runtime call that extends the properties array.
+    __ Mov(scratch1, Operand(transition));
+    __ Push(receiver_reg, scratch1, value_reg);
+    __ TailCallExternalReference(
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
+                          isolate()),
+        3, 1);
+    return;
+  }
+
+  // Update the map of the object.
+  __ Mov(scratch1, Operand(transition));
+  __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
+
+  // Update the write barrier for the map field.
+  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
+                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+
+  if (details.type() == CONSTANT) {
+    DCHECK(value_reg.is(x0));
+    __ Ret();
+    return;
+  }
+
+  int index = transition->instance_descriptors()->GetFieldIndex(
+      transition->LastAdded());
+
+  // Adjust for the number of properties stored in the object. Even in the
+  // face of a transition we can use the old map here because the size of the
+  // object and the number of in-object properties is not going to change.
+  index -= transition->inobject_properties();
+
+  // TODO(verwaest): Share this code as a code stub.
+  SmiCheck smi_check =
+      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  Register prop_reg = representation.IsDouble() ? storage_reg : value_reg;
+  if (index < 0) {
+    // Set the property straight into the object.
+    int offset = transition->instance_size() + (index * kPointerSize);
+    __ Str(prop_reg, FieldMemOperand(receiver_reg, offset));
+
+    if (!representation.IsSmi()) {
+      // Update the write barrier for the array address.
+      if (!representation.IsDouble()) {
+        __ Mov(storage_reg, value_reg);
+      }
+      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
+                          kLRHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
+    }
+  } else {
+    // Write to the properties array.
+    int offset = index * kPointerSize + FixedArray::kHeaderSize;
+    // Get the properties array
+    __ Ldr(scratch1,
+           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
+    __ Str(prop_reg, FieldMemOperand(scratch1, offset));
+
+    if (!representation.IsSmi()) {
+      // Update the write barrier for the array address.
+      if (!representation.IsDouble()) {
+        __ Mov(storage_reg, value_reg);
+      }
+      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
+                          kLRHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
+    }
+  }
+
+  __ Bind(&exit);
+  // Return the value (register x0).
+  DCHECK(value_reg.is(x0));
+  __ Ret();
+}
+
+
+void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
+                                                   Register value_reg,
+                                                   Label* miss_label) {
+  DCHECK(lookup->representation().IsHeapObject());
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
+  __ Ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
+  Label do_store;
+  while (true) {
+    __ CompareMap(scratch1(), it.Current());
+    it.Advance();
+    if (it.Done()) {
+      __ B(ne, miss_label);
+      break;
+    }
+    __ B(eq, &do_store);
+  }
+  __ Bind(&do_store);
+
+  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
+                      lookup->representation());
+  GenerateTailCall(masm(), stub.GetCode());
+}
+
+
+Register PropertyHandlerCompiler::CheckPrototypes(
+    Register object_reg, Register holder_reg, Register scratch1,
+    Register scratch2, Handle<Name> name, Label* miss,
+    PrototypeCheckType check) {
+  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
+
+  // object_reg and holder_reg registers can alias.
+  DCHECK(!AreAliased(object_reg, scratch1, scratch2));
+  DCHECK(!AreAliased(holder_reg, scratch1, scratch2));
+
+  // Keep track of the current object in register reg.
+  Register reg = object_reg;
+  int depth = 0;
+
+  Handle<JSObject> current = Handle<JSObject>::null();
+  if (type()->IsConstant()) {
+    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
+  }
+  Handle<JSObject> prototype = Handle<JSObject>::null();
+  Handle<Map> current_map = receiver_map;
+  Handle<Map> holder_map(holder()->map());
+  // Traverse the prototype chain and check the maps in the prototype chain for
+  // fast and global objects or do negative lookup for normal objects.
+  while (!current_map.is_identical_to(holder_map)) {
+    ++depth;
+
+    // Only global objects and objects that do not require access
+    // checks are allowed in stubs.
+    DCHECK(current_map->IsJSGlobalProxyMap() ||
+           !current_map->is_access_check_needed());
+
+    prototype = handle(JSObject::cast(current_map->prototype()));
+    if (current_map->is_dictionary_map() &&
+        !current_map->IsJSGlobalObjectMap()) {
+      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
+      if (!name->IsUniqueName()) {
+        DCHECK(name->IsString());
+        name = factory()->InternalizeString(Handle<String>::cast(name));
+      }
+      DCHECK(current.is_null() || (current->property_dictionary()->FindEntry(
+                                       name) == NameDictionary::kNotFound));
+
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
+
+      __ Ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+      __ Ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
+    } else {
+      // Two possible reasons for loading the prototype from the map:
+      // (1) Can't store references to new space in code.
+      // (2) Handler is shared for all receivers with the same prototype
+      //     map (but not necessarily the same prototype instance).
+      bool load_prototype_from_map =
+          heap()->InNewSpace(*prototype) || depth == 1;
+      Register map_reg = scratch1;
+      __ Ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
+
+      if (depth != 1 || check == CHECK_ALL_MAPS) {
+        __ CheckMap(map_reg, current_map, miss, DONT_DO_SMI_CHECK);
+      }
+
+      // Check access rights to the global object.  This has to happen after
+      // the map check so that we know that the object is actually a global
+      // object.
+      // This allows us to install generated handlers for accesses to the
+      // global proxy (as opposed to using slow ICs). See corresponding code
+      // in LookupForRead().
+      if (current_map->IsJSGlobalProxyMap()) {
+        UseScratchRegisterScope temps(masm());
+        __ CheckAccessGlobalProxy(reg, scratch2, temps.AcquireX(), miss);
+      } else if (current_map->IsJSGlobalObjectMap()) {
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
+      }
+
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+
+      if (load_prototype_from_map) {
+        __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
+      } else {
+        __ Mov(reg, Operand(prototype));
+      }
+    }
+
+    // Go to the next object in the prototype chain.
+    current = prototype;
+    current_map = handle(current->map());
+  }
+
+  // Log the check depth.
+  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
+
+  // Check the holder map.
+  if (depth != 0 || check == CHECK_ALL_MAPS) {
+    // Check the holder map.
+    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
+  }
+
+  // Perform security check for access to the global object.
+  DCHECK(current_map->IsJSGlobalProxyMap() ||
+         !current_map->is_access_check_needed());
+  if (current_map->IsJSGlobalProxyMap()) {
+    __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
+  }
+
+  // Return the register containing the holder.
+  return reg;
+}
+
+
+void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ B(&success);
+
+    __ Bind(miss);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+    __ Bind(&success);
+  }
+}
+
+
+void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ B(&success);
+
+    GenerateRestoreName(miss, name);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+    __ Bind(&success);
+  }
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
+  // Return the constant value.
+  __ LoadObject(x0, value);
+  __ Ret();
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadCallback(
+    Register reg, Handle<ExecutableAccessorInfo> callback) {
+  DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
+
+  // Build ExecutableAccessorInfo::args_ list on the stack and push property
+  // name below the exit frame to make GC aware of them and store pointers to
+  // them.
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
+  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
+
+  __ Push(receiver());
+
+  if (heap()->InNewSpace(callback->data())) {
+    __ Mov(scratch3(), Operand(callback));
+    __ Ldr(scratch3(),
+           FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
+  } else {
+    __ Mov(scratch3(), Operand(Handle<Object>(callback->data(), isolate())));
+  }
+  __ LoadRoot(scratch4(), Heap::kUndefinedValueRootIndex);
+  __ Mov(scratch2(), Operand(ExternalReference::isolate_address(isolate())));
+  __ Push(scratch3(), scratch4(), scratch4(), scratch2(), reg, name());
+
+  Register args_addr = scratch2();
+  __ Add(args_addr, __ StackPointer(), kPointerSize);
+
+  // Stack at this point:
+  //              sp[40] callback data
+  //              sp[32] undefined
+  //              sp[24] undefined
+  //              sp[16] isolate
+  // args_addr -> sp[8]  reg
+  //              sp[0]  name
+
+  // Abi for CallApiGetter.
+  Register getter_address_reg = x2;
+
+  // Set up the call.
+  Address getter_address = v8::ToCData<Address>(callback->getter());
+  ApiFunction fun(getter_address);
+  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
+  ExternalReference ref = ExternalReference(&fun, type, isolate());
+  __ Mov(getter_address_reg, ref);
+
+  CallApiGetterStub stub(isolate());
+  __ TailCallStub(&stub);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
+    LookupIterator* it, Register holder_reg) {
+  DCHECK(!AreAliased(receiver(), this->name(), scratch1(), scratch2(),
+                     scratch3()));
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+
+  // Compile the interceptor call, followed by inline code to load the
+  // property from further up the prototype chain if the call fails.
+  // Check that the maps haven't changed.
+  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
+
+  // Preserve the receiver register explicitly whenever it is different from the
+  // holder and it is needed should the interceptor return without any result.
+  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
+  // case might cause a miss during the prototype check.
+  bool must_perform_prototype_check =
+      !holder().is_identical_to(it->GetHolder<JSObject>());
+  bool must_preserve_receiver_reg =
+      !receiver().is(holder_reg) &&
+      (it->property_kind() == LookupIterator::ACCESSOR ||
+       must_perform_prototype_check);
+
+  // Save necessary data before invoking an interceptor.
+  // Requires a frame to make GC aware of pushed pointers.
+  {
+    FrameScope frame_scope(masm(), StackFrame::INTERNAL);
+    if (must_preserve_receiver_reg) {
+      __ Push(receiver(), holder_reg, this->name());
+    } else {
+      __ Push(holder_reg, this->name());
+    }
+    // Invoke an interceptor.  Note: map checks from receiver to
+    // interceptor's holder has been compiled before (see a caller
+    // of this method.)
+    CompileCallLoadPropertyWithInterceptor(
+        masm(), receiver(), holder_reg, this->name(), holder(),
+        IC::kLoadPropertyWithInterceptorOnly);
+
+    // Check if interceptor provided a value for property.  If it's
+    // the case, return immediately.
+    Label interceptor_failed;
+    __ JumpIfRoot(x0, Heap::kNoInterceptorResultSentinelRootIndex,
+                  &interceptor_failed);
+    frame_scope.GenerateLeaveFrame();
+    __ Ret();
+
+    __ Bind(&interceptor_failed);
+    if (must_preserve_receiver_reg) {
+      __ Pop(this->name(), holder_reg, receiver());
+    } else {
+      __ Pop(this->name(), holder_reg);
+    }
+    // Leave the internal frame.
+  }
+
+  GenerateLoadPostInterceptor(it, holder_reg);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
+  // Call the runtime system to load the interceptor.
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
+                           holder());
+
+  ExternalReference ref = ExternalReference(
+      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(
+      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
+    Handle<JSObject> object, Handle<Name> name,
+    Handle<ExecutableAccessorInfo> callback) {
+  ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
+  Register holder_reg = Frontend(receiver(), name);
+
+  // Stub never generated for non-global objects that require access checks.
+  DCHECK(holder()->IsJSGlobalProxy() || !holder()->IsAccessCheckNeeded());
+
+  // receiver() and holder_reg can alias.
+  DCHECK(!AreAliased(receiver(), scratch1(), scratch2(), value()));
+  DCHECK(!AreAliased(holder_reg, scratch1(), scratch2(), value()));
+  __ Mov(scratch1(), Operand(callback));
+  __ Mov(scratch2(), Operand(name));
+  __ Push(receiver(), holder_reg, scratch1(), scratch2(), value());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_callback_property =
+      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
+  __ TailCallExternalReference(store_callback_property, 5, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_IA32
diff --git a/src/ic/arm64/ic-arm64.cc b/src/ic/arm64/ic-arm64.cc
index bffa603..6985ea5 100644
--- a/src/ic/arm64/ic-arm64.cc
+++ b/src/ic/arm64/ic-arm64.cc
@@ -775,20 +775,6 @@
 }
 
 
-void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
-  ASM_LOCATION("KeyedStoreIC::GenerateSlow");
-
-  // Push receiver, key and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
 static void KeyedStoreGenerateGenericHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
@@ -1069,25 +1055,6 @@
 }
 
 
-void StoreIC::GenerateSlow(MacroAssembler* masm) {
-  // ---------- S t a t e --------------
-  //  -- x0     : value
-  //  -- x1     : receiver
-  //  -- x2     : name
-  //  -- lr     : return address
-  // -----------------------------------
-
-  // Push receiver, name and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
 Condition CompareIC::ComputeCondition(Token::Value op) {
   switch (op) {
     case Token::EQ_STRICT:
diff --git a/src/ic/arm64/ic-compiler-arm64.cc b/src/ic/arm64/ic-compiler-arm64.cc
index 3e7f8f5..64b5050 100644
--- a/src/ic/arm64/ic-compiler-arm64.cc
+++ b/src/ic/arm64/ic-compiler-arm64.cc
@@ -6,7 +6,6 @@
 
 #if V8_TARGET_ARCH_ARM64
 
-#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
@@ -14,195 +13,18 @@
 
 #define __ ACCESS_MASM(masm)
 
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  ASM_LOCATION("PropertyICCompiler::GenerateRuntimeSetProperty");
 
-void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
-    MacroAssembler* masm, Label* miss_label, Register receiver,
-    Handle<Name> name, Register scratch0, Register scratch1) {
-  DCHECK(!AreAliased(receiver, scratch0, scratch1));
-  DCHECK(name->IsUniqueName());
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
-  __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
 
-  Label done;
+  __ Mov(x10, Smi::FromInt(strict_mode));
+  __ Push(x10);
 
-  const int kInterceptorOrAccessCheckNeededMask =
-      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
-
-  // Bail out if the receiver has a named interceptor or requires access checks.
-  Register map = scratch1;
-  __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
-  __ Ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
-  __ Tst(scratch0, kInterceptorOrAccessCheckNeededMask);
-  __ B(ne, miss_label);
-
-  // Check that receiver is a JSObject.
-  __ Ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
-  __ Cmp(scratch0, FIRST_SPEC_OBJECT_TYPE);
-  __ B(lt, miss_label);
-
-  // Load properties array.
-  Register properties = scratch0;
-  __ Ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
-  // Check that the properties array is a dictionary.
-  __ Ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset));
-  __ JumpIfNotRoot(map, Heap::kHashTableMapRootIndex, miss_label);
-
-  NameDictionaryLookupStub::GenerateNegativeLookup(
-      masm, miss_label, &done, receiver, properties, name, scratch1);
-  __ Bind(&done);
-  __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
-  // Check we're still in the same context.
-  Register scratch = prototype;
-  __ Ldr(scratch, GlobalObjectMemOperand());
-  __ Ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ Ldr(scratch, ContextMemOperand(scratch, index));
-  __ Cmp(scratch, Operand(function));
-  __ B(ne, miss);
-
-  // Load its initial map. The global functions all have initial maps.
-  __ Mov(prototype, Operand(Handle<Map>(function->initial_map())));
-  // Load the prototype from the initial map.
-  __ Ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
-    MacroAssembler* masm, Register receiver, Register scratch1,
-    Register scratch2, Label* miss_label) {
-  __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
-  // TryGetFunctionPrototype can't put the result directly in x0 because the
-  // 3 inputs registers can't alias and we call this function from
-  // LoadIC::GenerateFunctionPrototype, where receiver is x0. So we explicitly
-  // move the result in x0.
-  __ Mov(x0, scratch1);
-  __ Ret();
-}
-
-
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-void PropertyHandlerCompiler::GenerateCheckPropertyCell(
-    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
-    Register scratch, Label* miss) {
-  Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
-  DCHECK(cell->value()->IsTheHole());
-  __ Mov(scratch, Operand(cell));
-  __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
-  __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss);
-}
-
-
-static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
-                                     Register holder, Register name,
-                                     Handle<JSObject> holder_obj) {
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
-
-  __ Push(name);
-  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
-  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
-  Register scratch = name;
-  __ Mov(scratch, Operand(interceptor));
-  __ Push(scratch, receiver, holder);
-}
-
-
-static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm, Register receiver, Register holder, Register name,
-    Handle<JSObject> holder_obj, IC::UtilityId id) {
-  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-
-  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
-                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
-}
-
-
-// Generate call to api function.
-void PropertyHandlerCompiler::GenerateFastApiCall(
-    MacroAssembler* masm, const CallOptimization& optimization,
-    Handle<Map> receiver_map, Register receiver, Register scratch,
-    bool is_store, int argc, Register* values) {
-  DCHECK(!AreAliased(receiver, scratch));
-
-  MacroAssembler::PushPopQueue queue(masm);
-  queue.Queue(receiver);
-  // Write the arguments to the stack frame.
-  for (int i = 0; i < argc; i++) {
-    Register arg = values[argc - 1 - i];
-    DCHECK(!AreAliased(receiver, scratch, arg));
-    queue.Queue(arg);
-  }
-  queue.PushQueued();
-
-  DCHECK(optimization.is_simple_api_call());
-
-  // Abi for CallApiFunctionStub.
-  Register callee = x0;
-  Register call_data = x4;
-  Register holder = x2;
-  Register api_function_address = x1;
-
-  // Put holder in place.
-  CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
-  switch (holder_lookup) {
-    case CallOptimization::kHolderIsReceiver:
-      __ Mov(holder, receiver);
-      break;
-    case CallOptimization::kHolderFound:
-      __ LoadObject(holder, api_holder);
-      break;
-    case CallOptimization::kHolderNotFound:
-      UNREACHABLE();
-      break;
-  }
-
-  Isolate* isolate = masm->isolate();
-  Handle<JSFunction> function = optimization.constant_function();
-  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
-  Handle<Object> call_data_obj(api_call_info->data(), isolate);
-
-  // Put callee in place.
-  __ LoadObject(callee, function);
-
-  bool call_data_undefined = false;
-  // Put call_data in place.
-  if (isolate->heap()->InNewSpace(*call_data_obj)) {
-    __ LoadObject(call_data, api_call_info);
-    __ Ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
-  } else if (call_data_obj->IsUndefined()) {
-    call_data_undefined = true;
-    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
-  } else {
-    __ LoadObject(call_data, call_data_obj);
-  }
-
-  // Put api_function_address in place.
-  Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  ApiFunction fun(function_address);
-  ExternalReference ref = ExternalReference(
-      &fun, ExternalReference::DIRECT_API_CALL, masm->isolate());
-  __ Mov(api_function_address, ref);
-
-  // Jump to stub.
-  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
-  __ TailCallStub(&stub);
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
 }
 
 
@@ -210,621 +32,6 @@
 #define __ ACCESS_MASM(masm())
 
 
-void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
-                                                    Handle<Name> name) {
-  if (!label->is_unused()) {
-    __ Bind(label);
-    __ Mov(this->name(), Operand(name));
-  }
-}
-
-
-// Generate StoreTransition code, value is passed in x0 register.
-// When leaving generated code after success, the receiver_reg and storage_reg
-// may be clobbered. Upon branch to miss_label, the receiver and name registers
-// have their original values.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
-  Label exit;
-
-  DCHECK(!AreAliased(receiver_reg, storage_reg, value_reg, scratch1, scratch2,
-                     scratch3));
-
-  // We don't need scratch3.
-  scratch3 = NoReg;
-
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ LoadObject(scratch1, constant);
-    __ Cmp(value_reg, scratch1);
-    __ B(ne, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
-      Label do_store;
-      while (true) {
-        __ CompareMap(scratch1, it.Current());
-        it.Advance();
-        if (it.Done()) {
-          __ B(ne, miss_label);
-          break;
-        }
-        __ B(eq, &do_store);
-      }
-      __ Bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    UseScratchRegisterScope temps(masm());
-    DoubleRegister temp_double = temps.AcquireD();
-    __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
-
-    Label do_store;
-    __ JumpIfSmi(value_reg, &do_store);
-
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
-                DONT_DO_SMI_CHECK);
-    __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ Bind(&do_store);
-    __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double,
-                          NoReg, MUTABLE);
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ Mov(scratch1, Operand(transition));
-    __ Push(receiver_reg, scratch1, value_reg);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ Mov(scratch1, Operand(transition));
-  __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(x0));
-    __ Ret();
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  Register prop_reg = representation.IsDouble() ? storage_reg : value_reg;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    __ Str(prop_reg, FieldMemOperand(receiver_reg, offset));
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ Mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array
-    __ Ldr(scratch1,
-           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    __ Str(prop_reg, FieldMemOperand(scratch1, offset));
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ Mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  __ Bind(&exit);
-  // Return the value (register x0).
-  DCHECK(value_reg.is(x0));
-  __ Ret();
-}
-
-
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  __ Ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
-  Label do_store;
-  while (true) {
-    __ CompareMap(scratch1(), it.Current());
-    it.Advance();
-    if (it.Done()) {
-      __ B(ne, miss_label);
-      break;
-    }
-    __ B(eq, &do_store);
-  }
-  __ Bind(&do_store);
-
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
-}
-
-
-Register PropertyHandlerCompiler::CheckPrototypes(
-    Register object_reg, Register holder_reg, Register scratch1,
-    Register scratch2, Handle<Name> name, Label* miss,
-    PrototypeCheckType check) {
-  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
-
-  // object_reg and holder_reg registers can alias.
-  DCHECK(!AreAliased(object_reg, scratch1, scratch2));
-  DCHECK(!AreAliased(holder_reg, scratch1, scratch2));
-
-  // Keep track of the current object in register reg.
-  Register reg = object_reg;
-  int depth = 0;
-
-  Handle<JSObject> current = Handle<JSObject>::null();
-  if (type()->IsConstant()) {
-    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
-  }
-  Handle<JSObject> prototype = Handle<JSObject>::null();
-  Handle<Map> current_map = receiver_map;
-  Handle<Map> holder_map(holder()->map());
-  // Traverse the prototype chain and check the maps in the prototype chain for
-  // fast and global objects or do negative lookup for normal objects.
-  while (!current_map.is_identical_to(holder_map)) {
-    ++depth;
-
-    // Only global objects and objects that do not require access
-    // checks are allowed in stubs.
-    DCHECK(current_map->IsJSGlobalProxyMap() ||
-           !current_map->is_access_check_needed());
-
-    prototype = handle(JSObject::cast(current_map->prototype()));
-    if (current_map->is_dictionary_map() &&
-        !current_map->IsJSGlobalObjectMap()) {
-      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
-      if (!name->IsUniqueName()) {
-        DCHECK(name->IsString());
-        name = factory()->InternalizeString(Handle<String>::cast(name));
-      }
-      DCHECK(current.is_null() || (current->property_dictionary()->FindEntry(
-                                       name) == NameDictionary::kNotFound));
-
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
-                                       scratch2);
-
-      __ Ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-      __ Ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
-    } else {
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map =
-          heap()->InNewSpace(*prototype) || depth == 1;
-      Register map_reg = scratch1;
-      __ Ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
-
-      if (depth != 1 || check == CHECK_ALL_MAPS) {
-        __ CheckMap(map_reg, current_map, miss, DONT_DO_SMI_CHECK);
-      }
-
-      // Check access rights to the global object.  This has to happen after
-      // the map check so that we know that the object is actually a global
-      // object.
-      // This allows us to install generated handlers for accesses to the
-      // global proxy (as opposed to using slow ICs). See corresponding code
-      // in LookupForRead().
-      if (current_map->IsJSGlobalProxyMap()) {
-        UseScratchRegisterScope temps(masm());
-        __ CheckAccessGlobalProxy(reg, scratch2, temps.AcquireX(), miss);
-      } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
-                                  name, scratch2, miss);
-      }
-
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-
-      if (load_prototype_from_map) {
-        __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
-      } else {
-        __ Mov(reg, Operand(prototype));
-      }
-    }
-
-    // Go to the next object in the prototype chain.
-    current = prototype;
-    current_map = handle(current->map());
-  }
-
-  // Log the check depth.
-  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
-
-  // Check the holder map.
-  if (depth != 0 || check == CHECK_ALL_MAPS) {
-    // Check the holder map.
-    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
-  }
-
-  // Perform security check for access to the global object.
-  DCHECK(current_map->IsJSGlobalProxyMap() ||
-         !current_map->is_access_check_needed());
-  if (current_map->IsJSGlobalProxyMap()) {
-    __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
-  }
-
-  // Return the register containing the holder.
-  return reg;
-}
-
-
-void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ B(&success);
-
-    __ Bind(miss);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-    __ Bind(&success);
-  }
-}
-
-
-void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ B(&success);
-
-    GenerateRestoreName(miss, name);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-    __ Bind(&success);
-  }
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
-  // Return the constant value.
-  __ LoadObject(x0, value);
-  __ Ret();
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadCallback(
-    Register reg, Handle<ExecutableAccessorInfo> callback) {
-  DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
-
-  // Build ExecutableAccessorInfo::args_ list on the stack and push property
-  // name below the exit frame to make GC aware of them and store pointers to
-  // them.
-  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
-  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
-  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
-  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
-  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
-
-  __ Push(receiver());
-
-  if (heap()->InNewSpace(callback->data())) {
-    __ Mov(scratch3(), Operand(callback));
-    __ Ldr(scratch3(),
-           FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
-  } else {
-    __ Mov(scratch3(), Operand(Handle<Object>(callback->data(), isolate())));
-  }
-  __ LoadRoot(scratch4(), Heap::kUndefinedValueRootIndex);
-  __ Mov(scratch2(), Operand(ExternalReference::isolate_address(isolate())));
-  __ Push(scratch3(), scratch4(), scratch4(), scratch2(), reg, name());
-
-  Register args_addr = scratch2();
-  __ Add(args_addr, __ StackPointer(), kPointerSize);
-
-  // Stack at this point:
-  //              sp[40] callback data
-  //              sp[32] undefined
-  //              sp[24] undefined
-  //              sp[16] isolate
-  // args_addr -> sp[8]  reg
-  //              sp[0]  name
-
-  // Abi for CallApiGetter.
-  Register getter_address_reg = x2;
-
-  // Set up the call.
-  Address getter_address = v8::ToCData<Address>(callback->getter());
-  ApiFunction fun(getter_address);
-  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
-  ExternalReference ref = ExternalReference(&fun, type, isolate());
-  __ Mov(getter_address_reg, ref);
-
-  CallApiGetterStub stub(isolate());
-  __ TailCallStub(&stub);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
-    LookupIterator* it, Register holder_reg) {
-  DCHECK(!AreAliased(receiver(), this->name(), scratch1(), scratch2(),
-                     scratch3()));
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-
-  // Compile the interceptor call, followed by inline code to load the
-  // property from further up the prototype chain if the call fails.
-  // Check that the maps haven't changed.
-  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
-
-  // Preserve the receiver register explicitly whenever it is different from the
-  // holder and it is needed should the interceptor return without any result.
-  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
-  // case might cause a miss during the prototype check.
-  bool must_perform_prototype_check =
-      !holder().is_identical_to(it->GetHolder<JSObject>());
-  bool must_preserve_receiver_reg =
-      !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
-
-  // Save necessary data before invoking an interceptor.
-  // Requires a frame to make GC aware of pushed pointers.
-  {
-    FrameScope frame_scope(masm(), StackFrame::INTERNAL);
-    if (must_preserve_receiver_reg) {
-      __ Push(receiver(), holder_reg, this->name());
-    } else {
-      __ Push(holder_reg, this->name());
-    }
-    // Invoke an interceptor.  Note: map checks from receiver to
-    // interceptor's holder has been compiled before (see a caller
-    // of this method.)
-    CompileCallLoadPropertyWithInterceptor(
-        masm(), receiver(), holder_reg, this->name(), holder(),
-        IC::kLoadPropertyWithInterceptorOnly);
-
-    // Check if interceptor provided a value for property.  If it's
-    // the case, return immediately.
-    Label interceptor_failed;
-    __ JumpIfRoot(x0, Heap::kNoInterceptorResultSentinelRootIndex,
-                  &interceptor_failed);
-    frame_scope.GenerateLeaveFrame();
-    __ Ret();
-
-    __ Bind(&interceptor_failed);
-    if (must_preserve_receiver_reg) {
-      __ Pop(this->name(), holder_reg, receiver());
-    } else {
-      __ Pop(this->name(), holder_reg);
-    }
-    // Leave the internal frame.
-  }
-
-  GenerateLoadPostInterceptor(it, holder_reg);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
-  // Call the runtime system to load the interceptor.
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
-                           holder());
-
-  ExternalReference ref = ExternalReference(
-      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(
-      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
-}
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
-    Handle<JSObject> object, Handle<Name> name,
-    Handle<ExecutableAccessorInfo> callback) {
-  ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
-  Register holder_reg = Frontend(receiver(), name);
-
-  // Stub never generated for non-global objects that require access checks.
-  DCHECK(holder()->IsJSGlobalProxy() || !holder()->IsAccessCheckNeeded());
-
-  // receiver() and holder_reg can alias.
-  DCHECK(!AreAliased(receiver(), scratch1(), scratch2(), value()));
-  DCHECK(!AreAliased(holder_reg, scratch1(), scratch2(), value()));
-  __ Mov(scratch1(), Operand(callback));
-  __ Mov(scratch2(), Operand(name));
-  __ Push(receiver(), holder_reg, scratch1(), scratch2(), value());
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_callback_property =
-      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
-  __ TailCallExternalReference(store_callback_property, 5, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- lr    : return address
-  // -----------------------------------
-  Label miss;
-
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Save value register, so we can restore it later.
-    __ Push(value());
-
-    if (!setter.is_null()) {
-      // Call the JavaScript setter with receiver and value on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ Ldr(receiver,
-               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ Push(receiver, value());
-      ParameterCount actual(1);
-      ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // We have to return the passed value, not the return value of the setter.
-    __ Pop(x0);
-
-    // Restore context register.
-    __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
-    Handle<Name> name) {
-  Label miss;
-
-  ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor");
-
-  __ Push(receiver(), this->name(), value());
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_ic_property = ExternalReference(
-      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(store_ic_property, 3, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    if (!getter.is_null()) {
-      // Call the JavaScript getter with the receiver on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ Ldr(receiver,
-               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ Push(receiver);
-      ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // Restore context register.
-    __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
-  Label miss;
-  FrontendHeader(receiver(), name, &miss);
-
-  // Get the value from the cell.
-  Register result = StoreIC::ValueRegister();
-  __ Mov(result, Operand(cell));
-  __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
-
-  // Check for deleted property if property can actually be deleted.
-  if (is_configurable) {
-    __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss);
-  }
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
-  __ Ret();
-
-  FrontendFooter(name, &miss);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, name);
-}
-
-
 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
                                                     CodeHandleList* handlers,
                                                     Handle<Name> name,
@@ -915,51 +122,6 @@
 
 
 #undef __
-#define __ ACCESS_MASM(masm)
-
-void ElementHandlerCompiler::GenerateLoadDictionaryElement(
-    MacroAssembler* masm) {
-  // The return address is in lr.
-  Label slow, miss;
-
-  Register result = x0;
-  Register key = LoadIC::NameRegister();
-  Register receiver = LoadIC::ReceiverRegister();
-  DCHECK(receiver.is(x1));
-  DCHECK(key.is(x2));
-
-  __ JumpIfNotSmi(key, &miss);
-  __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset));
-  __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6);
-  __ Ret();
-
-  __ Bind(&slow);
-  __ IncrementCounter(
-      masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3);
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
-
-  // Miss case, call the runtime.
-  __ Bind(&miss);
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
-}
-
-
-void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                                    StrictMode strict_mode) {
-  ASM_LOCATION("PropertyICCompiler::GenerateRuntimeSetProperty");
-
-  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
-          StoreIC::ValueRegister());
-
-  __ Mov(x10, Smi::FromInt(strict_mode));
-  __ Push(x10);
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
-#undef __
 }
 }  // namespace v8::internal
 
diff --git a/src/ic/handler-compiler.cc b/src/ic/handler-compiler.cc
new file mode 100644
index 0000000..5c747c1
--- /dev/null
+++ b/src/ic/handler-compiler.cc
@@ -0,0 +1,392 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
+#include "src/ic/ic-inl.h"
+
+namespace v8 {
+namespace internal {
+
+
+Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
+                                           Handle<Map> stub_holder,
+                                           Code::Kind kind,
+                                           CacheHolderFlag cache_holder,
+                                           Code::StubType type) {
+  Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
+  Object* probe = stub_holder->FindInCodeCache(*name, flags);
+  if (probe->IsCode()) return handle(Code::cast(probe));
+  return Handle<Code>::null();
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
+    Handle<Name> name, Handle<HeapType> type) {
+  Isolate* isolate = name->GetIsolate();
+  Handle<Map> receiver_map = IC::TypeToMap(*type, isolate);
+  if (receiver_map->prototype()->IsNull()) {
+    // TODO(jkummerow/verwaest): If there is no prototype and the property
+    // is nonexistent, introduce a builtin to handle this (fast properties
+    // -> return undefined, dictionary properties -> do negative lookup).
+    return Handle<Code>();
+  }
+  CacheHolderFlag flag;
+  Handle<Map> stub_holder_map =
+      IC::GetHandlerCacheHolder(*type, false, isolate, &flag);
+
+  // If no dictionary mode objects are present in the prototype chain, the load
+  // nonexistent IC stub can be shared for all names for a given map and we use
+  // the empty string for the map cache in that case. If there are dictionary
+  // mode objects involved, we need to do negative lookups in the stub and
+  // therefore the stub will be specific to the name.
+  Handle<Name> cache_name =
+      receiver_map->is_dictionary_map()
+          ? name
+          : Handle<Name>::cast(isolate->factory()->nonexistent_symbol());
+  Handle<Map> current_map = stub_holder_map;
+  Handle<JSObject> last(JSObject::cast(receiver_map->prototype()));
+  while (true) {
+    if (current_map->is_dictionary_map()) cache_name = name;
+    if (current_map->prototype()->IsNull()) break;
+    last = handle(JSObject::cast(current_map->prototype()));
+    current_map = handle(last->map());
+  }
+  // Compile the stub that is either shared for all names or
+  // name specific if there are global objects involved.
+  Handle<Code> handler = PropertyHandlerCompiler::Find(
+      cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST);
+  if (!handler.is_null()) return handler;
+
+  NamedLoadHandlerCompiler compiler(isolate, type, last, flag);
+  handler = compiler.CompileLoadNonexistent(cache_name);
+  Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
+  return handler;
+}
+
+
+Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
+                                              Code::StubType type,
+                                              Handle<Name> name) {
+  Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder());
+  Handle<Code> code = GetCodeWithFlags(flags, name);
+  PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name));
+  return code;
+}
+
+
+#define __ ACCESS_MASM(masm())
+
+
+Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
+                                                  Handle<Name> name,
+                                                  Label* miss) {
+  PrototypeCheckType check_type = CHECK_ALL_MAPS;
+  int function_index = -1;
+  if (type()->Is(HeapType::String())) {
+    function_index = Context::STRING_FUNCTION_INDEX;
+  } else if (type()->Is(HeapType::Symbol())) {
+    function_index = Context::SYMBOL_FUNCTION_INDEX;
+  } else if (type()->Is(HeapType::Number())) {
+    function_index = Context::NUMBER_FUNCTION_INDEX;
+  } else if (type()->Is(HeapType::Boolean())) {
+    function_index = Context::BOOLEAN_FUNCTION_INDEX;
+  } else {
+    check_type = SKIP_RECEIVER;
+  }
+
+  if (check_type == CHECK_ALL_MAPS) {
+    GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
+                                              scratch1(), miss);
+    Object* function = isolate()->native_context()->get(function_index);
+    Object* prototype = JSFunction::cast(function)->instance_prototype();
+    set_type_for_object(handle(prototype, isolate()));
+    object_reg = scratch1();
+  }
+
+  // Check that the maps starting from the prototype haven't changed.
+  return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
+                         miss, check_type);
+}
+
+
+// Frontend for store uses the name register. It has to be restored before a
+// miss.
+Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
+                                                   Handle<Name> name,
+                                                   Label* miss) {
+  return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
+                         miss, SKIP_RECEIVER);
+}
+
+
+Register PropertyHandlerCompiler::Frontend(Register object_reg,
+                                           Handle<Name> name) {
+  Label miss;
+  Register reg = FrontendHeader(object_reg, name, &miss);
+  FrontendFooter(name, &miss);
+  return reg;
+}
+
+
+void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
+                                                        Label* miss,
+                                                        Register scratch1,
+                                                        Register scratch2) {
+  Register holder_reg;
+  Handle<Map> last_map;
+  if (holder().is_null()) {
+    holder_reg = receiver();
+    last_map = IC::TypeToMap(*type(), isolate());
+    // If |type| has null as its prototype, |holder()| is
+    // Handle<JSObject>::null().
+    DCHECK(last_map->prototype() == isolate()->heap()->null_value());
+  } else {
+    holder_reg = FrontendHeader(receiver(), name, miss);
+    last_map = handle(holder()->map());
+  }
+
+  if (last_map->is_dictionary_map()) {
+    if (last_map->IsJSGlobalObjectMap()) {
+      Handle<JSGlobalObject> global =
+          holder().is_null()
+              ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value())
+              : Handle<JSGlobalObject>::cast(holder());
+      GenerateCheckPropertyCell(masm(), global, name, scratch1, miss);
+    } else {
+      if (!name->IsUniqueName()) {
+        DCHECK(name->IsString());
+        name = factory()->InternalizeString(Handle<String>::cast(name));
+      }
+      DCHECK(holder().is_null() ||
+             holder()->property_dictionary()->FindEntry(name) ==
+                 NameDictionary::kNotFound);
+      GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1,
+                                       scratch2);
+    }
+  }
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name,
+                                                        FieldIndex field) {
+  Register reg = Frontend(receiver(), name);
+  __ Move(receiver(), reg);
+  LoadFieldStub stub(isolate(), field);
+  GenerateTailCall(masm(), stub.GetCode());
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name,
+                                                           int constant_index) {
+  Register reg = Frontend(receiver(), name);
+  __ Move(receiver(), reg);
+  LoadConstantStub stub(isolate(), constant_index);
+  GenerateTailCall(masm(), stub.GetCode());
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
+    Handle<Name> name) {
+  Label miss;
+  NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
+  GenerateLoadConstant(isolate()->factory()->undefined_value());
+  FrontendFooter(name, &miss);
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
+    Handle<Name> name, Handle<ExecutableAccessorInfo> callback) {
+  Register reg = Frontend(receiver(), name);
+  GenerateLoadCallback(reg, callback);
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
+    Handle<Name> name, const CallOptimization& call_optimization) {
+  DCHECK(call_optimization.is_simple_api_call());
+  Frontend(receiver(), name);
+  Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
+  GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
+                      scratch1(), false, 0, NULL);
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
+    LookupIterator* it) {
+  // So far the most popular follow ups for interceptor loads are FIELD and
+  // ExecutableAccessorInfo, so inline only them. Other cases may be added
+  // later.
+  bool inline_followup = it->state() == LookupIterator::PROPERTY;
+  if (inline_followup) {
+    switch (it->property_kind()) {
+      case LookupIterator::DATA:
+        inline_followup = it->property_details().type() == FIELD;
+        break;
+      case LookupIterator::ACCESSOR: {
+        Handle<Object> accessors = it->GetAccessors();
+        inline_followup = accessors->IsExecutableAccessorInfo();
+        if (!inline_followup) break;
+        Handle<ExecutableAccessorInfo> info =
+            Handle<ExecutableAccessorInfo>::cast(accessors);
+        inline_followup = info->getter() != NULL &&
+                          ExecutableAccessorInfo::IsCompatibleReceiverType(
+                              isolate(), info, type());
+      }
+    }
+  }
+
+  Register reg = Frontend(receiver(), it->name());
+  if (inline_followup) {
+    // TODO(368): Compile in the whole chain: all the interceptors in
+    // prototypes and ultimate answer.
+    GenerateLoadInterceptorWithFollowup(it, reg);
+  } else {
+    GenerateLoadInterceptor(reg);
+  }
+  return GetCode(kind(), Code::FAST, it->name());
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
+    LookupIterator* it, Register interceptor_reg) {
+  Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
+
+  set_type_for_object(holder());
+  set_holder(real_named_property_holder);
+  Register reg = Frontend(interceptor_reg, it->name());
+
+  switch (it->property_kind()) {
+    case LookupIterator::DATA: {
+      DCHECK_EQ(FIELD, it->property_details().type());
+      __ Move(receiver(), reg);
+      LoadFieldStub stub(isolate(), it->GetFieldIndex());
+      GenerateTailCall(masm(), stub.GetCode());
+      break;
+    }
+    case LookupIterator::ACCESSOR:
+      Handle<ExecutableAccessorInfo> info =
+          Handle<ExecutableAccessorInfo>::cast(it->GetAccessors());
+      DCHECK_NE(NULL, info->getter());
+      GenerateLoadCallback(reg, info);
+  }
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
+    Handle<Name> name, Handle<JSFunction> getter) {
+  Frontend(receiver(), name);
+  GenerateLoadViaGetter(masm(), type(), receiver(), getter);
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+// TODO(verwaest): Cleanup. holder() is actually the receiver.
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
+    Handle<Map> transition, Handle<Name> name) {
+  Label miss, slow;
+
+  // Ensure no transitions to deprecated maps are followed.
+  __ CheckMapDeprecated(transition, scratch1(), &miss);
+
+  // Check that we are allowed to write this.
+  bool is_nonexistent = holder()->map() == transition->GetBackPointer();
+  if (is_nonexistent) {
+    // Find the top object.
+    Handle<JSObject> last;
+    PrototypeIterator iter(isolate(), holder());
+    while (!iter.IsAtEnd()) {
+      last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      iter.Advance();
+    }
+    if (!last.is_null()) set_holder(last);
+    NonexistentFrontendHeader(name, &miss, scratch1(), scratch2());
+  } else {
+    FrontendHeader(receiver(), name, &miss);
+    DCHECK(holder()->HasFastProperties());
+  }
+
+  GenerateStoreTransition(transition, name, receiver(), this->name(), value(),
+                          scratch1(), scratch2(), scratch3(), &miss, &slow);
+
+  GenerateRestoreName(&miss, name);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  GenerateRestoreName(&slow, name);
+  TailCallBuiltin(masm(), SlowBuiltin(kind()));
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
+  Label miss;
+  GenerateStoreField(it, value(), &miss);
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+  return GetCode(kind(), Code::FAST, it->name());
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
+    Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) {
+  Frontend(receiver(), name);
+  GenerateStoreViaSetter(masm(), type(), receiver(), setter);
+
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
+    Handle<JSObject> object, Handle<Name> name,
+    const CallOptimization& call_optimization) {
+  Frontend(receiver(), name);
+  Register values[] = {value()};
+  GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
+                      receiver(), scratch1(), true, 1, values);
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+#undef __
+
+
+void ElementHandlerCompiler::CompileElementHandlers(
+    MapHandleList* receiver_maps, CodeHandleList* handlers) {
+  for (int i = 0; i < receiver_maps->length(); ++i) {
+    Handle<Map> receiver_map = receiver_maps->at(i);
+    Handle<Code> cached_stub;
+
+    if ((receiver_map->instance_type() & kNotStringTag) == 0) {
+      cached_stub = isolate()->builtins()->KeyedLoadIC_String();
+    } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
+      cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
+    } else {
+      bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
+      ElementsKind elements_kind = receiver_map->elements_kind();
+
+      if (IsFastElementsKind(elements_kind) ||
+          IsExternalArrayElementsKind(elements_kind) ||
+          IsFixedTypedArrayElementsKind(elements_kind)) {
+        cached_stub = LoadFastElementStub(isolate(), is_js_array, elements_kind)
+                          .GetCode();
+      } else if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
+        cached_stub = isolate()->builtins()->KeyedLoadIC_SloppyArguments();
+      } else {
+        DCHECK(elements_kind == DICTIONARY_ELEMENTS);
+        cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
+      }
+    }
+
+    handlers->Add(cached_stub);
+  }
+}
+}
+}  // namespace v8::internal
diff --git a/src/ic/handler-compiler.h b/src/ic/handler-compiler.h
new file mode 100644
index 0000000..af54e2c
--- /dev/null
+++ b/src/ic/handler-compiler.h
@@ -0,0 +1,277 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_IC_HANDLER_COMPILER_H_
+#define V8_IC_HANDLER_COMPILER_H_
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+class CallOptimization;
+
+enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
+
+class PropertyHandlerCompiler : public PropertyAccessCompiler {
+ public:
+  static Handle<Code> Find(Handle<Name> name, Handle<Map> map, Code::Kind kind,
+                           CacheHolderFlag cache_holder, Code::StubType type);
+
+ protected:
+  PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind,
+                          Handle<HeapType> type, Handle<JSObject> holder,
+                          CacheHolderFlag cache_holder)
+      : PropertyAccessCompiler(isolate, kind, cache_holder),
+        type_(type),
+        holder_(holder) {}
+
+  virtual ~PropertyHandlerCompiler() {}
+
+  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
+                                  Label* miss) {
+    UNREACHABLE();
+    return receiver();
+  }
+
+  virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
+
+  Register Frontend(Register object_reg, Handle<Name> name);
+  void NonexistentFrontendHeader(Handle<Name> name, Label* miss,
+                                 Register scratch1, Register scratch2);
+
+  // TODO(verwaest): Make non-static.
+  static void GenerateFastApiCall(MacroAssembler* masm,
+                                  const CallOptimization& optimization,
+                                  Handle<Map> receiver_map, Register receiver,
+                                  Register scratch, bool is_store, int argc,
+                                  Register* values);
+
+  // Helper function used to check that the dictionary doesn't contain
+  // the property. This function may return false negatives, so miss_label
+  // must always call a backup property check that is complete.
+  // This function is safe to call if the receiver has fast properties.
+  // Name must be unique and receiver must be a heap object.
+  static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
+                                               Label* miss_label,
+                                               Register receiver,
+                                               Handle<Name> name, Register r0,
+                                               Register r1);
+
+  // Generate code to check that a global property cell is empty. Create
+  // the property cell at compilation time if no cell exists for the
+  // property.
+  static void GenerateCheckPropertyCell(MacroAssembler* masm,
+                                        Handle<JSGlobalObject> global,
+                                        Handle<Name> name, Register scratch,
+                                        Label* miss);
+
+  // Generates code that verifies that the property holder has not changed
+  // (checking maps of objects in the prototype chain for fast and global
+  // objects or doing negative lookup for slow objects, ensures that the
+  // property cells for global objects are still empty) and checks that the map
+  // of the holder has not changed. If necessary the function also generates
+  // code for security check in case of global object holders. Helps to make
+  // sure that the current IC is still valid.
+  //
+  // The scratch and holder registers are always clobbered, but the object
+  // register is only clobbered if it the same as the holder register. The
+  // function returns a register containing the holder - either object_reg or
+  // holder_reg.
+  Register CheckPrototypes(Register object_reg, Register holder_reg,
+                           Register scratch1, Register scratch2,
+                           Handle<Name> name, Label* miss,
+                           PrototypeCheckType check = CHECK_ALL_MAPS);
+
+  Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
+  void set_type_for_object(Handle<Object> object) {
+    type_ = IC::CurrentTypeOf(object, isolate());
+  }
+  void set_holder(Handle<JSObject> holder) { holder_ = holder; }
+  Handle<HeapType> type() const { return type_; }
+  Handle<JSObject> holder() const { return holder_; }
+
+ private:
+  Handle<HeapType> type_;
+  Handle<JSObject> holder_;
+};
+
+
+class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
+ public:
+  NamedLoadHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
+                           Handle<JSObject> holder,
+                           CacheHolderFlag cache_holder)
+      : PropertyHandlerCompiler(isolate, Code::LOAD_IC, type, holder,
+                                cache_holder) {}
+
+  virtual ~NamedLoadHandlerCompiler() {}
+
+  Handle<Code> CompileLoadField(Handle<Name> name, FieldIndex index);
+
+  Handle<Code> CompileLoadCallback(Handle<Name> name,
+                                   Handle<ExecutableAccessorInfo> callback);
+
+  Handle<Code> CompileLoadCallback(Handle<Name> name,
+                                   const CallOptimization& call_optimization);
+
+  Handle<Code> CompileLoadConstant(Handle<Name> name, int constant_index);
+
+  // The LookupIterator is used to perform a lookup behind the interceptor. If
+  // the iterator points to a LookupIterator::PROPERTY, its access will be
+  // inlined.
+  Handle<Code> CompileLoadInterceptor(LookupIterator* it);
+
+  Handle<Code> CompileLoadViaGetter(Handle<Name> name,
+                                    Handle<JSFunction> getter);
+
+  Handle<Code> CompileLoadGlobal(Handle<PropertyCell> cell, Handle<Name> name,
+                                 bool is_configurable);
+
+  // Static interface
+  static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
+                                             Handle<HeapType> type);
+
+  static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
+                                    Register receiver,
+                                    Handle<JSFunction> getter);
+
+  static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
+    GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg,
+                          Handle<JSFunction>());
+  }
+
+  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
+                                            Register receiver,
+                                            Register scratch1,
+                                            Register scratch2,
+                                            Label* miss_label);
+
+  // These constants describe the structure of the interceptor arguments on the
+  // stack. The arguments are pushed by the (platform-specific)
+  // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and
+  // LoadWithInterceptor.
+  static const int kInterceptorArgsNameIndex = 0;
+  static const int kInterceptorArgsInfoIndex = 1;
+  static const int kInterceptorArgsThisIndex = 2;
+  static const int kInterceptorArgsHolderIndex = 3;
+  static const int kInterceptorArgsLength = 4;
+
+ protected:
+  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
+                                  Label* miss);
+
+  virtual void FrontendFooter(Handle<Name> name, Label* miss);
+
+ private:
+  Handle<Code> CompileLoadNonexistent(Handle<Name> name);
+  void GenerateLoadConstant(Handle<Object> value);
+  void GenerateLoadCallback(Register reg,
+                            Handle<ExecutableAccessorInfo> callback);
+  void GenerateLoadCallback(const CallOptimization& call_optimization,
+                            Handle<Map> receiver_map);
+  void GenerateLoadInterceptor(Register holder_reg);
+  void GenerateLoadInterceptorWithFollowup(LookupIterator* it,
+                                           Register holder_reg);
+  void GenerateLoadPostInterceptor(LookupIterator* it, Register reg);
+
+  // Generates prototype loading code that uses the objects from the
+  // context we were in when this function was called. If the context
+  // has changed, a jump to miss is performed. This ties the generated
+  // code to a particular context and so must not be used in cases
+  // where the generated code is not allowed to have references to
+  // objects from a context.
+  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
+                                                        int index,
+                                                        Register prototype,
+                                                        Label* miss);
+
+
+  Register scratch4() { return registers_[5]; }
+};
+
+
+class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
+ public:
+  explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
+                                     Handle<JSObject> holder)
+      : PropertyHandlerCompiler(isolate, Code::STORE_IC, type, holder,
+                                kCacheOnReceiver) {}
+
+  virtual ~NamedStoreHandlerCompiler() {}
+
+  Handle<Code> CompileStoreTransition(Handle<Map> transition,
+                                      Handle<Name> name);
+  Handle<Code> CompileStoreField(LookupIterator* it);
+  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
+                                    Handle<ExecutableAccessorInfo> callback);
+  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
+                                    const CallOptimization& call_optimization);
+  Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, Handle<Name> name,
+                                     Handle<JSFunction> setter);
+  Handle<Code> CompileStoreInterceptor(Handle<Name> name);
+
+  static void GenerateStoreViaSetter(MacroAssembler* masm,
+                                     Handle<HeapType> type, Register receiver,
+                                     Handle<JSFunction> setter);
+
+  static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
+    GenerateStoreViaSetter(masm, Handle<HeapType>::null(), no_reg,
+                           Handle<JSFunction>());
+  }
+
+  static void GenerateSlow(MacroAssembler* masm);
+
+ protected:
+  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
+                                  Label* miss);
+
+  virtual void FrontendFooter(Handle<Name> name, Label* miss);
+  void GenerateRestoreName(Label* label, Handle<Name> name);
+
+ private:
+  void GenerateStoreTransition(Handle<Map> transition, Handle<Name> name,
+                               Register receiver_reg, Register name_reg,
+                               Register value_reg, Register scratch1,
+                               Register scratch2, Register scratch3,
+                               Label* miss_label, Label* slow);
+
+  void GenerateStoreField(LookupIterator* lookup, Register value_reg,
+                          Label* miss_label);
+
+  static Builtins::Name SlowBuiltin(Code::Kind kind) {
+    switch (kind) {
+      case Code::STORE_IC:
+        return Builtins::kStoreIC_Slow;
+      case Code::KEYED_STORE_IC:
+        return Builtins::kKeyedStoreIC_Slow;
+      default:
+        UNREACHABLE();
+    }
+    return Builtins::kStoreIC_Slow;
+  }
+
+  static Register value();
+};
+
+
+class ElementHandlerCompiler : public PropertyHandlerCompiler {
+ public:
+  explicit ElementHandlerCompiler(Isolate* isolate)
+      : PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC,
+                                Handle<HeapType>::null(),
+                                Handle<JSObject>::null(), kCacheOnReceiver) {}
+
+  virtual ~ElementHandlerCompiler() {}
+
+  void CompileElementHandlers(MapHandleList* receiver_maps,
+                              CodeHandleList* handlers);
+
+  static void GenerateLoadDictionaryElement(MacroAssembler* masm);
+  static void GenerateStoreSlow(MacroAssembler* masm);
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_IC_HANDLER_COMPILER_H_
diff --git a/src/x87/stub-cache-x87.cc b/src/ic/ia32/handler-compiler-ia32.cc
similarity index 68%
copy from src/x87/stub-cache-x87.cc
copy to src/ic/ia32/handler-compiler-ia32.cc
index dedbaa6..48b8adc 100644
--- a/src/x87/stub-cache-x87.cc
+++ b/src/ic/ia32/handler-compiler-ia32.cc
@@ -1,14 +1,13 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2014 the V8 project authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "src/v8.h"
 
-#if V8_TARGET_ARCH_X87
+#if V8_TARGET_ARCH_IA32
 
-#include "src/codegen.h"
-#include "src/ic-inl.h"
-#include "src/stub-cache.h"
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
 
 namespace v8 {
 namespace internal {
@@ -16,101 +15,80 @@
 #define __ ACCESS_MASM(masm)
 
 
-static void ProbeTable(Isolate* isolate,
-                       MacroAssembler* masm,
-                       Code::Flags flags,
-                       StubCache::Table table,
-                       Register name,
-                       Register receiver,
-                       // Number of the cache entry pointer-size scaled.
-                       Register offset,
-                       Register extra) {
-  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
-  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
-  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
+void ElementHandlerCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- ecx    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  DCHECK(edx.is(LoadIC::ReceiverRegister()));
+  DCHECK(ecx.is(LoadIC::NameRegister()));
+  Label slow, miss;
 
-  Label miss;
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+  __ JumpIfNotSmi(ecx, &miss);
+  __ mov(ebx, ecx);
+  __ SmiUntag(ebx);
+  __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
 
-  // Multiply by 3 because there are 3 fields per entry (name, code, map).
-  __ lea(offset, Operand(offset, offset, times_2, 0));
+  // Push receiver on the stack to free up a register for the dictionary
+  // probing.
+  __ push(edx);
+  __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax);
+  // Pop receiver before returning.
+  __ pop(edx);
+  __ ret(0);
 
-  if (extra.is_valid()) {
-    // Get the code entry from the cache.
-    __ mov(extra, Operand::StaticArray(offset, times_1, value_offset));
+  __ bind(&slow);
+  __ pop(edx);
 
-    // Check that the key in the entry matches the name.
-    __ cmp(name, Operand::StaticArray(offset, times_1, key_offset));
-    __ j(not_equal, &miss);
+  // ----------- S t a t e -------------
+  //  -- ecx    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
 
-    // Check the map matches.
-    __ mov(offset, Operand::StaticArray(offset, times_1, map_offset));
-    __ cmp(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-    __ j(not_equal, &miss);
+  __ bind(&miss);
+  // ----------- S t a t e -------------
+  //  -- ecx    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
+}
 
-    // Check that the flags match what we're looking for.
-    __ mov(offset, FieldOperand(extra, Code::kFlagsOffset));
-    __ and_(offset, ~Code::kFlagsNotUsedInLookup);
-    __ cmp(offset, flags);
-    __ j(not_equal, &miss);
 
-#ifdef DEBUG
-    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
-      __ jmp(&miss);
-    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
-      __ jmp(&miss);
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> getter) {
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    if (!getter.is_null()) {
+      // Call the JavaScript getter with the receiver on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ mov(receiver,
+               FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ push(receiver);
+      ParameterCount actual(0);
+      ParameterCount expected(getter);
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
     }
-#endif
 
-    // Jump to the first instruction in the code stub.
-    __ add(extra, Immediate(Code::kHeaderSize - kHeapObjectTag));
-    __ jmp(extra);
-
-    __ bind(&miss);
-  } else {
-    // Save the offset on the stack.
-    __ push(offset);
-
-    // Check that the key in the entry matches the name.
-    __ cmp(name, Operand::StaticArray(offset, times_1, key_offset));
-    __ j(not_equal, &miss);
-
-    // Check the map matches.
-    __ mov(offset, Operand::StaticArray(offset, times_1, map_offset));
-    __ cmp(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-    __ j(not_equal, &miss);
-
-    // Restore offset register.
-    __ mov(offset, Operand(esp, 0));
-
-    // Get the code entry from the cache.
-    __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
-
-    // Check that the flags match what we're looking for.
-    __ mov(offset, FieldOperand(offset, Code::kFlagsOffset));
-    __ and_(offset, ~Code::kFlagsNotUsedInLookup);
-    __ cmp(offset, flags);
-    __ j(not_equal, &miss);
-
-#ifdef DEBUG
-    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
-      __ jmp(&miss);
-    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
-      __ jmp(&miss);
-    }
-#endif
-
-    // Restore offset and re-load code entry from cache.
-    __ pop(offset);
-    __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
-
-    // Jump to the first instruction in the code stub.
-    __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag));
-    __ jmp(offset);
-
-    // Pop at miss.
-    __ bind(&miss);
-    __ pop(offset);
+    // Restore context register.
+    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   }
+  __ ret(0);
 }
 
 
@@ -147,89 +125,13 @@
   __ j(not_equal, miss_label);
 
   Label done;
-  NameDictionaryLookupStub::GenerateNegativeLookup(masm,
-                                                   miss_label,
-                                                   &done,
-                                                   properties,
-                                                   name,
-                                                   scratch1);
+  NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done,
+                                                   properties, name, scratch1);
   __ bind(&done);
   __ DecrementCounter(counters->negative_lookups_miss(), 1);
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm,
-                              Code::Flags flags,
-                              Register receiver,
-                              Register name,
-                              Register scratch,
-                              Register extra,
-                              Register extra2,
-                              Register extra3) {
-  Label miss;
-
-  // Assert that code is valid.  The multiplying code relies on the entry size
-  // being 12.
-  DCHECK(sizeof(Entry) == 12);
-
-  // Assert the flags do not name a specific type.
-  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
-
-  // Assert that there are no register conflicts.
-  DCHECK(!scratch.is(receiver));
-  DCHECK(!scratch.is(name));
-  DCHECK(!extra.is(receiver));
-  DCHECK(!extra.is(name));
-  DCHECK(!extra.is(scratch));
-
-  // Assert scratch and extra registers are valid, and extra2/3 are unused.
-  DCHECK(!scratch.is(no_reg));
-  DCHECK(extra2.is(no_reg));
-  DCHECK(extra3.is(no_reg));
-
-  Register offset = scratch;
-  scratch = no_reg;
-
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, &miss);
-
-  // Get the map of the receiver and compute the hash.
-  __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
-  __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-  __ xor_(offset, flags);
-  // We mask out the last two bits because they are not part of the hash and
-  // they are always 01 for maps.  Also in the two 'and' instructions below.
-  __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift);
-  // ProbeTable expects the offset to be pointer scaled, which it is, because
-  // the heap object tag size is 2 and the pointer size log 2 is also 2.
-  DCHECK(kCacheIndexShift == kPointerSizeLog2);
-
-  // Probe the primary table.
-  ProbeTable(isolate(), masm, flags, kPrimary, name, receiver, offset, extra);
-
-  // Primary miss: Compute hash for secondary probe.
-  __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
-  __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-  __ xor_(offset, flags);
-  __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift);
-  __ sub(offset, name);
-  __ add(offset, Immediate(flags));
-  __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift);
-
-  // Probe the secondary table.
-  ProbeTable(
-      isolate(), masm, flags, kSecondary, name, receiver, offset, extra);
-
-  // Cache miss: Fall-through and let caller handle the miss by
-  // entering the runtime system.
-  __ bind(&miss);
-  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
-}
-
-
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
     MacroAssembler* masm, int index, Register prototype, Label* miss) {
   // Get the global function with the given index.
@@ -259,40 +161,6 @@
 }
 
 
-static void PushInterceptorArguments(MacroAssembler* masm,
-                                     Register receiver,
-                                     Register holder,
-                                     Register name,
-                                     Handle<JSObject> holder_obj) {
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
-  __ push(name);
-  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
-  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
-  Register scratch = name;
-  __ mov(scratch, Immediate(interceptor));
-  __ push(scratch);
-  __ push(receiver);
-  __ push(holder);
-}
-
-
-static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm,
-    Register receiver,
-    Register holder,
-    Register name,
-    Handle<JSObject> holder_obj,
-    IC::UtilityId id) {
-  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
-                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
-}
-
-
 // Generate call to api function.
 // This function uses push() to generate smaller, faster code than
 // the version above. It is an optimization that should will be removed
@@ -307,7 +175,7 @@
   __ push(receiver);
   // Write the arguments to stack frame.
   for (int i = 0; i < argc; i++) {
-    Register arg = values[argc-1-i];
+    Register arg = values[argc - 1 - i];
     DCHECK(!receiver.is(arg));
     DCHECK(!scratch_in.is(arg));
     __ push(arg);
@@ -325,16 +193,15 @@
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
-      receiver_map,
-      &holder_lookup);
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
       __ LoadHeapObject(holder, api_holder);
-     break;
+      break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
       break;
@@ -376,8 +243,7 @@
 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
     MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
     Register scratch, Label* miss) {
-  Handle<PropertyCell> cell =
-      JSGlobalObject::EnsurePropertyCell(global, name);
+  Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
   DCHECK(cell->value()->IsTheHole());
   Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
   if (masm->serializer_enabled()) {
@@ -391,9 +257,107 @@
 }
 
 
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ jmp(code, RelocInfo::CODE_TARGET);
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> setter) {
+  // ----------- S t a t e -------------
+  //  -- esp[0] : return address
+  // -----------------------------------
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Save value register, so we can restore it later.
+    __ push(value());
+
+    if (!setter.is_null()) {
+      // Call the JavaScript setter with receiver and value on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ mov(receiver,
+               FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ push(receiver);
+      __ push(value());
+      ParameterCount actual(1);
+      ParameterCount expected(setter);
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // We have to return the passed value, not the return value of the setter.
+    __ pop(eax);
+
+    // Restore context register.
+    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+  }
+  __ ret(0);
+}
+
+
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
+                                     Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
+  __ push(name);
+  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
+  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
+  Register scratch = name;
+  __ mov(scratch, Immediate(interceptor));
+  __ push(scratch);
+  __ push(receiver);
+  __ push(holder);
+}
+
+
+static void CompileCallLoadPropertyWithInterceptor(
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
+  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
+  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
+                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
+}
+
+
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  Register value = StoreIC::ValueRegister();
+
+  DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value));
+
+  __ pop(ebx);
+  __ push(receiver);
+  __ push(name);
+  __ push(value);
+  __ push(ebx);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
+  // Return address is on the stack.
+  StoreIC_PushArgs(masm);
+
+  // Do tail-call to runtime routine.
+  ExternalReference ref(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
+  // Return address is on the stack.
+  StoreIC_PushArgs(masm);
+
+  // Do tail-call to runtime routine.
+  ExternalReference ref(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
 }
 
 
@@ -427,7 +391,7 @@
     __ CmpObject(value_reg, constant);
     __ j(not_equal, miss_label);
   } else if (representation.IsSmi()) {
-      __ JumpIfNotSmi(value_reg, miss_label);
+    __ JumpIfNotSmi(value_reg, miss_label);
   } else if (representation.IsHeapObject()) {
     __ JumpIfSmi(value_reg, miss_label);
     HeapType* field_type = descriptors->GetFieldType(descriptor);
@@ -451,19 +415,17 @@
 
     __ JumpIfNotSmi(value_reg, &heap_number);
     __ SmiUntag(value_reg);
-    __ push(value_reg);
-    __ fild_s(Operand(esp, 0));
-    __ pop(value_reg);
+    __ Cvtsi2sd(xmm0, value_reg);
     __ SmiTag(value_reg);
     __ jmp(&do_store);
 
     __ bind(&heap_number);
     __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
                 DONT_DO_SMI_CHECK);
-    __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset));
+    __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
 
     __ bind(&do_store);
-    __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset));
+    __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
   }
 
   // Stub never generated for objects that require access checks.
@@ -491,12 +453,8 @@
   __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
 
   // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg,
-                      HeapObject::kMapOffset,
-                      scratch1,
-                      scratch2,
-                      OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
+  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
+                      kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
 
   if (details.type() == CONSTANT) {
     DCHECK(value_reg.is(eax));
@@ -512,8 +470,8 @@
   // object and the number of in-object properties is not going to change.
   index -= transition->inobject_properties();
 
-  SmiCheck smi_check = representation.IsTagged()
-      ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  SmiCheck smi_check =
+      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
   // TODO(verwaest): Share this code as a code stub.
   if (index < 0) {
     // Set the property straight into the object.
@@ -529,12 +487,8 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(receiver_reg,
-                          offset,
-                          storage_reg,
-                          scratch1,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
+                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
     }
   } else {
     // Write to the properties array.
@@ -552,12 +506,8 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(scratch1,
-                          offset,
-                          storage_reg,
-                          receiver_reg,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
+                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
     }
   }
 
@@ -599,8 +549,8 @@
 
   // Make sure there's no overlap between holder and object registers.
   DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
-         && !scratch2.is(scratch1));
+  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
+         !scratch2.is(scratch1));
 
   // Keep track of the current object in register reg.
   Register reg = object_reg;
@@ -632,10 +582,10 @@
       }
       DCHECK(current.is_null() ||
              current->property_dictionary()->FindEntry(name) ==
-             NameDictionary::kNotFound);
+                 NameDictionary::kNotFound);
 
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
-                                       scratch1, scratch2);
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
 
       __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
       reg = holder_reg;  // From now on the object will be in holder_reg.
@@ -660,9 +610,8 @@
       if (current_map->IsJSGlobalProxyMap()) {
         __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
       } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(
-            masm(), Handle<JSGlobalObject>::cast(current), name,
-            scratch2, miss);
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
       }
 
       if (load_prototype_from_map) {
@@ -885,55 +834,6 @@
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- esp[0] : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Save value register, so we can restore it later.
-    __ push(value());
-
-    if (!setter.is_null()) {
-      // Call the JavaScript setter with receiver and value on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ mov(receiver,
-               FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ push(receiver);
-      __ push(value());
-      ParameterCount actual(1);
-      ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // We have to return the passed value, not the return value of the setter.
-    __ pop(eax);
-
-    // Restore context register.
-    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-  }
-  __ ret(0);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
     Handle<Name> name) {
   __ pop(scratch1());  // remove the return address
@@ -952,93 +852,9 @@
 }
 
 
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
-    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
-    MapHandleList* transitioned_maps) {
-  Label miss;
-  __ JumpIfSmi(receiver(), &miss, Label::kNear);
-  __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
-  for (int i = 0; i < receiver_maps->length(); ++i) {
-    __ cmp(scratch1(), receiver_maps->at(i));
-    if (transitioned_maps->at(i).is_null()) {
-      __ j(equal, handler_stubs->at(i));
-    } else {
-      Label next_map;
-      __ j(not_equal, &next_map, Label::kNear);
-      __ mov(transition_map(), Immediate(transitioned_maps->at(i)));
-      __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
-      __ bind(&next_map);
-    }
-  }
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
-}
-
-
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = { receiver, name, ebx, eax, edi, no_reg };
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3.
-  Register receiver = StoreIC::ReceiverRegister();
-  Register name = StoreIC::NameRegister();
-  DCHECK(ebx.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = { receiver, name, ebx, edi, no_reg };
-  return registers;
-}
-
-
 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    if (!getter.is_null()) {
-      // Call the JavaScript getter with the receiver on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ mov(receiver,
-               FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ push(receiver);
-      ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // Restore context register.
-    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-  }
-  __ ret(0);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
@@ -1074,113 +890,8 @@
 }
 
 
-Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
-                                                    CodeHandleList* handlers,
-                                                    Handle<Name> name,
-                                                    Code::StubType type,
-                                                    IcCheckType check) {
-  Label miss;
-
-  if (check == PROPERTY &&
-      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
-    // check whether the name is unique.
-    if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
-      __ JumpIfNotUniqueName(this->name(), &miss);
-    } else {
-      __ cmp(this->name(), Immediate(name));
-      __ j(not_equal, &miss);
-    }
-  }
-
-  Label number_case;
-  Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
-  __ JumpIfSmi(receiver(), smi_target);
-
-  // Polymorphic keyed stores may use the map register
-  Register map_reg = scratch1();
-  DCHECK(kind() != Code::KEYED_STORE_IC ||
-         map_reg.is(KeyedStoreIC::MapRegister()));
-  __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
-  int receiver_count = types->length();
-  int number_of_handled_maps = 0;
-  for (int current = 0; current < receiver_count; ++current) {
-    Handle<HeapType> type = types->at(current);
-    Handle<Map> map = IC::TypeToMap(*type, isolate());
-    if (!map->is_deprecated()) {
-      number_of_handled_maps++;
-      __ cmp(map_reg, map);
-      if (type->Is(HeapType::Number())) {
-        DCHECK(!number_case.is_unused());
-        __ bind(&number_case);
-      }
-      __ j(equal, handlers->at(current));
-    }
-  }
-  DCHECK(number_of_handled_maps != 0);
-
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  InlineCacheState state =
-      number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
-  return GetCode(kind(), type, name, state);
-}
-
-
 #undef __
-#define __ ACCESS_MASM(masm)
-
-
-void ElementHandlerCompiler::GenerateLoadDictionaryElement(
-    MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  DCHECK(edx.is(LoadIC::ReceiverRegister()));
-  DCHECK(ecx.is(LoadIC::NameRegister()));
-  Label slow, miss;
-
-  // This stub is meant to be tail-jumped to, the receiver must already
-  // have been verified by the caller to not be a smi.
-  __ JumpIfNotSmi(ecx, &miss);
-  __ mov(ebx, ecx);
-  __ SmiUntag(ebx);
-  __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
-
-  // Push receiver on the stack to free up a register for the dictionary
-  // probing.
-  __ push(edx);
-  __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax);
-  // Pop receiver before returning.
-  __ pop(edx);
-  __ ret(0);
-
-  __ bind(&slow);
-  __ pop(edx);
-
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
-
-  __ bind(&miss);
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
 }
+}  // namespace v8::internal
 
-
-#undef __
-
-} }  // namespace v8::internal
-
-#endif  // V8_TARGET_ARCH_X87
+#endif  // V8_TARGET_ARCH_IA32
diff --git a/src/ic/ia32/ic-compiler-ia32.cc b/src/ic/ia32/ic-compiler-ia32.cc
index fb1542d..4fce7cc 100644
--- a/src/ic/ia32/ic-compiler-ia32.cc
+++ b/src/ic/ia32/ic-compiler-ia32.cc
@@ -6,7 +6,6 @@
 
 #if V8_TARGET_ARCH_IA32
 
-#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
@@ -14,842 +13,27 @@
 
 #define __ ACCESS_MASM(masm)
 
-void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
-    MacroAssembler* masm, Label* miss_label, Register receiver,
-    Handle<Name> name, Register scratch0, Register scratch1) {
-  DCHECK(name->IsUniqueName());
-  DCHECK(!receiver.is(scratch0));
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->negative_lookups(), 1);
-  __ IncrementCounter(counters->negative_lookups_miss(), 1);
 
-  __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  // Return address is on the stack.
+  DCHECK(!ebx.is(StoreIC::ReceiverRegister()) &&
+         !ebx.is(StoreIC::NameRegister()) && !ebx.is(StoreIC::ValueRegister()));
+  __ pop(ebx);
+  __ push(StoreIC::ReceiverRegister());
+  __ push(StoreIC::NameRegister());
+  __ push(StoreIC::ValueRegister());
+  __ push(Immediate(Smi::FromInt(strict_mode)));
+  __ push(ebx);  // return address
 
-  const int kInterceptorOrAccessCheckNeededMask =
-      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
-
-  // Bail out if the receiver has a named interceptor or requires access checks.
-  __ test_b(FieldOperand(scratch0, Map::kBitFieldOffset),
-            kInterceptorOrAccessCheckNeededMask);
-  __ j(not_zero, miss_label);
-
-  // Check that receiver is a JSObject.
-  __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE);
-  __ j(below, miss_label);
-
-  // Load properties array.
-  Register properties = scratch0;
-  __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
-
-  // Check that the properties array is a dictionary.
-  __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
-         Immediate(masm->isolate()->factory()->hash_table_map()));
-  __ j(not_equal, miss_label);
-
-  Label done;
-  NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done,
-                                                   properties, name, scratch1);
-  __ bind(&done);
-  __ DecrementCounter(counters->negative_lookups_miss(), 1);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(masm->isolate()->native_context()->get(index)));
-  // Check we're still in the same context.
-  Register scratch = prototype;
-  const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ mov(scratch, Operand(esi, offset));
-  __ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ cmp(Operand(scratch, Context::SlotOffset(index)), function);
-  __ j(not_equal, miss);
-
-  // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Immediate(Handle<Map>(function->initial_map())));
-  // Load the prototype from the initial map.
-  __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
-    MacroAssembler* masm, Register receiver, Register scratch1,
-    Register scratch2, Label* miss_label) {
-  __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
-  __ mov(eax, scratch1);
-  __ ret(0);
-}
-
-
-static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
-                                     Register holder, Register name,
-                                     Handle<JSObject> holder_obj) {
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
-  __ push(name);
-  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
-  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
-  Register scratch = name;
-  __ mov(scratch, Immediate(interceptor));
-  __ push(scratch);
-  __ push(receiver);
-  __ push(holder);
-}
-
-
-static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm, Register receiver, Register holder, Register name,
-    Handle<JSObject> holder_obj, IC::UtilityId id) {
-  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
-                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
-}
-
-
-// Generate call to api function.
-// This function uses push() to generate smaller, faster code than
-// the version above. It is an optimization that should will be removed
-// when api call ICs are generated in hydrogen.
-void PropertyHandlerCompiler::GenerateFastApiCall(
-    MacroAssembler* masm, const CallOptimization& optimization,
-    Handle<Map> receiver_map, Register receiver, Register scratch_in,
-    bool is_store, int argc, Register* values) {
-  // Copy return value.
-  __ pop(scratch_in);
-  // receiver
-  __ push(receiver);
-  // Write the arguments to stack frame.
-  for (int i = 0; i < argc; i++) {
-    Register arg = values[argc - 1 - i];
-    DCHECK(!receiver.is(arg));
-    DCHECK(!scratch_in.is(arg));
-    __ push(arg);
-  }
-  __ push(scratch_in);
-  // Stack now matches JSFunction abi.
-  DCHECK(optimization.is_simple_api_call());
-
-  // Abi for CallApiFunctionStub.
-  Register callee = eax;
-  Register call_data = ebx;
-  Register holder = ecx;
-  Register api_function_address = edx;
-  Register scratch = edi;  // scratch_in is no longer valid.
-
-  // Put holder in place.
-  CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
-  switch (holder_lookup) {
-    case CallOptimization::kHolderIsReceiver:
-      __ Move(holder, receiver);
-      break;
-    case CallOptimization::kHolderFound:
-      __ LoadHeapObject(holder, api_holder);
-      break;
-    case CallOptimization::kHolderNotFound:
-      UNREACHABLE();
-      break;
-  }
-
-  Isolate* isolate = masm->isolate();
-  Handle<JSFunction> function = optimization.constant_function();
-  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
-  Handle<Object> call_data_obj(api_call_info->data(), isolate);
-
-  // Put callee in place.
-  __ LoadHeapObject(callee, function);
-
-  bool call_data_undefined = false;
-  // Put call_data in place.
-  if (isolate->heap()->InNewSpace(*call_data_obj)) {
-    __ mov(scratch, api_call_info);
-    __ mov(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset));
-  } else if (call_data_obj->IsUndefined()) {
-    call_data_undefined = true;
-    __ mov(call_data, Immediate(isolate->factory()->undefined_value()));
-  } else {
-    __ mov(call_data, call_data_obj);
-  }
-
-  // Put api_function_address in place.
-  Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  __ mov(api_function_address, Immediate(function_address));
-
-  // Jump to stub.
-  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
-  __ TailCallStub(&stub);
-}
-
-
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-void PropertyHandlerCompiler::GenerateCheckPropertyCell(
-    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
-    Register scratch, Label* miss) {
-  Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
-  DCHECK(cell->value()->IsTheHole());
-  Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
-  if (masm->serializer_enabled()) {
-    __ mov(scratch, Immediate(cell));
-    __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset),
-           Immediate(the_hole));
-  } else {
-    __ cmp(Operand::ForCell(cell), Immediate(the_hole));
-  }
-  __ j(not_equal, miss);
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
 }
 
 
 #undef __
 #define __ ACCESS_MASM(masm())
 
-
-void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
-                                                    Handle<Name> name) {
-  if (!label->is_unused()) {
-    __ bind(label);
-    __ mov(this->name(), Immediate(name));
-  }
-}
-
-
-// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
-// store is successful.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register unused, Label* miss_label, Label* slow) {
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ CmpObject(value_reg, constant);
-    __ j(not_equal, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      Label do_store;
-      while (true) {
-        __ CompareMap(value_reg, it.Current());
-        it.Advance();
-        if (it.Done()) {
-          __ j(not_equal, miss_label);
-          break;
-        }
-        __ j(equal, &do_store, Label::kNear);
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiUntag(value_reg);
-    __ Cvtsi2sd(xmm0, value_reg);
-    __ SmiTag(value_reg);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
-                DONT_DO_SMI_CHECK);
-    __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ pop(scratch1);  // Return address.
-    __ push(receiver_reg);
-    __ push(Immediate(transition));
-    __ push(value_reg);
-    __ push(scratch1);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ mov(scratch1, Immediate(transition));
-  __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(eax));
-    __ ret(0);
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  // TODO(verwaest): Share this code as a code stub.
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ mov(FieldOperand(receiver_reg, offset), storage_reg);
-    } else {
-      __ mov(FieldOperand(receiver_reg, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array (optimistically).
-    __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ mov(FieldOperand(scratch1, offset), storage_reg);
-    } else {
-      __ mov(FieldOperand(scratch1, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register eax).
-  DCHECK(value_reg.is(eax));
-  __ ret(0);
-}
-
-
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  Label do_store;
-  while (true) {
-    __ CompareMap(value_reg, it.Current());
-    it.Advance();
-    if (it.Done()) {
-      __ j(not_equal, miss_label);
-      break;
-    }
-    __ j(equal, &do_store, Label::kNear);
-  }
-  __ bind(&do_store);
-
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
-}
-
-
-Register PropertyHandlerCompiler::CheckPrototypes(
-    Register object_reg, Register holder_reg, Register scratch1,
-    Register scratch2, Handle<Name> name, Label* miss,
-    PrototypeCheckType check) {
-  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
-
-  // Make sure there's no overlap between holder and object registers.
-  DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
-         !scratch2.is(scratch1));
-
-  // Keep track of the current object in register reg.
-  Register reg = object_reg;
-  int depth = 0;
-
-  Handle<JSObject> current = Handle<JSObject>::null();
-  if (type()->IsConstant())
-    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
-  Handle<JSObject> prototype = Handle<JSObject>::null();
-  Handle<Map> current_map = receiver_map;
-  Handle<Map> holder_map(holder()->map());
-  // Traverse the prototype chain and check the maps in the prototype chain for
-  // fast and global objects or do negative lookup for normal objects.
-  while (!current_map.is_identical_to(holder_map)) {
-    ++depth;
-
-    // Only global objects and objects that do not require access
-    // checks are allowed in stubs.
-    DCHECK(current_map->IsJSGlobalProxyMap() ||
-           !current_map->is_access_check_needed());
-
-    prototype = handle(JSObject::cast(current_map->prototype()));
-    if (current_map->is_dictionary_map() &&
-        !current_map->IsJSGlobalObjectMap()) {
-      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
-      if (!name->IsUniqueName()) {
-        DCHECK(name->IsString());
-        name = factory()->InternalizeString(Handle<String>::cast(name));
-      }
-      DCHECK(current.is_null() ||
-             current->property_dictionary()->FindEntry(name) ==
-                 NameDictionary::kNotFound);
-
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
-                                       scratch2);
-
-      __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-      __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-    } else {
-      bool in_new_space = heap()->InNewSpace(*prototype);
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map = in_new_space || depth == 1;
-      if (depth != 1 || check == CHECK_ALL_MAPS) {
-        __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
-      }
-
-      // Check access rights to the global object.  This has to happen after
-      // the map check so that we know that the object is actually a global
-      // object.
-      // This allows us to install generated handlers for accesses to the
-      // global proxy (as opposed to using slow ICs). See corresponding code
-      // in LookupForRead().
-      if (current_map->IsJSGlobalProxyMap()) {
-        __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
-      } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
-                                  name, scratch2, miss);
-      }
-
-      if (load_prototype_from_map) {
-        // Save the map in scratch1 for later.
-        __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      }
-
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-
-      if (load_prototype_from_map) {
-        __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-      } else {
-        __ mov(reg, prototype);
-      }
-    }
-
-    // Go to the next object in the prototype chain.
-    current = prototype;
-    current_map = handle(current->map());
-  }
-
-  // Log the check depth.
-  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
-
-  if (depth != 0 || check == CHECK_ALL_MAPS) {
-    // Check the holder map.
-    __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
-  }
-
-  // Perform security check for access to the global object.
-  DCHECK(current_map->IsJSGlobalProxyMap() ||
-         !current_map->is_access_check_needed());
-  if (current_map->IsJSGlobalProxyMap()) {
-    __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
-  }
-
-  // Return the register containing the holder.
-  return reg;
-}
-
-
-void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ jmp(&success);
-    __ bind(miss);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-    __ bind(&success);
-  }
-}
-
-
-void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ jmp(&success);
-    GenerateRestoreName(miss, name);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-    __ bind(&success);
-  }
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadCallback(
-    Register reg, Handle<ExecutableAccessorInfo> callback) {
-  // Insert additional parameters into the stack frame above return address.
-  DCHECK(!scratch3().is(reg));
-  __ pop(scratch3());  // Get return address to place it below.
-
-  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
-  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
-  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
-  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
-  __ push(receiver());  // receiver
-  // Push data from ExecutableAccessorInfo.
-  if (isolate()->heap()->InNewSpace(callback->data())) {
-    DCHECK(!scratch2().is(reg));
-    __ mov(scratch2(), Immediate(callback));
-    __ push(FieldOperand(scratch2(), ExecutableAccessorInfo::kDataOffset));
-  } else {
-    __ push(Immediate(Handle<Object>(callback->data(), isolate())));
-  }
-  __ push(Immediate(isolate()->factory()->undefined_value()));  // ReturnValue
-  // ReturnValue default value
-  __ push(Immediate(isolate()->factory()->undefined_value()));
-  __ push(Immediate(reinterpret_cast<int>(isolate())));
-  __ push(reg);  // holder
-
-  // Save a pointer to where we pushed the arguments. This will be
-  // passed as the const PropertyAccessorInfo& to the C++ callback.
-  __ push(esp);
-
-  __ push(name());  // name
-
-  __ push(scratch3());  // Restore return address.
-
-  // Abi for CallApiGetter
-  Register getter_address = edx;
-  Address function_address = v8::ToCData<Address>(callback->getter());
-  __ mov(getter_address, Immediate(function_address));
-
-  CallApiGetterStub stub(isolate());
-  __ TailCallStub(&stub);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
-  // Return the constant value.
-  __ LoadObject(eax, value);
-  __ ret(0);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
-    LookupIterator* it, Register holder_reg) {
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-
-  // Compile the interceptor call, followed by inline code to load the
-  // property from further up the prototype chain if the call fails.
-  // Check that the maps haven't changed.
-  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
-
-  // Preserve the receiver register explicitly whenever it is different from the
-  // holder and it is needed should the interceptor return without any result.
-  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
-  // case might cause a miss during the prototype check.
-  bool must_perform_prototype_check =
-      !holder().is_identical_to(it->GetHolder<JSObject>());
-  bool must_preserve_receiver_reg =
-      !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
-
-  // Save necessary data before invoking an interceptor.
-  // Requires a frame to make GC aware of pushed pointers.
-  {
-    FrameScope frame_scope(masm(), StackFrame::INTERNAL);
-
-    if (must_preserve_receiver_reg) {
-      __ push(receiver());
-    }
-    __ push(holder_reg);
-    __ push(this->name());
-
-    // Invoke an interceptor.  Note: map checks from receiver to
-    // interceptor's holder has been compiled before (see a caller
-    // of this method.)
-    CompileCallLoadPropertyWithInterceptor(
-        masm(), receiver(), holder_reg, this->name(), holder(),
-        IC::kLoadPropertyWithInterceptorOnly);
-
-    // Check if interceptor provided a value for property.  If it's
-    // the case, return immediately.
-    Label interceptor_failed;
-    __ cmp(eax, factory()->no_interceptor_result_sentinel());
-    __ j(equal, &interceptor_failed);
-    frame_scope.GenerateLeaveFrame();
-    __ ret(0);
-
-    // Clobber registers when generating debug-code to provoke errors.
-    __ bind(&interceptor_failed);
-    if (FLAG_debug_code) {
-      __ mov(receiver(), Immediate(BitCast<int32_t>(kZapValue)));
-      __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue)));
-      __ mov(this->name(), Immediate(BitCast<int32_t>(kZapValue)));
-    }
-
-    __ pop(this->name());
-    __ pop(holder_reg);
-    if (must_preserve_receiver_reg) {
-      __ pop(receiver());
-    }
-
-    // Leave the internal frame.
-  }
-
-  GenerateLoadPostInterceptor(it, holder_reg);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-  // Call the runtime system to load the interceptor.
-  __ pop(scratch2());  // save old return address
-  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
-                           holder());
-  __ push(scratch2());  // restore old return address
-
-  ExternalReference ref = ExternalReference(
-      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(
-      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
-}
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
-    Handle<JSObject> object, Handle<Name> name,
-    Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
-
-  __ pop(scratch1());  // remove the return address
-  __ push(receiver());
-  __ push(holder_reg);
-  __ Push(callback);
-  __ Push(name);
-  __ push(value());
-  __ push(scratch1());  // restore return address
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_callback_property =
-      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
-  __ TailCallExternalReference(store_callback_property, 5, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- esp[0] : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Save value register, so we can restore it later.
-    __ push(value());
-
-    if (!setter.is_null()) {
-      // Call the JavaScript setter with receiver and value on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ mov(receiver,
-               FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ push(receiver);
-      __ push(value());
-      ParameterCount actual(1);
-      ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // We have to return the passed value, not the return value of the setter.
-    __ pop(eax);
-
-    // Restore context register.
-    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-  }
-  __ ret(0);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
-    Handle<Name> name) {
-  __ pop(scratch1());  // remove the return address
-  __ push(receiver());
-  __ push(this->name());
-  __ push(value());
-  __ push(scratch1());  // restore return address
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_ic_property = ExternalReference(
-      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(store_ic_property, 3, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
-    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
-    MapHandleList* transitioned_maps) {
-  Label miss;
-  __ JumpIfSmi(receiver(), &miss, Label::kNear);
-  __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
-  for (int i = 0; i < receiver_maps->length(); ++i) {
-    __ cmp(scratch1(), receiver_maps->at(i));
-    if (transitioned_maps->at(i).is_null()) {
-      __ j(equal, handler_stubs->at(i));
-    } else {
-      Label next_map;
-      __ j(not_equal, &next_map, Label::kNear);
-      __ mov(transition_map(), Immediate(transitioned_maps->at(i)));
-      __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
-      __ bind(&next_map);
-    }
-  }
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
-}
-
-
-Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    if (!getter.is_null()) {
-      // Call the JavaScript getter with the receiver on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ mov(receiver,
-               FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ push(receiver);
-      ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // Restore context register.
-    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-  }
-  __ ret(0);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
-  Label miss;
-
-  FrontendHeader(receiver(), name, &miss);
-  // Get the value from the cell.
-  Register result = StoreIC::ValueRegister();
-  if (masm()->serializer_enabled()) {
-    __ mov(result, Immediate(cell));
-    __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
-  } else {
-    __ mov(result, Operand::ForCell(cell));
-  }
-
-  // Check for deleted property if property can actually be deleted.
-  if (is_configurable) {
-    __ cmp(result, factory()->the_hole_value());
-    __ j(equal, &miss);
-  } else if (FLAG_debug_code) {
-    __ cmp(result, factory()->the_hole_value());
-    __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
-  }
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->named_load_global_stub(), 1);
-  // The code above already loads the result into the return register.
-  __ ret(0);
-
-  FrontendFooter(name, &miss);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, name);
-}
-
-
 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
                                                     CodeHandleList* handlers,
                                                     Handle<Name> name,
@@ -905,70 +89,29 @@
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void ElementHandlerCompiler::GenerateLoadDictionaryElement(
-    MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  DCHECK(edx.is(LoadIC::ReceiverRegister()));
-  DCHECK(ecx.is(LoadIC::NameRegister()));
-  Label slow, miss;
-
-  // This stub is meant to be tail-jumped to, the receiver must already
-  // have been verified by the caller to not be a smi.
-  __ JumpIfNotSmi(ecx, &miss);
-  __ mov(ebx, ecx);
-  __ SmiUntag(ebx);
-  __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
-
-  // Push receiver on the stack to free up a register for the dictionary
-  // probing.
-  __ push(edx);
-  __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax);
-  // Pop receiver before returning.
-  __ pop(edx);
-  __ ret(0);
-
-  __ bind(&slow);
-  __ pop(edx);
-
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
-
+Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
+    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
+    MapHandleList* transitioned_maps) {
+  Label miss;
+  __ JumpIfSmi(receiver(), &miss, Label::kNear);
+  __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
+  for (int i = 0; i < receiver_maps->length(); ++i) {
+    __ cmp(scratch1(), receiver_maps->at(i));
+    if (transitioned_maps->at(i).is_null()) {
+      __ j(equal, handler_stubs->at(i));
+    } else {
+      Label next_map;
+      __ j(not_equal, &next_map, Label::kNear);
+      __ mov(transition_map(), Immediate(transitioned_maps->at(i)));
+      __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
+      __ bind(&next_map);
+    }
+  }
   __ bind(&miss);
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
-}
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
-
-void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                                    StrictMode strict_mode) {
-  // Return address is on the stack.
-  DCHECK(!ebx.is(StoreIC::ReceiverRegister()) &&
-         !ebx.is(StoreIC::NameRegister()) && !ebx.is(StoreIC::ValueRegister()));
-  __ pop(ebx);
-  __ push(StoreIC::ReceiverRegister());
-  __ push(StoreIC::NameRegister());
-  __ push(StoreIC::ValueRegister());
-  __ push(Immediate(Smi::FromInt(strict_mode)));
-  __ push(ebx);  // return address
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
diff --git a/src/ic/ia32/ic-ia32.cc b/src/ic/ia32/ic-ia32.cc
index 4dd1a93..5f13078 100644
--- a/src/ic/ia32/ic-ia32.cc
+++ b/src/ic/ia32/ic-ia32.cc
@@ -1018,26 +1018,6 @@
 }
 
 
-void StoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Return address is on the stack.
-  StoreIC_PushArgs(masm);
-
-  // Do tail-call to runtime routine.
-  ExternalReference ref(IC_Utility(kStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
-void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Return address is on the stack.
-  StoreIC_PushArgs(masm);
-
-  // Do tail-call to runtime routine.
-  ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
 #undef __
 
 
diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc
index f555517..8b0b62a 100644
--- a/src/ic/ic-compiler.cc
+++ b/src/ic/ic-compiler.cc
@@ -4,7 +4,7 @@
 
 #include "src/v8.h"
 
-#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
 #include "src/ic/ic-inl.h"
 #include "src/ic/ic-compiler.h"
 
@@ -25,15 +25,24 @@
 }
 
 
-Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
-                                           Handle<Map> stub_holder,
-                                           Code::Kind kind,
-                                           CacheHolderFlag cache_holder,
-                                           Code::StubType type) {
-  Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
-  Object* probe = stub_holder->FindInCodeCache(*name, flags);
-  if (probe->IsCode()) return handle(Code::cast(probe));
-  return Handle<Code>::null();
+bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
+  for (int i = 0; i < types->length(); ++i) {
+    if (types->at(i)->Is(HeapType::Number())) return true;
+  }
+  return false;
+}
+
+
+Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
+                                                    Handle<Code> handler,
+                                                    Handle<Name> name,
+                                                    IcCheckType check) {
+  TypeHandleList types(1);
+  CodeHandleList handlers(1);
+  types.Add(type);
+  handlers.Add(handler);
+  Code::StubType stub_type = handler->type();
+  return CompilePolymorphic(&types, &handlers, name, stub_type, check);
 }
 
 
@@ -74,50 +83,6 @@
 }
 
 
-Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
-    Handle<Name> name, Handle<HeapType> type) {
-  Isolate* isolate = name->GetIsolate();
-  Handle<Map> receiver_map = IC::TypeToMap(*type, isolate);
-  if (receiver_map->prototype()->IsNull()) {
-    // TODO(jkummerow/verwaest): If there is no prototype and the property
-    // is nonexistent, introduce a builtin to handle this (fast properties
-    // -> return undefined, dictionary properties -> do negative lookup).
-    return Handle<Code>();
-  }
-  CacheHolderFlag flag;
-  Handle<Map> stub_holder_map =
-      IC::GetHandlerCacheHolder(*type, false, isolate, &flag);
-
-  // If no dictionary mode objects are present in the prototype chain, the load
-  // nonexistent IC stub can be shared for all names for a given map and we use
-  // the empty string for the map cache in that case. If there are dictionary
-  // mode objects involved, we need to do negative lookups in the stub and
-  // therefore the stub will be specific to the name.
-  Handle<Name> cache_name =
-      receiver_map->is_dictionary_map()
-          ? name
-          : Handle<Name>::cast(isolate->factory()->nonexistent_symbol());
-  Handle<Map> current_map = stub_holder_map;
-  Handle<JSObject> last(JSObject::cast(receiver_map->prototype()));
-  while (true) {
-    if (current_map->is_dictionary_map()) cache_name = name;
-    if (current_map->prototype()->IsNull()) break;
-    last = handle(JSObject::cast(current_map->prototype()));
-    current_map = handle(last->map());
-  }
-  // Compile the stub that is either shared for all names or
-  // name specific if there are global objects involved.
-  Handle<Code> handler = PropertyHandlerCompiler::Find(
-      cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST);
-  if (!handler.is_null()) return handler;
-
-  NamedLoadHandlerCompiler compiler(isolate, type, last, flag);
-  handler = compiler.CompileLoadNonexistent(cache_name);
-  Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
-  return handler;
-}
-
-
 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
     Handle<Map> receiver_map) {
   Isolate* isolate = receiver_map->GetIsolate();
@@ -400,330 +365,6 @@
 }
 
 
-#define __ ACCESS_MASM(masm())
-
-
-Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
-                                                  Handle<Name> name,
-                                                  Label* miss) {
-  PrototypeCheckType check_type = CHECK_ALL_MAPS;
-  int function_index = -1;
-  if (type()->Is(HeapType::String())) {
-    function_index = Context::STRING_FUNCTION_INDEX;
-  } else if (type()->Is(HeapType::Symbol())) {
-    function_index = Context::SYMBOL_FUNCTION_INDEX;
-  } else if (type()->Is(HeapType::Number())) {
-    function_index = Context::NUMBER_FUNCTION_INDEX;
-  } else if (type()->Is(HeapType::Boolean())) {
-    function_index = Context::BOOLEAN_FUNCTION_INDEX;
-  } else {
-    check_type = SKIP_RECEIVER;
-  }
-
-  if (check_type == CHECK_ALL_MAPS) {
-    GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
-                                              scratch1(), miss);
-    Object* function = isolate()->native_context()->get(function_index);
-    Object* prototype = JSFunction::cast(function)->instance_prototype();
-    set_type_for_object(handle(prototype, isolate()));
-    object_reg = scratch1();
-  }
-
-  // Check that the maps starting from the prototype haven't changed.
-  return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
-                         miss, check_type);
-}
-
-
-// Frontend for store uses the name register. It has to be restored before a
-// miss.
-Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
-                                                   Handle<Name> name,
-                                                   Label* miss) {
-  return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
-                         miss, SKIP_RECEIVER);
-}
-
-
-bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
-  for (int i = 0; i < types->length(); ++i) {
-    if (types->at(i)->Is(HeapType::Number())) return true;
-  }
-  return false;
-}
-
-
-Register PropertyHandlerCompiler::Frontend(Register object_reg,
-                                           Handle<Name> name) {
-  Label miss;
-  Register reg = FrontendHeader(object_reg, name, &miss);
-  FrontendFooter(name, &miss);
-  return reg;
-}
-
-
-void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
-                                                        Label* miss,
-                                                        Register scratch1,
-                                                        Register scratch2) {
-  Register holder_reg;
-  Handle<Map> last_map;
-  if (holder().is_null()) {
-    holder_reg = receiver();
-    last_map = IC::TypeToMap(*type(), isolate());
-    // If |type| has null as its prototype, |holder()| is
-    // Handle<JSObject>::null().
-    DCHECK(last_map->prototype() == isolate()->heap()->null_value());
-  } else {
-    holder_reg = FrontendHeader(receiver(), name, miss);
-    last_map = handle(holder()->map());
-  }
-
-  if (last_map->is_dictionary_map()) {
-    if (last_map->IsJSGlobalObjectMap()) {
-      Handle<JSGlobalObject> global =
-          holder().is_null()
-              ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value())
-              : Handle<JSGlobalObject>::cast(holder());
-      GenerateCheckPropertyCell(masm(), global, name, scratch1, miss);
-    } else {
-      if (!name->IsUniqueName()) {
-        DCHECK(name->IsString());
-        name = factory()->InternalizeString(Handle<String>::cast(name));
-      }
-      DCHECK(holder().is_null() ||
-             holder()->property_dictionary()->FindEntry(name) ==
-                 NameDictionary::kNotFound);
-      GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1,
-                                       scratch2);
-    }
-  }
-}
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name,
-                                                        FieldIndex field) {
-  Register reg = Frontend(receiver(), name);
-  __ Move(receiver(), reg);
-  LoadFieldStub stub(isolate(), field);
-  GenerateTailCall(masm(), stub.GetCode());
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name,
-                                                           int constant_index) {
-  Register reg = Frontend(receiver(), name);
-  __ Move(receiver(), reg);
-  LoadConstantStub stub(isolate(), constant_index);
-  GenerateTailCall(masm(), stub.GetCode());
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
-    Handle<Name> name) {
-  Label miss;
-  NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
-  GenerateLoadConstant(isolate()->factory()->undefined_value());
-  FrontendFooter(name, &miss);
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
-    Handle<Name> name, Handle<ExecutableAccessorInfo> callback) {
-  Register reg = Frontend(receiver(), name);
-  GenerateLoadCallback(reg, callback);
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
-    Handle<Name> name, const CallOptimization& call_optimization) {
-  DCHECK(call_optimization.is_simple_api_call());
-  Frontend(receiver(), name);
-  Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
-  GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
-                      scratch1(), false, 0, NULL);
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
-    LookupIterator* it) {
-  // So far the most popular follow ups for interceptor loads are FIELD and
-  // ExecutableAccessorInfo, so inline only them. Other cases may be added
-  // later.
-  bool inline_followup = it->state() == LookupIterator::PROPERTY;
-  if (inline_followup) {
-    switch (it->property_kind()) {
-      case LookupIterator::DATA:
-        inline_followup = it->property_details().type() == FIELD;
-        break;
-      case LookupIterator::ACCESSOR: {
-        Handle<Object> accessors = it->GetAccessors();
-        inline_followup = accessors->IsExecutableAccessorInfo();
-        if (!inline_followup) break;
-        Handle<ExecutableAccessorInfo> info =
-            Handle<ExecutableAccessorInfo>::cast(accessors);
-        inline_followup = info->getter() != NULL &&
-                          ExecutableAccessorInfo::IsCompatibleReceiverType(
-                              isolate(), info, type());
-      }
-    }
-  }
-
-  Register reg = Frontend(receiver(), it->name());
-  if (inline_followup) {
-    // TODO(368): Compile in the whole chain: all the interceptors in
-    // prototypes and ultimate answer.
-    GenerateLoadInterceptorWithFollowup(it, reg);
-  } else {
-    GenerateLoadInterceptor(reg);
-  }
-  return GetCode(kind(), Code::FAST, it->name());
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
-    LookupIterator* it, Register interceptor_reg) {
-  Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
-
-  set_type_for_object(holder());
-  set_holder(real_named_property_holder);
-  Register reg = Frontend(interceptor_reg, it->name());
-
-  switch (it->property_kind()) {
-    case LookupIterator::DATA: {
-      DCHECK_EQ(FIELD, it->property_details().type());
-      __ Move(receiver(), reg);
-      LoadFieldStub stub(isolate(), it->GetFieldIndex());
-      GenerateTailCall(masm(), stub.GetCode());
-      break;
-    }
-    case LookupIterator::ACCESSOR:
-      Handle<ExecutableAccessorInfo> info =
-          Handle<ExecutableAccessorInfo>::cast(it->GetAccessors());
-      DCHECK_NE(NULL, info->getter());
-      GenerateLoadCallback(reg, info);
-  }
-}
-
-
-Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
-                                                    Handle<Code> handler,
-                                                    Handle<Name> name,
-                                                    IcCheckType check) {
-  TypeHandleList types(1);
-  CodeHandleList handlers(1);
-  types.Add(type);
-  handlers.Add(handler);
-  Code::StubType stub_type = handler->type();
-  return CompilePolymorphic(&types, &handlers, name, stub_type, check);
-}
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
-    Handle<Name> name, Handle<JSFunction> getter) {
-  Frontend(receiver(), name);
-  GenerateLoadViaGetter(masm(), type(), receiver(), getter);
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-// TODO(verwaest): Cleanup. holder() is actually the receiver.
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
-    Handle<Map> transition, Handle<Name> name) {
-  Label miss, slow;
-
-  // Ensure no transitions to deprecated maps are followed.
-  __ CheckMapDeprecated(transition, scratch1(), &miss);
-
-  // Check that we are allowed to write this.
-  bool is_nonexistent = holder()->map() == transition->GetBackPointer();
-  if (is_nonexistent) {
-    // Find the top object.
-    Handle<JSObject> last;
-    PrototypeIterator iter(isolate(), holder());
-    while (!iter.IsAtEnd()) {
-      last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-      iter.Advance();
-    }
-    if (!last.is_null()) set_holder(last);
-    NonexistentFrontendHeader(name, &miss, scratch1(), scratch2());
-  } else {
-    FrontendHeader(receiver(), name, &miss);
-    DCHECK(holder()->HasFastProperties());
-  }
-
-  GenerateStoreTransition(transition, name, receiver(), this->name(), value(),
-                          scratch1(), scratch2(), scratch3(), &miss, &slow);
-
-  GenerateRestoreName(&miss, name);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  GenerateRestoreName(&slow, name);
-  TailCallBuiltin(masm(), SlowBuiltin(kind()));
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
-  Label miss;
-  GenerateStoreField(it, value(), &miss);
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-  return GetCode(kind(), Code::FAST, it->name());
-}
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
-    Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) {
-  Frontend(receiver(), name);
-  GenerateStoreViaSetter(masm(), type(), receiver(), setter);
-
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
-    Handle<JSObject> object, Handle<Name> name,
-    const CallOptimization& call_optimization) {
-  Frontend(receiver(), name);
-  Register values[] = {value()};
-  GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
-                      receiver(), scratch1(), true, 1, values);
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
-    Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
-  Handle<Code> stub;
-  if (receiver_map->has_fast_elements() ||
-      receiver_map->has_external_array_elements() ||
-      receiver_map->has_fixed_typed_array_elements()) {
-    stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
-                                store_mode).GetCode();
-  } else {
-    stub = StoreElementStub(isolate(), is_jsarray, elements_kind, store_mode)
-               .GetCode();
-  }
-
-  __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
-
-  TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
-
-  return GetCode(kind(), Code::NORMAL, factory()->empty_string());
-}
-
-
-#undef __
-
-
 Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type,
                                          Handle<Name> name,
                                          InlineCacheState state) {
@@ -736,48 +377,6 @@
 }
 
 
-Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
-                                              Code::StubType type,
-                                              Handle<Name> name) {
-  Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder());
-  Handle<Code> code = GetCodeWithFlags(flags, name);
-  PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name));
-  return code;
-}
-
-
-void ElementHandlerCompiler::CompileElementHandlers(
-    MapHandleList* receiver_maps, CodeHandleList* handlers) {
-  for (int i = 0; i < receiver_maps->length(); ++i) {
-    Handle<Map> receiver_map = receiver_maps->at(i);
-    Handle<Code> cached_stub;
-
-    if ((receiver_map->instance_type() & kNotStringTag) == 0) {
-      cached_stub = isolate()->builtins()->KeyedLoadIC_String();
-    } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
-      cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
-    } else {
-      bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
-      ElementsKind elements_kind = receiver_map->elements_kind();
-
-      if (IsFastElementsKind(elements_kind) ||
-          IsExternalArrayElementsKind(elements_kind) ||
-          IsFixedTypedArrayElementsKind(elements_kind)) {
-        cached_stub = LoadFastElementStub(isolate(), is_js_array, elements_kind)
-                          .GetCode();
-      } else if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
-        cached_stub = isolate()->builtins()->KeyedLoadIC_SloppyArguments();
-      } else {
-        DCHECK(elements_kind == DICTIONARY_ELEMENTS);
-        cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
-      }
-    }
-
-    handlers->Add(cached_stub);
-  }
-}
-
-
 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
     MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
   // Collect MONOMORPHIC stubs for all |receiver_maps|.
@@ -827,11 +426,32 @@
 }
 
 
-void ElementHandlerCompiler::GenerateStoreDictionaryElement(
-    MacroAssembler* masm) {
-  KeyedStoreIC::GenerateSlow(masm);
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
+    Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
+  ElementsKind elements_kind = receiver_map->elements_kind();
+  bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
+  Handle<Code> stub;
+  if (receiver_map->has_fast_elements() ||
+      receiver_map->has_external_array_elements() ||
+      receiver_map->has_fixed_typed_array_elements()) {
+    stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
+                                store_mode).GetCode();
+  } else {
+    stub = StoreElementStub(isolate(), is_jsarray, elements_kind, store_mode)
+               .GetCode();
+  }
+
+  __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
+
+  TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
+
+  return GetCode(kind(), Code::NORMAL, factory()->empty_string());
 }
 
 
+#undef __
 }
 }  // namespace v8::internal
diff --git a/src/ic/ic-compiler.h b/src/ic/ic-compiler.h
index 15e00d2..8ee0c38 100644
--- a/src/ic/ic-compiler.h
+++ b/src/ic/ic-compiler.h
@@ -5,19 +5,12 @@
 #ifndef V8_IC_IC_COMPILER_H_
 #define V8_IC_IC_COMPILER_H_
 
-#include "src/code-stubs.h"
 #include "src/ic/access-compiler.h"
-#include "src/macro-assembler.h"
-#include "src/objects.h"
 
 namespace v8 {
 namespace internal {
 
 
-class CallOptimization;
-
-
-enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
 enum IcCheckType { ELEMENT, PROPERTY };
 
 
@@ -127,263 +120,6 @@
 };
 
 
-class PropertyHandlerCompiler : public PropertyAccessCompiler {
- public:
-  static Handle<Code> Find(Handle<Name> name, Handle<Map> map, Code::Kind kind,
-                           CacheHolderFlag cache_holder, Code::StubType type);
-
- protected:
-  PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind,
-                          Handle<HeapType> type, Handle<JSObject> holder,
-                          CacheHolderFlag cache_holder)
-      : PropertyAccessCompiler(isolate, kind, cache_holder),
-        type_(type),
-        holder_(holder) {}
-
-  virtual ~PropertyHandlerCompiler() {}
-
-  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
-                                  Label* miss) {
-    UNREACHABLE();
-    return receiver();
-  }
-
-  virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
-
-  Register Frontend(Register object_reg, Handle<Name> name);
-  void NonexistentFrontendHeader(Handle<Name> name, Label* miss,
-                                 Register scratch1, Register scratch2);
-
-  // TODO(verwaest): Make non-static.
-  static void GenerateFastApiCall(MacroAssembler* masm,
-                                  const CallOptimization& optimization,
-                                  Handle<Map> receiver_map, Register receiver,
-                                  Register scratch, bool is_store, int argc,
-                                  Register* values);
-
-  // Helper function used to check that the dictionary doesn't contain
-  // the property. This function may return false negatives, so miss_label
-  // must always call a backup property check that is complete.
-  // This function is safe to call if the receiver has fast properties.
-  // Name must be unique and receiver must be a heap object.
-  static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
-                                               Label* miss_label,
-                                               Register receiver,
-                                               Handle<Name> name, Register r0,
-                                               Register r1);
-
-  // Generate code to check that a global property cell is empty. Create
-  // the property cell at compilation time if no cell exists for the
-  // property.
-  static void GenerateCheckPropertyCell(MacroAssembler* masm,
-                                        Handle<JSGlobalObject> global,
-                                        Handle<Name> name, Register scratch,
-                                        Label* miss);
-
-  // Generates code that verifies that the property holder has not changed
-  // (checking maps of objects in the prototype chain for fast and global
-  // objects or doing negative lookup for slow objects, ensures that the
-  // property cells for global objects are still empty) and checks that the map
-  // of the holder has not changed. If necessary the function also generates
-  // code for security check in case of global object holders. Helps to make
-  // sure that the current IC is still valid.
-  //
-  // The scratch and holder registers are always clobbered, but the object
-  // register is only clobbered if it the same as the holder register. The
-  // function returns a register containing the holder - either object_reg or
-  // holder_reg.
-  Register CheckPrototypes(Register object_reg, Register holder_reg,
-                           Register scratch1, Register scratch2,
-                           Handle<Name> name, Label* miss,
-                           PrototypeCheckType check = CHECK_ALL_MAPS);
-
-  Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
-  void set_type_for_object(Handle<Object> object) {
-    type_ = IC::CurrentTypeOf(object, isolate());
-  }
-  void set_holder(Handle<JSObject> holder) { holder_ = holder; }
-  Handle<HeapType> type() const { return type_; }
-  Handle<JSObject> holder() const { return holder_; }
-
- private:
-  Handle<HeapType> type_;
-  Handle<JSObject> holder_;
-};
-
-
-class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
- public:
-  NamedLoadHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
-                           Handle<JSObject> holder,
-                           CacheHolderFlag cache_holder)
-      : PropertyHandlerCompiler(isolate, Code::LOAD_IC, type, holder,
-                                cache_holder) {}
-
-  virtual ~NamedLoadHandlerCompiler() {}
-
-  Handle<Code> CompileLoadField(Handle<Name> name, FieldIndex index);
-
-  Handle<Code> CompileLoadCallback(Handle<Name> name,
-                                   Handle<ExecutableAccessorInfo> callback);
-
-  Handle<Code> CompileLoadCallback(Handle<Name> name,
-                                   const CallOptimization& call_optimization);
-
-  Handle<Code> CompileLoadConstant(Handle<Name> name, int constant_index);
-
-  // The LookupIterator is used to perform a lookup behind the interceptor. If
-  // the iterator points to a LookupIterator::PROPERTY, its access will be
-  // inlined.
-  Handle<Code> CompileLoadInterceptor(LookupIterator* it);
-
-  Handle<Code> CompileLoadViaGetter(Handle<Name> name,
-                                    Handle<JSFunction> getter);
-
-  Handle<Code> CompileLoadGlobal(Handle<PropertyCell> cell, Handle<Name> name,
-                                 bool is_configurable);
-
-  // Static interface
-  static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
-                                             Handle<HeapType> type);
-
-  static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
-                                    Register receiver,
-                                    Handle<JSFunction> getter);
-
-  static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
-    GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg,
-                          Handle<JSFunction>());
-  }
-
-  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
-                                            Register receiver,
-                                            Register scratch1,
-                                            Register scratch2,
-                                            Label* miss_label);
-
-  // These constants describe the structure of the interceptor arguments on the
-  // stack. The arguments are pushed by the (platform-specific)
-  // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and
-  // LoadWithInterceptor.
-  static const int kInterceptorArgsNameIndex = 0;
-  static const int kInterceptorArgsInfoIndex = 1;
-  static const int kInterceptorArgsThisIndex = 2;
-  static const int kInterceptorArgsHolderIndex = 3;
-  static const int kInterceptorArgsLength = 4;
-
- protected:
-  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
-                                  Label* miss);
-
-  virtual void FrontendFooter(Handle<Name> name, Label* miss);
-
- private:
-  Handle<Code> CompileLoadNonexistent(Handle<Name> name);
-  void GenerateLoadConstant(Handle<Object> value);
-  void GenerateLoadCallback(Register reg,
-                            Handle<ExecutableAccessorInfo> callback);
-  void GenerateLoadCallback(const CallOptimization& call_optimization,
-                            Handle<Map> receiver_map);
-  void GenerateLoadInterceptor(Register holder_reg);
-  void GenerateLoadInterceptorWithFollowup(LookupIterator* it,
-                                           Register holder_reg);
-  void GenerateLoadPostInterceptor(LookupIterator* it, Register reg);
-
-  // Generates prototype loading code that uses the objects from the
-  // context we were in when this function was called. If the context
-  // has changed, a jump to miss is performed. This ties the generated
-  // code to a particular context and so must not be used in cases
-  // where the generated code is not allowed to have references to
-  // objects from a context.
-  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
-                                                        int index,
-                                                        Register prototype,
-                                                        Label* miss);
-
-
-  Register scratch4() { return registers_[5]; }
-};
-
-
-class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
- public:
-  explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
-                                     Handle<JSObject> holder)
-      : PropertyHandlerCompiler(isolate, Code::STORE_IC, type, holder,
-                                kCacheOnReceiver) {}
-
-  virtual ~NamedStoreHandlerCompiler() {}
-
-  Handle<Code> CompileStoreTransition(Handle<Map> transition,
-                                      Handle<Name> name);
-  Handle<Code> CompileStoreField(LookupIterator* it);
-  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
-                                    Handle<ExecutableAccessorInfo> callback);
-  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
-                                    const CallOptimization& call_optimization);
-  Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, Handle<Name> name,
-                                     Handle<JSFunction> setter);
-  Handle<Code> CompileStoreInterceptor(Handle<Name> name);
-
-  static void GenerateStoreViaSetter(MacroAssembler* masm,
-                                     Handle<HeapType> type, Register receiver,
-                                     Handle<JSFunction> setter);
-
-  static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
-    GenerateStoreViaSetter(masm, Handle<HeapType>::null(), no_reg,
-                           Handle<JSFunction>());
-  }
-
- protected:
-  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
-                                  Label* miss);
-
-  virtual void FrontendFooter(Handle<Name> name, Label* miss);
-  void GenerateRestoreName(Label* label, Handle<Name> name);
-
- private:
-  void GenerateStoreTransition(Handle<Map> transition, Handle<Name> name,
-                               Register receiver_reg, Register name_reg,
-                               Register value_reg, Register scratch1,
-                               Register scratch2, Register scratch3,
-                               Label* miss_label, Label* slow);
-
-  void GenerateStoreField(LookupIterator* lookup, Register value_reg,
-                          Label* miss_label);
-
-  static Builtins::Name SlowBuiltin(Code::Kind kind) {
-    switch (kind) {
-      case Code::STORE_IC:
-        return Builtins::kStoreIC_Slow;
-      case Code::KEYED_STORE_IC:
-        return Builtins::kKeyedStoreIC_Slow;
-      default:
-        UNREACHABLE();
-    }
-    return Builtins::kStoreIC_Slow;
-  }
-
-  static Register value();
-};
-
-
-class ElementHandlerCompiler : public PropertyHandlerCompiler {
- public:
-  explicit ElementHandlerCompiler(Isolate* isolate)
-      : PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC,
-                                Handle<HeapType>::null(),
-                                Handle<JSObject>::null(), kCacheOnReceiver) {}
-
-  virtual ~ElementHandlerCompiler() {}
-
-  void CompileElementHandlers(MapHandleList* receiver_maps,
-                              CodeHandleList* handlers);
-
-  static void GenerateLoadDictionaryElement(MacroAssembler* masm);
-  static void GenerateStoreDictionaryElement(MacroAssembler* masm);
-};
-
-
 }
 }  // namespace v8::internal
 
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 4c297ee..46bd435 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -11,6 +11,7 @@
 #include "src/conversions.h"
 #include "src/execution.h"
 #include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
 #include "src/ic/ic-inl.h"
 #include "src/ic/ic-compiler.h"
 #include "src/ic/stub-cache.h"
@@ -281,7 +282,7 @@
 
   if (receiver->IsGlobalObject()) {
     Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
-    LookupIterator it(global, name, LookupIterator::CHECK_PROPERTY);
+    LookupIterator it(global, name, LookupIterator::OWN_PROPERTY);
     if (!it.IsFound() || !it.HasProperty()) return false;
     Handle<PropertyCell> cell = it.GetPropertyCell();
     return cell->type()->IsConstant();
@@ -970,7 +971,7 @@
                                       cache_holder);
     // Perform a lookup behind the interceptor. Copy the LookupIterator since
     // the original iterator will be used to fetch the value.
-    LookupIterator it(lookup);
+    LookupIterator it = *lookup;
     it.Next();
     LookupForRead(&it);
     return compiler.CompileLoadInterceptor(&it);
diff --git a/src/ic/mips/OWNERS b/src/ic/mips/OWNERS
new file mode 100644
index 0000000..5508ba6
--- /dev/null
+++ b/src/ic/mips/OWNERS
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/src/ic/mips/access-compiler-mips.cc b/src/ic/mips/access-compiler-mips.cc
new file mode 100644
index 0000000..7abf748
--- /dev/null
+++ b/src/ic/mips/access-compiler-mips.cc
@@ -0,0 +1,46 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ Jump(code, RelocInfo::CODE_TARGET);
+}
+
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadIC::ReceiverRegister();
+  Register name = LoadIC::NameRegister();
+  static Register registers[] = {receiver, name, a3, a0, t0, t1};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3.
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  DCHECK(a3.is(KeyedStoreIC::MapRegister()));
+  static Register registers[] = {receiver, name, a3, t0, t1};
+  return registers;
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_MIPS
diff --git a/src/mips/stub-cache-mips.cc b/src/ic/mips/handler-compiler-mips.cc
similarity index 66%
rename from src/mips/stub-cache-mips.cc
rename to src/ic/mips/handler-compiler-mips.cc
index f8487d3..d533414 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/ic/mips/handler-compiler-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2014 the V8 project authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,9 +6,8 @@
 
 #if V8_TARGET_ARCH_MIPS
 
-#include "src/codegen.h"
-#include "src/ic-inl.h"
-#include "src/stub-cache.h"
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
 
 namespace v8 {
 namespace internal {
@@ -16,81 +15,79 @@
 #define __ ACCESS_MASM(masm)
 
 
-static void ProbeTable(Isolate* isolate,
-                       MacroAssembler* masm,
-                       Code::Flags flags,
-                       StubCache::Table table,
-                       Register receiver,
-                       Register name,
-                       // Number of the cache entry, not scaled.
-                       Register offset,
-                       Register scratch,
-                       Register scratch2,
-                       Register offset_scratch) {
-  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
-  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
-  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> getter) {
+  // ----------- S t a t e -------------
+  //  -- a0    : receiver
+  //  -- a2    : name
+  //  -- ra    : return address
+  // -----------------------------------
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
 
-  uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address());
-  uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address());
-  uint32_t map_off_addr = reinterpret_cast<uint32_t>(map_offset.address());
-
-  // Check the relative positions of the address fields.
-  DCHECK(value_off_addr > key_off_addr);
-  DCHECK((value_off_addr - key_off_addr) % 4 == 0);
-  DCHECK((value_off_addr - key_off_addr) < (256 * 4));
-  DCHECK(map_off_addr > key_off_addr);
-  DCHECK((map_off_addr - key_off_addr) % 4 == 0);
-  DCHECK((map_off_addr - key_off_addr) < (256 * 4));
-
-  Label miss;
-  Register base_addr = scratch;
-  scratch = no_reg;
-
-  // Multiply by 3 because there are 3 fields per entry (name, code, map).
-  __ sll(offset_scratch, offset, 1);
-  __ Addu(offset_scratch, offset_scratch, offset);
-
-  // Calculate the base address of the entry.
-  __ li(base_addr, Operand(key_offset));
-  __ sll(at, offset_scratch, kPointerSizeLog2);
-  __ Addu(base_addr, base_addr, at);
-
-  // Check that the key in the entry matches the name.
-  __ lw(at, MemOperand(base_addr, 0));
-  __ Branch(&miss, ne, name, Operand(at));
-
-  // Check the map matches.
-  __ lw(at, MemOperand(base_addr, map_off_addr - key_off_addr));
-  __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
-  __ Branch(&miss, ne, at, Operand(scratch2));
-
-  // Get the code entry from the cache.
-  Register code = scratch2;
-  scratch2 = no_reg;
-  __ lw(code, MemOperand(base_addr, value_off_addr - key_off_addr));
-
-  // Check that the flags match what we're looking for.
-  Register flags_reg = base_addr;
-  base_addr = no_reg;
-  __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset));
-  __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup));
-  __ Branch(&miss, ne, flags_reg, Operand(flags));
-
-#ifdef DEBUG
-    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
-      __ jmp(&miss);
-    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
-      __ jmp(&miss);
+    if (!getter.is_null()) {
+      // Call the JavaScript getter with the receiver on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ lw(receiver,
+              FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ push(receiver);
+      ParameterCount actual(0);
+      ParameterCount expected(getter);
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
     }
-#endif
 
-  // Jump to the first instruction in the code stub.
-  __ Addu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ Jump(at);
+    // Restore context register.
+    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
 
-  // Miss: fall through.
-  __ bind(&miss);
+
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> setter) {
+  // ----------- S t a t e -------------
+  //  -- ra    : return address
+  // -----------------------------------
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Save value register, so we can restore it later.
+    __ push(value());
+
+    if (!setter.is_null()) {
+      // Call the JavaScript setter with receiver and value on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ lw(receiver,
+              FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver, value());
+      ParameterCount actual(1);
+      ParameterCount expected(setter);
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // We have to return the passed value, not the return value of the setter.
+    __ pop(v0);
+
+    // Restore context register.
+    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
 }
 
 
@@ -106,7 +103,7 @@
   Label done;
 
   const int kInterceptorOrAccessCheckNeededMask =
-      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
+  (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
 
   // Bail out if the receiver has a named interceptor or requires access checks.
   Register map = scratch1;
@@ -132,110 +129,13 @@
   __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
 
 
-  NameDictionaryLookupStub::GenerateNegativeLookup(masm,
-                                                   miss_label,
-                                                   &done,
-                                                   receiver,
-                                                   properties,
-                                                   name,
-                                                   scratch1);
+  NameDictionaryLookupStub::GenerateNegativeLookup(
+      masm, miss_label, &done, receiver, properties, name, scratch1);
   __ bind(&done);
   __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm,
-                              Code::Flags flags,
-                              Register receiver,
-                              Register name,
-                              Register scratch,
-                              Register extra,
-                              Register extra2,
-                              Register extra3) {
-  Isolate* isolate = masm->isolate();
-  Label miss;
-
-  // Make sure that code is valid. The multiplying code relies on the
-  // entry size being 12.
-  DCHECK(sizeof(Entry) == 12);
-
-  // Make sure the flags does not name a specific type.
-  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
-
-  // Make sure that there are no register conflicts.
-  DCHECK(!scratch.is(receiver));
-  DCHECK(!scratch.is(name));
-  DCHECK(!extra.is(receiver));
-  DCHECK(!extra.is(name));
-  DCHECK(!extra.is(scratch));
-  DCHECK(!extra2.is(receiver));
-  DCHECK(!extra2.is(name));
-  DCHECK(!extra2.is(scratch));
-  DCHECK(!extra2.is(extra));
-
-  // Check register validity.
-  DCHECK(!scratch.is(no_reg));
-  DCHECK(!extra.is(no_reg));
-  DCHECK(!extra2.is(no_reg));
-  DCHECK(!extra3.is(no_reg));
-
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1,
-                      extra2, extra3);
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, &miss);
-
-  // Get the map of the receiver and compute the hash.
-  __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
-  __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset));
-  __ Addu(scratch, scratch, at);
-  uint32_t mask = kPrimaryTableSize - 1;
-  // We shift out the last two bits because they are not part of the hash and
-  // they are always 01 for maps.
-  __ srl(scratch, scratch, kCacheIndexShift);
-  __ Xor(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask));
-  __ And(scratch, scratch, Operand(mask));
-
-  // Probe the primary table.
-  ProbeTable(isolate,
-             masm,
-             flags,
-             kPrimary,
-             receiver,
-             name,
-             scratch,
-             extra,
-             extra2,
-             extra3);
-
-  // Primary miss: Compute hash for secondary probe.
-  __ srl(at, name, kCacheIndexShift);
-  __ Subu(scratch, scratch, at);
-  uint32_t mask2 = kSecondaryTableSize - 1;
-  __ Addu(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask2));
-  __ And(scratch, scratch, Operand(mask2));
-
-  // Probe the secondary table.
-  ProbeTable(isolate,
-             masm,
-             flags,
-             kSecondary,
-             receiver,
-             name,
-             scratch,
-             extra,
-             extra2,
-             extra3);
-
-  // Cache miss: Fall-through and let caller handle the miss by
-  // entering the runtime system.
-  __ bind(&miss);
-  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1,
-                      extra2, extra3);
-}
-
-
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
     MacroAssembler* masm, int index, Register prototype, Label* miss) {
   Isolate* isolate = masm->isolate();
@@ -268,6 +168,9 @@
 }
 
 
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
     MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
     Register scratch, Label* miss) {
@@ -280,10 +183,8 @@
 }
 
 
-static void PushInterceptorArguments(MacroAssembler* masm,
-                                     Register receiver,
-                                     Register holder,
-                                     Register name,
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
                                      Handle<JSObject> holder_obj) {
   STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
   STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
@@ -300,12 +201,8 @@
 
 
 static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm,
-    Register receiver,
-    Register holder,
-    Register name,
-    Handle<JSObject> holder_obj,
-    IC::UtilityId id) {
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
   __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
                            NamedLoadHandlerCompiler::kInterceptorArgsLength);
@@ -323,10 +220,10 @@
   __ sw(receiver, MemOperand(sp, argc * kPointerSize));  // Push receiver.
   // Write the arguments to stack frame.
   for (int i = 0; i < argc; i++) {
-    Register arg = values[argc-1-i];
+    Register arg = values[argc - 1 - i];
     DCHECK(!receiver.is(arg));
     DCHECK(!scratch_in.is(arg));
-    __ sw(arg, MemOperand(sp, (argc-1-i) * kPointerSize));  // Push arg.
+    __ sw(arg, MemOperand(sp, (argc - 1 - i) * kPointerSize));  // Push arg.
   }
   DCHECK(optimization.is_simple_api_call());
 
@@ -338,16 +235,15 @@
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
-      receiver_map,
-      &holder_lookup);
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
       __ li(holder, api_holder);
-     break;
+      break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
       break;
@@ -385,9 +281,58 @@
 }
 
 
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ Jump(code, RelocInfo::CODE_TARGET);
+void ElementHandlerCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // The return address is in ra.
+  Label slow, miss;
+
+  Register key = LoadIC::NameRegister();
+  Register receiver = LoadIC::ReceiverRegister();
+  DCHECK(receiver.is(a1));
+  DCHECK(key.is(a2));
+
+  __ UntagAndJumpIfNotSmi(t2, key, &miss);
+  __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ LoadFromNumberDictionary(&slow, t0, key, v0, t2, a3, t1);
+  __ Ret();
+
+  // Slow case, key and receiver still unmodified.
+  __ bind(&slow);
+  __ IncrementCounter(
+      masm->isolate()->counters()->keyed_load_external_array_slow(), 1, a2, a3);
+
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
+
+  // Miss case, call the runtime.
+  __ bind(&miss);
+
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
 }
 
 
@@ -459,8 +404,8 @@
     __ jmp(&do_store);
 
     __ bind(&heap_number);
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
-                miss_label, DONT_DO_SMI_CHECK);
+    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
+                DONT_DO_SMI_CHECK);
     __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
 
     __ bind(&do_store);
@@ -479,9 +424,9 @@
     __ li(a2, Operand(transition));
     __ Push(a2, a0);
     __ TailCallExternalReference(
-           ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                             isolate()),
-           3, 1);
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
+                          isolate()),
+        3, 1);
     return;
   }
 
@@ -490,13 +435,8 @@
   __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
 
   // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg,
-                      HeapObject::kMapOffset,
-                      scratch1,
-                      scratch2,
-                      kRAHasNotBeenSaved,
-                      kDontSaveFPRegs,
-                      OMIT_REMEMBERED_SET,
+  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
+                      kRAHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
                       OMIT_SMI_CHECK);
 
   if (details.type() == CONSTANT) {
@@ -515,8 +455,8 @@
   index -= transition->inobject_properties();
 
   // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check = representation.IsTagged()
-      ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  SmiCheck smi_check =
+      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
   if (index < 0) {
     // Set the property straight into the object.
     int offset = transition->instance_size() + (index * kPointerSize);
@@ -531,21 +471,15 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(receiver_reg,
-                          offset,
-                          storage_reg,
-                          scratch1,
-                          kRAHasNotBeenSaved,
-                          kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
+                          kRAHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
     }
   } else {
     // Write to the properties array.
     int offset = index * kPointerSize + FixedArray::kHeaderSize;
     // Get the properties array
-    __ lw(scratch1,
-          FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
+    __ lw(scratch1, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
     if (representation.IsDouble()) {
       __ sw(storage_reg, FieldMemOperand(scratch1, offset));
     } else {
@@ -557,14 +491,9 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(scratch1,
-                          offset,
-                          storage_reg,
-                          receiver_reg,
-                          kRAHasNotBeenSaved,
-                          kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
+                          kRAHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
     }
   }
 
@@ -611,8 +540,8 @@
 
   // Make sure there's no overlap between holder and object registers.
   DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
-         && !scratch2.is(scratch1));
+  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
+         !scratch2.is(scratch1));
 
   // Keep track of the current object in register reg.
   Register reg = object_reg;
@@ -645,10 +574,10 @@
       }
       DCHECK(current.is_null() ||
              current->property_dictionary()->FindEntry(name) ==
-             NameDictionary::kNotFound);
+                 NameDictionary::kNotFound);
 
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
-                                       scratch1, scratch2);
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
 
       __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
       reg = holder_reg;  // From now on the object will be in holder_reg.
@@ -671,9 +600,8 @@
       if (current_map->IsJSGlobalProxyMap()) {
         __ CheckAccessGlobalProxy(reg, scratch2, miss);
       } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(
-            masm(), Handle<JSGlobalObject>::cast(current), name,
-            scratch2, miss);
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
       }
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
@@ -762,8 +690,8 @@
   __ push(receiver());
   if (heap()->InNewSpace(callback->data())) {
     __ li(scratch3(), callback);
-    __ lw(scratch3(), FieldMemOperand(scratch3(),
-                                      ExecutableAccessorInfo::kDataOffset));
+    __ lw(scratch3(),
+          FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
   } else {
     __ li(scratch3(), Handle<Object>(callback->data(), isolate()));
   }
@@ -772,8 +700,7 @@
   __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
   __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize));
   __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize));
-  __ li(scratch4(),
-        Operand(ExternalReference::isolate_address(isolate())));
+  __ li(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
   __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize));
   __ sw(reg, MemOperand(sp, 1 * kPointerSize));
   __ sw(name(), MemOperand(sp, 0 * kPointerSize));
@@ -872,7 +799,7 @@
   Register holder_reg = Frontend(receiver(), name);
 
   __ Push(receiver(), holder_reg);  // Receiver.
-  __ li(at, Operand(callback));  // Callback info.
+  __ li(at, Operand(callback));     // Callback info.
   __ push(at);
   __ li(at, Operand(name));
   __ Push(at, value());
@@ -887,54 +814,6 @@
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- ra    : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Save value register, so we can restore it later.
-    __ push(value());
-
-    if (!setter.is_null()) {
-      // Call the JavaScript setter with receiver and value on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ lw(receiver,
-               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ Push(receiver, value());
-      ParameterCount actual(1);
-      ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // We have to return the passed value, not the return value of the setter.
-    __ pop(v0);
-
-    // Restore context register.
-    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
     Handle<Name> name) {
   __ Push(receiver(), this->name(), value());
@@ -949,72 +828,9 @@
 }
 
 
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = { receiver, name, a3, a0, t0, t1 };
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3.
-  Register receiver = StoreIC::ReceiverRegister();
-  Register name = StoreIC::NameRegister();
-  DCHECK(a3.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = { receiver, name, a3, t0, t1 };
-  return registers;
-}
-
-
 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
-  // ----------- S t a t e -------------
-  //  -- a0    : receiver
-  //  -- a2    : name
-  //  -- ra    : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    if (!getter.is_null()) {
-      // Call the JavaScript getter with the receiver on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ lw(receiver,
-                FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ push(receiver);
-      ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // Restore context register.
-    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
@@ -1044,130 +860,8 @@
 }
 
 
-Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
-                                                    CodeHandleList* handlers,
-                                                    Handle<Name> name,
-                                                    Code::StubType type,
-                                                    IcCheckType check) {
-  Label miss;
-
-  if (check == PROPERTY &&
-      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
-    // check whether the name is unique.
-    if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
-      __ JumpIfNotUniqueName(this->name(), &miss);
-    } else {
-      __ Branch(&miss, ne, this->name(), Operand(name));
-    }
-  }
-
-  Label number_case;
-  Register match = scratch2();
-  Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
-  __ JumpIfSmi(receiver(), smi_target, match);  // Reg match is 0 if Smi.
-
-  // Polymorphic keyed stores may use the map register
-  Register map_reg = scratch1();
-  DCHECK(kind() != Code::KEYED_STORE_IC ||
-         map_reg.is(KeyedStoreIC::MapRegister()));
-
-  int receiver_count = types->length();
-  int number_of_handled_maps = 0;
-  __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
-  for (int current = 0; current < receiver_count; ++current) {
-    Handle<HeapType> type = types->at(current);
-    Handle<Map> map = IC::TypeToMap(*type, isolate());
-    if (!map->is_deprecated()) {
-      number_of_handled_maps++;
-      // Check map and tail call if there's a match.
-      // Separate compare from branch, to provide path for above JumpIfSmi().
-      __ Subu(match, map_reg, Operand(map));
-      if (type->Is(HeapType::Number())) {
-        DCHECK(!number_case.is_unused());
-        __ bind(&number_case);
-      }
-      __ Jump(handlers->at(current), RelocInfo::CODE_TARGET,
-          eq, match, Operand(zero_reg));
-    }
-  }
-  DCHECK(number_of_handled_maps != 0);
-
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  InlineCacheState state =
-      number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
-  return GetCode(kind(), type, name, state);
-}
-
-
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
-    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
-    MapHandleList* transitioned_maps) {
-  Label miss;
-  __ JumpIfSmi(receiver(), &miss);
-
-  int receiver_count = receiver_maps->length();
-  __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
-  for (int i = 0; i < receiver_count; ++i) {
-    if (transitioned_maps->at(i).is_null()) {
-      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq,
-          scratch1(), Operand(receiver_maps->at(i)));
-    } else {
-      Label next_map;
-      __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
-      __ li(transition_map(), Operand(transitioned_maps->at(i)));
-      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
-      __ bind(&next_map);
-    }
-  }
-
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
-}
-
-
 #undef __
-#define __ ACCESS_MASM(masm)
-
-
-void ElementHandlerCompiler::GenerateLoadDictionaryElement(
-    MacroAssembler* masm) {
-  // The return address is in ra.
-  Label slow, miss;
-
-  Register key = LoadIC::NameRegister();
-  Register receiver = LoadIC::ReceiverRegister();
-  DCHECK(receiver.is(a1));
-  DCHECK(key.is(a2));
-
-  __ UntagAndJumpIfNotSmi(t2, key, &miss);
-  __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
-  __ LoadFromNumberDictionary(&slow, t0, key, v0, t2, a3, t1);
-  __ Ret();
-
-  // Slow case, key and receiver still unmodified.
-  __ bind(&slow);
-  __ IncrementCounter(
-      masm->isolate()->counters()->keyed_load_external_array_slow(),
-      1, a2, a3);
-
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
-
-  // Miss case, call the runtime.
-  __ bind(&miss);
-
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
 }
-
-
-#undef __
-
-} }  // namespace v8::internal
+}  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_MIPS
diff --git a/src/ic/mips/ic-compiler-mips.cc b/src/ic/mips/ic-compiler-mips.cc
new file mode 100644
index 0000000..a563061
--- /dev/null
+++ b/src/ic/mips/ic-compiler-mips.cc
@@ -0,0 +1,126 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS
+
+#include "src/ic/ic-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
+                                                    CodeHandleList* handlers,
+                                                    Handle<Name> name,
+                                                    Code::StubType type,
+                                                    IcCheckType check) {
+  Label miss;
+
+  if (check == PROPERTY &&
+      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
+    // In case we are compiling an IC for dictionary loads and stores, just
+    // check whether the name is unique.
+    if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      __ JumpIfNotUniqueName(this->name(), &miss);
+    } else {
+      __ Branch(&miss, ne, this->name(), Operand(name));
+    }
+  }
+
+  Label number_case;
+  Register match = scratch2();
+  Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
+  __ JumpIfSmi(receiver(), smi_target, match);  // Reg match is 0 if Smi.
+
+  // Polymorphic keyed stores may use the map register
+  Register map_reg = scratch1();
+  DCHECK(kind() != Code::KEYED_STORE_IC ||
+         map_reg.is(KeyedStoreIC::MapRegister()));
+
+  int receiver_count = types->length();
+  int number_of_handled_maps = 0;
+  __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  for (int current = 0; current < receiver_count; ++current) {
+    Handle<HeapType> type = types->at(current);
+    Handle<Map> map = IC::TypeToMap(*type, isolate());
+    if (!map->is_deprecated()) {
+      number_of_handled_maps++;
+      // Check map and tail call if there's a match.
+      // Separate compare from branch, to provide path for above JumpIfSmi().
+      __ Subu(match, map_reg, Operand(map));
+      if (type->Is(HeapType::Number())) {
+        DCHECK(!number_case.is_unused());
+        __ bind(&number_case);
+      }
+      __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq, match,
+              Operand(zero_reg));
+    }
+  }
+  DCHECK(number_of_handled_maps != 0);
+
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  InlineCacheState state =
+      number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
+  return GetCode(kind(), type, name, state);
+}
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
+    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
+    MapHandleList* transitioned_maps) {
+  Label miss;
+  __ JumpIfSmi(receiver(), &miss);
+
+  int receiver_count = receiver_maps->length();
+  __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  for (int i = 0; i < receiver_count; ++i) {
+    if (transitioned_maps->at(i).is_null()) {
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, scratch1(),
+              Operand(receiver_maps->at(i)));
+    } else {
+      Label next_map;
+      __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
+      __ li(transition_map(), Operand(transitioned_maps->at(i)));
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
+      __ bind(&next_map);
+    }
+  }
+
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  __ li(a0, Operand(Smi::FromInt(strict_mode)));
+  __ Push(a0);
+
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_MIPS
diff --git a/src/mips/ic-mips.cc b/src/ic/mips/ic-mips.cc
similarity index 78%
rename from src/mips/ic-mips.cc
rename to src/ic/mips/ic-mips.cc
index 1f4a7be..5e72e89 100644
--- a/src/mips/ic-mips.cc
+++ b/src/ic/mips/ic-mips.cc
@@ -3,16 +3,14 @@
 // found in the LICENSE file.
 
 
-
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_MIPS
 
-#include "src/code-stubs.h"
 #include "src/codegen.h"
-#include "src/ic-inl.h"
-#include "src/runtime.h"
-#include "src/stub-cache.h"
+#include "src/ic/ic.h"
+#include "src/ic/ic-compiler.h"
+#include "src/ic/stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -25,8 +23,7 @@
 #define __ ACCESS_MASM(masm)
 
 
-static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm,
-                                            Register type,
+static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, Register type,
                                             Label* global_object) {
   // Register usage:
   //   type: holds the receiver instance type on entry.
@@ -51,12 +48,9 @@
 // is not a global object and does not have interceptors.
 // The address returned from GenerateStringDictionaryProbes() in scratch2
 // is used.
-static void GenerateDictionaryLoad(MacroAssembler* masm,
-                                   Label* miss,
-                                   Register elements,
-                                   Register name,
-                                   Register result,
-                                   Register scratch1,
+static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss,
+                                   Register elements, Register name,
+                                   Register result, Register scratch1,
                                    Register scratch2) {
   // Main use of the scratch registers.
   // scratch1: Used as temporary and to hold the capacity of the property
@@ -65,23 +59,18 @@
   Label done;
 
   // Probe the dictionary.
-  NameDictionaryLookupStub::GeneratePositiveLookup(masm,
-                                                   miss,
-                                                   &done,
-                                                   elements,
-                                                   name,
-                                                   scratch1,
-                                                   scratch2);
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
+                                                   name, scratch1, scratch2);
 
   // If probing finds an entry check that the value is a normal
   // property.
   __ bind(&done);  // scratch2 == elements + 4 * index.
-  const int kElementsStartOffset = NameDictionary::kHeaderSize +
+  const int kElementsStartOffset =
+      NameDictionary::kHeaderSize +
       NameDictionary::kElementsStartIndex * kPointerSize;
   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
   __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
-  __ And(at,
-         scratch1,
+  __ And(at, scratch1,
          Operand(PropertyDetails::TypeField::kMask << kSmiTagSize));
   __ Branch(miss, ne, at, Operand(zero_reg));
 
@@ -104,12 +93,9 @@
 // is not a global object and does not have interceptors.
 // The address returned from GenerateStringDictionaryProbes() in scratch2
 // is used.
-static void GenerateDictionaryStore(MacroAssembler* masm,
-                                    Label* miss,
-                                    Register elements,
-                                    Register name,
-                                    Register value,
-                                    Register scratch1,
+static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss,
+                                    Register elements, Register name,
+                                    Register value, Register scratch1,
                                     Register scratch2) {
   // Main use of the scratch registers.
   // scratch1: Used as temporary and to hold the capacity of the property
@@ -118,23 +104,20 @@
   Label done;
 
   // Probe the dictionary.
-  NameDictionaryLookupStub::GeneratePositiveLookup(masm,
-                                                   miss,
-                                                   &done,
-                                                   elements,
-                                                   name,
-                                                   scratch1,
-                                                   scratch2);
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
+                                                   name, scratch1, scratch2);
 
   // If probing finds an entry in the dictionary check that the value
   // is a normal property that is not read only.
   __ bind(&done);  // scratch2 == elements + 4 * index.
-  const int kElementsStartOffset = NameDictionary::kHeaderSize +
+  const int kElementsStartOffset =
+      NameDictionary::kHeaderSize +
       NameDictionary::kElementsStartIndex * kPointerSize;
   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
   const int kTypeAndReadOnlyMask =
       (PropertyDetails::TypeField::kMask |
-       PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
+       PropertyDetails::AttributesField::encode(READ_ONLY))
+      << kSmiTagSize;
   __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
   __ And(at, scratch1, Operand(kTypeAndReadOnlyMask));
   __ Branch(miss, ne, at, Operand(zero_reg));
@@ -146,19 +129,17 @@
 
   // Update the write barrier. Make sure not to clobber the value.
   __ mov(scratch1, value);
-  __ RecordWrite(
-      elements, scratch2, scratch1, kRAHasNotBeenSaved, kDontSaveFPRegs);
+  __ RecordWrite(elements, scratch2, scratch1, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs);
 }
 
 
 // Checks the receiver for special cases (value type, slow case bits).
 // Falls through for regular JS object.
 static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
-                                           Register receiver,
-                                           Register map,
+                                           Register receiver, Register map,
                                            Register scratch,
-                                           int interceptor_bit,
-                                           Label* slow) {
+                                           int interceptor_bit, Label* slow) {
   // Check that the object isn't a smi.
   __ JumpIfSmi(receiver, slow);
   // Get the map of the receiver.
@@ -180,14 +161,10 @@
 
 // Loads an indexed element from a fast case array.
 // If not_fast_array is NULL, doesn't perform the elements map check.
-static void GenerateFastArrayLoad(MacroAssembler* masm,
-                                  Register receiver,
-                                  Register key,
-                                  Register elements,
-                                  Register scratch1,
-                                  Register scratch2,
-                                  Register result,
-                                  Label* not_fast_array,
+static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
+                                  Register key, Register elements,
+                                  Register scratch1, Register scratch2,
+                                  Register result, Label* not_fast_array,
                                   Label* out_of_range) {
   // Register use:
   //
@@ -244,12 +221,9 @@
 
 // Checks whether a key is an array index string or a unique name.
 // Falls through if a key is a unique name.
-static void GenerateKeyNameCheck(MacroAssembler* masm,
-                                 Register key,
-                                 Register map,
-                                 Register hash,
-                                 Label* index_string,
-                                 Label* not_unique) {
+static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
+                                 Register map, Register hash,
+                                 Label* index_string, Label* not_unique) {
   // The key is not a smi.
   Label unique;
   // Is it a name?
@@ -285,8 +259,8 @@
   // Probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, receiver, name, a3, t0, t1, t2);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, a3,
+                                               t0, t1, t2);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -340,14 +314,10 @@
 }
 
 
-static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
-                                                Register object,
-                                                Register key,
-                                                Register scratch1,
-                                                Register scratch2,
-                                                Register scratch3,
-                                                Label* unmapped_case,
-                                                Label* slow_case) {
+static MemOperand GenerateMappedArgumentsLookup(
+    MacroAssembler* masm, Register object, Register key, Register scratch1,
+    Register scratch2, Register scratch3, Label* unmapped_case,
+    Label* slow_case) {
   Heap* heap = masm->isolate()->heap();
 
   // Check that the receiver is a JSObject. Because of the map check
@@ -365,11 +335,7 @@
   // Load the elements into scratch1 and check its map.
   Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
   __ lw(scratch1, FieldMemOperand(object, JSObject::kElementsOffset));
-  __ CheckMap(scratch1,
-              scratch2,
-              arguments_map,
-              slow_case,
-              DONT_DO_SMI_CHECK);
+  __ CheckMap(scratch1, scratch2, arguments_map, slow_case, DONT_DO_SMI_CHECK);
   // Check if element is in the range of mapped arguments. If not, jump
   // to the unmapped lookup with the parameter map in scratch1.
   __ lw(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset));
@@ -413,18 +379,13 @@
   const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize;
   Register backing_store = parameter_map;
   __ lw(backing_store, FieldMemOperand(parameter_map, kBackingStoreOffset));
-  __ CheckMap(backing_store,
-              scratch,
-              Heap::kFixedArrayMapRootIndex,
-              slow_case,
+  __ CheckMap(backing_store, scratch, Heap::kFixedArrayMapRootIndex, slow_case,
               DONT_DO_SMI_CHECK);
   __ lw(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
   __ Branch(slow_case, Ugreater_equal, key, Operand(scratch));
   __ li(scratch, Operand(kPointerSize >> 1));
   __ Mul(scratch, key, scratch);
-  __ Addu(scratch,
-          scratch,
-          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ Addu(scratch, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ Addu(scratch, backing_store, scratch);
   return MemOperand(scratch);
 }
@@ -438,9 +399,8 @@
   DCHECK(key.is(a2));
 
   Label slow, notin;
-  MemOperand mapped_location =
-      GenerateMappedArgumentsLookup(
-          masm, receiver, key, a0, a3, t0, &notin, &slow);
+  MemOperand mapped_location = GenerateMappedArgumentsLookup(
+      masm, receiver, key, a0, a3, t0, &notin, &slow);
   __ Ret(USE_DELAY_SLOT);
   __ lw(v0, mapped_location);
   __ bind(&notin);
@@ -470,8 +430,8 @@
   __ sw(value, mapped_location);
   __ mov(t5, value);
   DCHECK_EQ(mapped_location.offset(), 0);
-  __ RecordWrite(a3, mapped_location.rm(), t5,
-                 kRAHasNotBeenSaved, kDontSaveFPRegs);
+  __ RecordWrite(a3, mapped_location.rm(), t5, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs);
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, value);  // (In delay slot) return the value stored in v0.
   __ bind(&notin);
@@ -482,8 +442,8 @@
   __ sw(value, unmapped_location);
   __ mov(t5, value);
   DCHECK_EQ(unmapped_location.offset(), 0);
-  __ RecordWrite(a3, unmapped_location.rm(), t5,
-                 kRAHasNotBeenSaved, kDontSaveFPRegs);
+  __ RecordWrite(a3, unmapped_location.rm(), t5, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs);
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, a0);  // (In delay slot) return the value stored in v0.
   __ bind(&slow);
@@ -529,9 +489,7 @@
 const Register StoreIC::ValueRegister() { return a0; }
 
 
-const Register KeyedStoreIC::MapRegister() {
-  return a3;
-}
+const Register KeyedStoreIC::MapRegister() { return a3; }
 
 
 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
@@ -561,14 +519,13 @@
   // Now the key is known to be a smi. This place is also jumped to from below
   // where a numeric string is converted to a smi.
 
-  GenerateKeyedLoadReceiverCheck(
-      masm, receiver, a0, a3, Map::kHasIndexedInterceptor, &slow);
+  GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3,
+                                 Map::kHasIndexedInterceptor, &slow);
 
   // Check the receiver's map to see if it has fast elements.
   __ CheckFastElements(a0, a3, &check_number_dictionary);
 
-  GenerateFastArrayLoad(
-      masm, receiver, key, a0, a3, t0, v0, NULL, &slow);
+  GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, NULL, &slow);
   __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, t0, a3);
   __ Ret();
 
@@ -587,17 +544,15 @@
 
   // Slow case, key and receiver still in a2 and a1.
   __ bind(&slow);
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
-                      1,
-                      t0,
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, t0,
                       a3);
   GenerateRuntimeGetProperty(masm);
 
   __ bind(&check_name);
   GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);
 
-  GenerateKeyedLoadReceiverCheck(
-       masm, receiver, a0, a3, Map::kHasNamedInterceptor, &slow);
+  GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3,
+                                 Map::kHasNamedInterceptor, &slow);
 
 
   // If the receiver is a fast-case object, check the keyed lookup
@@ -671,10 +626,8 @@
   __ sll(at, t2, kPointerSizeLog2);
   __ addu(at, receiver, at);
   __ lw(v0, MemOperand(at));
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
-                      1,
-                      t0,
-                      a3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
+                      t0, a3);
   __ Ret();
 
   // Load property array property.
@@ -684,10 +637,8 @@
   __ sll(v0, t1, kPointerSizeLog2);
   __ Addu(v0, v0, receiver);
   __ lw(v0, MemOperand(v0));
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
-                      1,
-                      t0,
-                      a3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
+                      t0, a3);
   __ Ret();
 
 
@@ -700,9 +651,7 @@
   GenerateGlobalInstanceTypeCheck(masm, a0, &slow);
   // Load the property to v0.
   GenerateDictionaryLoad(masm, &slow, a3, key, v0, t1, t0);
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(),
-                      1,
-                      t0,
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), 1, t0,
                       a3);
   __ Ret();
 
@@ -723,10 +672,7 @@
   Register result = v0;
   DCHECK(!scratch.is(receiver) && !scratch.is(index));
 
-  StringCharAtGenerator char_at_generator(receiver,
-                                          index,
-                                          scratch,
-                                          result,
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
                                           &miss,  // When not a string.
                                           &miss,  // When not a number.
                                           &miss,  // When index out of range.
@@ -742,30 +688,11 @@
 }
 
 
-void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictMode strict_mode) {
-  // Push receiver, key and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-  __ li(a0, Operand(Smi::FromInt(strict_mode)));   // Strict mode.
-  __ Push(a0);
-
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
 static void KeyedStoreGenerateGenericHelper(
-    MacroAssembler* masm,
-    Label* fast_object,
-    Label* fast_double,
-    Label* slow,
-    KeyedStoreCheckMap check_map,
-    KeyedStoreIncrementLength increment_length,
-    Register value,
-    Register key,
-    Register receiver,
-    Register receiver_map,
-    Register elements_map,
-    Register elements) {
+    MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
+    KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
+    Register value, Register key, Register receiver, Register receiver_map,
+    Register elements_map, Register elements) {
   Label transition_smi_elements;
   Label finish_object_store, non_double_value, transition_double_elements;
   Label fast_double_without_map_check;
@@ -829,13 +756,8 @@
   __ sw(value, MemOperand(address));
   // Update write barrier for the elements array address.
   __ mov(scratch_value, value);  // Preserve the value which is returned.
-  __ RecordWrite(elements,
-                 address,
-                 scratch_value,
-                 kRAHasNotBeenSaved,
-                 kDontSaveFPRegs,
-                 EMIT_REMEMBERED_SET,
-                 OMIT_SMI_CHECK);
+  __ RecordWrite(elements, address, scratch_value, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
   __ Ret();
 
   __ bind(fast_double);
@@ -849,9 +771,8 @@
   // HOLECHECK: guards "A[i] double hole?"
   // We have to see if the double version of the hole is present. If so
   // go to the runtime.
-  __ Addu(address, elements,
-          Operand(FixedDoubleArray::kHeaderSize + kHoleNanUpper32Offset
-                  - kHeapObjectTag));
+  __ Addu(address, elements, Operand(FixedDoubleArray::kHeaderSize +
+                                     kHoleNanUpper32Offset - kHeapObjectTag));
   __ sll(at, key, kPointerSizeLog2);
   __ addu(address, address, at);
   __ lw(scratch_value, MemOperand(address));
@@ -861,13 +782,10 @@
                                       slow);
 
   __ bind(&fast_double_without_map_check);
-  __ StoreNumberToDoubleElements(value,
-                                 key,
+  __ StoreNumberToDoubleElements(value, key,
                                  elements,  // Overwritten.
                                  a3,        // Scratch regs...
-                                 t0,
-                                 t1,
-                                 &transition_double_elements);
+                                 t0, t1, &transition_double_elements);
   if (increment_length == kIncrementLength) {
     // Add 1 to receiver->length.
     __ Addu(scratch_value, key, Operand(Smi::FromInt(1)));
@@ -883,25 +801,19 @@
 
   // Value is a double. Transition FAST_SMI_ELEMENTS ->
   // FAST_DOUBLE_ELEMENTS and complete the store.
-  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
-                                         FAST_DOUBLE_ELEMENTS,
-                                         receiver_map,
-                                         t0,
-                                         slow);
-  AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS,
-                                                    FAST_DOUBLE_ELEMENTS);
-  ElementsTransitionGenerator::GenerateSmiToDouble(
-      masm, receiver, key, value, receiver_map, mode, slow);
+  __ LoadTransitionedArrayMapConditional(
+      FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, t0, slow);
+  AllocationSiteMode mode =
+      AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
+  ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
+                                                   receiver_map, mode, slow);
   __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
   __ jmp(&fast_double_without_map_check);
 
   __ bind(&non_double_value);
   // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
-  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
-                                         FAST_ELEMENTS,
-                                         receiver_map,
-                                         t0,
-                                         slow);
+  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
+                                         receiver_map, t0, slow);
   mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
   ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
       masm, receiver, key, value, receiver_map, mode, slow);
@@ -912,11 +824,8 @@
   // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
   // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
   // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
-  __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
-                                         FAST_ELEMENTS,
-                                         receiver_map,
-                                         t0,
-                                         slow);
+  __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
+                                         receiver_map, t0, slow);
   mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
   ElementsTransitionGenerator::GenerateDoubleToObject(
       masm, receiver, key, value, receiver_map, mode, slow);
@@ -956,8 +865,8 @@
   // Check that the receiver does not require access checks and is not observed.
   // The generic stub does not perform map checks or handle observed objects.
   __ lbu(t0, FieldMemOperand(receiver_map, Map::kBitFieldOffset));
-  __ And(t0, t0, Operand(1 << Map::kIsAccessCheckNeeded |
-                         1 << Map::kIsObserved));
+  __ And(t0, t0,
+         Operand(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
   __ Branch(&slow, ne, t0, Operand(zero_reg));
   // Check if the object is a JS array or not.
   __ lbu(t0, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset));
@@ -977,7 +886,7 @@
   // a0: value.
   // a1: key.
   // a2: receiver.
-  GenerateRuntimeSetProperty(masm, strict_mode);
+  PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -991,8 +900,8 @@
   __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
   __ Branch(&slow, hs, key, Operand(t0));
   __ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
-  __ Branch(
-      &check_if_double_array, ne, elements_map, Heap::kFixedArrayMapRootIndex);
+  __ Branch(&check_if_double_array, ne, elements_map,
+            Heap::kFixedArrayMapRootIndex);
 
   __ jmp(&fast_object_grow);
 
@@ -1010,14 +919,13 @@
   __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
   __ Branch(&extra, hs, key, Operand(t0));
 
-  KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
-                                  &slow, kCheckMap, kDontIncrementLength,
-                                  value, key, receiver, receiver_map,
-                                  elements_map, elements);
+  KeyedStoreGenerateGenericHelper(
+      masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
+      value, key, receiver, receiver_map, elements_map, elements);
   KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength,
-                                  value, key, receiver, receiver_map,
-                                  elements_map, elements);
+                                  &slow, kDontCheckMap, kIncrementLength, value,
+                                  key, receiver, receiver_map, elements_map,
+                                  elements);
 }
 
 
@@ -1051,8 +959,10 @@
   __ Push(receiver, key);  // Receiver, key.
 
   // Perform tail call to the entry.
-  __ TailCallExternalReference(ExternalReference(
-       IC_Utility(kLoadElementWithInterceptor), masm->isolate()), 2, 1);
+  __ TailCallExternalReference(
+      ExternalReference(IC_Utility(kLoadElementWithInterceptor),
+                        masm->isolate()),
+      2, 1);
 
   __ bind(&slow);
   GenerateMiss(masm);
@@ -1069,32 +979,6 @@
 }
 
 
-void StoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Push receiver, key and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
-void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Push receiver, key and value for runtime call.
-  // We can't use MultiPush as the order of the registers is important.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
-
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   Register receiver = ReceiverRegister();
   Register name = NameRegister();
@@ -1105,8 +989,8 @@
   // Get the receiver from the stack and probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, receiver, name, a3, t0, t1, t2);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, a3,
+                                               t0, t1, t2);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -1116,8 +1000,8 @@
 void StoreIC::GenerateMiss(MacroAssembler* masm) {
   __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
   // Perform tail call to the entry.
-  ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss),
-                                            masm->isolate());
+  ExternalReference ref =
+      ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate());
   __ TailCallExternalReference(ref, 3, 1);
 }
 
@@ -1145,18 +1029,6 @@
 }
 
 
-void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictMode strict_mode) {
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  __ li(a0, Operand(Smi::FromInt(strict_mode)));
-  __ Push(a0);
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
 #undef __
 
 
@@ -1189,7 +1061,7 @@
   // was inlined.
   Instr instr = Assembler::instr_at(andi_instruction_address);
   return Assembler::IsAndImmediate(instr) &&
-      Assembler::GetRt(instr) == static_cast<uint32_t>(zero_reg.code());
+         Assembler::GetRt(instr) == static_cast<uint32_t>(zero_reg.code());
 }
 
 
@@ -1216,8 +1088,8 @@
   }
 
   if (FLAG_trace_ic) {
-    PrintF("[  patching ic at %p, andi=%p, delta=%d\n",
-           address, andi_instruction_address, delta);
+    PrintF("[  patching ic at %p, andi=%p, delta=%d\n", address,
+           andi_instruction_address, delta);
   }
 
   Address patch_address =
@@ -1252,8 +1124,7 @@
     patcher.ChangeBranchCondition(eq);
   }
 }
-
-
-} }  // namespace v8::internal
+}
+}  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_MIPS
diff --git a/src/ic/mips/stub-cache-mips.cc b/src/ic/mips/stub-cache-mips.cc
new file mode 100644
index 0000000..6196f26
--- /dev/null
+++ b/src/ic/mips/stub-cache-mips.cc
@@ -0,0 +1,167 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS
+
+#include "src/codegen.h"
+#include "src/ic/stub-cache.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
+                       Code::Flags flags, StubCache::Table table,
+                       Register receiver, Register name,
+                       // Number of the cache entry, not scaled.
+                       Register offset, Register scratch, Register scratch2,
+                       Register offset_scratch) {
+  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
+  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
+  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
+
+  uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address());
+  uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address());
+  uint32_t map_off_addr = reinterpret_cast<uint32_t>(map_offset.address());
+
+  // Check the relative positions of the address fields.
+  DCHECK(value_off_addr > key_off_addr);
+  DCHECK((value_off_addr - key_off_addr) % 4 == 0);
+  DCHECK((value_off_addr - key_off_addr) < (256 * 4));
+  DCHECK(map_off_addr > key_off_addr);
+  DCHECK((map_off_addr - key_off_addr) % 4 == 0);
+  DCHECK((map_off_addr - key_off_addr) < (256 * 4));
+
+  Label miss;
+  Register base_addr = scratch;
+  scratch = no_reg;
+
+  // Multiply by 3 because there are 3 fields per entry (name, code, map).
+  __ sll(offset_scratch, offset, 1);
+  __ Addu(offset_scratch, offset_scratch, offset);
+
+  // Calculate the base address of the entry.
+  __ li(base_addr, Operand(key_offset));
+  __ sll(at, offset_scratch, kPointerSizeLog2);
+  __ Addu(base_addr, base_addr, at);
+
+  // Check that the key in the entry matches the name.
+  __ lw(at, MemOperand(base_addr, 0));
+  __ Branch(&miss, ne, name, Operand(at));
+
+  // Check the map matches.
+  __ lw(at, MemOperand(base_addr, map_off_addr - key_off_addr));
+  __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ Branch(&miss, ne, at, Operand(scratch2));
+
+  // Get the code entry from the cache.
+  Register code = scratch2;
+  scratch2 = no_reg;
+  __ lw(code, MemOperand(base_addr, value_off_addr - key_off_addr));
+
+  // Check that the flags match what we're looking for.
+  Register flags_reg = base_addr;
+  base_addr = no_reg;
+  __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset));
+  __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup));
+  __ Branch(&miss, ne, flags_reg, Operand(flags));
+
+#ifdef DEBUG
+  if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
+    __ jmp(&miss);
+  } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
+    __ jmp(&miss);
+  }
+#endif
+
+  // Jump to the first instruction in the code stub.
+  __ Addu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ Jump(at);
+
+  // Miss: fall through.
+  __ bind(&miss);
+}
+
+
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
+  Isolate* isolate = masm->isolate();
+  Label miss;
+
+  // Make sure that code is valid. The multiplying code relies on the
+  // entry size being 12.
+  DCHECK(sizeof(Entry) == 12);
+
+  // Make sure the flags does not name a specific type.
+  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
+
+  // Make sure that there are no register conflicts.
+  DCHECK(!scratch.is(receiver));
+  DCHECK(!scratch.is(name));
+  DCHECK(!extra.is(receiver));
+  DCHECK(!extra.is(name));
+  DCHECK(!extra.is(scratch));
+  DCHECK(!extra2.is(receiver));
+  DCHECK(!extra2.is(name));
+  DCHECK(!extra2.is(scratch));
+  DCHECK(!extra2.is(extra));
+
+  // Check register validity.
+  DCHECK(!scratch.is(no_reg));
+  DCHECK(!extra.is(no_reg));
+  DCHECK(!extra2.is(no_reg));
+  DCHECK(!extra3.is(no_reg));
+
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
+                      extra3);
+
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, &miss);
+
+  // Get the map of the receiver and compute the hash.
+  __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
+  __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ Addu(scratch, scratch, at);
+  uint32_t mask = kPrimaryTableSize - 1;
+  // We shift out the last two bits because they are not part of the hash and
+  // they are always 01 for maps.
+  __ srl(scratch, scratch, kCacheIndexShift);
+  __ Xor(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask));
+  __ And(scratch, scratch, Operand(mask));
+
+  // Probe the primary table.
+  ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch, extra,
+             extra2, extra3);
+
+  // Primary miss: Compute hash for secondary probe.
+  __ srl(at, name, kCacheIndexShift);
+  __ Subu(scratch, scratch, at);
+  uint32_t mask2 = kSecondaryTableSize - 1;
+  __ Addu(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask2));
+  __ And(scratch, scratch, Operand(mask2));
+
+  // Probe the secondary table.
+  ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch, extra,
+             extra2, extra3);
+
+  // Cache miss: Fall-through and let caller handle the miss by
+  // entering the runtime system.
+  __ bind(&miss);
+  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2,
+                      extra3);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_MIPS
diff --git a/src/ic/mips64/OWNERS b/src/ic/mips64/OWNERS
new file mode 100644
index 0000000..5508ba6
--- /dev/null
+++ b/src/ic/mips64/OWNERS
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/src/ic/mips64/access-compiler-mips64.cc b/src/ic/mips64/access-compiler-mips64.cc
new file mode 100644
index 0000000..1249467
--- /dev/null
+++ b/src/ic/mips64/access-compiler-mips64.cc
@@ -0,0 +1,46 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS64
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ Jump(code, RelocInfo::CODE_TARGET);
+}
+
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadIC::ReceiverRegister();
+  Register name = LoadIC::NameRegister();
+  static Register registers[] = {receiver, name, a3, a0, a4, a5};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3.
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  DCHECK(a3.is(KeyedStoreIC::MapRegister()));
+  static Register registers[] = {receiver, name, a3, a4, a5};
+  return registers;
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_MIPS64
diff --git a/src/mips64/stub-cache-mips64.cc b/src/ic/mips64/handler-compiler-mips64.cc
similarity index 66%
rename from src/mips64/stub-cache-mips64.cc
rename to src/ic/mips64/handler-compiler-mips64.cc
index 3e73fd5..d26a1fd 100644
--- a/src/mips64/stub-cache-mips64.cc
+++ b/src/ic/mips64/handler-compiler-mips64.cc
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2014 the V8 project authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,9 +6,8 @@
 
 #if V8_TARGET_ARCH_MIPS64
 
-#include "src/codegen.h"
-#include "src/ic-inl.h"
-#include "src/stub-cache.h"
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
 
 namespace v8 {
 namespace internal {
@@ -16,81 +15,79 @@
 #define __ ACCESS_MASM(masm)
 
 
-static void ProbeTable(Isolate* isolate,
-                       MacroAssembler* masm,
-                       Code::Flags flags,
-                       StubCache::Table table,
-                       Register receiver,
-                       Register name,
-                       // Number of the cache entry, not scaled.
-                       Register offset,
-                       Register scratch,
-                       Register scratch2,
-                       Register offset_scratch) {
-  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
-  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
-  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> getter) {
+  // ----------- S t a t e -------------
+  //  -- a0    : receiver
+  //  -- a2    : name
+  //  -- ra    : return address
+  // -----------------------------------
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
 
-  uint64_t key_off_addr = reinterpret_cast<uint64_t>(key_offset.address());
-  uint64_t value_off_addr = reinterpret_cast<uint64_t>(value_offset.address());
-  uint64_t map_off_addr = reinterpret_cast<uint64_t>(map_offset.address());
-
-  // Check the relative positions of the address fields.
-  DCHECK(value_off_addr > key_off_addr);
-  DCHECK((value_off_addr - key_off_addr) % 4 == 0);
-  DCHECK((value_off_addr - key_off_addr) < (256 * 4));
-  DCHECK(map_off_addr > key_off_addr);
-  DCHECK((map_off_addr - key_off_addr) % 4 == 0);
-  DCHECK((map_off_addr - key_off_addr) < (256 * 4));
-
-  Label miss;
-  Register base_addr = scratch;
-  scratch = no_reg;
-
-  // Multiply by 3 because there are 3 fields per entry (name, code, map).
-  __ dsll(offset_scratch, offset, 1);
-  __ Daddu(offset_scratch, offset_scratch, offset);
-
-  // Calculate the base address of the entry.
-  __ li(base_addr, Operand(key_offset));
-  __ dsll(at, offset_scratch, kPointerSizeLog2);
-  __ Daddu(base_addr, base_addr, at);
-
-  // Check that the key in the entry matches the name.
-  __ ld(at, MemOperand(base_addr, 0));
-  __ Branch(&miss, ne, name, Operand(at));
-
-  // Check the map matches.
-  __ ld(at, MemOperand(base_addr, map_off_addr - key_off_addr));
-  __ ld(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
-  __ Branch(&miss, ne, at, Operand(scratch2));
-
-  // Get the code entry from the cache.
-  Register code = scratch2;
-  scratch2 = no_reg;
-  __ ld(code, MemOperand(base_addr, value_off_addr - key_off_addr));
-
-  // Check that the flags match what we're looking for.
-  Register flags_reg = base_addr;
-  base_addr = no_reg;
-  __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset));
-  __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup));
-  __ Branch(&miss, ne, flags_reg, Operand(flags));
-
-#ifdef DEBUG
-    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
-      __ jmp(&miss);
-    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
-      __ jmp(&miss);
+    if (!getter.is_null()) {
+      // Call the JavaScript getter with the receiver on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ ld(receiver,
+              FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ push(receiver);
+      ParameterCount actual(0);
+      ParameterCount expected(getter);
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
     }
-#endif
 
-  // Jump to the first instruction in the code stub.
-  __ Daddu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ Jump(at);
+    // Restore context register.
+    __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
 
-  // Miss: fall through.
-  __ bind(&miss);
+
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> setter) {
+  // ----------- S t a t e -------------
+  //  -- ra    : return address
+  // -----------------------------------
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Save value register, so we can restore it later.
+    __ push(value());
+
+    if (!setter.is_null()) {
+      // Call the JavaScript setter with receiver and value on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ ld(receiver,
+              FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver, value());
+      ParameterCount actual(1);
+      ParameterCount expected(setter);
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // We have to return the passed value, not the return value of the setter.
+    __ pop(v0);
+
+    // Restore context register.
+    __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
 }
 
 
@@ -132,111 +129,13 @@
   __ ld(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
 
 
-  NameDictionaryLookupStub::GenerateNegativeLookup(masm,
-                                                   miss_label,
-                                                   &done,
-                                                   receiver,
-                                                   properties,
-                                                   name,
-                                                   scratch1);
+  NameDictionaryLookupStub::GenerateNegativeLookup(
+      masm, miss_label, &done, receiver, properties, name, scratch1);
   __ bind(&done);
   __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm,
-                              Code::Flags flags,
-                              Register receiver,
-                              Register name,
-                              Register scratch,
-                              Register extra,
-                              Register extra2,
-                              Register extra3) {
-  Isolate* isolate = masm->isolate();
-  Label miss;
-
-  // Make sure that code is valid. The multiplying code relies on the
-  // entry size being 12.
-  // DCHECK(sizeof(Entry) == 12);
-  // DCHECK(sizeof(Entry) == 3 * kPointerSize);
-
-  // Make sure the flags does not name a specific type.
-  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
-
-  // Make sure that there are no register conflicts.
-  DCHECK(!scratch.is(receiver));
-  DCHECK(!scratch.is(name));
-  DCHECK(!extra.is(receiver));
-  DCHECK(!extra.is(name));
-  DCHECK(!extra.is(scratch));
-  DCHECK(!extra2.is(receiver));
-  DCHECK(!extra2.is(name));
-  DCHECK(!extra2.is(scratch));
-  DCHECK(!extra2.is(extra));
-
-  // Check register validity.
-  DCHECK(!scratch.is(no_reg));
-  DCHECK(!extra.is(no_reg));
-  DCHECK(!extra2.is(no_reg));
-  DCHECK(!extra3.is(no_reg));
-
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1,
-                      extra2, extra3);
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, &miss);
-
-  // Get the map of the receiver and compute the hash.
-  __ ld(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
-  __ ld(at, FieldMemOperand(receiver, HeapObject::kMapOffset));
-  __ Daddu(scratch, scratch, at);
-  uint64_t mask = kPrimaryTableSize - 1;
-  // We shift out the last two bits because they are not part of the hash and
-  // they are always 01 for maps.
-  __ dsrl(scratch, scratch, kCacheIndexShift);
-  __ Xor(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask));
-  __ And(scratch, scratch, Operand(mask));
-
-  // Probe the primary table.
-  ProbeTable(isolate,
-             masm,
-             flags,
-             kPrimary,
-             receiver,
-             name,
-             scratch,
-             extra,
-             extra2,
-             extra3);
-
-  // Primary miss: Compute hash for secondary probe.
-  __ dsrl(at, name, kCacheIndexShift);
-  __ Dsubu(scratch, scratch, at);
-  uint64_t mask2 = kSecondaryTableSize - 1;
-  __ Daddu(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask2));
-  __ And(scratch, scratch, Operand(mask2));
-
-  // Probe the secondary table.
-  ProbeTable(isolate,
-             masm,
-             flags,
-             kSecondary,
-             receiver,
-             name,
-             scratch,
-             extra,
-             extra2,
-             extra3);
-
-  // Cache miss: Fall-through and let caller handle the miss by
-  // entering the runtime system.
-  __ bind(&miss);
-  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1,
-                      extra2, extra3);
-}
-
-
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
     MacroAssembler* masm, int index, Register prototype, Label* miss) {
   Isolate* isolate = masm->isolate();
@@ -269,6 +168,9 @@
 }
 
 
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
     MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
     Register scratch, Label* miss) {
@@ -281,10 +183,8 @@
 }
 
 
-static void PushInterceptorArguments(MacroAssembler* masm,
-                                     Register receiver,
-                                     Register holder,
-                                     Register name,
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
                                      Handle<JSObject> holder_obj) {
   STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
   STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
@@ -301,12 +201,8 @@
 
 
 static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm,
-    Register receiver,
-    Register holder,
-    Register name,
-    Handle<JSObject> holder_obj,
-    IC::UtilityId id) {
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
   __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
                            NamedLoadHandlerCompiler::kInterceptorArgsLength);
@@ -324,10 +220,10 @@
   __ sd(receiver, MemOperand(sp, argc * kPointerSize));  // Push receiver.
   // Write the arguments to stack frame.
   for (int i = 0; i < argc; i++) {
-    Register arg = values[argc-1-i];
+    Register arg = values[argc - 1 - i];
     DCHECK(!receiver.is(arg));
     DCHECK(!scratch_in.is(arg));
-    __ sd(arg, MemOperand(sp, (argc-1-i) * kPointerSize));  // Push arg.
+    __ sd(arg, MemOperand(sp, (argc - 1 - i) * kPointerSize));  // Push arg.
   }
   DCHECK(optimization.is_simple_api_call());
 
@@ -339,16 +235,15 @@
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
-      receiver_map,
-      &holder_lookup);
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
       __ li(holder, api_holder);
-     break;
+      break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
       break;
@@ -377,10 +272,7 @@
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
   ApiFunction fun(function_address);
   ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
-  ExternalReference ref =
-      ExternalReference(&fun,
-                        type,
-                        masm->isolate());
+  ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
   __ li(api_function_address, Operand(ref));
 
   // Jump to stub.
@@ -389,9 +281,59 @@
 }
 
 
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ Jump(code, RelocInfo::CODE_TARGET);
+void ElementHandlerCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // The return address is in ra
+  Label slow, miss;
+
+  Register key = LoadIC::NameRegister();
+  Register receiver = LoadIC::ReceiverRegister();
+  DCHECK(receiver.is(a1));
+  DCHECK(key.is(a2));
+
+  __ UntagAndJumpIfNotSmi(a6, key, &miss);
+  __ ld(a4, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  DCHECK(kSmiTagSize + kSmiShiftSize == 32);
+  __ LoadFromNumberDictionary(&slow, a4, key, v0, a6, a3, a5);
+  __ Ret();
+
+  // Slow case, key and receiver still unmodified.
+  __ bind(&slow);
+  __ IncrementCounter(
+      masm->isolate()->counters()->keyed_load_external_array_slow(), 1, a2, a3);
+
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
+
+  // Miss case, call the runtime.
+  __ bind(&miss);
+
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
 }
 
 
@@ -463,8 +405,8 @@
     __ jmp(&do_store);
 
     __ bind(&heap_number);
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
-                miss_label, DONT_DO_SMI_CHECK);
+    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
+                DONT_DO_SMI_CHECK);
     __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
 
     __ bind(&do_store);
@@ -483,9 +425,9 @@
     __ li(a2, Operand(transition));
     __ Push(a2, a0);
     __ TailCallExternalReference(
-           ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                             isolate()),
-           3, 1);
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
+                          isolate()),
+        3, 1);
     return;
   }
 
@@ -494,13 +436,8 @@
   __ sd(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
 
   // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg,
-                      HeapObject::kMapOffset,
-                      scratch1,
-                      scratch2,
-                      kRAHasNotBeenSaved,
-                      kDontSaveFPRegs,
-                      OMIT_REMEMBERED_SET,
+  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
+                      kRAHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
                       OMIT_SMI_CHECK);
 
   if (details.type() == CONSTANT) {
@@ -519,8 +456,8 @@
   index -= transition->inobject_properties();
 
   // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check = representation.IsTagged()
-      ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  SmiCheck smi_check =
+      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
   if (index < 0) {
     // Set the property straight into the object.
     int offset = transition->instance_size() + (index * kPointerSize);
@@ -535,21 +472,15 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(receiver_reg,
-                          offset,
-                          storage_reg,
-                          scratch1,
-                          kRAHasNotBeenSaved,
-                          kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
+                          kRAHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
     }
   } else {
     // Write to the properties array.
     int offset = index * kPointerSize + FixedArray::kHeaderSize;
     // Get the properties array
-    __ ld(scratch1,
-          FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
+    __ ld(scratch1, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
     if (representation.IsDouble()) {
       __ sd(storage_reg, FieldMemOperand(scratch1, offset));
     } else {
@@ -561,14 +492,9 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(scratch1,
-                          offset,
-                          storage_reg,
-                          receiver_reg,
-                          kRAHasNotBeenSaved,
-                          kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
+                          kRAHasNotBeenSaved, kDontSaveFPRegs,
+                          EMIT_REMEMBERED_SET, smi_check);
     }
   }
 
@@ -615,8 +541,8 @@
 
   // Make sure there's no overlap between holder and object registers.
   DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
-         && !scratch2.is(scratch1));
+  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
+         !scratch2.is(scratch1));
 
   // Keep track of the current object in register reg.
   Register reg = object_reg;
@@ -649,10 +575,10 @@
       }
       DCHECK(current.is_null() ||
              current->property_dictionary()->FindEntry(name) ==
-             NameDictionary::kNotFound);
+                 NameDictionary::kNotFound);
 
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
-                                       scratch1, scratch2);
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
 
       __ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
       reg = holder_reg;  // From now on the object will be in holder_reg.
@@ -681,9 +607,8 @@
       if (current_map->IsJSGlobalProxyMap()) {
         __ CheckAccessGlobalProxy(reg, scratch2, miss);
       } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(
-            masm(), Handle<JSGlobalObject>::cast(current), name,
-            scratch2, miss);
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
       }
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
@@ -766,8 +691,8 @@
   __ push(receiver());
   if (heap()->InNewSpace(callback->data())) {
     __ li(scratch3(), callback);
-    __ ld(scratch3(), FieldMemOperand(scratch3(),
-                                      ExecutableAccessorInfo::kDataOffset));
+    __ ld(scratch3(),
+          FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
   } else {
     __ li(scratch3(), Handle<Object>(callback->data(), isolate()));
   }
@@ -776,8 +701,7 @@
   __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
   __ sd(scratch3(), MemOperand(sp, 4 * kPointerSize));
   __ sd(scratch3(), MemOperand(sp, 3 * kPointerSize));
-  __ li(scratch4(),
-        Operand(ExternalReference::isolate_address(isolate())));
+  __ li(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
   __ sd(scratch4(), MemOperand(sp, 2 * kPointerSize));
   __ sd(reg, MemOperand(sp, 1 * kPointerSize));
   __ sd(name(), MemOperand(sp, 0 * kPointerSize));
@@ -876,7 +800,7 @@
   Register holder_reg = Frontend(receiver(), name);
 
   __ Push(receiver(), holder_reg);  // Receiver.
-  __ li(at, Operand(callback));  // Callback info.
+  __ li(at, Operand(callback));     // Callback info.
   __ push(at);
   __ li(at, Operand(name));
   __ Push(at, value());
@@ -891,54 +815,6 @@
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- ra    : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Save value register, so we can restore it later.
-    __ push(value());
-
-    if (!setter.is_null()) {
-      // Call the JavaScript setter with receiver and value on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ ld(receiver,
-               FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ Push(receiver, value());
-      ParameterCount actual(1);
-      ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // We have to return the passed value, not the return value of the setter.
-    __ pop(v0);
-
-    // Restore context register.
-    __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
     Handle<Name> name) {
   __ Push(receiver(), this->name(), value());
@@ -953,72 +829,9 @@
 }
 
 
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = { receiver, name, a3, a0, a4, a5 };
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3.
-  Register receiver = StoreIC::ReceiverRegister();
-  Register name = StoreIC::NameRegister();
-  DCHECK(a3.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = { receiver, name, a3, a4, a5 };
-  return registers;
-}
-
-
 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
 
 
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
-  // ----------- S t a t e -------------
-  //  -- a0    : receiver
-  //  -- a2    : name
-  //  -- ra    : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    if (!getter.is_null()) {
-      // Call the JavaScript getter with the receiver on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ ld(receiver,
-                FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ push(receiver);
-      ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // Restore context register.
-    __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  }
-  __ Ret();
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
@@ -1048,131 +861,8 @@
 }
 
 
-Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
-                                                    CodeHandleList* handlers,
-                                                    Handle<Name> name,
-                                                    Code::StubType type,
-                                                    IcCheckType check) {
-  Label miss;
-
-  if (check == PROPERTY &&
-      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
-    // check whether the name is unique.
-    if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
-      __ JumpIfNotUniqueName(this->name(), &miss);
-    } else {
-      __ Branch(&miss, ne, this->name(), Operand(name));
-    }
-  }
-
-  Label number_case;
-  Register match = scratch2();
-  Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
-  __ JumpIfSmi(receiver(), smi_target, match);  // Reg match is 0 if Smi.
-
-  // Polymorphic keyed stores may use the map register
-  Register map_reg = scratch1();
-  DCHECK(kind() != Code::KEYED_STORE_IC ||
-         map_reg.is(KeyedStoreIC::MapRegister()));
-
-  int receiver_count = types->length();
-  int number_of_handled_maps = 0;
-  __ ld(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
-  for (int current = 0; current < receiver_count; ++current) {
-    Handle<HeapType> type = types->at(current);
-    Handle<Map> map = IC::TypeToMap(*type, isolate());
-    if (!map->is_deprecated()) {
-      number_of_handled_maps++;
-      // Check map and tail call if there's a match.
-      // Separate compare from branch, to provide path for above JumpIfSmi().
-      __ Dsubu(match, map_reg, Operand(map));
-      if (type->Is(HeapType::Number())) {
-        DCHECK(!number_case.is_unused());
-        __ bind(&number_case);
-      }
-      __ Jump(handlers->at(current), RelocInfo::CODE_TARGET,
-          eq, match, Operand(zero_reg));
-    }
-  }
-  DCHECK(number_of_handled_maps != 0);
-
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  InlineCacheState state =
-      number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
-  return GetCode(kind(), type, name, state);
-}
-
-
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
-    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
-    MapHandleList* transitioned_maps) {
-  Label miss;
-  __ JumpIfSmi(receiver(), &miss);
-
-  int receiver_count = receiver_maps->length();
-  __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
-  for (int i = 0; i < receiver_count; ++i) {
-    if (transitioned_maps->at(i).is_null()) {
-      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq,
-          scratch1(), Operand(receiver_maps->at(i)));
-    } else {
-      Label next_map;
-      __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
-      __ li(transition_map(), Operand(transitioned_maps->at(i)));
-      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
-      __ bind(&next_map);
-    }
-  }
-
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
-}
-
-
 #undef __
-#define __ ACCESS_MASM(masm)
-
-
-void ElementHandlerCompiler::GenerateLoadDictionaryElement(
-    MacroAssembler* masm) {
-  // The return address is in ra
-  Label slow, miss;
-
-  Register key = LoadIC::NameRegister();
-  Register receiver = LoadIC::ReceiverRegister();
-  DCHECK(receiver.is(a1));
-  DCHECK(key.is(a2));
-
-  __ UntagAndJumpIfNotSmi(a6, key, &miss);
-  __ ld(a4, FieldMemOperand(receiver, JSObject::kElementsOffset));
-  DCHECK(kSmiTagSize + kSmiShiftSize == 32);
-  __ LoadFromNumberDictionary(&slow, a4, key, v0, a6, a3, a5);
-  __ Ret();
-
-  // Slow case, key and receiver still unmodified.
-  __ bind(&slow);
-  __ IncrementCounter(
-      masm->isolate()->counters()->keyed_load_external_array_slow(),
-      1, a2, a3);
-
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
-
-  // Miss case, call the runtime.
-  __ bind(&miss);
-
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
 }
-
-
-#undef __
-
-} }  // namespace v8::internal
+}  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_MIPS64
diff --git a/src/ic/mips64/ic-compiler-mips64.cc b/src/ic/mips64/ic-compiler-mips64.cc
new file mode 100644
index 0000000..a503f72
--- /dev/null
+++ b/src/ic/mips64/ic-compiler-mips64.cc
@@ -0,0 +1,126 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS64
+
+#include "src/ic/ic-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
+                                                    CodeHandleList* handlers,
+                                                    Handle<Name> name,
+                                                    Code::StubType type,
+                                                    IcCheckType check) {
+  Label miss;
+
+  if (check == PROPERTY &&
+      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
+    // In case we are compiling an IC for dictionary loads and stores, just
+    // check whether the name is unique.
+    if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      __ JumpIfNotUniqueName(this->name(), &miss);
+    } else {
+      __ Branch(&miss, ne, this->name(), Operand(name));
+    }
+  }
+
+  Label number_case;
+  Register match = scratch2();
+  Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
+  __ JumpIfSmi(receiver(), smi_target, match);  // Reg match is 0 if Smi.
+
+  // Polymorphic keyed stores may use the map register
+  Register map_reg = scratch1();
+  DCHECK(kind() != Code::KEYED_STORE_IC ||
+         map_reg.is(KeyedStoreIC::MapRegister()));
+
+  int receiver_count = types->length();
+  int number_of_handled_maps = 0;
+  __ ld(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  for (int current = 0; current < receiver_count; ++current) {
+    Handle<HeapType> type = types->at(current);
+    Handle<Map> map = IC::TypeToMap(*type, isolate());
+    if (!map->is_deprecated()) {
+      number_of_handled_maps++;
+      // Check map and tail call if there's a match.
+      // Separate compare from branch, to provide path for above JumpIfSmi().
+      __ Dsubu(match, map_reg, Operand(map));
+      if (type->Is(HeapType::Number())) {
+        DCHECK(!number_case.is_unused());
+        __ bind(&number_case);
+      }
+      __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq, match,
+              Operand(zero_reg));
+    }
+  }
+  DCHECK(number_of_handled_maps != 0);
+
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  InlineCacheState state =
+      number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
+  return GetCode(kind(), type, name, state);
+}
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
+    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
+    MapHandleList* transitioned_maps) {
+  Label miss;
+  __ JumpIfSmi(receiver(), &miss);
+
+  int receiver_count = receiver_maps->length();
+  __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  for (int i = 0; i < receiver_count; ++i) {
+    if (transitioned_maps->at(i).is_null()) {
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, scratch1(),
+              Operand(receiver_maps->at(i)));
+    } else {
+      Label next_map;
+      __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
+      __ li(transition_map(), Operand(transitioned_maps->at(i)));
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
+      __ bind(&next_map);
+    }
+  }
+
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
+          StoreIC::ValueRegister());
+
+  __ li(a0, Operand(Smi::FromInt(strict_mode)));
+  __ Push(a0);
+
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_MIPS64
diff --git a/src/mips64/ic-mips64.cc b/src/ic/mips64/ic-mips64.cc
similarity index 78%
rename from src/mips64/ic-mips64.cc
rename to src/ic/mips64/ic-mips64.cc
index 5187342..897880c 100644
--- a/src/mips64/ic-mips64.cc
+++ b/src/ic/mips64/ic-mips64.cc
@@ -3,16 +3,14 @@
 // found in the LICENSE file.
 
 
-
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_MIPS64
 
-#include "src/code-stubs.h"
 #include "src/codegen.h"
-#include "src/ic-inl.h"
-#include "src/runtime.h"
-#include "src/stub-cache.h"
+#include "src/ic/ic.h"
+#include "src/ic/ic-compiler.h"
+#include "src/ic/stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -25,8 +23,7 @@
 #define __ ACCESS_MASM(masm)
 
 
-static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm,
-                                            Register type,
+static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, Register type,
                                             Label* global_object) {
   // Register usage:
   //   type: holds the receiver instance type on entry.
@@ -51,12 +48,9 @@
 // is not a global object and does not have interceptors.
 // The address returned from GenerateStringDictionaryProbes() in scratch2
 // is used.
-static void GenerateDictionaryLoad(MacroAssembler* masm,
-                                   Label* miss,
-                                   Register elements,
-                                   Register name,
-                                   Register result,
-                                   Register scratch1,
+static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss,
+                                   Register elements, Register name,
+                                   Register result, Register scratch1,
                                    Register scratch2) {
   // Main use of the scratch registers.
   // scratch1: Used as temporary and to hold the capacity of the property
@@ -65,23 +59,18 @@
   Label done;
 
   // Probe the dictionary.
-  NameDictionaryLookupStub::GeneratePositiveLookup(masm,
-                                                   miss,
-                                                   &done,
-                                                   elements,
-                                                   name,
-                                                   scratch1,
-                                                   scratch2);
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
+                                                   name, scratch1, scratch2);
 
   // If probing finds an entry check that the value is a normal
   // property.
   __ bind(&done);  // scratch2 == elements + 4 * index.
-  const int kElementsStartOffset = NameDictionary::kHeaderSize +
+  const int kElementsStartOffset =
+      NameDictionary::kHeaderSize +
       NameDictionary::kElementsStartIndex * kPointerSize;
   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
   __ ld(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
-  __ And(at,
-         scratch1,
+  __ And(at, scratch1,
          Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
   __ Branch(miss, ne, at, Operand(zero_reg));
 
@@ -104,12 +93,9 @@
 // is not a global object and does not have interceptors.
 // The address returned from GenerateStringDictionaryProbes() in scratch2
 // is used.
-static void GenerateDictionaryStore(MacroAssembler* masm,
-                                    Label* miss,
-                                    Register elements,
-                                    Register name,
-                                    Register value,
-                                    Register scratch1,
+static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss,
+                                    Register elements, Register name,
+                                    Register value, Register scratch1,
                                     Register scratch2) {
   // Main use of the scratch registers.
   // scratch1: Used as temporary and to hold the capacity of the property
@@ -118,18 +104,14 @@
   Label done;
 
   // Probe the dictionary.
-  NameDictionaryLookupStub::GeneratePositiveLookup(masm,
-                                                   miss,
-                                                   &done,
-                                                   elements,
-                                                   name,
-                                                   scratch1,
-                                                   scratch2);
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
+                                                   name, scratch1, scratch2);
 
   // If probing finds an entry in the dictionary check that the value
   // is a normal property that is not read only.
   __ bind(&done);  // scratch2 == elements + 4 * index.
-  const int kElementsStartOffset = NameDictionary::kHeaderSize +
+  const int kElementsStartOffset =
+      NameDictionary::kHeaderSize +
       NameDictionary::kElementsStartIndex * kPointerSize;
   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
   const int kTypeAndReadOnlyMask =
@@ -146,19 +128,17 @@
 
   // Update the write barrier. Make sure not to clobber the value.
   __ mov(scratch1, value);
-  __ RecordWrite(
-      elements, scratch2, scratch1, kRAHasNotBeenSaved, kDontSaveFPRegs);
+  __ RecordWrite(elements, scratch2, scratch1, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs);
 }
 
 
 // Checks the receiver for special cases (value type, slow case bits).
 // Falls through for regular JS object.
 static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
-                                           Register receiver,
-                                           Register map,
+                                           Register receiver, Register map,
                                            Register scratch,
-                                           int interceptor_bit,
-                                           Label* slow) {
+                                           int interceptor_bit, Label* slow) {
   // Check that the object isn't a smi.
   __ JumpIfSmi(receiver, slow);
   // Get the map of the receiver.
@@ -180,14 +160,10 @@
 
 // Loads an indexed element from a fast case array.
 // If not_fast_array is NULL, doesn't perform the elements map check.
-static void GenerateFastArrayLoad(MacroAssembler* masm,
-                                  Register receiver,
-                                  Register key,
-                                  Register elements,
-                                  Register scratch1,
-                                  Register scratch2,
-                                  Register result,
-                                  Label* not_fast_array,
+static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
+                                  Register key, Register elements,
+                                  Register scratch1, Register scratch2,
+                                  Register result, Label* not_fast_array,
                                   Label* out_of_range) {
   // Register use:
   //
@@ -227,7 +203,7 @@
 
   // Fast case: Do the load.
   __ Daddu(scratch1, elements,
-          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+           Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   // The key is a smi.
   STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
   __ SmiScale(at, key, kPointerSizeLog2);
@@ -244,12 +220,9 @@
 
 // Checks whether a key is an array index string or a unique name.
 // Falls through if a key is a unique name.
-static void GenerateKeyNameCheck(MacroAssembler* masm,
-                                 Register key,
-                                 Register map,
-                                 Register hash,
-                                 Label* index_string,
-                                 Label* not_unique) {
+static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
+                                 Register map, Register hash,
+                                 Label* index_string, Label* not_unique) {
   // The key is not a smi.
   Label unique;
   // Is it a name?
@@ -285,8 +258,8 @@
   // Probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, receiver, name, a3, a4, a5, a6);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, a3,
+                                               a4, a5, a6);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -339,14 +312,10 @@
 }
 
 
-static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
-                                                Register object,
-                                                Register key,
-                                                Register scratch1,
-                                                Register scratch2,
-                                                Register scratch3,
-                                                Label* unmapped_case,
-                                                Label* slow_case) {
+static MemOperand GenerateMappedArgumentsLookup(
+    MacroAssembler* masm, Register object, Register key, Register scratch1,
+    Register scratch2, Register scratch3, Label* unmapped_case,
+    Label* slow_case) {
   Heap* heap = masm->isolate()->heap();
 
   // Check that the receiver is a JSObject. Because of the map check
@@ -364,11 +333,7 @@
   // Load the elements into scratch1 and check its map.
   Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
   __ ld(scratch1, FieldMemOperand(object, JSObject::kElementsOffset));
-  __ CheckMap(scratch1,
-              scratch2,
-              arguments_map,
-              slow_case,
-              DONT_DO_SMI_CHECK);
+  __ CheckMap(scratch1, scratch2, arguments_map, slow_case, DONT_DO_SMI_CHECK);
   // Check if element is in the range of mapped arguments. If not, jump
   // to the unmapped lookup with the parameter map in scratch1.
   __ ld(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset));
@@ -412,18 +377,13 @@
   const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize;
   Register backing_store = parameter_map;
   __ ld(backing_store, FieldMemOperand(parameter_map, kBackingStoreOffset));
-  __ CheckMap(backing_store,
-              scratch,
-              Heap::kFixedArrayMapRootIndex,
-              slow_case,
+  __ CheckMap(backing_store, scratch, Heap::kFixedArrayMapRootIndex, slow_case,
               DONT_DO_SMI_CHECK);
   __ ld(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
   __ Branch(slow_case, Ugreater_equal, key, Operand(scratch));
   __ SmiUntag(scratch, key);
   __ dsll(scratch, scratch, kPointerSizeLog2);
-  __ Daddu(scratch,
-          scratch,
-          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ Daddu(scratch, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ Daddu(scratch, backing_store, scratch);
   return MemOperand(scratch);
 }
@@ -437,9 +397,8 @@
   DCHECK(key.is(a2));
 
   Label slow, notin;
-  MemOperand mapped_location =
-      GenerateMappedArgumentsLookup(
-          masm, receiver, key, a0, a3, a4, &notin, &slow);
+  MemOperand mapped_location = GenerateMappedArgumentsLookup(
+      masm, receiver, key, a0, a3, a4, &notin, &slow);
   __ Ret(USE_DELAY_SLOT);
   __ ld(v0, mapped_location);
   __ bind(&notin);
@@ -469,8 +428,8 @@
   __ sd(value, mapped_location);
   __ mov(t1, value);
   DCHECK_EQ(mapped_location.offset(), 0);
-  __ RecordWrite(a3, mapped_location.rm(), t1,
-                 kRAHasNotBeenSaved, kDontSaveFPRegs);
+  __ RecordWrite(a3, mapped_location.rm(), t1, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs);
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, value);  // (In delay slot) return the value stored in v0.
   __ bind(&notin);
@@ -481,8 +440,8 @@
   __ sd(value, unmapped_location);
   __ mov(t1, value);
   DCHECK_EQ(unmapped_location.offset(), 0);
-  __ RecordWrite(a3, unmapped_location.rm(), t1,
-                 kRAHasNotBeenSaved, kDontSaveFPRegs);
+  __ RecordWrite(a3, unmapped_location.rm(), t1, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs);
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, a0);  // (In delay slot) return the value stored in v0.
   __ bind(&slow);
@@ -528,9 +487,7 @@
 const Register StoreIC::ValueRegister() { return a0; }
 
 
-const Register KeyedStoreIC::MapRegister() {
-  return a3;
-}
+const Register KeyedStoreIC::MapRegister() { return a3; }
 
 
 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
@@ -560,14 +517,13 @@
   // Now the key is known to be a smi. This place is also jumped to from below
   // where a numeric string is converted to a smi.
 
-  GenerateKeyedLoadReceiverCheck(
-      masm, receiver, a0, a3, Map::kHasIndexedInterceptor, &slow);
+  GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3,
+                                 Map::kHasIndexedInterceptor, &slow);
 
   // Check the receiver's map to see if it has fast elements.
   __ CheckFastElements(a0, a3, &check_number_dictionary);
 
-  GenerateFastArrayLoad(
-      masm, receiver, key, a0, a3, a4, v0, NULL, &slow);
+  GenerateFastArrayLoad(masm, receiver, key, a0, a3, a4, v0, NULL, &slow);
   __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, a4, a3);
   __ Ret();
 
@@ -586,17 +542,15 @@
 
   // Slow case, key and receiver still in a2 and a1.
   __ bind(&slow);
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
-                      1,
-                      a4,
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, a4,
                       a3);
   GenerateRuntimeGetProperty(masm);
 
   __ bind(&check_name);
   GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);
 
-  GenerateKeyedLoadReceiverCheck(
-      masm, receiver, a0, a3, Map::kHasNamedInterceptor, &slow);
+  GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3,
+                                 Map::kHasNamedInterceptor, &slow);
 
 
   // If the receiver is a fast-case object, check the keyed lookup
@@ -677,10 +631,8 @@
   __ dsll(at, a6, kPointerSizeLog2);
   __ daddu(at, receiver, at);
   __ ld(v0, MemOperand(at));
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
-                      1,
-                      a4,
-                      a3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
+                      a4, a3);
   __ Ret();
 
   // Load property array property.
@@ -690,10 +642,8 @@
   __ dsll(v0, a5, kPointerSizeLog2);
   __ Daddu(v0, v0, a1);
   __ ld(v0, MemOperand(v0));
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
-                      1,
-                      a4,
-                      a3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
+                      a4, a3);
   __ Ret();
 
 
@@ -706,9 +656,7 @@
   GenerateGlobalInstanceTypeCheck(masm, a0, &slow);
   // Load the property to v0.
   GenerateDictionaryLoad(masm, &slow, a3, key, v0, a5, a4);
-  __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(),
-                      1,
-                      a4,
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), 1, a4,
                       a3);
   __ Ret();
 
@@ -729,10 +677,7 @@
   Register result = v0;
   DCHECK(!scratch.is(receiver) && !scratch.is(index));
 
-  StringCharAtGenerator char_at_generator(receiver,
-                                          index,
-                                          scratch,
-                                          result,
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
                                           &miss,  // When not a string.
                                           &miss,  // When not a number.
                                           &miss,  // When index out of range.
@@ -748,31 +693,11 @@
 }
 
 
-void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictMode strict_mode) {
-  // Push receiver, key and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  __ li(a0, Operand(Smi::FromInt(strict_mode)));   // Strict mode.
-  __ Push(a0);
-
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
 static void KeyedStoreGenerateGenericHelper(
-    MacroAssembler* masm,
-    Label* fast_object,
-    Label* fast_double,
-    Label* slow,
-    KeyedStoreCheckMap check_map,
-    KeyedStoreIncrementLength increment_length,
-    Register value,
-    Register key,
-    Register receiver,
-    Register receiver_map,
-    Register elements_map,
-    Register elements) {
+    MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
+    KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
+    Register value, Register key, Register receiver, Register receiver_map,
+    Register elements_map, Register elements) {
   Label transition_smi_elements;
   Label finish_object_store, non_double_value, transition_double_elements;
   Label fast_double_without_map_check;
@@ -814,7 +739,7 @@
   }
   // It's irrelevant whether array is smi-only or not when writing a smi.
   __ Daddu(address, elements,
-      Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+           Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ SmiScale(scratch_value, key, kPointerSizeLog2);
   __ Daddu(address, address, scratch_value);
   __ sd(value, MemOperand(address));
@@ -833,19 +758,14 @@
     __ sd(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
   }
   __ Daddu(address, elements,
-      Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+           Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ SmiScale(scratch_value, key, kPointerSizeLog2);
   __ Daddu(address, address, scratch_value);
   __ sd(value, MemOperand(address));
   // Update write barrier for the elements array address.
   __ mov(scratch_value, value);  // Preserve the value which is returned.
-  __ RecordWrite(elements,
-                 address,
-                 scratch_value,
-                 kRAHasNotBeenSaved,
-                 kDontSaveFPRegs,
-                 EMIT_REMEMBERED_SET,
-                 OMIT_SMI_CHECK);
+  __ RecordWrite(elements, address, scratch_value, kRAHasNotBeenSaved,
+                 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
   __ Ret();
 
   __ bind(fast_double);
@@ -860,8 +780,8 @@
   // We have to see if the double version of the hole is present. If so
   // go to the runtime.
   __ Daddu(address, elements,
-          Operand(FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32)
-                  - kHeapObjectTag));
+           Operand(FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32) -
+                   kHeapObjectTag));
   __ SmiScale(at, key, kPointerSizeLog2);
   __ daddu(address, address, at);
   __ lw(scratch_value, MemOperand(address));
@@ -871,13 +791,10 @@
                                       slow);
 
   __ bind(&fast_double_without_map_check);
-  __ StoreNumberToDoubleElements(value,
-                                 key,
+  __ StoreNumberToDoubleElements(value, key,
                                  elements,  // Overwritten.
                                  a3,        // Scratch regs...
-                                 a4,
-                                 a5,
-                                 &transition_double_elements);
+                                 a4, a5, &transition_double_elements);
   if (increment_length == kIncrementLength) {
     // Add 1 to receiver->length.
     __ Daddu(scratch_value, key, Operand(Smi::FromInt(1)));
@@ -893,25 +810,19 @@
 
   // Value is a double. Transition FAST_SMI_ELEMENTS ->
   // FAST_DOUBLE_ELEMENTS and complete the store.
-  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
-                                         FAST_DOUBLE_ELEMENTS,
-                                         receiver_map,
-                                         a4,
-                                         slow);
-  AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS,
-                                                    FAST_DOUBLE_ELEMENTS);
-  ElementsTransitionGenerator::GenerateSmiToDouble(
-      masm, receiver, key, value, receiver_map, mode, slow);
+  __ LoadTransitionedArrayMapConditional(
+      FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, a4, slow);
+  AllocationSiteMode mode =
+      AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
+  ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
+                                                   receiver_map, mode, slow);
   __ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
   __ jmp(&fast_double_without_map_check);
 
   __ bind(&non_double_value);
   // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
-  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
-                                         FAST_ELEMENTS,
-                                         receiver_map,
-                                         a4,
-                                         slow);
+  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
+                                         receiver_map, a4, slow);
   mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
   ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
       masm, receiver, key, value, receiver_map, mode, slow);
@@ -922,11 +833,8 @@
   // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
   // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
   // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
-  __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
-                                         FAST_ELEMENTS,
-                                         receiver_map,
-                                         a4,
-                                         slow);
+  __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
+                                         receiver_map, a4, slow);
   mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
   ElementsTransitionGenerator::GenerateDoubleToObject(
       masm, receiver, key, value, receiver_map, mode, slow);
@@ -966,8 +874,8 @@
   // Check that the receiver does not require access checks and is not observed.
   // The generic stub does not perform map checks or handle observed objects.
   __ lbu(a4, FieldMemOperand(receiver_map, Map::kBitFieldOffset));
-  __ And(a4, a4, Operand(1 << Map::kIsAccessCheckNeeded |
-                         1 << Map::kIsObserved));
+  __ And(a4, a4,
+         Operand(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
   __ Branch(&slow, ne, a4, Operand(zero_reg));
   // Check if the object is a JS array or not.
   __ lbu(a4, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset));
@@ -987,7 +895,7 @@
   // a0: value.
   // a1: key.
   // a2: receiver.
-  GenerateRuntimeSetProperty(masm, strict_mode);
+  PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -1001,8 +909,8 @@
   __ ld(a4, FieldMemOperand(elements, FixedArray::kLengthOffset));
   __ Branch(&slow, hs, key, Operand(a4));
   __ ld(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
-  __ Branch(
-      &check_if_double_array, ne, elements_map, Heap::kFixedArrayMapRootIndex);
+  __ Branch(&check_if_double_array, ne, elements_map,
+            Heap::kFixedArrayMapRootIndex);
 
   __ jmp(&fast_object_grow);
 
@@ -1020,14 +928,13 @@
   __ ld(a4, FieldMemOperand(receiver, JSArray::kLengthOffset));
   __ Branch(&extra, hs, key, Operand(a4));
 
-  KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
-                                  &slow, kCheckMap, kDontIncrementLength,
-                                  value, key, receiver, receiver_map,
-                                  elements_map, elements);
+  KeyedStoreGenerateGenericHelper(
+      masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
+      value, key, receiver, receiver_map, elements_map, elements);
   KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength,
-                                  value, key, receiver, receiver_map,
-                                  elements_map, elements);
+                                  &slow, kDontCheckMap, kIncrementLength, value,
+                                  key, receiver, receiver_map, elements_map,
+                                  elements);
 }
 
 
@@ -1061,8 +968,10 @@
   __ Push(receiver, key);  // Receiver, key.
 
   // Perform tail call to the entry.
-  __ TailCallExternalReference(ExternalReference(
-       IC_Utility(kLoadElementWithInterceptor), masm->isolate()), 2, 1);
+  __ TailCallExternalReference(
+      ExternalReference(IC_Utility(kLoadElementWithInterceptor),
+                        masm->isolate()),
+      2, 1);
 
   __ bind(&slow);
   GenerateMiss(masm);
@@ -1079,31 +988,6 @@
 }
 
 
-void StoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Push receiver, key and value for runtime call.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
-void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Push receiver, key and value for runtime call.
-  // We can't use MultiPush as the order of the registers is important.
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-  // The slow case calls into the runtime to complete the store without causing
-  // an IC miss that would otherwise cause a transition to the generic stub.
-  ExternalReference ref =
-      ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
-
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   Register receiver = ReceiverRegister();
   Register name = NameRegister();
@@ -1114,8 +998,8 @@
   // Get the receiver from the stack and probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, receiver, name, a3, a4, a5, a6);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, a3,
+                                               a4, a5, a6);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -1125,8 +1009,8 @@
 void StoreIC::GenerateMiss(MacroAssembler* masm) {
   __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
   // Perform tail call to the entry.
-  ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss),
-                                            masm->isolate());
+  ExternalReference ref =
+      ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate());
   __ TailCallExternalReference(ref, 3, 1);
 }
 
@@ -1152,18 +1036,6 @@
 }
 
 
-void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictMode strict_mode) {
-  __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
-
-  __ li(a0, Operand(Smi::FromInt(strict_mode)));
-  __ Push(a0);
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
 #undef __
 
 
@@ -1196,7 +1068,7 @@
   // was inlined.
   Instr instr = Assembler::instr_at(andi_instruction_address);
   return Assembler::IsAndImmediate(instr) &&
-      Assembler::GetRt(instr) == static_cast<uint32_t>(zero_reg.code());
+         Assembler::GetRt(instr) == static_cast<uint32_t>(zero_reg.code());
 }
 
 
@@ -1223,8 +1095,8 @@
   }
 
   if (FLAG_trace_ic) {
-    PrintF("[  patching ic at %p, andi=%p, delta=%d\n",
-           address, andi_instruction_address, delta);
+    PrintF("[  patching ic at %p, andi=%p, delta=%d\n", address,
+           andi_instruction_address, delta);
   }
 
   Address patch_address =
@@ -1259,8 +1131,7 @@
     patcher.ChangeBranchCondition(eq);
   }
 }
-
-
-} }  // namespace v8::internal
+}
+}  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_MIPS64
diff --git a/src/ic/mips64/stub-cache-mips64.cc b/src/ic/mips64/stub-cache-mips64.cc
new file mode 100644
index 0000000..6d3fcb3
--- /dev/null
+++ b/src/ic/mips64/stub-cache-mips64.cc
@@ -0,0 +1,168 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS64
+
+#include "src/codegen.h"
+#include "src/ic/stub-cache.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
+                       Code::Flags flags, StubCache::Table table,
+                       Register receiver, Register name,
+                       // Number of the cache entry, not scaled.
+                       Register offset, Register scratch, Register scratch2,
+                       Register offset_scratch) {
+  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
+  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
+  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
+
+  uint64_t key_off_addr = reinterpret_cast<uint64_t>(key_offset.address());
+  uint64_t value_off_addr = reinterpret_cast<uint64_t>(value_offset.address());
+  uint64_t map_off_addr = reinterpret_cast<uint64_t>(map_offset.address());
+
+  // Check the relative positions of the address fields.
+  DCHECK(value_off_addr > key_off_addr);
+  DCHECK((value_off_addr - key_off_addr) % 4 == 0);
+  DCHECK((value_off_addr - key_off_addr) < (256 * 4));
+  DCHECK(map_off_addr > key_off_addr);
+  DCHECK((map_off_addr - key_off_addr) % 4 == 0);
+  DCHECK((map_off_addr - key_off_addr) < (256 * 4));
+
+  Label miss;
+  Register base_addr = scratch;
+  scratch = no_reg;
+
+  // Multiply by 3 because there are 3 fields per entry (name, code, map).
+  __ dsll(offset_scratch, offset, 1);
+  __ Daddu(offset_scratch, offset_scratch, offset);
+
+  // Calculate the base address of the entry.
+  __ li(base_addr, Operand(key_offset));
+  __ dsll(at, offset_scratch, kPointerSizeLog2);
+  __ Daddu(base_addr, base_addr, at);
+
+  // Check that the key in the entry matches the name.
+  __ ld(at, MemOperand(base_addr, 0));
+  __ Branch(&miss, ne, name, Operand(at));
+
+  // Check the map matches.
+  __ ld(at, MemOperand(base_addr, map_off_addr - key_off_addr));
+  __ ld(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ Branch(&miss, ne, at, Operand(scratch2));
+
+  // Get the code entry from the cache.
+  Register code = scratch2;
+  scratch2 = no_reg;
+  __ ld(code, MemOperand(base_addr, value_off_addr - key_off_addr));
+
+  // Check that the flags match what we're looking for.
+  Register flags_reg = base_addr;
+  base_addr = no_reg;
+  __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset));
+  __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup));
+  __ Branch(&miss, ne, flags_reg, Operand(flags));
+
+#ifdef DEBUG
+  if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
+    __ jmp(&miss);
+  } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
+    __ jmp(&miss);
+  }
+#endif
+
+  // Jump to the first instruction in the code stub.
+  __ Daddu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ Jump(at);
+
+  // Miss: fall through.
+  __ bind(&miss);
+}
+
+
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
+  Isolate* isolate = masm->isolate();
+  Label miss;
+
+  // Make sure that code is valid. The multiplying code relies on the
+  // entry size being 12.
+  // DCHECK(sizeof(Entry) == 12);
+  // DCHECK(sizeof(Entry) == 3 * kPointerSize);
+
+  // Make sure the flags does not name a specific type.
+  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
+
+  // Make sure that there are no register conflicts.
+  DCHECK(!scratch.is(receiver));
+  DCHECK(!scratch.is(name));
+  DCHECK(!extra.is(receiver));
+  DCHECK(!extra.is(name));
+  DCHECK(!extra.is(scratch));
+  DCHECK(!extra2.is(receiver));
+  DCHECK(!extra2.is(name));
+  DCHECK(!extra2.is(scratch));
+  DCHECK(!extra2.is(extra));
+
+  // Check register validity.
+  DCHECK(!scratch.is(no_reg));
+  DCHECK(!extra.is(no_reg));
+  DCHECK(!extra2.is(no_reg));
+  DCHECK(!extra3.is(no_reg));
+
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
+                      extra3);
+
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, &miss);
+
+  // Get the map of the receiver and compute the hash.
+  __ ld(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
+  __ ld(at, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ Daddu(scratch, scratch, at);
+  uint64_t mask = kPrimaryTableSize - 1;
+  // We shift out the last two bits because they are not part of the hash and
+  // they are always 01 for maps.
+  __ dsrl(scratch, scratch, kCacheIndexShift);
+  __ Xor(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask));
+  __ And(scratch, scratch, Operand(mask));
+
+  // Probe the primary table.
+  ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch, extra,
+             extra2, extra3);
+
+  // Primary miss: Compute hash for secondary probe.
+  __ dsrl(at, name, kCacheIndexShift);
+  __ Dsubu(scratch, scratch, at);
+  uint64_t mask2 = kSecondaryTableSize - 1;
+  __ Daddu(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask2));
+  __ And(scratch, scratch, Operand(mask2));
+
+  // Probe the secondary table.
+  ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch, extra,
+             extra2, extra3);
+
+  // Cache miss: Fall-through and let caller handle the miss by
+  // entering the runtime system.
+  __ bind(&miss);
+  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2,
+                      extra3);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_MIPS64
diff --git a/src/ic/x64/handler-compiler-x64.cc b/src/ic/x64/handler-compiler-x64.cc
new file mode 100644
index 0000000..d332bb4
--- /dev/null
+++ b/src/ic/x64/handler-compiler-x64.cc
@@ -0,0 +1,878 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_X64
+
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
+    MacroAssembler* masm, Label* miss_label, Register receiver,
+    Handle<Name> name, Register scratch0, Register scratch1) {
+  DCHECK(name->IsUniqueName());
+  DCHECK(!receiver.is(scratch0));
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->negative_lookups(), 1);
+  __ IncrementCounter(counters->negative_lookups_miss(), 1);
+
+  __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
+
+  const int kInterceptorOrAccessCheckNeededMask =
+      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
+
+  // Bail out if the receiver has a named interceptor or requires access checks.
+  __ testb(FieldOperand(scratch0, Map::kBitFieldOffset),
+           Immediate(kInterceptorOrAccessCheckNeededMask));
+  __ j(not_zero, miss_label);
+
+  // Check that receiver is a JSObject.
+  __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE);
+  __ j(below, miss_label);
+
+  // Load properties array.
+  Register properties = scratch0;
+  __ movp(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
+
+  // Check that the properties array is a dictionary.
+  __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset),
+                 Heap::kHashTableMapRootIndex);
+  __ j(not_equal, miss_label);
+
+  Label done;
+  NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done,
+                                                   properties, name, scratch1);
+  __ bind(&done);
+  __ DecrementCounter(counters->negative_lookups_miss(), 1);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
+    MacroAssembler* masm, int index, Register prototype, Label* miss) {
+  Isolate* isolate = masm->isolate();
+  // Get the global function with the given index.
+  Handle<JSFunction> function(
+      JSFunction::cast(isolate->native_context()->get(index)));
+
+  // Check we're still in the same context.
+  Register scratch = prototype;
+  const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
+  __ movp(scratch, Operand(rsi, offset));
+  __ movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
+  __ Cmp(Operand(scratch, Context::SlotOffset(index)), function);
+  __ j(not_equal, miss);
+
+  // Load its initial map. The global functions all have initial maps.
+  __ Move(prototype, Handle<Map>(function->initial_map()));
+  // Load the prototype from the initial map.
+  __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
+    MacroAssembler* masm, Register receiver, Register result, Register scratch,
+    Label* miss_label) {
+  __ TryGetFunctionPrototype(receiver, result, miss_label);
+  if (!result.is(rax)) __ movp(rax, result);
+  __ ret(0);
+}
+
+
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
+                                     Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
+  __ Push(name);
+  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
+  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
+  __ Move(kScratchRegister, interceptor);
+  __ Push(kScratchRegister);
+  __ Push(receiver);
+  __ Push(holder);
+}
+
+
+static void CompileCallLoadPropertyWithInterceptor(
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
+  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
+  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
+                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
+}
+
+
+// Generate call to api function.
+void PropertyHandlerCompiler::GenerateFastApiCall(
+    MacroAssembler* masm, const CallOptimization& optimization,
+    Handle<Map> receiver_map, Register receiver, Register scratch_in,
+    bool is_store, int argc, Register* values) {
+  DCHECK(optimization.is_simple_api_call());
+
+  __ PopReturnAddressTo(scratch_in);
+  // receiver
+  __ Push(receiver);
+  // Write the arguments to stack frame.
+  for (int i = 0; i < argc; i++) {
+    Register arg = values[argc - 1 - i];
+    DCHECK(!receiver.is(arg));
+    DCHECK(!scratch_in.is(arg));
+    __ Push(arg);
+  }
+  __ PushReturnAddressFrom(scratch_in);
+  // Stack now matches JSFunction abi.
+
+  // Abi for CallApiFunctionStub.
+  Register callee = rax;
+  Register call_data = rbx;
+  Register holder = rcx;
+  Register api_function_address = rdx;
+  Register scratch = rdi;  // scratch_in is no longer valid.
+
+  // Put holder in place.
+  CallOptimization::HolderLookup holder_lookup;
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  switch (holder_lookup) {
+    case CallOptimization::kHolderIsReceiver:
+      __ Move(holder, receiver);
+      break;
+    case CallOptimization::kHolderFound:
+      __ Move(holder, api_holder);
+      break;
+    case CallOptimization::kHolderNotFound:
+      UNREACHABLE();
+      break;
+  }
+
+  Isolate* isolate = masm->isolate();
+  Handle<JSFunction> function = optimization.constant_function();
+  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
+  Handle<Object> call_data_obj(api_call_info->data(), isolate);
+
+  // Put callee in place.
+  __ Move(callee, function);
+
+  bool call_data_undefined = false;
+  // Put call_data in place.
+  if (isolate->heap()->InNewSpace(*call_data_obj)) {
+    __ Move(scratch, api_call_info);
+    __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset));
+  } else if (call_data_obj->IsUndefined()) {
+    call_data_undefined = true;
+    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
+  } else {
+    __ Move(call_data, call_data_obj);
+  }
+
+  // Put api_function_address in place.
+  Address function_address = v8::ToCData<Address>(api_call_info->callback());
+  __ Move(api_function_address, function_address,
+          RelocInfo::EXTERNAL_REFERENCE);
+
+  // Jump to stub.
+  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
+  __ TailCallStub(&stub);
+}
+
+
+void PropertyHandlerCompiler::GenerateCheckPropertyCell(
+    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
+    Register scratch, Label* miss) {
+  Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
+  DCHECK(cell->value()->IsTheHole());
+  __ Move(scratch, cell);
+  __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
+         masm->isolate()->factory()->the_hole_value());
+  __ j(not_equal, miss);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> setter) {
+  // ----------- S t a t e -------------
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Save value register, so we can restore it later.
+    __ Push(value());
+
+    if (!setter.is_null()) {
+      // Call the JavaScript setter with receiver and value on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ movp(receiver,
+                FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver);
+      __ Push(value());
+      ParameterCount actual(1);
+      ParameterCount expected(setter);
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // We have to return the passed value, not the return value of the setter.
+    __ Pop(rax);
+
+    // Restore context register.
+    __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+  }
+  __ ret(0);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> getter) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    if (!getter.is_null()) {
+      // Call the JavaScript getter with the receiver on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ movp(receiver,
+                FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver);
+      ParameterCount actual(0);
+      ParameterCount expected(getter);
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // Restore context register.
+    __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+  }
+  __ ret(0);
+}
+
+
+void ElementHandlerCompiler::GenerateLoadDictionaryElement(
+    MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rcx    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  DCHECK(rdx.is(LoadIC::ReceiverRegister()));
+  DCHECK(rcx.is(LoadIC::NameRegister()));
+  Label slow, miss;
+
+  // This stub is meant to be tail-jumped to, the receiver must already
+  // have been verified by the caller to not be a smi.
+
+  __ JumpIfNotSmi(rcx, &miss);
+  __ SmiToInteger32(rbx, rcx);
+  __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset));
+
+  // Check whether the elements is a number dictionary.
+  // rdx: receiver
+  // rcx: key
+  // rbx: key as untagged int32
+  // rax: elements
+  __ LoadFromNumberDictionary(&slow, rax, rcx, rbx, r9, rdi, rax);
+  __ ret(0);
+
+  __ bind(&slow);
+  // ----------- S t a t e -------------
+  //  -- rcx    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
+
+  __ bind(&miss);
+  // ----------- S t a t e -------------
+  //  -- rcx    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
+}
+
+
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  Register value = StoreIC::ValueRegister();
+
+  DCHECK(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value));
+
+  __ PopReturnAddressTo(rbx);
+  __ Push(receiver);
+  __ Push(name);
+  __ Push(value);
+  __ PushReturnAddressFrom(rbx);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
+  // Return address is on the stack.
+  StoreIC_PushArgs(masm);
+
+  // Do tail-call to runtime routine.
+  ExternalReference ref(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
+  // Return address is on the stack.
+  StoreIC_PushArgs(masm);
+
+  // Do tail-call to runtime routine.
+  ExternalReference ref(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+#undef __
+#define __ ACCESS_MASM((masm()))
+
+
+void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
+                                                    Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ bind(label);
+    __ Move(this->name(), name);
+  }
+}
+
+
+// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
+// store is successful.
+void NamedStoreHandlerCompiler::GenerateStoreTransition(
+    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
+    Register storage_reg, Register value_reg, Register scratch1,
+    Register scratch2, Register unused, Label* miss_label, Label* slow) {
+  int descriptor = transition->LastAdded();
+  DescriptorArray* descriptors = transition->instance_descriptors();
+  PropertyDetails details = descriptors->GetDetails(descriptor);
+  Representation representation = details.representation();
+  DCHECK(!representation.IsNone());
+
+  if (details.type() == CONSTANT) {
+    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
+    __ Cmp(value_reg, constant);
+    __ j(not_equal, miss_label);
+  } else if (representation.IsSmi()) {
+    __ JumpIfNotSmi(value_reg, miss_label);
+  } else if (representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_label);
+    HeapType* field_type = descriptors->GetFieldType(descriptor);
+    HeapType::Iterator<Map> it = field_type->Classes();
+    if (!it.Done()) {
+      Label do_store;
+      while (true) {
+        __ CompareMap(value_reg, it.Current());
+        it.Advance();
+        if (it.Done()) {
+          __ j(not_equal, miss_label);
+          break;
+        }
+        __ j(equal, &do_store, Label::kNear);
+      }
+      __ bind(&do_store);
+    }
+  } else if (representation.IsDouble()) {
+    Label do_store, heap_number;
+    __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE);
+
+    __ JumpIfNotSmi(value_reg, &heap_number);
+    __ SmiToInteger32(scratch1, value_reg);
+    __ Cvtlsi2sd(xmm0, scratch1);
+    __ jmp(&do_store);
+
+    __ bind(&heap_number);
+    __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
+                DONT_DO_SMI_CHECK);
+    __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
+
+    __ bind(&do_store);
+    __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
+  }
+
+  // Stub never generated for objects that require access checks.
+  DCHECK(!transition->is_access_check_needed());
+
+  // Perform map transition for the receiver if necessary.
+  if (details.type() == FIELD &&
+      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
+    // The properties must be extended before we can store the value.
+    // We jump to a runtime call that extends the properties array.
+    __ PopReturnAddressTo(scratch1);
+    __ Push(receiver_reg);
+    __ Push(transition);
+    __ Push(value_reg);
+    __ PushReturnAddressFrom(scratch1);
+    __ TailCallExternalReference(
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
+                          isolate()),
+        3, 1);
+    return;
+  }
+
+  // Update the map of the object.
+  __ Move(scratch1, transition);
+  __ movp(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
+
+  // Update the write barrier for the map field.
+  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
+                      kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+
+  if (details.type() == CONSTANT) {
+    DCHECK(value_reg.is(rax));
+    __ ret(0);
+    return;
+  }
+
+  int index = transition->instance_descriptors()->GetFieldIndex(
+      transition->LastAdded());
+
+  // Adjust for the number of properties stored in the object. Even in the
+  // face of a transition we can use the old map here because the size of the
+  // object and the number of in-object properties is not going to change.
+  index -= transition->inobject_properties();
+
+  // TODO(verwaest): Share this code as a code stub.
+  SmiCheck smi_check =
+      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  if (index < 0) {
+    // Set the property straight into the object.
+    int offset = transition->instance_size() + (index * kPointerSize);
+    if (representation.IsDouble()) {
+      __ movp(FieldOperand(receiver_reg, offset), storage_reg);
+    } else {
+      __ movp(FieldOperand(receiver_reg, offset), value_reg);
+    }
+
+    if (!representation.IsSmi()) {
+      // Update the write barrier for the array address.
+      if (!representation.IsDouble()) {
+        __ movp(storage_reg, value_reg);
+      }
+      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
+                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
+    }
+  } else {
+    // Write to the properties array.
+    int offset = index * kPointerSize + FixedArray::kHeaderSize;
+    // Get the properties array (optimistically).
+    __ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
+    if (representation.IsDouble()) {
+      __ movp(FieldOperand(scratch1, offset), storage_reg);
+    } else {
+      __ movp(FieldOperand(scratch1, offset), value_reg);
+    }
+
+    if (!representation.IsSmi()) {
+      // Update the write barrier for the array address.
+      if (!representation.IsDouble()) {
+        __ movp(storage_reg, value_reg);
+      }
+      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
+                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
+    }
+  }
+
+  // Return the value (register rax).
+  DCHECK(value_reg.is(rax));
+  __ ret(0);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
+                                                   Register value_reg,
+                                                   Label* miss_label) {
+  DCHECK(lookup->representation().IsHeapObject());
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
+  Label do_store;
+  while (true) {
+    __ CompareMap(value_reg, it.Current());
+    it.Advance();
+    if (it.Done()) {
+      __ j(not_equal, miss_label);
+      break;
+    }
+    __ j(equal, &do_store, Label::kNear);
+  }
+  __ bind(&do_store);
+
+  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
+                      lookup->representation());
+  GenerateTailCall(masm(), stub.GetCode());
+}
+
+
+Register PropertyHandlerCompiler::CheckPrototypes(
+    Register object_reg, Register holder_reg, Register scratch1,
+    Register scratch2, Handle<Name> name, Label* miss,
+    PrototypeCheckType check) {
+  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
+
+  // Make sure there's no overlap between holder and object registers.
+  DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
+  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
+         !scratch2.is(scratch1));
+
+  // Keep track of the current object in register reg.  On the first
+  // iteration, reg is an alias for object_reg, on later iterations,
+  // it is an alias for holder_reg.
+  Register reg = object_reg;
+  int depth = 0;
+
+  Handle<JSObject> current = Handle<JSObject>::null();
+  if (type()->IsConstant()) {
+    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
+  }
+  Handle<JSObject> prototype = Handle<JSObject>::null();
+  Handle<Map> current_map = receiver_map;
+  Handle<Map> holder_map(holder()->map());
+  // Traverse the prototype chain and check the maps in the prototype chain for
+  // fast and global objects or do negative lookup for normal objects.
+  while (!current_map.is_identical_to(holder_map)) {
+    ++depth;
+
+    // Only global objects and objects that do not require access
+    // checks are allowed in stubs.
+    DCHECK(current_map->IsJSGlobalProxyMap() ||
+           !current_map->is_access_check_needed());
+
+    prototype = handle(JSObject::cast(current_map->prototype()));
+    if (current_map->is_dictionary_map() &&
+        !current_map->IsJSGlobalObjectMap()) {
+      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
+      if (!name->IsUniqueName()) {
+        DCHECK(name->IsString());
+        name = factory()->InternalizeString(Handle<String>::cast(name));
+      }
+      DCHECK(current.is_null() ||
+             current->property_dictionary()->FindEntry(name) ==
+                 NameDictionary::kNotFound);
+
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
+
+      __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+      __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
+    } else {
+      bool in_new_space = heap()->InNewSpace(*prototype);
+      // Two possible reasons for loading the prototype from the map:
+      // (1) Can't store references to new space in code.
+      // (2) Handler is shared for all receivers with the same prototype
+      //     map (but not necessarily the same prototype instance).
+      bool load_prototype_from_map = in_new_space || depth == 1;
+      if (load_prototype_from_map) {
+        // Save the map in scratch1 for later.
+        __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+      }
+      if (depth != 1 || check == CHECK_ALL_MAPS) {
+        __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+      }
+
+      // Check access rights to the global object.  This has to happen after
+      // the map check so that we know that the object is actually a global
+      // object.
+      // This allows us to install generated handlers for accesses to the
+      // global proxy (as opposed to using slow ICs). See corresponding code
+      // in LookupForRead().
+      if (current_map->IsJSGlobalProxyMap()) {
+        __ CheckAccessGlobalProxy(reg, scratch2, miss);
+      } else if (current_map->IsJSGlobalObjectMap()) {
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
+      }
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+
+      if (load_prototype_from_map) {
+        __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
+      } else {
+        __ Move(reg, prototype);
+      }
+    }
+
+    // Go to the next object in the prototype chain.
+    current = prototype;
+    current_map = handle(current->map());
+  }
+
+  // Log the check depth.
+  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
+
+  if (depth != 0 || check == CHECK_ALL_MAPS) {
+    // Check the holder map.
+    __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+  }
+
+  // Perform security check for access to the global object.
+  DCHECK(current_map->IsJSGlobalProxyMap() ||
+         !current_map->is_access_check_needed());
+  if (current_map->IsJSGlobalProxyMap()) {
+    __ CheckAccessGlobalProxy(reg, scratch1, miss);
+  }
+
+  // Return the register containing the holder.
+  return reg;
+}
+
+
+void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ jmp(&success);
+    __ bind(miss);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+    __ bind(&success);
+  }
+}
+
+
+void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ jmp(&success);
+    GenerateRestoreName(miss, name);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+    __ bind(&success);
+  }
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadCallback(
+    Register reg, Handle<ExecutableAccessorInfo> callback) {
+  // Insert additional parameters into the stack frame above return address.
+  DCHECK(!scratch4().is(reg));
+  __ PopReturnAddressTo(scratch4());
+
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
+  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
+  __ Push(receiver());  // receiver
+  if (heap()->InNewSpace(callback->data())) {
+    DCHECK(!scratch2().is(reg));
+    __ Move(scratch2(), callback);
+    __ Push(FieldOperand(scratch2(),
+                         ExecutableAccessorInfo::kDataOffset));  // data
+  } else {
+    __ Push(Handle<Object>(callback->data(), isolate()));
+  }
+  DCHECK(!kScratchRegister.is(reg));
+  __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
+  __ Push(kScratchRegister);  // return value
+  __ Push(kScratchRegister);  // return value default
+  __ PushAddress(ExternalReference::isolate_address(isolate()));
+  __ Push(reg);     // holder
+  __ Push(name());  // name
+  // Save a pointer to where we pushed the arguments pointer.  This will be
+  // passed as the const PropertyAccessorInfo& to the C++ callback.
+
+  __ PushReturnAddressFrom(scratch4());
+
+  // Abi for CallApiGetter
+  Register api_function_address = r8;
+  Address getter_address = v8::ToCData<Address>(callback->getter());
+  __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE);
+
+  CallApiGetterStub stub(isolate());
+  __ TailCallStub(&stub);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
+  // Return the constant value.
+  __ Move(rax, value);
+  __ ret(0);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
+    LookupIterator* it, Register holder_reg) {
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+
+  // Compile the interceptor call, followed by inline code to load the
+  // property from further up the prototype chain if the call fails.
+  // Check that the maps haven't changed.
+  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
+
+  // Preserve the receiver register explicitly whenever it is different from the
+  // holder and it is needed should the interceptor return without any result.
+  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
+  // case might cause a miss during the prototype check.
+  bool must_perform_prototype_check =
+      !holder().is_identical_to(it->GetHolder<JSObject>());
+  bool must_preserve_receiver_reg =
+      !receiver().is(holder_reg) &&
+      (it->property_kind() == LookupIterator::ACCESSOR ||
+       must_perform_prototype_check);
+
+  // Save necessary data before invoking an interceptor.
+  // Requires a frame to make GC aware of pushed pointers.
+  {
+    FrameScope frame_scope(masm(), StackFrame::INTERNAL);
+
+    if (must_preserve_receiver_reg) {
+      __ Push(receiver());
+    }
+    __ Push(holder_reg);
+    __ Push(this->name());
+
+    // Invoke an interceptor.  Note: map checks from receiver to
+    // interceptor's holder has been compiled before (see a caller
+    // of this method.)
+    CompileCallLoadPropertyWithInterceptor(
+        masm(), receiver(), holder_reg, this->name(), holder(),
+        IC::kLoadPropertyWithInterceptorOnly);
+
+    // Check if interceptor provided a value for property.  If it's
+    // the case, return immediately.
+    Label interceptor_failed;
+    __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
+    __ j(equal, &interceptor_failed);
+    frame_scope.GenerateLeaveFrame();
+    __ ret(0);
+
+    __ bind(&interceptor_failed);
+    __ Pop(this->name());
+    __ Pop(holder_reg);
+    if (must_preserve_receiver_reg) {
+      __ Pop(receiver());
+    }
+
+    // Leave the internal frame.
+  }
+
+  GenerateLoadPostInterceptor(it, holder_reg);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
+  // Call the runtime system to load the interceptor.
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+  __ PopReturnAddressTo(scratch2());
+  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
+                           holder());
+  __ PushReturnAddressFrom(scratch2());
+
+  ExternalReference ref = ExternalReference(
+      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(
+      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
+    Handle<JSObject> object, Handle<Name> name,
+    Handle<ExecutableAccessorInfo> callback) {
+  Register holder_reg = Frontend(receiver(), name);
+
+  __ PopReturnAddressTo(scratch1());
+  __ Push(receiver());
+  __ Push(holder_reg);
+  __ Push(callback);  // callback info
+  __ Push(name);
+  __ Push(value());
+  __ PushReturnAddressFrom(scratch1());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_callback_property =
+      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
+  __ TailCallExternalReference(store_callback_property, 5, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
+    Handle<Name> name) {
+  __ PopReturnAddressTo(scratch1());
+  __ Push(receiver());
+  __ Push(this->name());
+  __ Push(value());
+  __ PushReturnAddressFrom(scratch1());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_ic_property = ExternalReference(
+      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(store_ic_property, 3, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
+    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
+  Label miss;
+  FrontendHeader(receiver(), name, &miss);
+
+  // Get the value from the cell.
+  Register result = StoreIC::ValueRegister();
+  __ Move(result, cell);
+  __ movp(result, FieldOperand(result, PropertyCell::kValueOffset));
+
+  // Check for deleted property if property can actually be deleted.
+  if (is_configurable) {
+    __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
+    __ j(equal, &miss);
+  } else if (FLAG_debug_code) {
+    __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
+    __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
+  }
+
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->named_load_global_stub(), 1);
+  __ ret(0);
+
+  FrontendFooter(name, &miss);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, name);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_X64
diff --git a/src/ic/x64/ic-compiler-x64.cc b/src/ic/x64/ic-compiler-x64.cc
index 793bd0e..b2b02fb 100644
--- a/src/ic/x64/ic-compiler-x64.cc
+++ b/src/ic/x64/ic-compiler-x64.cc
@@ -6,7 +6,6 @@
 
 #if V8_TARGET_ARCH_X64
 
-#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
@@ -15,697 +14,21 @@
 #define __ ACCESS_MASM(masm)
 
 
-void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
-    MacroAssembler* masm, Label* miss_label, Register receiver,
-    Handle<Name> name, Register scratch0, Register scratch1) {
-  DCHECK(name->IsUniqueName());
-  DCHECK(!receiver.is(scratch0));
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->negative_lookups(), 1);
-  __ IncrementCounter(counters->negative_lookups_miss(), 1);
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  // Return address is on the stack.
+  DCHECK(!rbx.is(StoreIC::ReceiverRegister()) &&
+         !rbx.is(StoreIC::NameRegister()) && !rbx.is(StoreIC::ValueRegister()));
 
-  __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
+  __ PopReturnAddressTo(rbx);
+  __ Push(StoreIC::ReceiverRegister());
+  __ Push(StoreIC::NameRegister());
+  __ Push(StoreIC::ValueRegister());
+  __ Push(Smi::FromInt(strict_mode));
+  __ PushReturnAddressFrom(rbx);
 
-  const int kInterceptorOrAccessCheckNeededMask =
-      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
-
-  // Bail out if the receiver has a named interceptor or requires access checks.
-  __ testb(FieldOperand(scratch0, Map::kBitFieldOffset),
-           Immediate(kInterceptorOrAccessCheckNeededMask));
-  __ j(not_zero, miss_label);
-
-  // Check that receiver is a JSObject.
-  __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE);
-  __ j(below, miss_label);
-
-  // Load properties array.
-  Register properties = scratch0;
-  __ movp(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
-
-  // Check that the properties array is a dictionary.
-  __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset),
-                 Heap::kHashTableMapRootIndex);
-  __ j(not_equal, miss_label);
-
-  Label done;
-  NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done,
-                                                   properties, name, scratch1);
-  __ bind(&done);
-  __ DecrementCounter(counters->negative_lookups_miss(), 1);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
-  // Check we're still in the same context.
-  Register scratch = prototype;
-  const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ movp(scratch, Operand(rsi, offset));
-  __ movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ Cmp(Operand(scratch, Context::SlotOffset(index)), function);
-  __ j(not_equal, miss);
-
-  // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Handle<Map>(function->initial_map()));
-  // Load the prototype from the initial map.
-  __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
-    MacroAssembler* masm, Register receiver, Register result, Register scratch,
-    Label* miss_label) {
-  __ TryGetFunctionPrototype(receiver, result, miss_label);
-  if (!result.is(rax)) __ movp(rax, result);
-  __ ret(0);
-}
-
-
-static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
-                                     Register holder, Register name,
-                                     Handle<JSObject> holder_obj) {
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
-  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
-  __ Push(name);
-  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
-  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
-  __ Move(kScratchRegister, interceptor);
-  __ Push(kScratchRegister);
-  __ Push(receiver);
-  __ Push(holder);
-}
-
-
-static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm, Register receiver, Register holder, Register name,
-    Handle<JSObject> holder_obj, IC::UtilityId id) {
-  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
-                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
-}
-
-
-// Generate call to api function.
-void PropertyHandlerCompiler::GenerateFastApiCall(
-    MacroAssembler* masm, const CallOptimization& optimization,
-    Handle<Map> receiver_map, Register receiver, Register scratch_in,
-    bool is_store, int argc, Register* values) {
-  DCHECK(optimization.is_simple_api_call());
-
-  __ PopReturnAddressTo(scratch_in);
-  // receiver
-  __ Push(receiver);
-  // Write the arguments to stack frame.
-  for (int i = 0; i < argc; i++) {
-    Register arg = values[argc - 1 - i];
-    DCHECK(!receiver.is(arg));
-    DCHECK(!scratch_in.is(arg));
-    __ Push(arg);
-  }
-  __ PushReturnAddressFrom(scratch_in);
-  // Stack now matches JSFunction abi.
-
-  // Abi for CallApiFunctionStub.
-  Register callee = rax;
-  Register call_data = rbx;
-  Register holder = rcx;
-  Register api_function_address = rdx;
-  Register scratch = rdi;  // scratch_in is no longer valid.
-
-  // Put holder in place.
-  CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
-  switch (holder_lookup) {
-    case CallOptimization::kHolderIsReceiver:
-      __ Move(holder, receiver);
-      break;
-    case CallOptimization::kHolderFound:
-      __ Move(holder, api_holder);
-      break;
-    case CallOptimization::kHolderNotFound:
-      UNREACHABLE();
-      break;
-  }
-
-  Isolate* isolate = masm->isolate();
-  Handle<JSFunction> function = optimization.constant_function();
-  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
-  Handle<Object> call_data_obj(api_call_info->data(), isolate);
-
-  // Put callee in place.
-  __ Move(callee, function);
-
-  bool call_data_undefined = false;
-  // Put call_data in place.
-  if (isolate->heap()->InNewSpace(*call_data_obj)) {
-    __ Move(scratch, api_call_info);
-    __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset));
-  } else if (call_data_obj->IsUndefined()) {
-    call_data_undefined = true;
-    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
-  } else {
-    __ Move(call_data, call_data_obj);
-  }
-
-  // Put api_function_address in place.
-  Address function_address = v8::ToCData<Address>(api_call_info->callback());
-  __ Move(api_function_address, function_address,
-          RelocInfo::EXTERNAL_REFERENCE);
-
-  // Jump to stub.
-  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
-  __ TailCallStub(&stub);
-}
-
-
-void PropertyHandlerCompiler::GenerateCheckPropertyCell(
-    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
-    Register scratch, Label* miss) {
-  Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
-  DCHECK(cell->value()->IsTheHole());
-  __ Move(scratch, cell);
-  __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
-         masm->isolate()->factory()->the_hole_value());
-  __ j(not_equal, miss);
-}
-
-
-#undef __
-#define __ ACCESS_MASM((masm()))
-
-
-void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
-                                                    Handle<Name> name) {
-  if (!label->is_unused()) {
-    __ bind(label);
-    __ Move(this->name(), name);
-  }
-}
-
-
-// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
-// store is successful.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register unused, Label* miss_label, Label* slow) {
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ Cmp(value_reg, constant);
-    __ j(not_equal, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      Label do_store;
-      while (true) {
-        __ CompareMap(value_reg, it.Current());
-        it.Advance();
-        if (it.Done()) {
-          __ j(not_equal, miss_label);
-          break;
-        }
-        __ j(equal, &do_store, Label::kNear);
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiToInteger32(scratch1, value_reg);
-    __ Cvtlsi2sd(xmm0, scratch1);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
-                DONT_DO_SMI_CHECK);
-    __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ PopReturnAddressTo(scratch1);
-    __ Push(receiver_reg);
-    __ Push(transition);
-    __ Push(value_reg);
-    __ PushReturnAddressFrom(scratch1);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ Move(scratch1, transition);
-  __ movp(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(rax));
-    __ ret(0);
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ movp(FieldOperand(receiver_reg, offset), storage_reg);
-    } else {
-      __ movp(FieldOperand(receiver_reg, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ movp(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array (optimistically).
-    __ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ movp(FieldOperand(scratch1, offset), storage_reg);
-    } else {
-      __ movp(FieldOperand(scratch1, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ movp(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register rax).
-  DCHECK(value_reg.is(rax));
-  __ ret(0);
-}
-
-
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  Label do_store;
-  while (true) {
-    __ CompareMap(value_reg, it.Current());
-    it.Advance();
-    if (it.Done()) {
-      __ j(not_equal, miss_label);
-      break;
-    }
-    __ j(equal, &do_store, Label::kNear);
-  }
-  __ bind(&do_store);
-
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
-}
-
-
-Register PropertyHandlerCompiler::CheckPrototypes(
-    Register object_reg, Register holder_reg, Register scratch1,
-    Register scratch2, Handle<Name> name, Label* miss,
-    PrototypeCheckType check) {
-  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
-
-  // Make sure there's no overlap between holder and object registers.
-  DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
-         !scratch2.is(scratch1));
-
-  // Keep track of the current object in register reg.  On the first
-  // iteration, reg is an alias for object_reg, on later iterations,
-  // it is an alias for holder_reg.
-  Register reg = object_reg;
-  int depth = 0;
-
-  Handle<JSObject> current = Handle<JSObject>::null();
-  if (type()->IsConstant()) {
-    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
-  }
-  Handle<JSObject> prototype = Handle<JSObject>::null();
-  Handle<Map> current_map = receiver_map;
-  Handle<Map> holder_map(holder()->map());
-  // Traverse the prototype chain and check the maps in the prototype chain for
-  // fast and global objects or do negative lookup for normal objects.
-  while (!current_map.is_identical_to(holder_map)) {
-    ++depth;
-
-    // Only global objects and objects that do not require access
-    // checks are allowed in stubs.
-    DCHECK(current_map->IsJSGlobalProxyMap() ||
-           !current_map->is_access_check_needed());
-
-    prototype = handle(JSObject::cast(current_map->prototype()));
-    if (current_map->is_dictionary_map() &&
-        !current_map->IsJSGlobalObjectMap()) {
-      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
-      if (!name->IsUniqueName()) {
-        DCHECK(name->IsString());
-        name = factory()->InternalizeString(Handle<String>::cast(name));
-      }
-      DCHECK(current.is_null() ||
-             current->property_dictionary()->FindEntry(name) ==
-                 NameDictionary::kNotFound);
-
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
-                                       scratch2);
-
-      __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-      __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-    } else {
-      bool in_new_space = heap()->InNewSpace(*prototype);
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map = in_new_space || depth == 1;
-      if (load_prototype_from_map) {
-        // Save the map in scratch1 for later.
-        __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      }
-      if (depth != 1 || check == CHECK_ALL_MAPS) {
-        __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
-      }
-
-      // Check access rights to the global object.  This has to happen after
-      // the map check so that we know that the object is actually a global
-      // object.
-      // This allows us to install generated handlers for accesses to the
-      // global proxy (as opposed to using slow ICs). See corresponding code
-      // in LookupForRead().
-      if (current_map->IsJSGlobalProxyMap()) {
-        __ CheckAccessGlobalProxy(reg, scratch2, miss);
-      } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
-                                  name, scratch2, miss);
-      }
-      reg = holder_reg;  // From now on the object will be in holder_reg.
-
-      if (load_prototype_from_map) {
-        __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-      } else {
-        __ Move(reg, prototype);
-      }
-    }
-
-    // Go to the next object in the prototype chain.
-    current = prototype;
-    current_map = handle(current->map());
-  }
-
-  // Log the check depth.
-  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
-
-  if (depth != 0 || check == CHECK_ALL_MAPS) {
-    // Check the holder map.
-    __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
-  }
-
-  // Perform security check for access to the global object.
-  DCHECK(current_map->IsJSGlobalProxyMap() ||
-         !current_map->is_access_check_needed());
-  if (current_map->IsJSGlobalProxyMap()) {
-    __ CheckAccessGlobalProxy(reg, scratch1, miss);
-  }
-
-  // Return the register containing the holder.
-  return reg;
-}
-
-
-void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ jmp(&success);
-    __ bind(miss);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-    __ bind(&success);
-  }
-}
-
-
-void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
-  if (!miss->is_unused()) {
-    Label success;
-    __ jmp(&success);
-    GenerateRestoreName(miss, name);
-    TailCallBuiltin(masm(), MissBuiltin(kind()));
-    __ bind(&success);
-  }
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadCallback(
-    Register reg, Handle<ExecutableAccessorInfo> callback) {
-  // Insert additional parameters into the stack frame above return address.
-  DCHECK(!scratch4().is(reg));
-  __ PopReturnAddressTo(scratch4());
-
-  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
-  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
-  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
-  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
-  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
-  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
-  __ Push(receiver());  // receiver
-  if (heap()->InNewSpace(callback->data())) {
-    DCHECK(!scratch2().is(reg));
-    __ Move(scratch2(), callback);
-    __ Push(FieldOperand(scratch2(),
-                         ExecutableAccessorInfo::kDataOffset));  // data
-  } else {
-    __ Push(Handle<Object>(callback->data(), isolate()));
-  }
-  DCHECK(!kScratchRegister.is(reg));
-  __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
-  __ Push(kScratchRegister);  // return value
-  __ Push(kScratchRegister);  // return value default
-  __ PushAddress(ExternalReference::isolate_address(isolate()));
-  __ Push(reg);     // holder
-  __ Push(name());  // name
-  // Save a pointer to where we pushed the arguments pointer.  This will be
-  // passed as the const PropertyAccessorInfo& to the C++ callback.
-
-  __ PushReturnAddressFrom(scratch4());
-
-  // Abi for CallApiGetter
-  Register api_function_address = r8;
-  Address getter_address = v8::ToCData<Address>(callback->getter());
-  __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE);
-
-  CallApiGetterStub stub(isolate());
-  __ TailCallStub(&stub);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
-  // Return the constant value.
-  __ Move(rax, value);
-  __ ret(0);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
-    LookupIterator* it, Register holder_reg) {
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-
-  // Compile the interceptor call, followed by inline code to load the
-  // property from further up the prototype chain if the call fails.
-  // Check that the maps haven't changed.
-  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
-
-  // Preserve the receiver register explicitly whenever it is different from the
-  // holder and it is needed should the interceptor return without any result.
-  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
-  // case might cause a miss during the prototype check.
-  bool must_perform_prototype_check =
-      !holder().is_identical_to(it->GetHolder<JSObject>());
-  bool must_preserve_receiver_reg =
-      !receiver().is(holder_reg) &&
-      (it->property_kind() == LookupIterator::ACCESSOR ||
-       must_perform_prototype_check);
-
-  // Save necessary data before invoking an interceptor.
-  // Requires a frame to make GC aware of pushed pointers.
-  {
-    FrameScope frame_scope(masm(), StackFrame::INTERNAL);
-
-    if (must_preserve_receiver_reg) {
-      __ Push(receiver());
-    }
-    __ Push(holder_reg);
-    __ Push(this->name());
-
-    // Invoke an interceptor.  Note: map checks from receiver to
-    // interceptor's holder has been compiled before (see a caller
-    // of this method.)
-    CompileCallLoadPropertyWithInterceptor(
-        masm(), receiver(), holder_reg, this->name(), holder(),
-        IC::kLoadPropertyWithInterceptorOnly);
-
-    // Check if interceptor provided a value for property.  If it's
-    // the case, return immediately.
-    Label interceptor_failed;
-    __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
-    __ j(equal, &interceptor_failed);
-    frame_scope.GenerateLeaveFrame();
-    __ ret(0);
-
-    __ bind(&interceptor_failed);
-    __ Pop(this->name());
-    __ Pop(holder_reg);
-    if (must_preserve_receiver_reg) {
-      __ Pop(receiver());
-    }
-
-    // Leave the internal frame.
-  }
-
-  GenerateLoadPostInterceptor(it, holder_reg);
-}
-
-
-void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
-  // Call the runtime system to load the interceptor.
-  DCHECK(holder()->HasNamedInterceptor());
-  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
-  __ PopReturnAddressTo(scratch2());
-  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
-                           holder());
-  __ PushReturnAddressFrom(scratch2());
-
-  ExternalReference ref = ExternalReference(
-      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(
-      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
-}
-
-
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
-    Handle<JSObject> object, Handle<Name> name,
-    Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
-
-  __ PopReturnAddressTo(scratch1());
-  __ Push(receiver());
-  __ Push(holder_reg);
-  __ Push(callback);  // callback info
-  __ Push(name);
-  __ Push(value());
-  __ PushReturnAddressFrom(scratch1());
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_callback_property =
-      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
-  __ TailCallExternalReference(store_callback_property, 5, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Save value register, so we can restore it later.
-    __ Push(value());
-
-    if (!setter.is_null()) {
-      // Call the JavaScript setter with receiver and value on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ movp(receiver,
-                FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ Push(receiver);
-      __ Push(value());
-      ParameterCount actual(1);
-      ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // We have to return the passed value, not the return value of the setter.
-    __ Pop(rax);
-
-    // Restore context register.
-    __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
-  }
-  __ ret(0);
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
 }
 
 
@@ -713,24 +36,6 @@
 #define __ ACCESS_MASM(masm())
 
 
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
-    Handle<Name> name) {
-  __ PopReturnAddressTo(scratch1());
-  __ Push(receiver());
-  __ Push(this->name());
-  __ Push(value());
-  __ PushReturnAddressFrom(scratch1());
-
-  // Do tail-call to the runtime system.
-  ExternalReference store_ic_property = ExternalReference(
-      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
-  __ TailCallExternalReference(store_ic_property, 3, 1);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::FAST, name);
-}
-
-
 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
     MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
@@ -763,83 +68,6 @@
 }
 
 
-Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
-
-
-#undef __
-#define __ ACCESS_MASM(masm)
-
-
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
-    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    if (!getter.is_null()) {
-      // Call the JavaScript getter with the receiver on the stack.
-      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
-        // Swap in the global receiver.
-        __ movp(receiver,
-                FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
-      }
-      __ Push(receiver);
-      ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
-    } else {
-      // If we generate a global code snippet for deoptimization only, remember
-      // the place to continue after deoptimization.
-      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
-    }
-
-    // Restore context register.
-    __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
-  }
-  __ ret(0);
-}
-
-
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
-  Label miss;
-  FrontendHeader(receiver(), name, &miss);
-
-  // Get the value from the cell.
-  Register result = StoreIC::ValueRegister();
-  __ Move(result, cell);
-  __ movp(result, FieldOperand(result, PropertyCell::kValueOffset));
-
-  // Check for deleted property if property can actually be deleted.
-  if (is_configurable) {
-    __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
-    __ j(equal, &miss);
-  } else if (FLAG_debug_code) {
-    __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
-    __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
-  }
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->named_load_global_stub(), 1);
-  __ ret(0);
-
-  FrontendFooter(name, &miss);
-
-  // Return the generated code.
-  return GetCode(kind(), Code::NORMAL, name);
-}
-
-
 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
                                                     CodeHandleList* handlers,
                                                     Handle<Name> name,
@@ -897,72 +125,6 @@
 
 
 #undef __
-#define __ ACCESS_MASM(masm)
-
-
-void ElementHandlerCompiler::GenerateLoadDictionaryElement(
-    MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rcx    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  DCHECK(rdx.is(LoadIC::ReceiverRegister()));
-  DCHECK(rcx.is(LoadIC::NameRegister()));
-  Label slow, miss;
-
-  // This stub is meant to be tail-jumped to, the receiver must already
-  // have been verified by the caller to not be a smi.
-
-  __ JumpIfNotSmi(rcx, &miss);
-  __ SmiToInteger32(rbx, rcx);
-  __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset));
-
-  // Check whether the elements is a number dictionary.
-  // rdx: receiver
-  // rcx: key
-  // rbx: key as untagged int32
-  // rax: elements
-  __ LoadFromNumberDictionary(&slow, rax, rcx, rbx, r9, rdi, rax);
-  __ ret(0);
-
-  __ bind(&slow);
-  // ----------- S t a t e -------------
-  //  -- rcx    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
-
-  __ bind(&miss);
-  // ----------- S t a t e -------------
-  //  -- rcx    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
-}
-
-
-void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                                    StrictMode strict_mode) {
-  // Return address is on the stack.
-  DCHECK(!rbx.is(StoreIC::ReceiverRegister()) &&
-         !rbx.is(StoreIC::NameRegister()) && !rbx.is(StoreIC::ValueRegister()));
-
-  __ PopReturnAddressTo(rbx);
-  __ Push(StoreIC::ReceiverRegister());
-  __ Push(StoreIC::NameRegister());
-  __ Push(StoreIC::ValueRegister());
-  __ Push(Smi::FromInt(strict_mode));
-  __ PushReturnAddressFrom(rbx);
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
-#undef __
 }
 }  // namespace v8::internal
 
diff --git a/src/ic/x64/ic-x64.cc b/src/ic/x64/ic-x64.cc
index 1abb931..7516882 100644
--- a/src/ic/x64/ic-x64.cc
+++ b/src/ic/x64/ic-x64.cc
@@ -1012,26 +1012,6 @@
 }
 
 
-void StoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Return address is on the stack.
-  StoreIC_PushArgs(masm);
-
-  // Do tail-call to runtime routine.
-  ExternalReference ref(IC_Utility(kStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
-void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
-  // Return address is on the stack.
-  StoreIC_PushArgs(masm);
-
-  // Do tail-call to runtime routine.
-  ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
   // Return address is on the stack.
   StoreIC_PushArgs(masm);
diff --git a/src/ic/x87/OWNERS b/src/ic/x87/OWNERS
new file mode 100644
index 0000000..dd9998b
--- /dev/null
+++ b/src/ic/x87/OWNERS
@@ -0,0 +1 @@
+weiliang.lin@intel.com
diff --git a/src/ic/x87/access-compiler-x87.cc b/src/ic/x87/access-compiler-x87.cc
new file mode 100644
index 0000000..d30c257
--- /dev/null
+++ b/src/ic/x87/access-compiler-x87.cc
@@ -0,0 +1,44 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_X87
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ jmp(code, RelocInfo::CODE_TARGET);
+}
+
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadIC::ReceiverRegister();
+  Register name = LoadIC::NameRegister();
+  static Register registers[] = {receiver, name, ebx, eax, edi, no_reg};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3.
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  DCHECK(ebx.is(KeyedStoreIC::MapRegister()));
+  static Register registers[] = {receiver, name, ebx, edi, no_reg};
+  return registers;
+}
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_X87
diff --git a/src/x87/stub-cache-x87.cc b/src/ic/x87/ic-compiler-x87.cc
similarity index 76%
rename from src/x87/stub-cache-x87.cc
rename to src/ic/x87/ic-compiler-x87.cc
index dedbaa6..5c68d54 100644
--- a/src/x87/stub-cache-x87.cc
+++ b/src/ic/x87/ic-compiler-x87.cc
@@ -6,114 +6,14 @@
 
 #if V8_TARGET_ARCH_X87
 
-#include "src/codegen.h"
-#include "src/ic-inl.h"
-#include "src/stub-cache.h"
+#include "src/ic/call-optimization.h"
+#include "src/ic/ic-compiler.h"
 
 namespace v8 {
 namespace internal {
 
 #define __ ACCESS_MASM(masm)
 
-
-static void ProbeTable(Isolate* isolate,
-                       MacroAssembler* masm,
-                       Code::Flags flags,
-                       StubCache::Table table,
-                       Register name,
-                       Register receiver,
-                       // Number of the cache entry pointer-size scaled.
-                       Register offset,
-                       Register extra) {
-  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
-  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
-  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
-
-  Label miss;
-
-  // Multiply by 3 because there are 3 fields per entry (name, code, map).
-  __ lea(offset, Operand(offset, offset, times_2, 0));
-
-  if (extra.is_valid()) {
-    // Get the code entry from the cache.
-    __ mov(extra, Operand::StaticArray(offset, times_1, value_offset));
-
-    // Check that the key in the entry matches the name.
-    __ cmp(name, Operand::StaticArray(offset, times_1, key_offset));
-    __ j(not_equal, &miss);
-
-    // Check the map matches.
-    __ mov(offset, Operand::StaticArray(offset, times_1, map_offset));
-    __ cmp(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-    __ j(not_equal, &miss);
-
-    // Check that the flags match what we're looking for.
-    __ mov(offset, FieldOperand(extra, Code::kFlagsOffset));
-    __ and_(offset, ~Code::kFlagsNotUsedInLookup);
-    __ cmp(offset, flags);
-    __ j(not_equal, &miss);
-
-#ifdef DEBUG
-    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
-      __ jmp(&miss);
-    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
-      __ jmp(&miss);
-    }
-#endif
-
-    // Jump to the first instruction in the code stub.
-    __ add(extra, Immediate(Code::kHeaderSize - kHeapObjectTag));
-    __ jmp(extra);
-
-    __ bind(&miss);
-  } else {
-    // Save the offset on the stack.
-    __ push(offset);
-
-    // Check that the key in the entry matches the name.
-    __ cmp(name, Operand::StaticArray(offset, times_1, key_offset));
-    __ j(not_equal, &miss);
-
-    // Check the map matches.
-    __ mov(offset, Operand::StaticArray(offset, times_1, map_offset));
-    __ cmp(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-    __ j(not_equal, &miss);
-
-    // Restore offset register.
-    __ mov(offset, Operand(esp, 0));
-
-    // Get the code entry from the cache.
-    __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
-
-    // Check that the flags match what we're looking for.
-    __ mov(offset, FieldOperand(offset, Code::kFlagsOffset));
-    __ and_(offset, ~Code::kFlagsNotUsedInLookup);
-    __ cmp(offset, flags);
-    __ j(not_equal, &miss);
-
-#ifdef DEBUG
-    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
-      __ jmp(&miss);
-    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
-      __ jmp(&miss);
-    }
-#endif
-
-    // Restore offset and re-load code entry from cache.
-    __ pop(offset);
-    __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
-
-    // Jump to the first instruction in the code stub.
-    __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag));
-    __ jmp(offset);
-
-    // Pop at miss.
-    __ bind(&miss);
-    __ pop(offset);
-  }
-}
-
-
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
     Handle<Name> name, Register scratch0, Register scratch1) {
@@ -147,89 +47,13 @@
   __ j(not_equal, miss_label);
 
   Label done;
-  NameDictionaryLookupStub::GenerateNegativeLookup(masm,
-                                                   miss_label,
-                                                   &done,
-                                                   properties,
-                                                   name,
-                                                   scratch1);
+  NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done,
+                                                   properties, name, scratch1);
   __ bind(&done);
   __ DecrementCounter(counters->negative_lookups_miss(), 1);
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm,
-                              Code::Flags flags,
-                              Register receiver,
-                              Register name,
-                              Register scratch,
-                              Register extra,
-                              Register extra2,
-                              Register extra3) {
-  Label miss;
-
-  // Assert that code is valid.  The multiplying code relies on the entry size
-  // being 12.
-  DCHECK(sizeof(Entry) == 12);
-
-  // Assert the flags do not name a specific type.
-  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
-
-  // Assert that there are no register conflicts.
-  DCHECK(!scratch.is(receiver));
-  DCHECK(!scratch.is(name));
-  DCHECK(!extra.is(receiver));
-  DCHECK(!extra.is(name));
-  DCHECK(!extra.is(scratch));
-
-  // Assert scratch and extra registers are valid, and extra2/3 are unused.
-  DCHECK(!scratch.is(no_reg));
-  DCHECK(extra2.is(no_reg));
-  DCHECK(extra3.is(no_reg));
-
-  Register offset = scratch;
-  scratch = no_reg;
-
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, &miss);
-
-  // Get the map of the receiver and compute the hash.
-  __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
-  __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-  __ xor_(offset, flags);
-  // We mask out the last two bits because they are not part of the hash and
-  // they are always 01 for maps.  Also in the two 'and' instructions below.
-  __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift);
-  // ProbeTable expects the offset to be pointer scaled, which it is, because
-  // the heap object tag size is 2 and the pointer size log 2 is also 2.
-  DCHECK(kCacheIndexShift == kPointerSizeLog2);
-
-  // Probe the primary table.
-  ProbeTable(isolate(), masm, flags, kPrimary, name, receiver, offset, extra);
-
-  // Primary miss: Compute hash for secondary probe.
-  __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
-  __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset));
-  __ xor_(offset, flags);
-  __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift);
-  __ sub(offset, name);
-  __ add(offset, Immediate(flags));
-  __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift);
-
-  // Probe the secondary table.
-  ProbeTable(
-      isolate(), masm, flags, kSecondary, name, receiver, offset, extra);
-
-  // Cache miss: Fall-through and let caller handle the miss by
-  // entering the runtime system.
-  __ bind(&miss);
-  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
-}
-
-
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
     MacroAssembler* masm, int index, Register prototype, Label* miss) {
   // Get the global function with the given index.
@@ -259,10 +83,8 @@
 }
 
 
-static void PushInterceptorArguments(MacroAssembler* masm,
-                                     Register receiver,
-                                     Register holder,
-                                     Register name,
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
                                      Handle<JSObject> holder_obj) {
   STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
   STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
@@ -281,12 +103,8 @@
 
 
 static void CompileCallLoadPropertyWithInterceptor(
-    MacroAssembler* masm,
-    Register receiver,
-    Register holder,
-    Register name,
-    Handle<JSObject> holder_obj,
-    IC::UtilityId id) {
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
   __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
                            NamedLoadHandlerCompiler::kInterceptorArgsLength);
@@ -307,7 +125,7 @@
   __ push(receiver);
   // Write the arguments to stack frame.
   for (int i = 0; i < argc; i++) {
-    Register arg = values[argc-1-i];
+    Register arg = values[argc - 1 - i];
     DCHECK(!receiver.is(arg));
     DCHECK(!scratch_in.is(arg));
     __ push(arg);
@@ -325,16 +143,15 @@
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
-      receiver_map,
-      &holder_lookup);
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
       __ LoadHeapObject(holder, api_holder);
-     break;
+      break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
       break;
@@ -376,8 +193,7 @@
 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
     MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
     Register scratch, Label* miss) {
-  Handle<PropertyCell> cell =
-      JSGlobalObject::EnsurePropertyCell(global, name);
+  Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
   DCHECK(cell->value()->IsTheHole());
   Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
   if (masm->serializer_enabled()) {
@@ -391,12 +207,6 @@
 }
 
 
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ jmp(code, RelocInfo::CODE_TARGET);
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm())
 
@@ -427,7 +237,7 @@
     __ CmpObject(value_reg, constant);
     __ j(not_equal, miss_label);
   } else if (representation.IsSmi()) {
-      __ JumpIfNotSmi(value_reg, miss_label);
+    __ JumpIfNotSmi(value_reg, miss_label);
   } else if (representation.IsHeapObject()) {
     __ JumpIfSmi(value_reg, miss_label);
     HeapType* field_type = descriptors->GetFieldType(descriptor);
@@ -491,12 +301,8 @@
   __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
 
   // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg,
-                      HeapObject::kMapOffset,
-                      scratch1,
-                      scratch2,
-                      OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
+  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
+                      OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
 
   if (details.type() == CONSTANT) {
     DCHECK(value_reg.is(eax));
@@ -512,8 +318,8 @@
   // object and the number of in-object properties is not going to change.
   index -= transition->inobject_properties();
 
-  SmiCheck smi_check = representation.IsTagged()
-      ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
+  SmiCheck smi_check =
+      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
   // TODO(verwaest): Share this code as a code stub.
   if (index < 0) {
     // Set the property straight into the object.
@@ -529,12 +335,8 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(receiver_reg,
-                          offset,
-                          storage_reg,
-                          scratch1,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
+                          EMIT_REMEMBERED_SET, smi_check);
     }
   } else {
     // Write to the properties array.
@@ -552,12 +354,8 @@
       if (!representation.IsDouble()) {
         __ mov(storage_reg, value_reg);
       }
-      __ RecordWriteField(scratch1,
-                          offset,
-                          storage_reg,
-                          receiver_reg,
-                          EMIT_REMEMBERED_SET,
-                          smi_check);
+      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
+                          EMIT_REMEMBERED_SET, smi_check);
     }
   }
 
@@ -599,8 +397,8 @@
 
   // Make sure there's no overlap between holder and object registers.
   DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
-         && !scratch2.is(scratch1));
+  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
+         !scratch2.is(scratch1));
 
   // Keep track of the current object in register reg.
   Register reg = object_reg;
@@ -632,10 +430,10 @@
       }
       DCHECK(current.is_null() ||
              current->property_dictionary()->FindEntry(name) ==
-             NameDictionary::kNotFound);
+                 NameDictionary::kNotFound);
 
-      GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
-                                       scratch1, scratch2);
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
 
       __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
       reg = holder_reg;  // From now on the object will be in holder_reg.
@@ -660,9 +458,8 @@
       if (current_map->IsJSGlobalProxyMap()) {
         __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
       } else if (current_map->IsJSGlobalObjectMap()) {
-        GenerateCheckPropertyCell(
-            masm(), Handle<JSGlobalObject>::cast(current), name,
-            scratch2, miss);
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
       }
 
       if (load_prototype_from_map) {
@@ -912,8 +709,8 @@
       __ push(value());
       ParameterCount actual(1);
       ParameterCount expected(setter);
-      __ InvokeFunction(setter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
       // the place to continue after deoptimization.
@@ -978,25 +775,6 @@
 }
 
 
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = { receiver, name, ebx, eax, edi, no_reg };
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3.
-  Register receiver = StoreIC::ReceiverRegister();
-  Register name = StoreIC::NameRegister();
-  DCHECK(ebx.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = { receiver, name, ebx, edi, no_reg };
-  return registers;
-}
-
-
 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
 
 
@@ -1020,8 +798,8 @@
       __ push(receiver);
       ParameterCount actual(0);
       ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual,
-                        CALL_FUNCTION, NullCallWrapper());
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
       // the place to continue after deoptimization.
@@ -1179,8 +957,25 @@
 }
 
 
-#undef __
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  // Return address is on the stack.
+  DCHECK(!ebx.is(StoreIC::ReceiverRegister()) &&
+         !ebx.is(StoreIC::NameRegister()) && !ebx.is(StoreIC::ValueRegister()));
+  __ pop(ebx);
+  __ push(StoreIC::ReceiverRegister());
+  __ push(StoreIC::NameRegister());
+  __ push(StoreIC::ValueRegister());
+  __ push(Immediate(Smi::FromInt(strict_mode)));
+  __ push(ebx);  // return address
 
-} }  // namespace v8::internal
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X87
diff --git a/src/x87/ic-x87.cc b/src/ic/x87/ic-x87.cc
similarity index 81%
rename from src/x87/ic-x87.cc
rename to src/ic/x87/ic-x87.cc
index 4f7d810..8301588 100644
--- a/src/x87/ic-x87.cc
+++ b/src/ic/x87/ic-x87.cc
@@ -7,9 +7,9 @@
 #if V8_TARGET_ARCH_X87
 
 #include "src/codegen.h"
-#include "src/ic-inl.h"
-#include "src/runtime.h"
-#include "src/stub-cache.h"
+#include "src/ic/ic.h"
+#include "src/ic/ic-compiler.h"
+#include "src/ic/stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -21,8 +21,7 @@
 #define __ ACCESS_MASM(masm)
 
 
-static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm,
-                                            Register type,
+static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, Register type,
                                             Label* global_object) {
   // Register usage:
   //   type: holds the receiver instance type on entry.
@@ -42,13 +41,9 @@
 // name is not internalized, and will jump to the miss_label in that
 // case. The generated code assumes that the receiver has slow
 // properties, is not a global object and does not have interceptors.
-static void GenerateDictionaryLoad(MacroAssembler* masm,
-                                   Label* miss_label,
-                                   Register elements,
-                                   Register name,
-                                   Register r0,
-                                   Register r1,
-                                   Register result) {
+static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label,
+                                   Register elements, Register name,
+                                   Register r0, Register r1, Register result) {
   // Register use:
   //
   // elements - holds the property dictionary on entry and is unchanged.
@@ -66,13 +61,8 @@
   Label done;
 
   // Probe the dictionary.
-  NameDictionaryLookupStub::GeneratePositiveLookup(masm,
-                                                   miss_label,
-                                                   &done,
-                                                   elements,
-                                                   name,
-                                                   r0,
-                                                   r1);
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done,
+                                                   elements, name, r0, r1);
 
   // If probing finds an entry in the dictionary, r0 contains the
   // index into the dictionary. Check that the value is a normal
@@ -99,13 +89,9 @@
 // call if name is not internalized, and will jump to the miss_label in
 // that case. The generated code assumes that the receiver has slow
 // properties, is not a global object and does not have interceptors.
-static void GenerateDictionaryStore(MacroAssembler* masm,
-                                    Label* miss_label,
-                                    Register elements,
-                                    Register name,
-                                    Register value,
-                                    Register r0,
-                                    Register r1) {
+static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss_label,
+                                    Register elements, Register name,
+                                    Register value, Register r0, Register r1) {
   // Register use:
   //
   // elements - holds the property dictionary on entry and is clobbered.
@@ -121,13 +107,8 @@
 
 
   // Probe the dictionary.
-  NameDictionaryLookupStub::GeneratePositiveLookup(masm,
-                                                   miss_label,
-                                                   &done,
-                                                   elements,
-                                                   name,
-                                                   r0,
-                                                   r1);
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done,
+                                                   elements, name, r0, r1);
 
   // If probing finds an entry in the dictionary, r0 contains the
   // index into the dictionary. Check that the value is a normal
@@ -139,7 +120,8 @@
   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
   const int kTypeAndReadOnlyMask =
       (PropertyDetails::TypeField::kMask |
-       PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
+       PropertyDetails::AttributesField::encode(READ_ONLY))
+      << kSmiTagSize;
   __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
           Immediate(kTypeAndReadOnlyMask));
   __ j(not_zero, miss_label);
@@ -158,10 +140,8 @@
 // Checks the receiver for special cases (value type, slow case bits).
 // Falls through for regular JS object.
 static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
-                                           Register receiver,
-                                           Register map,
-                                           int interceptor_bit,
-                                           Label* slow) {
+                                           Register receiver, Register map,
+                                           int interceptor_bit, Label* slow) {
   // Register use:
   //   receiver - holds the receiver and is unchanged.
   // Scratch registers:
@@ -190,12 +170,9 @@
 
 // Loads an indexed element from a fast case array.
 // If not_fast_array is NULL, doesn't perform the elements map check.
-static void GenerateFastArrayLoad(MacroAssembler* masm,
-                                  Register receiver,
-                                  Register key,
-                                  Register scratch,
-                                  Register result,
-                                  Label* not_fast_array,
+static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
+                                  Register key, Register scratch,
+                                  Register result, Label* not_fast_array,
                                   Label* out_of_range) {
   // Register use:
   //   receiver - holds the receiver and is unchanged.
@@ -233,12 +210,9 @@
 
 // Checks whether a key is an array index string or a unique name.
 // Falls through if the key is a unique name.
-static void GenerateKeyNameCheck(MacroAssembler* masm,
-                                 Register key,
-                                 Register map,
-                                 Register hash,
-                                 Label* index_string,
-                                 Label* not_unique) {
+static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
+                                 Register map, Register hash,
+                                 Label* index_string, Label* not_unique) {
   // Register use:
   //   key - holds the key and is unchanged. Assumed to be non-smi.
   // Scratch registers:
@@ -266,13 +240,9 @@
 }
 
 
-static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
-                                             Register object,
-                                             Register key,
-                                             Register scratch1,
-                                             Register scratch2,
-                                             Label* unmapped_case,
-                                             Label* slow_case) {
+static Operand GenerateMappedArgumentsLookup(
+    MacroAssembler* masm, Register object, Register key, Register scratch1,
+    Register scratch2, Label* unmapped_case, Label* slow_case) {
   Heap* heap = masm->isolate()->heap();
   Factory* factory = masm->isolate()->factory();
 
@@ -302,10 +272,8 @@
 
   // Load element index and check whether it is the hole.
   const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize;
-  __ mov(scratch2, FieldOperand(scratch1,
-                                key,
-                                times_half_pointer_size,
-                                kHeaderSize));
+  __ mov(scratch2,
+         FieldOperand(scratch1, key, times_half_pointer_size, kHeaderSize));
   __ cmp(scratch2, factory->the_hole_value());
   __ j(equal, unmapped_case);
 
@@ -314,9 +282,7 @@
   // map in scratch1).
   const int kContextOffset = FixedArray::kHeaderSize;
   __ mov(scratch1, FieldOperand(scratch1, kContextOffset));
-  return FieldOperand(scratch1,
-                      scratch2,
-                      times_half_pointer_size,
+  return FieldOperand(scratch1, scratch2, times_half_pointer_size,
                       Context::kHeaderSize);
 }
 
@@ -336,9 +302,7 @@
   __ mov(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset));
   __ cmp(key, scratch);
   __ j(greater_equal, slow_case);
-  return FieldOperand(backing_store,
-                      key,
-                      times_half_pointer_size,
+  return FieldOperand(backing_store, key, times_half_pointer_size,
                       FixedArray::kHeaderSize);
 }
 
@@ -359,8 +323,8 @@
   // Now the key is known to be a smi. This place is also jumped to from
   // where a numeric string is converted to a smi.
 
-  GenerateKeyedLoadReceiverCheck(
-      masm, receiver, eax, Map::kHasIndexedInterceptor, &slow);
+  GenerateKeyedLoadReceiverCheck(masm, receiver, eax,
+                                 Map::kHasIndexedInterceptor, &slow);
 
   // Check the receiver's map to see if it has fast elements.
   __ CheckFastElements(eax, &check_number_dictionary);
@@ -379,9 +343,7 @@
   // Check whether the elements is a number dictionary.
   // ebx: untagged index
   // eax: elements
-  __ CheckMap(eax,
-              isolate->factory()->hash_table_map(),
-              &slow,
+  __ CheckMap(eax, isolate->factory()->hash_table_map(), &slow,
               DONT_DO_SMI_CHECK);
   Label slow_pop_receiver;
   // Push receiver on the stack to free up a register for the dictionary
@@ -404,8 +366,8 @@
   __ bind(&check_name);
   GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow);
 
-  GenerateKeyedLoadReceiverCheck(
-      masm, receiver, eax, Map::kHasNamedInterceptor, &slow);
+  GenerateKeyedLoadReceiverCheck(masm, receiver, eax, Map::kHasNamedInterceptor,
+                                 &slow);
 
   // If the receiver is a fast-case object, check the keyed lookup
   // cache. Otherwise probe the dictionary.
@@ -492,8 +454,8 @@
   // Load property array property.
   __ bind(&property_array_property);
   __ mov(eax, FieldOperand(receiver, JSObject::kPropertiesOffset));
-  __ mov(eax, FieldOperand(eax, edi, times_pointer_size,
-                           FixedArray::kHeaderSize));
+  __ mov(eax,
+         FieldOperand(eax, edi, times_pointer_size, FixedArray::kHeaderSize));
   __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
   __ ret(0);
 
@@ -527,10 +489,7 @@
   Register result = eax;
   DCHECK(!result.is(scratch));
 
-  StringCharAtGenerator char_at_generator(receiver,
-                                          index,
-                                          scratch,
-                                          result,
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
                                           &miss,  // When not a string.
                                           &miss,  // When not a number.
                                           &miss,  // When index out of range.
@@ -597,9 +556,8 @@
 
   Label slow, notin;
   Factory* factory = masm->isolate()->factory();
-  Operand mapped_location =
-      GenerateMappedArgumentsLookup(
-          masm, receiver, key, ebx, eax, &notin, &slow);
+  Operand mapped_location = GenerateMappedArgumentsLookup(
+      masm, receiver, key, ebx, eax, &notin, &slow);
   __ mov(eax, mapped_location);
   __ Ret();
   __ bind(&notin);
@@ -625,9 +583,8 @@
   DCHECK(name.is(ecx));
   DCHECK(value.is(eax));
 
-  Operand mapped_location =
-      GenerateMappedArgumentsLookup(masm, receiver, name, ebx, edi, &notin,
-                                    &slow);
+  Operand mapped_location = GenerateMappedArgumentsLookup(
+      masm, receiver, name, ebx, edi, &notin, &slow);
   __ mov(mapped_location, value);
   __ lea(ecx, mapped_location);
   __ mov(edx, value);
@@ -648,12 +605,8 @@
 
 
 static void KeyedStoreGenerateGenericHelper(
-    MacroAssembler* masm,
-    Label* fast_object,
-    Label* fast_double,
-    Label* slow,
-    KeyedStoreCheckMap check_map,
-    KeyedStoreIncrementLength increment_length) {
+    MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
+    KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) {
   Label transition_smi_elements;
   Label finish_object_store, non_double_value, transition_double_elements;
   Label fast_double_without_map_check;
@@ -713,8 +666,7 @@
   __ mov(FixedArrayElementOperand(ebx, key), value);
   // Update write barrier for the elements array address.
   __ mov(edx, value);  // Preserve the value which is returned.
-  __ RecordWriteArray(
-      ebx, edx, key, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ RecordWriteArray(ebx, edx, key, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
   __ ret(0);
 
   __ bind(fast_double);
@@ -750,32 +702,24 @@
   __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset));
 
   // Transition the array appropriately depending on the value type.
-  __ CheckMap(value,
-              masm->isolate()->factory()->heap_number_map(),
-              &non_double_value,
-              DONT_DO_SMI_CHECK);
+  __ CheckMap(value, masm->isolate()->factory()->heap_number_map(),
+              &non_double_value, DONT_DO_SMI_CHECK);
 
   // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS
   // and complete the store.
   __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
-                                         FAST_DOUBLE_ELEMENTS,
-                                         ebx,
-                                         edi,
-                                         slow);
-  AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS,
-                                                    FAST_DOUBLE_ELEMENTS);
-  ElementsTransitionGenerator::GenerateSmiToDouble(
-      masm, receiver, key, value, ebx, mode, slow);
+                                         FAST_DOUBLE_ELEMENTS, ebx, edi, slow);
+  AllocationSiteMode mode =
+      AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
+  ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
+                                                   ebx, mode, slow);
   __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
   __ jmp(&fast_double_without_map_check);
 
   __ bind(&non_double_value);
   // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
-  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
-                                         FAST_ELEMENTS,
-                                         ebx,
-                                         edi,
-                                         slow);
+  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS, ebx,
+                                         edi, slow);
   mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
   ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
       masm, receiver, key, value, ebx, mode, slow);
@@ -787,14 +731,11 @@
   // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
   // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
   __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset));
-  __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
-                                         FAST_ELEMENTS,
-                                         ebx,
-                                         edi,
-                                         slow);
+  __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
+                                         ebx, edi, slow);
   mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
-  ElementsTransitionGenerator::GenerateDoubleToObject(
-      masm, receiver, key, value, ebx, mode, slow);
+  ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key,
+                                                      value, ebx, mode, slow);
   __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
   __ jmp(&finish_object_store);
 }
@@ -838,7 +779,7 @@
 
   // Slow case: call runtime.
   __ bind(&slow);
-  GenerateRuntimeSetProperty(masm, strict_mode);
+  PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -877,8 +818,8 @@
   __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset));  // Compare smis.
   __ j(above_equal, &extra);
 
-  KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
-                                  &slow, kCheckMap, kDontIncrementLength);
+  KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow,
+                                  kCheckMap, kDontIncrementLength);
   KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
                                   &slow, kDontCheckMap, kIncrementLength);
 }
@@ -894,8 +835,8 @@
   // Probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, receiver, name, ebx, eax);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, ebx,
+                                               eax);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -990,9 +931,7 @@
 const Register StoreIC::ValueRegister() { return eax; }
 
 
-const Register KeyedStoreIC::MapRegister() {
-  return ebx;
-}
+const Register KeyedStoreIC::MapRegister() { return ebx; }
 
 
 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
@@ -1008,9 +947,8 @@
   // Return address is on the stack.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, ReceiverRegister(), NameRegister(),
-      ebx, no_reg);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, ReceiverRegister(),
+                                               NameRegister(), ebx, no_reg);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -1070,40 +1008,6 @@
 }
 
 
-void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                         StrictMode strict_mode) {
-  // Return address is on the stack.
-  DCHECK(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) &&
-         !ebx.is(ValueRegister()));
-  __ pop(ebx);
-  __ push(ReceiverRegister());
-  __ push(NameRegister());
-  __ push(ValueRegister());
-  __ push(Immediate(Smi::FromInt(strict_mode)));
-  __ push(ebx);  // return address
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
-void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
-                                              StrictMode strict_mode) {
-  // Return address is on the stack.
-  DCHECK(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) &&
-         !ebx.is(ValueRegister()));
-  __ pop(ebx);
-  __ push(ReceiverRegister());
-  __ push(NameRegister());
-  __ push(ValueRegister());
-  __ push(Immediate(Smi::FromInt(strict_mode)));
-  __ push(ebx);  // return address
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
-}
-
-
 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
   // Return address is on the stack.
   StoreIC_PushArgs(masm);
@@ -1186,8 +1090,8 @@
   // condition code uses at the patched jump.
   uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address);
   if (FLAG_trace_ic) {
-    PrintF("[  patching ic at %p, test=%p, delta=%d\n",
-           address, test_instruction_address, delta);
+    PrintF("[  patching ic at %p, test=%p, delta=%d\n", address,
+           test_instruction_address, delta);
   }
 
   // Patch with a short conditional jump. Enabling means switching from a short
@@ -1195,17 +1099,17 @@
   // reverse operation of that.
   Address jmp_address = test_instruction_address - delta;
   DCHECK((check == ENABLE_INLINED_SMI_CHECK)
-         ? (*jmp_address == Assembler::kJncShortOpcode ||
-            *jmp_address == Assembler::kJcShortOpcode)
-         : (*jmp_address == Assembler::kJnzShortOpcode ||
-            *jmp_address == Assembler::kJzShortOpcode));
-  Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
-      ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
-      : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
+             ? (*jmp_address == Assembler::kJncShortOpcode ||
+                *jmp_address == Assembler::kJcShortOpcode)
+             : (*jmp_address == Assembler::kJnzShortOpcode ||
+                *jmp_address == Assembler::kJzShortOpcode));
+  Condition cc =
+      (check == ENABLE_INLINED_SMI_CHECK)
+          ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
+          : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
 }
-
-
-} }  // namespace v8::internal
+}
+}  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X87
diff --git a/src/ic/x87/stub-cache-x87.cc b/src/ic/x87/stub-cache-x87.cc
new file mode 100644
index 0000000..8b4f0fd
--- /dev/null
+++ b/src/ic/x87/stub-cache-x87.cc
@@ -0,0 +1,183 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_X87
+
+#include "src/codegen.h"
+#include "src/ic/stub-cache.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
+                       Code::Flags flags, StubCache::Table table, Register name,
+                       Register receiver,
+                       // Number of the cache entry pointer-size scaled.
+                       Register offset, Register extra) {
+  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
+  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
+  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
+
+  Label miss;
+
+  // Multiply by 3 because there are 3 fields per entry (name, code, map).
+  __ lea(offset, Operand(offset, offset, times_2, 0));
+
+  if (extra.is_valid()) {
+    // Get the code entry from the cache.
+    __ mov(extra, Operand::StaticArray(offset, times_1, value_offset));
+
+    // Check that the key in the entry matches the name.
+    __ cmp(name, Operand::StaticArray(offset, times_1, key_offset));
+    __ j(not_equal, &miss);
+
+    // Check the map matches.
+    __ mov(offset, Operand::StaticArray(offset, times_1, map_offset));
+    __ cmp(offset, FieldOperand(receiver, HeapObject::kMapOffset));
+    __ j(not_equal, &miss);
+
+    // Check that the flags match what we're looking for.
+    __ mov(offset, FieldOperand(extra, Code::kFlagsOffset));
+    __ and_(offset, ~Code::kFlagsNotUsedInLookup);
+    __ cmp(offset, flags);
+    __ j(not_equal, &miss);
+
+#ifdef DEBUG
+    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
+      __ jmp(&miss);
+    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
+      __ jmp(&miss);
+    }
+#endif
+
+    // Jump to the first instruction in the code stub.
+    __ add(extra, Immediate(Code::kHeaderSize - kHeapObjectTag));
+    __ jmp(extra);
+
+    __ bind(&miss);
+  } else {
+    // Save the offset on the stack.
+    __ push(offset);
+
+    // Check that the key in the entry matches the name.
+    __ cmp(name, Operand::StaticArray(offset, times_1, key_offset));
+    __ j(not_equal, &miss);
+
+    // Check the map matches.
+    __ mov(offset, Operand::StaticArray(offset, times_1, map_offset));
+    __ cmp(offset, FieldOperand(receiver, HeapObject::kMapOffset));
+    __ j(not_equal, &miss);
+
+    // Restore offset register.
+    __ mov(offset, Operand(esp, 0));
+
+    // Get the code entry from the cache.
+    __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
+
+    // Check that the flags match what we're looking for.
+    __ mov(offset, FieldOperand(offset, Code::kFlagsOffset));
+    __ and_(offset, ~Code::kFlagsNotUsedInLookup);
+    __ cmp(offset, flags);
+    __ j(not_equal, &miss);
+
+#ifdef DEBUG
+    if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
+      __ jmp(&miss);
+    } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
+      __ jmp(&miss);
+    }
+#endif
+
+    // Restore offset and re-load code entry from cache.
+    __ pop(offset);
+    __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
+
+    // Jump to the first instruction in the code stub.
+    __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag));
+    __ jmp(offset);
+
+    // Pop at miss.
+    __ bind(&miss);
+    __ pop(offset);
+  }
+}
+
+
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
+  Label miss;
+
+  // Assert that code is valid.  The multiplying code relies on the entry size
+  // being 12.
+  DCHECK(sizeof(Entry) == 12);
+
+  // Assert the flags do not name a specific type.
+  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
+
+  // Assert that there are no register conflicts.
+  DCHECK(!scratch.is(receiver));
+  DCHECK(!scratch.is(name));
+  DCHECK(!extra.is(receiver));
+  DCHECK(!extra.is(name));
+  DCHECK(!extra.is(scratch));
+
+  // Assert scratch and extra registers are valid, and extra2/3 are unused.
+  DCHECK(!scratch.is(no_reg));
+  DCHECK(extra2.is(no_reg));
+  DCHECK(extra3.is(no_reg));
+
+  Register offset = scratch;
+  scratch = no_reg;
+
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
+
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, &miss);
+
+  // Get the map of the receiver and compute the hash.
+  __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
+  __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset));
+  __ xor_(offset, flags);
+  // We mask out the last two bits because they are not part of the hash and
+  // they are always 01 for maps.  Also in the two 'and' instructions below.
+  __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift);
+  // ProbeTable expects the offset to be pointer scaled, which it is, because
+  // the heap object tag size is 2 and the pointer size log 2 is also 2.
+  DCHECK(kCacheIndexShift == kPointerSizeLog2);
+
+  // Probe the primary table.
+  ProbeTable(isolate(), masm, flags, kPrimary, name, receiver, offset, extra);
+
+  // Primary miss: Compute hash for secondary probe.
+  __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
+  __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset));
+  __ xor_(offset, flags);
+  __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift);
+  __ sub(offset, name);
+  __ add(offset, Immediate(flags));
+  __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift);
+
+  // Probe the secondary table.
+  ProbeTable(isolate(), masm, flags, kSecondary, name, receiver, offset, extra);
+
+  // Cache miss: Fall-through and let caller handle the miss by
+  // entering the runtime system.
+  __ bind(&miss);
+  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_X87
diff --git a/src/isolate.cc b/src/isolate.cc
index fc8d34d..0f1f702 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1057,7 +1057,7 @@
           // probably not a valid Error object.  In that case, we fall through
           // and capture the stack trace at this throw site.
           LookupIterator lookup(exception_handle, key,
-                                LookupIterator::CHECK_PROPERTY);
+                                LookupIterator::OWN_PROPERTY);
           Handle<Object> stack_trace_property;
           if (Object::GetProperty(&lookup).ToHandle(&stack_trace_property) &&
               stack_trace_property->IsJSArray()) {
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index 1970c2d..1b108ce 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -340,7 +340,7 @@
 MaybeHandle<Object> BasicJsonStringifier::ApplyToJsonFunction(
     Handle<Object> object, Handle<Object> key) {
   LookupIterator it(object, tojson_string_,
-                    LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR);
+                    LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
   Handle<Object> fun;
   ASSIGN_RETURN_ON_EXCEPTION(isolate_, fun, Object::GetProperty(&it), Object);
   if (!fun->IsJSFunction()) return object;
diff --git a/src/lookup-inl.h b/src/lookup-inl.h
index a32295b..d87221e 100644
--- a/src/lookup-inl.h
+++ b/src/lookup-inl.h
@@ -19,11 +19,11 @@
   DCHECK(!next->map()->IsGlobalObjectMap() ||
          next->map()->is_hidden_prototype());
 
-  if (!check_derived() &&
+  if (!check_prototype_chain() &&
       !(check_hidden() && next->map()->is_hidden_prototype()) &&
       // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even
       // when not checking other hidden prototypes.
-      !(map->IsJSGlobalProxyMap() && next->IsJSGlobalObject())) {
+      !map->IsJSGlobalProxyMap()) {
     return NULL;
   }
 
diff --git a/src/lookup.cc b/src/lookup.cc
index 56001c3..5bce620 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -35,8 +35,8 @@
   // Either was found in the receiver, or the receiver has no prototype.
   if (holder == NULL) return;
 
-  maybe_holder_ = handle(holder);
-  holder_map_ = handle(map);
+  maybe_holder_ = handle(holder, isolate_);
+  holder_map_ = handle(map, isolate_);
 }
 
 
@@ -53,7 +53,7 @@
 Handle<Map> LookupIterator::GetReceiverMap() const {
   Handle<Object> receiver = GetReceiver();
   if (receiver->IsNumber()) return isolate_->factory()->heap_number_map();
-  return handle(Handle<HeapObject>::cast(receiver)->map());
+  return handle(Handle<HeapObject>::cast(receiver)->map(), isolate_);
 }
 
 
@@ -184,7 +184,7 @@
   }
 
   transition_map_ = Map::TransitionToDataProperty(
-      handle(receiver->map()), name_, value, attributes, store_mode);
+      handle(receiver->map(), isolate_), name_, value, attributes, store_mode);
   state_ = TRANSITION;
 }
 
@@ -209,8 +209,9 @@
   // observable.
   Handle<JSObject> receiver = GetStoreTarget();
   maybe_holder_ = receiver;
-  holder_map_ = Map::TransitionToAccessorProperty(
-      handle(receiver->map()), name_, component, accessor, attributes);
+  holder_map_ =
+      Map::TransitionToAccessorProperty(handle(receiver->map(), isolate_),
+                                        name_, component, accessor, attributes);
   JSObject::MigrateToMap(receiver, holder_map_);
 
   ReloadPropertyInformation();
@@ -243,7 +244,7 @@
   JSObject::SetNormalizedProperty(receiver, name_, pair, details);
 
   JSObject::ReoptimizeIfPrototype(receiver);
-  holder_map_ = handle(receiver->map());
+  holder_map_ = handle(receiver->map(), isolate_);
   ReloadPropertyInformation();
 }
 
@@ -251,7 +252,7 @@
 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
   DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
   // Optimization that only works if configuration_ is not mutable.
-  if (!check_derived()) return true;
+  if (!check_prototype_chain()) return true;
   DisallowHeapAllocation no_gc;
   Handle<Object> receiver = GetReceiver();
   if (!receiver->IsJSReceiver()) return false;
@@ -272,16 +273,6 @@
 }
 
 
-bool LookupIterator::HolderIsNonGlobalHiddenPrototype() const {
-  if (!HolderIsReceiverOrHiddenPrototype()) return false;
-  Handle<Object> receiver = GetReceiver();
-  Handle<JSReceiver> holder = GetHolder<JSReceiver>();
-  if (receiver.is_identical_to(holder)) return false;
-  if (receiver->IsJSGlobalProxy()) return !holder->IsJSGlobalObject();
-  return true;
-}
-
-
 Handle<Object> LookupIterator::FetchValue() const {
   Object* result = NULL;
   Handle<JSObject> holder = GetHolder<JSObject>();
diff --git a/src/lookup.h b/src/lookup.h
index d6fa35b..bf2fb1b 100644
--- a/src/lookup.h
+++ b/src/lookup.h
@@ -16,19 +16,21 @@
  public:
   enum Configuration {
     // Configuration bits.
-    CHECK_HIDDEN_PROPERTY = 1 << 0,
-    CHECK_DERIVED_PROPERTY = 1 << 1,
-    CHECK_INTERCEPTOR = 1 << 2,
-    CHECK_ACCESS_CHECK = 1 << 3,
+    kAccessCheck = 1 << 0,
+    kHidden = 1 << 1,
+    kInterceptor = 1 << 2,
+    kPrototypeChain = 1 << 3,
 
     // Convience combinations of bits.
-    CHECK_PROPERTY = 0,
-    CHECK_OWN = CHECK_ACCESS_CHECK | CHECK_INTERCEPTOR,
-    CHECK_HIDDEN_SKIP_INTERCEPTOR = CHECK_HIDDEN_PROPERTY | CHECK_ACCESS_CHECK,
-    CHECK_DERIVED_SKIP_INTERCEPTOR =
-        CHECK_HIDDEN_SKIP_INTERCEPTOR | CHECK_DERIVED_PROPERTY,
-    CHECK_DERIVED = CHECK_DERIVED_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR,
-    CHECK_HIDDEN = CHECK_HIDDEN_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR
+    OWN_PROPERTY = 0,
+    OWN_SKIP_INTERCEPTOR = kAccessCheck,
+    OWN = kAccessCheck | kInterceptor,
+    HIDDEN_PROPERTY = kHidden,
+    HIDDEN_SKIP_INTERCEPTOR = kAccessCheck | kHidden,
+    HIDDEN = kAccessCheck | kHidden | kInterceptor,
+    PROTOTYPE_CHAIN_PROPERTY = kHidden | kPrototypeChain,
+    PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kAccessCheck | kHidden | kPrototypeChain,
+    PROTOTYPE_CHAIN = kAccessCheck | kHidden | kPrototypeChain | kInterceptor
   };
 
   enum State {
@@ -53,20 +55,8 @@
     DESCRIPTOR
   };
 
-  explicit LookupIterator(const LookupIterator* other)
-      : configuration_(other->configuration_),
-        state_(other->state_),
-        property_kind_(other->property_kind_),
-        property_encoding_(other->property_encoding_),
-        property_details_(other->property_details_),
-        isolate_(other->isolate_),
-        name_(other->name_),
-        holder_map_(other->holder_map_),
-        maybe_receiver_(other->maybe_receiver_),
-        maybe_holder_(other->maybe_holder_) {}
-
   LookupIterator(Handle<Object> receiver, Handle<Name> name,
-                 Configuration configuration = CHECK_DERIVED)
+                 Configuration configuration = PROTOTYPE_CHAIN)
       : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
         property_kind_(DATA),
@@ -77,14 +67,14 @@
         maybe_receiver_(receiver),
         number_(DescriptorArray::kNotFound) {
     Handle<JSReceiver> root = GetRoot();
-    holder_map_ = handle(root->map());
+    holder_map_ = handle(root->map(), isolate_);
     maybe_holder_ = root;
     Next();
   }
 
   LookupIterator(Handle<Object> receiver, Handle<Name> name,
                  Handle<JSReceiver> holder,
-                 Configuration configuration = CHECK_DERIVED)
+                 Configuration configuration = PROTOTYPE_CHAIN)
       : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
         property_kind_(DATA),
@@ -92,7 +82,7 @@
         property_details_(NONE, NORMAL, Representation::None()),
         isolate_(name->GetIsolate()),
         name_(name),
-        holder_map_(holder->map()),
+        holder_map_(holder->map(), isolate_),
         maybe_receiver_(receiver),
         maybe_holder_(holder),
         number_(DescriptorArray::kNotFound) {
@@ -110,7 +100,6 @@
     state_ = NOT_FOUND;
   }
 
-  Heap* heap() const { return isolate_->heap(); }
   Factory* factory() const { return isolate_->factory(); }
   Handle<Object> GetReceiver() const {
     return maybe_receiver_.ToHandleChecked();
@@ -128,7 +117,6 @@
   }
   Handle<JSReceiver> GetRoot() const;
   bool HolderIsReceiverOrHiddenPrototype() const;
-  bool HolderIsNonGlobalHiddenPrototype() const;
 
   /* ACCESS_CHECK */
   bool HasAccess(v8::AccessType access_type) const;
@@ -203,17 +191,15 @@
   bool is_guaranteed_to_have_holder() const {
     return !maybe_receiver_.is_null();
   }
-  bool check_interceptor() const {
-    return !IsBootstrapping() && (configuration_ & CHECK_INTERCEPTOR) != 0;
-  }
-  bool check_derived() const {
-    return (configuration_ & CHECK_DERIVED_PROPERTY) != 0;
-  }
-  bool check_hidden() const {
-    return (configuration_ & CHECK_HIDDEN_PROPERTY) != 0;
-  }
   bool check_access_check() const {
-    return (configuration_ & CHECK_ACCESS_CHECK) != 0;
+    return (configuration_ & kAccessCheck) != 0;
+  }
+  bool check_hidden() const { return (configuration_ & kHidden) != 0; }
+  bool check_interceptor() const {
+    return !IsBootstrapping() && (configuration_ & kInterceptor) != 0;
+  }
+  bool check_prototype_chain() const {
+    return (configuration_ & kPrototypeChain) != 0;
   }
   int descriptor_number() const {
     DCHECK(has_property_);
@@ -229,7 +215,7 @@
   static Configuration ComputeConfiguration(
       Configuration configuration, Handle<Name> name) {
     if (name->IsOwn()) {
-      return static_cast<Configuration>(configuration & CHECK_HIDDEN);
+      return static_cast<Configuration>(configuration & HIDDEN);
     } else {
       return configuration;
     }
diff --git a/src/mips/OWNERS b/src/mips/OWNERS
index 8d6807d..5508ba6 100644
--- a/src/mips/OWNERS
+++ b/src/mips/OWNERS
@@ -1,10 +1,5 @@
-plind44@gmail.com
 paul.lind@imgtec.com
-gergely@homejinni.com
 gergely.kis@imgtec.com
-palfia@homejinni.com
 akos.palfi@imgtec.com
-kilvadyb@homejinni.com
 balazs.kilvady@imgtec.com
-Dusan.Milosavljevic@rt-rk.com
 dusan.milosavljevic@imgtec.com
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 462ef67..f6785d2 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -13,7 +13,7 @@
 #include "src/deoptimizer.h"
 #include "src/full-codegen.h"
 #include "src/runtime.h"
-#include "src/stub-cache.h"
+
 
 namespace v8 {
 namespace internal {
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 3169b1a..0b844a5 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -9,8 +9,11 @@
 #include "src/bootstrapper.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
+#include "src/ic/handler-compiler.h"
+#include "src/isolate.h"
+#include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/stub-cache.h"
+#include "src/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -404,7 +407,7 @@
   class OpBits: public BitField<Token::Value, 2, 14> {};
 
   Major MajorKey() const { return ConvertToDouble; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     // Encode the parameters in a unique 16 bit value.
     return  result1_.code() +
            (result2_.code() << 4) +
@@ -1483,7 +1486,7 @@
 
   // Enter the exit frame that transitions from JavaScript to C++.
   FrameScope scope(masm, StackFrame::MANUAL);
-  __ EnterExitFrame(save_doubles_);
+  __ EnterExitFrame(save_doubles());
 
   // s0: number of arguments  including receiver (C callee-saved)
   // s1: pointer to first argument (C callee-saved)
@@ -1571,7 +1574,7 @@
   // sp: stack pointer
   // fp: frame pointer
   // s0: still holds argc (callee-saved).
-  __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
+  __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN);
 
   // Handling of exception.
   __ bind(&exception_returned);
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index 0e3f1c3..9133304 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -5,7 +5,7 @@
 #ifndef V8_MIPS_CODE_STUBS_ARM_H_
 #define V8_MIPS_CODE_STUBS_ARM_H_
 
-#include "src/ic-inl.h"
+#include "src/code-stubs.h"
 
 
 namespace v8 {
@@ -29,7 +29,7 @@
   SaveFPRegsMode save_doubles_;
 
   Major MajorKey() const { return StoreBufferOverflow; }
-  int MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
+  uint32_t MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
 };
 
 
@@ -70,7 +70,7 @@
 
  private:
   Major MajorKey() const { return SubString; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -84,7 +84,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);
  private:
   Major MajorKey() const { return StoreRegistersState; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -97,7 +97,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);
  private:
   Major MajorKey() const { return RestoreRegistersState; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -126,7 +126,7 @@
 
  private:
   virtual Major MajorKey() const { return StringCompare; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
   virtual void Generate(MacroAssembler* masm);
 
   static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
@@ -176,7 +176,7 @@
   class SignRegisterBits: public BitField<int, 12, 4> {};
 
   Major MajorKey() const { return WriteInt32ToHeapNumber; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     // Encode the parameters in a unique 16 bit value.
     return IntRegisterBits::encode(the_int_.code())
            | HeapNumberRegisterBits::encode(the_heap_number_.code())
@@ -348,7 +348,7 @@
 
   Major MajorKey() const { return RecordWrite; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return ObjectBits::encode(object_.code()) |
         ValueBits::encode(value_.code()) |
         AddressBits::encode(address_.code()) |
@@ -389,7 +389,7 @@
 
  private:
   Major MajorKey() const { return DirectCEntry; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   bool NeedsImmovableCode() { return true; }
 };
@@ -436,7 +436,7 @@
 
   Major MajorKey() const { return NameDictionaryLookup; }
 
-  int MinorKey() const { return LookupModeBits::encode(mode_); }
+  uint32_t MinorKey() const { return LookupModeBits::encode(mode_); }
 
   class LookupModeBits: public BitField<LookupMode, 0, 1> {};
 
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index 82a410e..b02ec4f 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -8,7 +8,7 @@
 
 
 #include "src/ast.h"
-#include "src/ic-inl.h"
+#include "src/macro-assembler.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 1327bf6..bd3e821 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -22,7 +22,6 @@
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
-#include "src/stub-cache.h"
 
 #include "src/mips/code-stubs-mips.h"
 #include "src/mips/macro-assembler-mips.h"
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 193db1e..91e2911 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -31,7 +31,7 @@
 #include "src/hydrogen-osr.h"
 #include "src/mips/lithium-codegen-mips.h"
 #include "src/mips/lithium-gap-resolver-mips.h"
-#include "src/stub-cache.h"
+
 
 namespace v8 {
 namespace internal {
@@ -897,7 +897,7 @@
   int length = deoptimizations_.length();
   if (length == 0) return;
   Handle<DeoptimizationInputData> data =
-      DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+      DeoptimizationInputData::New(isolate(), length, TENURED);
 
   Handle<ByteArray> translations =
       translations_.CreateByteArray(isolate()->factory());
@@ -2887,6 +2887,19 @@
 }
 
 
+template <class T>
+void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
+  DCHECK(FLAG_vector_ics);
+  Register vector = ToRegister(instr->temp_vector());
+  DCHECK(vector.is(LoadIC::VectorRegister()));
+  __ li(vector, instr->hydrogen()->feedback_vector());
+  // No need to allocate this register.
+  DCHECK(LoadIC::SlotRegister().is(a0));
+  __ li(LoadIC::SlotRegister(),
+        Operand(Smi::FromInt(instr->hydrogen()->slot())));
+}
+
+
 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
   DCHECK(ToRegister(instr->context()).is(cp));
   DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
@@ -2894,13 +2907,7 @@
 
   __ li(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ li(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(a0));
-    __ li(LoadIC::SlotRegister(),
-          Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
@@ -3028,13 +3035,7 @@
   // Name is always in a2.
   __ li(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ li(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(a0));
-    __ li(LoadIC::SlotRegister(),
-          Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3341,13 +3342,7 @@
   DCHECK(ToRegister(instr->key()).is(LoadIC::NameRegister()));
 
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ li(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(a0));
-    __ li(LoadIC::SlotRegister(),
-          Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index 5c19e0d..d379eb9 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -364,6 +364,9 @@
   void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
   void DoStoreKeyedFixedArray(LStoreKeyed* instr);
 
+  template <class T>
+  void EmitVectorLoadICRegisters(T* instr);
+
   ZoneList<LEnvironment*> deoptimizations_;
   ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
   ZoneList<Handle<Object> > deoptimization_literals_;
diff --git a/src/mips64/OWNERS b/src/mips64/OWNERS
index 8d6807d..5508ba6 100644
--- a/src/mips64/OWNERS
+++ b/src/mips64/OWNERS
@@ -1,10 +1,5 @@
-plind44@gmail.com
 paul.lind@imgtec.com
-gergely@homejinni.com
 gergely.kis@imgtec.com
-palfia@homejinni.com
 akos.palfi@imgtec.com
-kilvadyb@homejinni.com
 balazs.kilvady@imgtec.com
-Dusan.Milosavljevic@rt-rk.com
 dusan.milosavljevic@imgtec.com
diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc
index cbbcc05..91dcfc8 100644
--- a/src/mips64/builtins-mips64.cc
+++ b/src/mips64/builtins-mips64.cc
@@ -13,7 +13,6 @@
 #include "src/deoptimizer.h"
 #include "src/full-codegen.h"
 #include "src/runtime.h"
-#include "src/stub-cache.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc
index 970792a..78a169c 100644
--- a/src/mips64/code-stubs-mips64.cc
+++ b/src/mips64/code-stubs-mips64.cc
@@ -9,8 +9,11 @@
 #include "src/bootstrapper.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
+#include "src/ic/handler-compiler.h"
+#include "src/isolate.h"
+#include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/stub-cache.h"
+#include "src/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -403,7 +406,7 @@
   class OpBits: public BitField<Token::Value, 2, 14> {};
 
   Major MajorKey() const { return ConvertToDouble; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     // Encode the parameters in a unique 16 bit value.
     return  result1_.code() +
            (result2_.code() << 4) +
@@ -1477,7 +1480,7 @@
 
   // Enter the exit frame that transitions from JavaScript to C++.
   FrameScope scope(masm, StackFrame::MANUAL);
-  __ EnterExitFrame(save_doubles_);
+  __ EnterExitFrame(save_doubles());
 
   // s0: number of arguments  including receiver (C callee-saved)
   // s1: pointer to first argument (C callee-saved)
@@ -1564,7 +1567,7 @@
   // sp: stack pointer
   // fp: frame pointer
   // s0: still holds argc (callee-saved).
-  __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
+  __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN);
 
   // Handling of exception.
   __ bind(&exception_returned);
diff --git a/src/mips64/code-stubs-mips64.h b/src/mips64/code-stubs-mips64.h
index 73f19cd..614c3f6 100644
--- a/src/mips64/code-stubs-mips64.h
+++ b/src/mips64/code-stubs-mips64.h
@@ -5,7 +5,7 @@
 #ifndef V8_MIPS_CODE_STUBS_ARM_H_
 #define V8_MIPS_CODE_STUBS_ARM_H_
 
-#include "src/ic-inl.h"
+#include "src/code-stubs.h"
 
 
 namespace v8 {
@@ -29,7 +29,7 @@
   SaveFPRegsMode save_doubles_;
 
   Major MajorKey() const { return StoreBufferOverflow; }
-  int MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
+  uint32_t MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
 };
 
 
@@ -69,7 +69,7 @@
 
  private:
   Major MajorKey() const { return SubString; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -83,7 +83,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);
  private:
   Major MajorKey() const { return StoreRegistersState; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -96,7 +96,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);
  private:
   Major MajorKey() const { return RestoreRegistersState; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -125,7 +125,7 @@
 
  private:
   virtual Major MajorKey() const { return StringCompare; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
   virtual void Generate(MacroAssembler* masm);
 
   static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
@@ -175,7 +175,7 @@
   class SignRegisterBits: public BitField<int, 12, 4> {};
 
   Major MajorKey() const { return WriteInt32ToHeapNumber; }
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     // Encode the parameters in a unique 16 bit value.
     return IntRegisterBits::encode(the_int_.code())
            | HeapNumberRegisterBits::encode(the_heap_number_.code())
@@ -347,7 +347,7 @@
 
   Major MajorKey() const { return RecordWrite; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return ObjectBits::encode(object_.code()) |
         ValueBits::encode(value_.code()) |
         AddressBits::encode(address_.code()) |
@@ -388,7 +388,7 @@
 
  private:
   Major MajorKey() const { return DirectCEntry; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   bool NeedsImmovableCode() { return true; }
 };
@@ -435,7 +435,7 @@
 
   Major MajorKey() const { return NameDictionaryLookup; }
 
-  int MinorKey() const { return LookupModeBits::encode(mode_); }
+  uint32_t MinorKey() const { return LookupModeBits::encode(mode_); }
 
   class LookupModeBits: public BitField<LookupMode, 0, 1> {};
 
diff --git a/src/mips64/codegen-mips64.h b/src/mips64/codegen-mips64.h
index 82a410e..b02ec4f 100644
--- a/src/mips64/codegen-mips64.h
+++ b/src/mips64/codegen-mips64.h
@@ -8,7 +8,7 @@
 
 
 #include "src/ast.h"
-#include "src/ic-inl.h"
+#include "src/macro-assembler.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc
index b874625..dc90608 100644
--- a/src/mips64/full-codegen-mips64.cc
+++ b/src/mips64/full-codegen-mips64.cc
@@ -22,7 +22,6 @@
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
-#include "src/stub-cache.h"
 
 #include "src/mips64/code-stubs-mips64.h"
 #include "src/mips64/macro-assembler-mips64.h"
diff --git a/src/mips64/lithium-codegen-mips64.cc b/src/mips64/lithium-codegen-mips64.cc
index ab0d8c7..42b6ea1 100644
--- a/src/mips64/lithium-codegen-mips64.cc
+++ b/src/mips64/lithium-codegen-mips64.cc
@@ -8,7 +8,6 @@
 #include "src/hydrogen-osr.h"
 #include "src/mips64/lithium-codegen-mips64.h"
 #include "src/mips64/lithium-gap-resolver-mips64.h"
-#include "src/stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -852,7 +851,7 @@
   int length = deoptimizations_.length();
   if (length == 0) return;
   Handle<DeoptimizationInputData> data =
-      DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+      DeoptimizationInputData::New(isolate(), length, TENURED);
 
   Handle<ByteArray> translations =
       translations_.CreateByteArray(isolate()->factory());
@@ -2866,6 +2865,19 @@
 }
 
 
+template <class T>
+void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
+  DCHECK(FLAG_vector_ics);
+  Register vector = ToRegister(instr->temp_vector());
+  DCHECK(vector.is(LoadIC::VectorRegister()));
+  __ li(vector, instr->hydrogen()->feedback_vector());
+  // No need to allocate this register.
+  DCHECK(LoadIC::SlotRegister().is(a0));
+  __ li(LoadIC::SlotRegister(),
+        Operand(Smi::FromInt(instr->hydrogen()->slot())));
+}
+
+
 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
   DCHECK(ToRegister(instr->context()).is(cp));
   DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
@@ -2873,13 +2885,7 @@
 
   __ li(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ li(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(a0));
-    __ li(LoadIC::SlotRegister(),
-          Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
@@ -3021,13 +3027,7 @@
   // Name is always in a2.
   __ li(LoadIC::NameRegister(), Operand(instr->name()));
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ li(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(a0));
-    __ li(LoadIC::SlotRegister(),
-          Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3375,13 +3375,7 @@
   DCHECK(ToRegister(instr->key()).is(LoadIC::NameRegister()));
 
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ li(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(a0));
-    __ li(LoadIC::SlotRegister(),
-          Operand(Smi::FromInt(instr->hydrogen()->slot())));
+    EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
diff --git a/src/mips64/lithium-codegen-mips64.h b/src/mips64/lithium-codegen-mips64.h
index d42a10e..d67abdb 100644
--- a/src/mips64/lithium-codegen-mips64.h
+++ b/src/mips64/lithium-codegen-mips64.h
@@ -365,6 +365,9 @@
   void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
   void DoStoreKeyedFixedArray(LStoreKeyed* instr);
 
+  template <class T>
+  void EmitVectorLoadICRegisters(T* instr);
+
   ZoneList<LEnvironment*> deoptimizations_;
   ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
   ZoneList<Handle<Object> > deoptimization_literals_;
diff --git a/src/objects-inl.h b/src/objects-inl.h
index e2414d2..9289900 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -717,19 +717,9 @@
   // the entry size.
   int length = FixedArray::cast(this)->length();
   if (length == 0) return true;
-  if (length < DeoptimizationInputData::kFirstDeoptEntryIndex) return false;
 
-  FixedArray* self = FixedArray::cast(const_cast<Object*>(this));
-  int deopt_count =
-      Smi::cast(self->get(DeoptimizationInputData::kDeoptEntryCountIndex))
-          ->value();
-  int patch_count =
-      Smi::cast(
-          self->get(
-              DeoptimizationInputData::kReturnAddressPatchEntryCountIndex))
-          ->value();
-
-  return length == DeoptimizationInputData::LengthFor(deopt_count, patch_count);
+  length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
+  return length >= 0 && length % DeoptimizationInputData::kDeoptEntrySize == 0;
 }
 
 
@@ -7022,6 +7012,16 @@
 }
 
 
+Handle<Object> TypeFeedbackInfo::PremonomorphicSentinel(Isolate* isolate) {
+  return isolate->factory()->megamorphic_symbol();
+}
+
+
+Handle<Object> TypeFeedbackInfo::GenericSentinel(Isolate* isolate) {
+  return isolate->factory()->generic_symbol();
+}
+
+
 Handle<Object> TypeFeedbackInfo::MonomorphicArraySentinel(Isolate* isolate,
     ElementsKind elements_kind) {
   return Handle<Object>(Smi::FromInt(static_cast<int>(elements_kind)), isolate);
diff --git a/src/objects.cc b/src/objects.cc
index f223b0f..e3c45c4 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -143,7 +143,7 @@
 
 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object,
                                          Handle<Name> key) {
-  LookupIterator it(object, key, LookupIterator::CHECK_DERIVED_PROPERTY);
+  LookupIterator it(object, key, LookupIterator::PROTOTYPE_CHAIN_PROPERTY);
   return GetDataProperty(&it);
 }
 
@@ -3787,7 +3787,7 @@
 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name,
                            Handle<Object> value,
                            PropertyAttributes attributes) {
-  LookupIterator it(object, name, LookupIterator::CHECK_PROPERTY);
+  LookupIterator it(object, name, LookupIterator::OWN_PROPERTY);
 #ifdef DEBUG
   uint32_t index;
   DCHECK(!object->IsJSProxy());
@@ -3812,8 +3812,7 @@
     PropertyAttributes attributes,
     ExecutableAccessorInfoHandling handling) {
   DCHECK(!value->IsTheHole());
-  LookupIterator it(object, name,
-                    LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR);
+  LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   bool is_observed = object->map()->is_observed() &&
                      *name != it.isolate()->heap()->hidden_string();
   for (; it.IsFound(); it.Next()) {
@@ -3832,7 +3831,6 @@
 
       case LookupIterator::PROPERTY: {
         if (!it.HasProperty()) break;
-        if (it.HolderIsNonGlobalHiddenPrototype()) break;
         PropertyDetails details = it.property_details();
         Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
         switch (it.property_kind()) {
@@ -3984,7 +3982,7 @@
   if (object->IsJSObject() && name->AsArrayIndex(&index)) {
     return GetOwnElementAttribute(object, index);
   }
-  LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN);
+  LookupIterator it(object, name, LookupIterator::HIDDEN);
   return GetPropertyAttributes(&it);
 }
 
@@ -4692,7 +4690,7 @@
 
 bool JSObject::HasHiddenProperties(Handle<JSObject> object) {
   Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
-  LookupIterator it(object, hidden, LookupIterator::CHECK_PROPERTY);
+  LookupIterator it(object, hidden, LookupIterator::OWN_PROPERTY);
   Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
   // Cannot get an exception since the hidden_string isn't accessible to JS.
   DCHECK(maybe.has_value);
@@ -4727,7 +4725,7 @@
   } else {
     Isolate* isolate = GetIsolate();
     LookupIterator it(handle(this), isolate->factory()->hidden_string(),
-                      LookupIterator::CHECK_PROPERTY);
+                      LookupIterator::OWN_PROPERTY);
     if (it.IsFound() && it.HasProperty()) {
       DCHECK_EQ(LookupIterator::DATA, it.property_kind());
       return *it.GetDataValue();
@@ -4923,9 +4921,8 @@
 
   // Skip interceptors on FORCE_DELETION.
   LookupIterator::Configuration config =
-      delete_mode == FORCE_DELETION
-          ? LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR
-          : LookupIterator::CHECK_HIDDEN;
+      delete_mode == FORCE_DELETION ? LookupIterator::HIDDEN_SKIP_INTERCEPTOR
+                                    : LookupIterator::HIDDEN;
 
   LookupIterator it(object, name, config);
 
@@ -6154,8 +6151,7 @@
             Object::GetElement(isolate, object, index).ToHandleChecked();
       }
     } else {
-      LookupIterator it(object, name,
-                        LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR);
+      LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
       CHECK(GetPropertyAttributes(&it).has_value);
       preexists = it.IsFound();
       if (preexists && (it.property_kind() == LookupIterator::DATA ||
@@ -6174,7 +6170,7 @@
            setter->IsNull());
     // At least one of the accessors needs to be a new value.
     DCHECK(!getter->IsNull() || !setter->IsNull());
-    LookupIterator it(object, name, LookupIterator::CHECK_PROPERTY);
+    LookupIterator it(object, name, LookupIterator::OWN_PROPERTY);
     if (!getter->IsNull()) {
       it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes);
     }
@@ -6257,8 +6253,7 @@
     SetElementCallback(object, index, info, info->property_attributes());
   } else {
     // Lookup the name.
-    LookupIterator it(object, name,
-                      LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR);
+    LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
     CHECK(GetPropertyAttributes(&it).has_value);
     // ES5 forbids turning a property into an accessor if it's not
     // configurable. See 8.6.1 (Table 5).
@@ -6316,7 +6311,7 @@
     }
   } else {
     LookupIterator it(object, name,
-                      LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR);
+                      LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
     for (; it.IsFound(); it.Next()) {
       switch (it.state()) {
         case LookupIterator::INTERCEPTOR:
@@ -7933,17 +7928,11 @@
 
 
 Handle<DeoptimizationInputData> DeoptimizationInputData::New(
-    Isolate* isolate, int deopt_entry_count, int return_patch_address_count,
-    PretenureFlag pretenure) {
-  DCHECK(deopt_entry_count + return_patch_address_count > 0);
-  Handle<FixedArray> deoptimization_data =
-      Handle<FixedArray>::cast(isolate->factory()->NewFixedArray(
-          LengthFor(deopt_entry_count, return_patch_address_count), pretenure));
-  deoptimization_data->set(kDeoptEntryCountIndex,
-                           Smi::FromInt(deopt_entry_count));
-  deoptimization_data->set(kReturnAddressPatchEntryCountIndex,
-                           Smi::FromInt(return_patch_address_count));
-  return Handle<DeoptimizationInputData>::cast(deoptimization_data);
+    Isolate* isolate, int deopt_entry_count, PretenureFlag pretenure) {
+  DCHECK(deopt_entry_count > 0);
+  return Handle<DeoptimizationInputData>::cast(
+      isolate->factory()->NewFixedArray(LengthFor(deopt_entry_count),
+                                        pretenure));
 }
 
 
@@ -10291,26 +10280,7 @@
 
 SafepointEntry Code::GetSafepointEntry(Address pc) {
   SafepointTable table(this);
-  SafepointEntry entry = table.FindEntry(pc);
-  if (entry.is_valid() || !is_turbofanned()) {
-    return entry;
-  }
-
-  // If the code is turbofanned, we might be looking for
-  // an address that was patched by lazy deoptimization.
-  // In that case look through the patch table, try to
-  // lookup the original address there, and then use this
-  // to find the safepoint entry.
-  DeoptimizationInputData* deopt_data =
-      DeoptimizationInputData::cast(deoptimization_data());
-  intptr_t offset = pc - instruction_start();
-  for (int i = 0; i < deopt_data->ReturnAddressPatchCount(); i++) {
-    if (deopt_data->PatchedAddressPc(i)->value() == offset) {
-      int original_offset = deopt_data->ReturnAddressPc(i)->value();
-      return table.FindEntry(instruction_start() + original_offset);
-    }
-  }
-  return SafepointEntry();
+  return table.FindEntry(pc);
 }
 
 
@@ -10863,19 +10833,6 @@
       os << "\n";
     }
   }
-
-  int return_address_patch_count = ReturnAddressPatchCount();
-  if (return_address_patch_count != 0) {
-    os << "Return address patch data (count = " << return_address_patch_count
-       << ")\n";
-    os << " index    pc  patched_pc\n";
-  }
-  for (int i = 0; i < return_address_patch_count; i++) {
-    Vector<char> buf = Vector<char>::New(128);
-    SNPrintF(buf, "%6d  %6d  %12d\n", i, ReturnAddressPc(i)->value(),
-             PatchedAddressPc(i)->value());
-    os << buf.start();
-  }
 }
 
 
@@ -11006,6 +10963,13 @@
       } else {
         os << "<none>";
       }
+      if (entry.deoptimization_pc() != Safepoint::kNoDeoptimizationPc) {
+        Vector<char> buf2 = Vector<char>::New(30);
+        SNPrintF(buf2, "%6d", entry.deoptimization_pc());
+        os << buf2.start();
+      } else {
+        os << "<none>";
+      }
       if (entry.argument_count() > 0) {
         os << " argc: " << entry.argument_count();
       }
@@ -11708,10 +11672,9 @@
       return "allocation-site-tenuring-changed";
     case kAllocationSiteTransitionChangedGroup:
       return "allocation-site-transition-changed";
-    default:
-      UNREACHABLE();
-      return "?";
   }
+  UNREACHABLE();
+  return "?";
 }
 
 
@@ -12875,12 +12838,12 @@
 
 
 bool JSArray::IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map) {
-    Isolate* isolate = jsarray_map->GetIsolate();
-    DCHECK(!jsarray_map->is_dictionary_map());
-    LookupResult lookup(isolate);
-    Handle<Name> length_string = isolate->factory()->length_string();
-    jsarray_map->LookupDescriptor(NULL, *length_string, &lookup);
-    return lookup.IsReadOnly();
+  Isolate* isolate = jsarray_map->GetIsolate();
+  DCHECK(!jsarray_map->is_dictionary_map());
+  LookupResult lookup(isolate);
+  Handle<Name> length_string = isolate->factory()->length_string();
+  jsarray_map->LookupDescriptor(NULL, *length_string, &lookup);
+  return lookup.IsReadOnly();
 }
 
 
@@ -12890,7 +12853,7 @@
   CHECK(array->length()->ToArrayIndex(&length));
   if (length <= index) {
     LookupIterator it(array, array->GetIsolate()->factory()->length_string(),
-                      LookupIterator::CHECK_PROPERTY);
+                      LookupIterator::OWN_PROPERTY);
     CHECK(it.IsFound());
     CHECK(it.HasProperty());
     return it.IsReadOnly();
@@ -13277,7 +13240,7 @@
 
 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
                                            Handle<Name> key) {
-  LookupIterator it(object, key, LookupIterator::CHECK_ACCESS_CHECK);
+  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
   if (!maybe_result.has_value) return Maybe<bool>();
   return maybe(it.IsFound());
@@ -13315,7 +13278,7 @@
 
 Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
                                                    Handle<Name> key) {
-  LookupIterator it(object, key, LookupIterator::CHECK_ACCESS_CHECK);
+  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
   if (!maybe_result.has_value) return Maybe<bool>();
   return maybe(it.IsFound() && it.property_kind() == LookupIterator::ACCESSOR);
@@ -14646,13 +14609,6 @@
 }
 
 
-PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
-  DCHECK(!HasFastProperties());
-  Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
-  return PropertyCell::cast(value);
-}
-
-
 Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell(
     Handle<JSGlobalObject> global,
     Handle<Name> name) {
diff --git a/src/objects.h b/src/objects.h
index 3c814f2..4ba4c95 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5151,16 +5151,14 @@
 class DeoptimizationInputData: public FixedArray {
  public:
   // Layout description.  Indices in the array.
-  static const int kDeoptEntryCountIndex = 0;
-  static const int kReturnAddressPatchEntryCountIndex = 1;
-  static const int kTranslationByteArrayIndex = 2;
-  static const int kInlinedFunctionCountIndex = 3;
-  static const int kLiteralArrayIndex = 4;
-  static const int kOsrAstIdIndex = 5;
-  static const int kOsrPcOffsetIndex = 6;
-  static const int kOptimizationIdIndex = 7;
-  static const int kSharedFunctionInfoIndex = 8;
-  static const int kFirstDeoptEntryIndex = 9;
+  static const int kTranslationByteArrayIndex = 0;
+  static const int kInlinedFunctionCountIndex = 1;
+  static const int kLiteralArrayIndex = 2;
+  static const int kOsrAstIdIndex = 3;
+  static const int kOsrPcOffsetIndex = 4;
+  static const int kOptimizationIdIndex = 5;
+  static const int kSharedFunctionInfoIndex = 6;
+  static const int kFirstDeoptEntryIndex = 7;
 
   // Offsets of deopt entry elements relative to the start of the entry.
   static const int kAstIdRawOffset = 0;
@@ -5169,12 +5167,6 @@
   static const int kPcOffset = 3;
   static const int kDeoptEntrySize = 4;
 
-  // Offsets of return address patch entry elements relative to the start of the
-  // entry
-  static const int kReturnAddressPcOffset = 0;
-  static const int kPatchedAddressPcOffset = 1;
-  static const int kReturnAddressPatchEntrySize = 2;
-
   // Simple element accessors.
 #define DEFINE_ELEMENT_ACCESSORS(name, type)      \
   type* name() {                                  \
@@ -5195,7 +5187,7 @@
 #undef DEFINE_ELEMENT_ACCESSORS
 
   // Accessors for elements of the ith deoptimization entry.
-#define DEFINE_DEOPT_ENTRY_ACCESSORS(name, type)                \
+#define DEFINE_ENTRY_ACCESSORS(name, type)                      \
   type* name(int i) {                                           \
     return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
   }                                                             \
@@ -5203,28 +5195,13 @@
     set(IndexForEntry(i) + k##name##Offset, value);             \
   }
 
-  DEFINE_DEOPT_ENTRY_ACCESSORS(AstIdRaw, Smi)
-  DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
-  DEFINE_DEOPT_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
-  DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
+  DEFINE_ENTRY_ACCESSORS(AstIdRaw, Smi)
+  DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
+  DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
+  DEFINE_ENTRY_ACCESSORS(Pc, Smi)
 
 #undef DEFINE_DEOPT_ENTRY_ACCESSORS
 
-// Accessors for elements of the ith deoptimization entry.
-#define DEFINE_PATCH_ENTRY_ACCESSORS(name, type)                      \
-  type* name(int i) {                                                 \
-    return type::cast(                                                \
-        get(IndexForReturnAddressPatchEntry(i) + k##name##Offset));   \
-  }                                                                   \
-  void Set##name(int i, type* value) {                                \
-    set(IndexForReturnAddressPatchEntry(i) + k##name##Offset, value); \
-  }
-
-  DEFINE_PATCH_ENTRY_ACCESSORS(ReturnAddressPc, Smi)
-  DEFINE_PATCH_ENTRY_ACCESSORS(PatchedAddressPc, Smi)
-
-#undef DEFINE_PATCH_ENTRY_ACCESSORS
-
   BailoutId AstId(int i) {
     return BailoutId(AstIdRaw(i)->value());
   }
@@ -5234,19 +5211,12 @@
   }
 
   int DeoptCount() {
-    return length() == 0 ? 0 : Smi::cast(get(kDeoptEntryCountIndex))->value();
-  }
-
-  int ReturnAddressPatchCount() {
-    return length() == 0
-               ? 0
-               : Smi::cast(get(kReturnAddressPatchEntryCountIndex))->value();
+    return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
   }
 
   // Allocates a DeoptimizationInputData.
   static Handle<DeoptimizationInputData> New(Isolate* isolate,
                                              int deopt_entry_count,
-                                             int return_address_patch_count,
                                              PretenureFlag pretenure);
 
   DECLARE_CAST(DeoptimizationInputData)
@@ -5256,21 +5226,12 @@
 #endif
 
  private:
-  friend class Object;  // For accessing LengthFor.
-
   static int IndexForEntry(int i) {
     return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
   }
 
-  int IndexForReturnAddressPatchEntry(int i) {
-    return kFirstDeoptEntryIndex + (DeoptCount() * kDeoptEntrySize) +
-           (i * kReturnAddressPatchEntrySize);
-  }
 
-  static int LengthFor(int deopt_count, int return_address_patch_count) {
-    return kFirstDeoptEntryIndex + (deopt_count * kDeoptEntrySize) +
-           (return_address_patch_count * kReturnAddressPatchEntrySize);
-  }
+  static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
 };
 
 
@@ -5924,10 +5885,11 @@
     kAllocationSiteTenuringChangedGroup,
     // Group of code that depends on element transition information in
     // AllocationSites not being changed.
-    kAllocationSiteTransitionChangedGroup,
-    kGroupCount = kAllocationSiteTransitionChangedGroup + 1
+    kAllocationSiteTransitionChangedGroup
   };
 
+  static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
+
   // Array for holding the index of the first code object of each group.
   // The last element stores the total number of code objects.
   class GroupStartIndexes {
@@ -7836,9 +7798,6 @@
   // [global proxy]: the global proxy object of the context
   DECL_ACCESSORS(global_proxy, JSObject)
 
-  // Retrieve the property cell used to store a property.
-  PropertyCell* GetPropertyCell(LookupResult* result);
-
   DECLARE_CAST(GlobalObject)
 
   // Layout description.
@@ -8449,6 +8408,12 @@
   // The object that indicates a megamorphic state.
   static inline Handle<Object> MegamorphicSentinel(Isolate* isolate);
 
+  // The object that indicates a premonomorphic state.
+  static inline Handle<Object> PremonomorphicSentinel(Isolate* isolate);
+
+  // The object that indicates a generic state.
+  static inline Handle<Object> GenericSentinel(Isolate* isolate);
+
   // The object that indicates a monomorphic state of Array with
   // ElementsKind
   static inline Handle<Object> MonomorphicArraySentinel(Isolate* isolate,
diff --git a/src/regexp.js b/src/regexp.js
index 1a2a4f0..d8e3ea4 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -394,7 +394,7 @@
   // The length of compile is 1 in SpiderMonkey.
   %FunctionSetLength($RegExp.prototype.compile, 1);
 
-  // The properties input, $input, and $_ are aliases for each other.  When this
+  // The properties `input` and `$_` are aliases for each other.  When this
   // value is set the value it is set to is coerced to a string.
   // Getter and setter for the input.
   var RegExpGetInput = function() {
diff --git a/src/runtime.cc b/src/runtime.cc
index 1616434..63a57e9 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1714,7 +1714,8 @@
       Handle<Object> key(table->KeyAt(i), isolate);
       if (table->IsKey(*key)) {
         entries->set(number_of_non_hole_elements++, *key);
-        entries->set(number_of_non_hole_elements++, table->Lookup(key));
+        Object* value = table->Lookup(key);
+        entries->set(number_of_non_hole_elements++, value);
       }
     }
     DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
@@ -1980,7 +1981,7 @@
     }
   } else {
     // Get attributes.
-    LookupIterator it(obj, name, LookupIterator::CHECK_HIDDEN);
+    LookupIterator it(obj, name, LookupIterator::HIDDEN);
     Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
     if (!maybe.has_value) return MaybeHandle<Object>();
     attrs = maybe.value;
@@ -2178,7 +2179,7 @@
                               PropertyAttributes attr, bool is_var,
                               bool is_const, bool is_function) {
   // Do the lookup own properties only, see ES5 erratum.
-  LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN_PROPERTY);
+  LookupIterator it(global, name, LookupIterator::HIDDEN_PROPERTY);
   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   DCHECK(maybe.has_value);
   PropertyAttributes old_attributes = maybe.value;
@@ -2308,7 +2309,7 @@
   Handle<GlobalObject> global = isolate->global_object();
 
   // Lookup the property as own on the global object.
-  LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN_PROPERTY);
+  LookupIterator it(global, name, LookupIterator::HIDDEN_PROPERTY);
   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   DCHECK(maybe.has_value);
   PropertyAttributes old_attributes = maybe.value;
@@ -2458,7 +2459,7 @@
     // code can run in between that modifies the declared property.
     DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
 
-    LookupIterator it(holder, name, LookupIterator::CHECK_HIDDEN_PROPERTY);
+    LookupIterator it(holder, name, LookupIterator::HIDDEN_PROPERTY);
     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
     if (!maybe.has_value) return isolate->heap()->exception();
     PropertyAttributes old_attributes = maybe.value;
@@ -4889,7 +4890,7 @@
         }
         // Lookup cache miss.  Perform lookup and update the cache if
         // appropriate.
-        LookupIterator it(receiver, key, LookupIterator::CHECK_OWN);
+        LookupIterator it(receiver, key, LookupIterator::OWN);
         if (it.IsFound() && it.state() == LookupIterator::PROPERTY &&
             it.HasProperty() && it.property_details().type() == FIELD) {
           FieldIndex field_index = it.GetFieldIndex();
@@ -5045,7 +5046,7 @@
     return isolate->heap()->undefined_value();
   }
 
-  LookupIterator it(js_object, name, LookupIterator::CHECK_PROPERTY);
+  LookupIterator it(js_object, name, LookupIterator::OWN_PROPERTY);
 
   // Take special care when attributes are different and there is already
   // a property.
@@ -5293,7 +5294,7 @@
 #ifdef DEBUG
   uint32_t index = 0;
   DCHECK(!key->ToArrayIndex(&index));
-  LookupIterator it(object, key, LookupIterator::CHECK_PROPERTY);
+  LookupIterator it(object, key, LookupIterator::OWN_PROPERTY);
   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
   DCHECK(maybe.has_value);
   RUNTIME_ASSERT(!it.IsFound());
@@ -5325,7 +5326,7 @@
   bool duplicate;
   if (key->IsName()) {
     LookupIterator it(object, Handle<Name>::cast(key),
-                      LookupIterator::CHECK_PROPERTY);
+                      LookupIterator::OWN_PROPERTY);
     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
     DCHECK(maybe.has_value);
     duplicate = it.IsFound();
@@ -6010,6 +6011,10 @@
 
   HandleScope scope(isolate);
   if (raw_key->IsSymbol()) {
+    Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
+    if (symbol->Equals(isolate->native_context()->iterator_symbol())) {
+      return isolate->native_context()->array_values_iterator();
+    }
     // Lookup in the initial Object.prototype object.
     Handle<Object> result;
     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
@@ -10894,8 +10899,8 @@
 }
 
 
-static Handle<Object> DebugLookupResultValue(LookupIterator* it,
-                                             bool* has_caught = NULL) {
+static Handle<Object> DebugGetProperty(LookupIterator* it,
+                                       bool* has_caught = NULL) {
   for (; it->IsFound(); it->Next()) {
     switch (it->state()) {
       case LookupIterator::NOT_FOUND:
@@ -10979,9 +10984,9 @@
     return *isolate->factory()->NewJSArrayWithElements(details);
   }
 
-  LookupIterator it(obj, name, LookupIterator::CHECK_HIDDEN);
+  LookupIterator it(obj, name, LookupIterator::HIDDEN);
   bool has_caught = false;
-  Handle<Object> value = DebugLookupResultValue(&it, &has_caught);
+  Handle<Object> value = DebugGetProperty(&it, &has_caught);
   if (!it.IsFound()) return isolate->heap()->undefined_value();
 
   Handle<Object> maybe_pair;
@@ -11020,8 +11025,8 @@
   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
 
-  LookupIterator it(obj, name, LookupIterator::CHECK_DERIVED);
-  return *DebugLookupResultValue(&it);
+  LookupIterator it(obj, name);
+  return *DebugGetProperty(&it);
 }
 
 
diff --git a/src/safepoint-table.cc b/src/safepoint-table.cc
index d00b751..5f91547 100644
--- a/src/safepoint-table.cc
+++ b/src/safepoint-table.cc
@@ -43,8 +43,8 @@
   length_ = Memory::uint32_at(header + kLengthOffset);
   entry_size_ = Memory::uint32_at(header + kEntrySizeOffset);
   pc_and_deoptimization_indexes_ = header + kHeaderSize;
-  entries_ = pc_and_deoptimization_indexes_ +
-            (length_ * kPcAndDeoptimizationIndexSize);
+  entries_ =
+      pc_and_deoptimization_indexes_ + (length_ * kPcAndDeoptimizationInfoSize);
   DCHECK(entry_size_ > 0);
   STATIC_ASSERT(SafepointEntry::DeoptimizationIndexField::kMax ==
                 Safepoint::kNoDeoptimizationIndex);
@@ -56,6 +56,7 @@
   for (unsigned i = 0; i < length(); i++) {
     // TODO(kasperl): Replace the linear search with binary search.
     if (GetPcOffset(i) == pc_offset) return GetEntry(i);
+    if (GetDeoptimizationPcOffset(i) == pc_offset) return GetEntry(i);
   }
   return SafepointEntry();
 }
@@ -110,6 +111,8 @@
   info.pc = assembler->pc_offset();
   info.arguments = arguments;
   info.has_doubles = (kind & Safepoint::kWithDoubles);
+  info.deoptimization_pc = Safepoint::kNoDeoptimizationPc;
+  int safepoint_id = deoptimization_info_.length();
   deoptimization_info_.Add(info, zone_);
   deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_);
   if (deopt_mode == Safepoint::kNoLazyDeopt) {
@@ -120,7 +123,7 @@
       ? new(zone_) ZoneList<int>(4, zone_)
       : NULL,
       zone_);
-  return Safepoint(indexes_.last(), registers_.last());
+  return Safepoint(safepoint_id, indexes_.last(), registers_.last());
 }
 
 
@@ -159,6 +162,7 @@
     assembler->dd(deoptimization_info_[i].pc);
     assembler->dd(EncodeExceptPC(deoptimization_info_[i],
                                  deopt_index_list_[i]));
+    assembler->dd(deoptimization_info_[i].deoptimization_pc);
   }
 
   // Emit table of bitmaps.
diff --git a/src/safepoint-table.h b/src/safepoint-table.h
index 0bdd431..d91a195 100644
--- a/src/safepoint-table.h
+++ b/src/safepoint-table.h
@@ -17,9 +17,10 @@
 
 class SafepointEntry BASE_EMBEDDED {
  public:
-  SafepointEntry() : info_(0), bits_(NULL) {}
+  SafepointEntry() : info_(0), deoptimization_pc_(0), bits_(NULL) {}
 
-  SafepointEntry(unsigned info, uint8_t* bits) : info_(info), bits_(bits) {
+  SafepointEntry(unsigned info, unsigned deoptimization_pc, uint8_t* bits)
+      : info_(info), deoptimization_pc_(deoptimization_pc), bits_(bits) {
     DCHECK(is_valid());
   }
 
@@ -39,6 +40,11 @@
     return DeoptimizationIndexField::decode(info_);
   }
 
+  unsigned deoptimization_pc() const {
+    DCHECK(is_valid());
+    return deoptimization_pc_;
+  }
+
   static const int kArgumentsFieldBits = 3;
   static const int kSaveDoublesFieldBits = 1;
   static const int kDeoptIndexBits =
@@ -74,6 +80,7 @@
 
  private:
   unsigned info_;
+  unsigned deoptimization_pc_;
   uint8_t* bits_;
 };
 
@@ -84,7 +91,8 @@
 
   int size() const {
     return kHeaderSize +
-           (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); }
+           (length_ * (kPcAndDeoptimizationInfoSize + entry_size_));
+  }
   unsigned length() const { return length_; }
   unsigned entry_size() const { return entry_size_; }
 
@@ -93,11 +101,17 @@
     return Memory::uint32_at(GetPcOffsetLocation(index));
   }
 
+  unsigned GetDeoptimizationPcOffset(unsigned index) const {
+    DCHECK(index < length_);
+    return Memory::uint32_at(GetDeoptimizationPcLocation(index));
+  }
+
   SafepointEntry GetEntry(unsigned index) const {
     DCHECK(index < length_);
     unsigned info = Memory::uint32_at(GetInfoLocation(index));
+    unsigned deopt_pc = Memory::uint32_at(GetDeoptimizationPcLocation(index));
     uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_));
-    return SafepointEntry(info, bits);
+    return SafepointEntry(info, deopt_pc, bits);
   }
 
   // Returns the entry for the given pc.
@@ -114,18 +128,23 @@
 
   static const int kPcSize = kIntSize;
   static const int kDeoptimizationIndexSize = kIntSize;
-  static const int kPcAndDeoptimizationIndexSize =
-      kPcSize + kDeoptimizationIndexSize;
+  static const int kDeoptimizationPcSize = kIntSize;
+  static const int kPcAndDeoptimizationInfoSize =
+      kPcSize + kDeoptimizationIndexSize + kDeoptimizationPcSize;
 
   Address GetPcOffsetLocation(unsigned index) const {
     return pc_and_deoptimization_indexes_ +
-           (index * kPcAndDeoptimizationIndexSize);
+           (index * kPcAndDeoptimizationInfoSize);
   }
 
   Address GetInfoLocation(unsigned index) const {
     return GetPcOffsetLocation(index) + kPcSize;
   }
 
+  Address GetDeoptimizationPcLocation(unsigned index) const {
+    return GetInfoLocation(index) + kDeoptimizationIndexSize;
+  }
+
   static void PrintBits(OStream& os,  // NOLINT
                         uint8_t byte, int digits);
 
@@ -158,15 +177,30 @@
     kLazyDeopt
   };
 
+  class Id {
+   private:
+    explicit Id(int id) : id_(id) {}
+
+    int id_;
+
+    friend class SafepointTableBuilder;
+    friend class Safepoint;
+  };
+
   static const int kNoDeoptimizationIndex =
       (1 << (SafepointEntry::kDeoptIndexBits)) - 1;
 
+  static const unsigned kNoDeoptimizationPc = ~0U;
+
   void DefinePointerSlot(int index, Zone* zone) { indexes_->Add(index, zone); }
   void DefinePointerRegister(Register reg, Zone* zone);
 
+  Id id() const { return Id(id_); }
+
  private:
-  Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) :
-      indexes_(indexes), registers_(registers) { }
+  Safepoint(int id, ZoneList<int>* indexes, ZoneList<int>* registers)
+      : id_(id), indexes_(indexes), registers_(registers) {}
+  int id_;
   ZoneList<int>* indexes_;
   ZoneList<int>* registers_;
 
@@ -200,6 +234,11 @@
   void BumpLastLazySafepointIndex() {
     last_lazy_safepoint_ = deopt_index_list_.length();
   }
+  void SetDeoptimizationPc(Safepoint::Id safepoint_id,
+                           unsigned deoptimization_pc) {
+    deoptimization_info_[safepoint_id.id_].deoptimization_pc =
+        deoptimization_pc;
+  }
 
   // Emit the safepoint table after the body. The number of bits per
   // entry must be enough to hold all the pointer indexes.
@@ -211,6 +250,7 @@
     unsigned pc;
     unsigned arguments;
     bool has_doubles;
+    unsigned deoptimization_pc;
   };
 
   uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index);
diff --git a/src/version.cc b/src/version.cc
index 6efbd75..e7ecf4a 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     29
-#define BUILD_NUMBER      16
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      17
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 694c77d..55eede6 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -9,7 +9,7 @@
 #include "src/bootstrapper.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
-#include "src/ic/ic-compiler.h"
+#include "src/ic/handler-compiler.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -2435,11 +2435,11 @@
 
   // Enter the exit frame that transitions from JavaScript to C++.
 #ifdef _WIN64
-  int arg_stack_space = (result_size_ < 2 ? 2 : 4);
-#else
+  int arg_stack_space = (result_size() < 2 ? 2 : 4);
+#else   // _WIN64
   int arg_stack_space = 0;
-#endif
-  __ EnterExitFrame(arg_stack_space, save_doubles_);
+#endif  // _WIN64
+  __ EnterExitFrame(arg_stack_space, save_doubles());
 
   // rbx: pointer to builtin function  (C callee-saved).
   // rbp: frame pointer of exit frame  (restored after C call).
@@ -2461,14 +2461,14 @@
   // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9.
   // Pass argv and argc as two parameters. The arguments object will
   // be created by stubs declared by DECLARE_RUNTIME_FUNCTION().
-  if (result_size_ < 2) {
+  if (result_size() < 2) {
     // Pass a pointer to the Arguments object as the first argument.
     // Return result in single register (rax).
     __ movp(rcx, r14);  // argc.
     __ movp(rdx, r15);  // argv.
     __ Move(r8, ExternalReference::isolate_address(isolate()));
   } else {
-    DCHECK_EQ(2, result_size_);
+    DCHECK_EQ(2, result_size());
     // Pass a pointer to the result location as the first argument.
     __ leap(rcx, StackSpaceOperand(2));
     // Pass a pointer to the Arguments object as the second argument.
@@ -2482,21 +2482,21 @@
   __ movp(rdi, r14);  // argc.
   __ movp(rsi, r15);  // argv.
   __ Move(rdx, ExternalReference::isolate_address(isolate()));
-#endif
+#endif  // _WIN64
   __ call(rbx);
   // Result is in rax - do not destroy this register!
 
 #ifdef _WIN64
   // If return value is on the stack, pop it to registers.
-  if (result_size_ > 1) {
-    DCHECK_EQ(2, result_size_);
+  if (result_size() > 1) {
+    DCHECK_EQ(2, result_size());
     // Read result values stored on stack. Result is stored
     // above the four argument mirror slots and the two
     // Arguments object slots.
     __ movq(rax, Operand(rsp, 6 * kRegisterSize));
     __ movq(rdx, Operand(rsp, 7 * kRegisterSize));
   }
-#endif
+#endif  // _WIN64
 
   // Runtime functions should not return 'the hole'.  Allowing it to escape may
   // lead to crashes in the IC code later.
@@ -2530,7 +2530,7 @@
   }
 
   // Exit the JavaScript to C++ exit frame.
-  __ LeaveExitFrame(save_doubles_);
+  __ LeaveExitFrame(save_doubles());
   __ ret(0);
 
   // Handling of exception.
diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h
index a020ce5..0732a93 100644
--- a/src/x64/code-stubs-x64.h
+++ b/src/x64/code-stubs-x64.h
@@ -27,7 +27,7 @@
   SaveFPRegsMode save_doubles_;
 
   Major MajorKey() const { return StoreBufferOverflow; }
-  int MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
+  uint32_t MinorKey() const { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
 };
 
 
@@ -67,7 +67,7 @@
 
  private:
   Major MajorKey() const { return SubString; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -96,7 +96,7 @@
 
  private:
   virtual Major MajorKey() const { return StringCompare; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
   virtual void Generate(MacroAssembler* masm);
 
   static void GenerateAsciiCharsCompareLoop(
@@ -158,7 +158,7 @@
 
   Major MajorKey() const { return NameDictionaryLookup; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return DictionaryBits::encode(dictionary_.code()) |
         ResultBits::encode(result_.code()) |
         IndexBits::encode(index_.code()) |
@@ -389,7 +389,7 @@
 
   Major MajorKey() const { return RecordWrite; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return ObjectBits::encode(object_.code()) |
         ValueBits::encode(value_.code()) |
         AddressBits::encode(address_.code()) |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 0a6ac17..928b874 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -810,7 +810,7 @@
   int length = deoptimizations_.length();
   if (length == 0) return;
   Handle<DeoptimizationInputData> data =
-      DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+      DeoptimizationInputData::New(isolate(), length, TENURED);
 
   Handle<ByteArray> translations =
       translations_.CreateByteArray(isolate()->factory());
@@ -2846,6 +2846,18 @@
 }
 
 
+template <class T>
+void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
+  DCHECK(FLAG_vector_ics);
+  Register vector = ToRegister(instr->temp_vector());
+  DCHECK(vector.is(LoadIC::VectorRegister()));
+  __ Move(vector, instr->hydrogen()->feedback_vector());
+  // No need to allocate this register.
+  DCHECK(LoadIC::SlotRegister().is(rax));
+  __ Move(LoadIC::SlotRegister(), Smi::FromInt(instr->hydrogen()->slot()));
+}
+
+
 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
   DCHECK(ToRegister(instr->context()).is(rsi));
   DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
@@ -2853,12 +2865,7 @@
 
   __ Move(LoadIC::NameRegister(), instr->name());
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Move(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(rax));
-    __ Move(LoadIC::SlotRegister(), Smi::FromInt(instr->hydrogen()->slot()));
+    EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
@@ -3001,12 +3008,7 @@
 
   __ Move(LoadIC::NameRegister(), instr->name());
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Move(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(rax));
-    __ Move(LoadIC::SlotRegister(), Smi::FromInt(instr->hydrogen()->slot()));
+    EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
   Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3289,12 +3291,7 @@
   DCHECK(ToRegister(instr->key()).is(LoadIC::NameRegister()));
 
   if (FLAG_vector_ics) {
-    Register vector = ToRegister(instr->temp_vector());
-    DCHECK(vector.is(LoadIC::VectorRegister()));
-    __ Move(vector, instr->hydrogen()->feedback_vector());
-    // No need to allocate this register.
-    DCHECK(LoadIC::SlotRegister().is(rax));
-    __ Move(LoadIC::SlotRegister(), Smi::FromInt(instr->hydrogen()->slot()));
+    EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index b3070c0..66a1d84 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -314,6 +314,10 @@
   void DoStoreKeyedExternalArray(LStoreKeyed* instr);
   void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
   void DoStoreKeyedFixedArray(LStoreKeyed* instr);
+
+  template <class T>
+  void EmitVectorLoadICRegisters(T* instr);
+
 #ifdef _MSC_VER
   // On windows, you may not access the stack more than one page below
   // the most recently mapped page. To make the allocated area randomly
diff --git a/src/x87/builtins-x87.cc b/src/x87/builtins-x87.cc
index 59ecda3..f7feaff 100644
--- a/src/x87/builtins-x87.cc
+++ b/src/x87/builtins-x87.cc
@@ -9,7 +9,6 @@
 #include "src/codegen.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen.h"
-#include "src/stub-cache.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc
index 6191aaf..b5b6ba0 100644
--- a/src/x87/code-stubs-x87.cc
+++ b/src/x87/code-stubs-x87.cc
@@ -9,11 +9,11 @@
 #include "src/bootstrapper.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
+#include "src/ic/ic-compiler.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
 #include "src/runtime.h"
-#include "src/stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -2240,7 +2240,7 @@
   // edi: number of arguments including receiver  (C callee-saved)
   // esi: pointer to the first argument (C callee-saved)
 
-  // Result returned in eax, or eax+edx if result_size_ is 2.
+  // Result returned in eax, or eax+edx if result size is 2.
 
   // Check stack alignment.
   if (FLAG_debug_code) {
diff --git a/src/x87/code-stubs-x87.h b/src/x87/code-stubs-x87.h
index e32902f..5f42573 100644
--- a/src/x87/code-stubs-x87.h
+++ b/src/x87/code-stubs-x87.h
@@ -5,8 +5,7 @@
 #ifndef V8_X87_CODE_STUBS_X87_H_
 #define V8_X87_CODE_STUBS_X87_H_
 
-#include "src/ic-inl.h"
-#include "src/macro-assembler.h"
+#include "src/code-stubs.h"
 
 namespace v8 {
 namespace internal {
@@ -29,7 +28,7 @@
 
  private:
   Major MajorKey() const { return StoreBufferOverflow; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 };
 
 
@@ -69,7 +68,7 @@
 
  private:
   Major MajorKey() const { return SubString; }
-  int MinorKey() const { return 0; }
+  uint32_t MinorKey() const { return 0; }
 
   void Generate(MacroAssembler* masm);
 };
@@ -97,7 +96,7 @@
 
  private:
   virtual Major MajorKey() const { return StringCompare; }
-  virtual int MinorKey() const { return 0; }
+  virtual uint32_t MinorKey() const { return 0; }
   virtual void Generate(MacroAssembler* masm);
 
   static void GenerateAsciiCharsCompareLoop(
@@ -156,7 +155,7 @@
 
   Major MajorKey() const { return NameDictionaryLookup; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return DictionaryBits::encode(dictionary_.code()) |
         ResultBits::encode(result_.code()) |
         IndexBits::encode(index_.code()) |
@@ -384,7 +383,7 @@
 
   Major MajorKey() const { return RecordWrite; }
 
-  int MinorKey() const {
+  uint32_t MinorKey() const {
     return ObjectBits::encode(object_.code()) |
         ValueBits::encode(value_.code()) |
         AddressBits::encode(address_.code()) |
diff --git a/src/x87/codegen-x87.h b/src/x87/codegen-x87.h
index 15b2702..c23e866 100644
--- a/src/x87/codegen-x87.h
+++ b/src/x87/codegen-x87.h
@@ -6,7 +6,7 @@
 #define V8_X87_CODEGEN_X87_H_
 
 #include "src/ast.h"
-#include "src/ic-inl.h"
+#include "src/macro-assembler.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc
index c360353..a9ea85a 100644
--- a/src/x87/full-codegen-x87.cc
+++ b/src/x87/full-codegen-x87.cc
@@ -14,7 +14,6 @@
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
-#include "src/stub-cache.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc
index 4116b46..9654133 100644
--- a/src/x87/lithium-codegen-x87.cc
+++ b/src/x87/lithium-codegen-x87.cc
@@ -10,8 +10,6 @@
 #include "src/codegen.h"
 #include "src/deoptimizer.h"
 #include "src/hydrogen-osr.h"
-#include "src/ic.h"
-#include "src/stub-cache.h"
 #include "src/x87/lithium-codegen-x87.h"
 
 namespace v8 {
@@ -1095,7 +1093,7 @@
   int length = deoptimizations_.length();
   if (length == 0) return;
   Handle<DeoptimizationInputData> data =
-      DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+      DeoptimizationInputData::New(isolate(), length, TENURED);
 
   Handle<ByteArray> translations =
       translations_.CreateByteArray(isolate()->factory());
diff --git a/test/base-unittests/bits-unittest.cc b/test/base-unittests/bits-unittest.cc
index 56d3d92..9113675 100644
--- a/test/base-unittests/bits-unittest.cc
+++ b/test/base-unittests/bits-unittest.cc
@@ -10,13 +10,13 @@
 namespace base {
 namespace bits {
 
-TEST(BitsTest, CountSetBits32) {
-  EXPECT_EQ(0u, CountSetBits32(0));
-  EXPECT_EQ(1u, CountSetBits32(1));
-  EXPECT_EQ(8u, CountSetBits32(0x11111111));
-  EXPECT_EQ(16u, CountSetBits32(0xf0f0f0f0));
-  EXPECT_EQ(24u, CountSetBits32(0xfff0f0ff));
-  EXPECT_EQ(32u, CountSetBits32(0xffffffff));
+TEST(BitsTest, CountPopulation32) {
+  EXPECT_EQ(0u, CountPopulation32(0));
+  EXPECT_EQ(1u, CountPopulation32(1));
+  EXPECT_EQ(8u, CountPopulation32(0x11111111));
+  EXPECT_EQ(16u, CountPopulation32(0xf0f0f0f0));
+  EXPECT_EQ(24u, CountPopulation32(0xfff0f0ff));
+  EXPECT_EQ(32u, CountPopulation32(0xffffffff));
 }
 
 
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 0278056..90617c9 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -84,9 +84,6 @@
   ##############################################################################
   # TurboFan compiler failures.
 
-  # TODO(mstarzinger): These need investigation and are not categorized yet.
-  'test-heap/NextCodeLinkIsWeak': [PASS, NO_VARIANTS],
-
   # TODO(mstarzinger): Sometimes the try-catch blacklist fails.
   'test-debug/DebugEvaluateWithoutStack': [PASS, NO_VARIANTS],
   'test-debug/MessageQueues': [PASS, NO_VARIANTS],
diff --git a/test/cctest/compiler/call-tester.h b/test/cctest/compiler/call-tester.h
index 27c6044..1dbed16 100644
--- a/test/cctest/compiler/call-tester.h
+++ b/test/cctest/compiler/call-tester.h
@@ -86,12 +86,24 @@
 };
 
 template <>
+struct ReturnValueTraits<uint16_t> {
+  static uint16_t Cast(uintptr_t r) { return static_cast<uint16_t>(r); }
+  static MachineType Representation() { return kMachUint16; }
+};
+
+template <>
 struct ReturnValueTraits<int8_t> {
   static int8_t Cast(uintptr_t r) { return static_cast<int8_t>(r); }
   static MachineType Representation() { return kMachInt8; }
 };
 
 template <>
+struct ReturnValueTraits<uint8_t> {
+  static uint8_t Cast(uintptr_t r) { return static_cast<uint8_t>(r); }
+  static MachineType Representation() { return kMachUint8; }
+};
+
+template <>
 struct ReturnValueTraits<double> {
   static double Cast(uintptr_t r) {
     UNREACHABLE();
diff --git a/test/cctest/compiler/test-codegen-deopt.cc b/test/cctest/compiler/test-codegen-deopt.cc
index 1e30e93..fd2463e 100644
--- a/test/cctest/compiler/test-codegen-deopt.cc
+++ b/test/cctest/compiler/test-codegen-deopt.cc
@@ -201,11 +201,12 @@
   Label* cont_label = t.code->GetLabel(t.cont_block);
   Label* deopt_label = t.code->GetLabel(t.deopt_block);
 
-  // Check the patch table. It should patch the continuation address to the
-  // deoptimization block address.
-  CHECK_EQ(1, data->ReturnAddressPatchCount());
-  CHECK_EQ(cont_label->pos(), data->ReturnAddressPc(0)->value());
-  CHECK_EQ(deopt_label->pos(), data->PatchedAddressPc(0)->value());
+  // Check the safepoint - it should contain an entry for the call
+  // with the right deoptimization address.
+  SafepointEntry entry = t.result_code->GetSafepointEntry(
+      t.result_code->instruction_start() + cont_label->pos());
+  CHECK(entry.is_valid());
+  CHECK_EQ(deopt_label->pos(), entry.deoptimization_pc());
 
   // Check that we deoptimize to the right AST id.
   CHECK_EQ(1, data->DeoptCount());
diff --git a/test/cctest/compiler/test-run-inlining.cc b/test/cctest/compiler/test-run-inlining.cc
index e676fb2..5e5b604 100644
--- a/test/cctest/compiler/test-run-inlining.cc
+++ b/test/cctest/compiler/test-run-inlining.cc
@@ -36,6 +36,7 @@
 
 
 TEST(SimpleInlining) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function(){"
@@ -49,6 +50,7 @@
 
 
 TEST(SimpleInliningContext) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function () {"
@@ -63,6 +65,7 @@
 
 
 TEST(CaptureContext) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "var f = (function () {"
@@ -80,6 +83,7 @@
 // TODO(sigurds) For now we do not inline any native functions. If we do at
 // some point, change this test.
 TEST(DontInlineEval) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "var x = 42;"
@@ -94,6 +98,7 @@
 
 
 TEST(InlineOmitArguments) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function () {"
@@ -108,6 +113,7 @@
 
 
 TEST(InlineSurplusArguments) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function () {"
@@ -123,6 +129,7 @@
 
 
 TEST(InlineTwice) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function () {"
@@ -137,6 +144,7 @@
 
 
 TEST(InlineTwiceDependent) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function () {"
@@ -152,6 +160,7 @@
 
 
 TEST(InlineTwiceDependentDiamond) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function () {"
@@ -167,6 +176,7 @@
 
 
 TEST(InlineTwiceDependentDiamondReal) {
+  FLAG_context_specialization = true;
   FLAG_turbo_inlining = true;
   FunctionTester T(
       "(function () {"
diff --git a/test/cctest/compiler/test-run-jsbranches.cc b/test/cctest/compiler/test-run-jsbranches.cc
index 2eb4fa6..df2fcdc 100644
--- a/test/cctest/compiler/test-run-jsbranches.cc
+++ b/test/cctest/compiler/test-run-jsbranches.cc
@@ -148,6 +148,26 @@
 }
 
 
+TEST(ForInContinueStatement) {
+  const char* src =
+      "(function(a,b) {"
+      "  var r = '-';"
+      "  for (var x in a) {"
+      "    r += 'A-';"
+      "    if (b) continue;"
+      "    r += 'B-';"
+      "  }"
+      "  return r;"
+      "})";
+  FunctionTester T(src);
+
+  T.CheckCall(T.Val("-A-B-"), T.NewObject("({x:1})"), T.false_value());
+  T.CheckCall(T.Val("-A-B-A-B-"), T.NewObject("({x:1,y:2})"), T.false_value());
+  T.CheckCall(T.Val("-A-"), T.NewObject("({x:1})"), T.true_value());
+  T.CheckCall(T.Val("-A-A-"), T.NewObject("({x:1,y:2})"), T.true_value());
+}
+
+
 TEST(SwitchStatement) {
   const char* src =
       "(function(a,b) {"
diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc
index 2c7d16f..9a80daf 100644
--- a/test/cctest/compiler/test-run-machops.cc
+++ b/test/cctest/compiler/test-run-machops.cc
@@ -2672,10 +2672,10 @@
 }
 
 
-template <typename Type, typename CType>
+template <typename Type>
 static void RunLoadImmIndex(MachineType rep) {
   const int kNumElems = 3;
-  CType buffer[kNumElems];
+  Type buffer[kNumElems];
 
   // initialize the buffer with raw data.
   byte* raw = reinterpret_cast<byte*>(buffer);
@@ -2692,19 +2692,21 @@
       m.Return(m.Load(rep, base, index));
 
       Type expected = buffer[i];
-      Type actual = static_cast<CType>(m.Call());
-      CHECK_EQ(expected, actual);
-      printf("XXX\n");
+      Type actual = m.Call();
+      CHECK(expected == actual);
     }
   }
 }
 
 
 TEST(RunLoadImmIndex) {
-  RunLoadImmIndex<int8_t, uint8_t>(kMachInt8);
-  RunLoadImmIndex<int16_t, uint16_t>(kMachInt16);
-  RunLoadImmIndex<int32_t, uint32_t>(kMachInt32);
-  RunLoadImmIndex<int32_t*, int32_t*>(kMachAnyTagged);
+  RunLoadImmIndex<int8_t>(kMachInt8);
+  RunLoadImmIndex<uint8_t>(kMachUint8);
+  RunLoadImmIndex<int16_t>(kMachInt16);
+  RunLoadImmIndex<uint16_t>(kMachUint16);
+  RunLoadImmIndex<int32_t>(kMachInt32);
+  RunLoadImmIndex<uint32_t>(kMachUint32);
+  RunLoadImmIndex<int32_t*>(kMachAnyTagged);
 
   // TODO(titzer): test kRepBit loads
   // TODO(titzer): test kMachFloat64 loads
@@ -2734,17 +2736,20 @@
     m.Store(rep, base, index1, load);
     m.Return(m.Int32Constant(OK));
 
-    CHECK_NE(buffer[x], buffer[y]);
+    CHECK(buffer[x] != buffer[y]);
     CHECK_EQ(OK, m.Call());
-    CHECK_EQ(buffer[x], buffer[y]);
+    CHECK(buffer[x] == buffer[y]);
   }
 }
 
 
 TEST(RunLoadStore) {
   RunLoadStore<int8_t>(kMachInt8);
+  RunLoadStore<uint8_t>(kMachUint8);
   RunLoadStore<int16_t>(kMachInt16);
+  RunLoadStore<uint16_t>(kMachUint16);
   RunLoadStore<int32_t>(kMachInt32);
+  RunLoadStore<uint32_t>(kMachUint32);
   RunLoadStore<void*>(kMachAnyTagged);
   RunLoadStore<double>(kMachFloat64);
 }
@@ -3792,15 +3797,15 @@
 
   // Test lower bound.
   input = min;
-  CHECK_EQ(max + 2, m.Call());
+  CHECK_EQ(static_cast<IntType>(max + 2), m.Call());
   CHECK_EQ(min + 1, input);
 
   // Test all one byte values that are not one byte bounds.
   for (int i = -127; i < 127; i++) {
     input = i;
     int expected = i >= 0 ? i + 1 : max + (i - min) + 2;
-    CHECK_EQ(expected, m.Call());
-    CHECK_EQ(i + 1, input);
+    CHECK_EQ(static_cast<IntType>(expected), m.Call());
+    CHECK_EQ(static_cast<IntType>(i + 1), input);
   }
 }
 
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1a292fc..c910f0e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1556,6 +1556,42 @@
 }
 
 
+THREADED_TEST(IsMapOrSet) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+  v8::Handle<Value> map = CompileRun("new Map()");
+  v8::Handle<Value> set = CompileRun("new Set()");
+  v8::Handle<Value> weak_map = CompileRun("new WeakMap()");
+  v8::Handle<Value> weak_set = CompileRun("new WeakSet()");
+  CHECK(map->IsMap());
+  CHECK(set->IsSet());
+  CHECK(weak_map->IsWeakMap());
+  CHECK(weak_set->IsWeakSet());
+
+  CHECK(!map->IsSet());
+  CHECK(!map->IsWeakMap());
+  CHECK(!map->IsWeakSet());
+
+  CHECK(!set->IsMap());
+  CHECK(!set->IsWeakMap());
+  CHECK(!set->IsWeakSet());
+
+  CHECK(!weak_map->IsMap());
+  CHECK(!weak_map->IsSet());
+  CHECK(!weak_map->IsWeakSet());
+
+  CHECK(!weak_set->IsMap());
+  CHECK(!weak_set->IsSet());
+  CHECK(!weak_set->IsWeakMap());
+
+  v8::Handle<Value> object = CompileRun("{a:42}");
+  CHECK(!object->IsMap());
+  CHECK(!object->IsSet());
+  CHECK(!object->IsWeakMap());
+  CHECK(!object->IsWeakSet());
+}
+
+
 THREADED_TEST(StringObject) {
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
@@ -2009,7 +2045,7 @@
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
   i::LookupResult lookup(i_isolate);
   i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length")));
-  i::LookupIterator it(a, name, i::LookupIterator::CHECK_PROPERTY);
+  i::LookupIterator it(a, name, i::LookupIterator::OWN_PROPERTY);
   CHECK(it.HasProperty());
   CHECK(it.GetAccessors()->IsExecutableAccessorInfo());
 }
diff --git a/test/cctest/test-disasm-x87.cc b/test/cctest/test-disasm-x87.cc
index 1515cc7..17c49af 100644
--- a/test/cctest/test-disasm-x87.cc
+++ b/test/cctest/test-disasm-x87.cc
@@ -32,9 +32,9 @@
 #include "src/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
+#include "src/ic/ic.h"
 #include "src/macro-assembler.h"
 #include "src/serialize.h"
-#include "src/stub-cache.h"
 #include "test/cctest/cctest.h"
 
 using namespace v8::internal;
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 462979d..0fef82d 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -4050,6 +4050,7 @@
 
 TEST(NextCodeLinkIsWeak) {
   i::FLAG_allow_natives_syntax = true;
+  i::FLAG_turbo_deoptimization = true;
   CcTest::InitializeVM();
   Isolate* isolate = CcTest::i_isolate();
   v8::internal::Heap* heap = CcTest::heap();
diff --git a/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc b/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc
index 843285e..d8fbcf1 100644
--- a/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc
+++ b/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc
@@ -1188,6 +1188,140 @@
 
 
 // -----------------------------------------------------------------------------
+// Memory access instructions.
+
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode ldr_opcode;
+  ArchOpcode str_opcode;
+  const int32_t immediates[40];
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  OStringStream ost;
+  ost << memacc.type;
+  return os << ost.c_str();
+}
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8,
+     kArmLdrsb,
+     kArmStrb,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachUint8,
+     kArmLdrb,
+     kArmStrb,
+     {-4095, -3914, -3536, -3234, -3185, -3169, -1073, -990, -859, -720, -434,
+      -127, -124, -122, -105, -91, -86, -64, -55, -53, -30, -10, -3, 0, 20, 28,
+      39, 58, 64, 73, 75, 100, 108, 121, 686, 963, 1363, 2759, 3449, 4095}},
+    {kMachInt16,
+     kArmLdrsh,
+     kArmStrh,
+     {-255, -251, -232, -220, -144, -138, -130, -126, -116, -115, -102, -101,
+      -98, -69, -59, -56, -39, -35, -23, -19, -7, 0, 22, 26, 37, 68, 83, 87, 98,
+      102, 108, 111, 117, 171, 195, 203, 204, 245, 246, 255}},
+    {kMachUint16,
+     kArmLdrh,
+     kArmStrh,
+     {-255, -230, -201, -172, -125, -119, -118, -105, -98, -79, -54, -42, -41,
+      -32, -12, -11, -5, -4, 0, 5, 9, 25, 28, 51, 58, 60, 89, 104, 108, 109,
+      114, 116, 120, 138, 150, 161, 166, 172, 228, 255}},
+    {kMachInt32,
+     kArmLdr,
+     kArmStr,
+     {-4095, -1898, -1685, -1562, -1408, -1313, -344, -128, -116, -100, -92,
+      -80, -72, -71, -56, -25, -21, -11, -9, 0, 3, 5, 27, 28, 42, 52, 63, 88,
+      93, 97, 125, 846, 1037, 2102, 2403, 2597, 2632, 2997, 3935, 4095}},
+    {kMachFloat64,
+     kArmVldr64,
+     kArmVstr64,
+     {-1020, -948, -796, -696, -612, -364, -320, -308, -128, -112, -108, -104,
+      -96, -84, -80, -56, -48, -40, -20, 0, 24, 28, 36, 48, 64, 84, 96, 100,
+      108, 116, 120, 140, 156, 408, 432, 444, 772, 832, 940, 1020}}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
+
+// -----------------------------------------------------------------------------
 // Miscellaneous.
 
 
diff --git a/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc b/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc
index a0c3ab5..109986c 100644
--- a/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc
+++ b/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc
@@ -298,6 +298,76 @@
   EXPECT_EQ(kArm64Mov32, s[0]->arch_opcode());
 }
 
+
+// -----------------------------------------------------------------------------
+// Memory access instructions.
+
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode ldr_opcode;
+  ArchOpcode str_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  OStringStream ost;
+  ost << memacc.type;
+  return os << ost.c_str();
+}
+
+}  // namespace
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8, kArm64Ldrsb, kArm64Strb},
+    {kMachUint8, kArm64Ldrb, kArm64Strb},
+    {kMachInt16, kArm64Ldrsh, kArm64Strh},
+    {kMachUint16, kArm64Ldrh, kArm64Strh},
+    {kMachInt32, kArm64LdrW, kArm64StrW},
+    {kMachUint32, kArm64LdrW, kArm64StrW},
+    {kMachInt64, kArm64Ldr, kArm64Str},
+    {kMachUint64, kArm64Ldr, kArm64Str},
+    {kMachFloat64, kArm64LdrD, kArm64StrD}};
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/compiler-unittests/ia32/instruction-selector-ia32-unittest.cc b/test/compiler-unittests/ia32/instruction-selector-ia32-unittest.cc
index c9431ea..bab8f94 100644
--- a/test/compiler-unittests/ia32/instruction-selector-ia32-unittest.cc
+++ b/test/compiler-unittests/ia32/instruction-selector-ia32-unittest.cc
@@ -73,6 +73,138 @@
   }
 }
 
+
+// -----------------------------------------------------------------------------
+// Loads and stores
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  OStringStream ost;
+  ost << memacc.type;
+  return os << ost.c_str();
+}
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8, kIA32Movsxbl, kIA32Movb},
+    {kMachUint8, kIA32Movzxbl, kIA32Movb},
+    {kMachInt16, kIA32Movsxwl, kIA32Movw},
+    {kMachUint16, kIA32Movzxwl, kIA32Movw},
+    {kMachInt32, kIA32Movl, kIA32Movl},
+    {kMachUint32, kIA32Movl, kIA32Movl},
+    {kMachFloat64, kIA32Movsd, kIA32Movsd}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateBase) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, base, kImmediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Int32Constant(base), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, kImmediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, base, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type);
+    m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/compiler-unittests/x64/instruction-selector-x64-unittest.cc b/test/compiler-unittests/x64/instruction-selector-x64-unittest.cc
index 4e5c655..2d815a3 100644
--- a/test/compiler-unittests/x64/instruction-selector-x64-unittest.cc
+++ b/test/compiler-unittests/x64/instruction-selector-x64-unittest.cc
@@ -38,6 +38,73 @@
   EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
 }
 
+
+// -----------------------------------------------------------------------------
+// Loads and stores
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  OStringStream ost;
+  ost << memacc.type;
+  return os << ost.c_str();
+}
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8, kX64Movsxbl, kX64Movb},
+    {kMachUint8, kX64Movzxbl, kX64Movb},
+    {kMachInt16, kX64Movsxwl, kX64Movw},
+    {kMachUint16, kX64Movzxwl, kX64Movw},
+    {kMachInt32, kX64Movl, kX64Movl},
+    {kMachUint32, kX64Movl, kX64Movl},
+    {kMachInt64, kX64Movq, kX64Movq},
+    {kMachUint64, kX64Movq, kX64Movq},
+    {kMachFloat64, kX64Movsd, kX64Movsd}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/mjsunit/es6/arguments-iterator.js b/test/mjsunit/es6/arguments-iterator.js
new file mode 100644
index 0000000..a65bf8b
--- /dev/null
+++ b/test/mjsunit/es6/arguments-iterator.js
@@ -0,0 +1,230 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+
+// Note in general that "arguments.foo" and "var o = arguments; o.foo"
+// are treated differently by full-codegen, and so both cases need to be
+// tested.
+
+function TestDirectArgumentsIteratorProperty() {
+  assertTrue(arguments.hasOwnProperty(Symbol.iterator));
+  assertFalse(arguments.propertyIsEnumerable(Symbol.iterator));
+  var descriptor = Object.getOwnPropertyDescriptor(arguments, Symbol.iterator);
+  assertTrue(descriptor.writable);
+  assertFalse(descriptor.enumerable);
+  assertTrue(descriptor.configurable);
+  assertEquals(descriptor.value, [].values);
+  assertEquals(arguments[Symbol.iterator], [].values);
+}
+TestDirectArgumentsIteratorProperty();
+
+
+function TestIndirectArgumentsIteratorProperty() {
+  var o = arguments;
+  assertTrue(o.hasOwnProperty(Symbol.iterator));
+  assertFalse(o.propertyIsEnumerable(Symbol.iterator));
+  assertEquals(o[Symbol.iterator], [].values);
+}
+TestIndirectArgumentsIteratorProperty();
+
+
+function assertIteratorResult(value, done, result) {
+  assertEquals({value: value, done: done}, result);
+}
+
+
+function TestDirectValues1(a, b, c) {
+  var iterator = arguments[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+  assertIteratorResult(c, false, iterator.next());
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestDirectValues1(1, 2, 3);
+
+
+function TestIndirectValues1(a, b, c) {
+  var args = arguments;
+  var iterator = args[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+  assertIteratorResult(c, false, iterator.next());
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestIndirectValues1(1, 2, 3);
+
+
+function TestDirectValues2(a, b, c) {
+  var iterator = arguments[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+  assertIteratorResult(c, false, iterator.next());
+  assertIteratorResult(undefined, true, iterator.next());
+
+  arguments[3] = 4;
+  arguments.length = 4;
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestDirectValues2(1, 2, 3);
+
+
+function TestIndirectValues2(a, b, c) {
+  var args = arguments;
+  var iterator = args[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+  assertIteratorResult(c, false, iterator.next());
+  assertIteratorResult(undefined, true, iterator.next());
+
+  arguments[3] = 4;
+  arguments.length = 4;
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestIndirectValues2(1, 2, 3);
+
+
+function TestDirectValues3(a, b, c) {
+  var iterator = arguments[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+
+  arguments.length = 2;
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestDirectValues3(1, 2, 3);
+
+
+function TestIndirectValues3(a, b, c) {
+  var args = arguments;
+  var iterator = args[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+
+  arguments.length = 2;
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestIndirectValues3(1, 2, 3);
+
+
+function TestDirectValues4(a, b, c) {
+  var iterator = arguments[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+  assertIteratorResult(c, false, iterator.next());
+
+  arguments.length = 4;
+  assertIteratorResult(undefined, false, iterator.next());
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestDirectValues4(1, 2, 3);
+
+
+function TestIndirectValues4(a, b, c) {
+  var args = arguments;
+  var iterator = args[Symbol.iterator]();
+  assertIteratorResult(a, false, iterator.next());
+  assertIteratorResult(b, false, iterator.next());
+  assertIteratorResult(c, false, iterator.next());
+
+  arguments.length = 4;
+  assertIteratorResult(undefined, false, iterator.next());
+  assertIteratorResult(undefined, true, iterator.next());
+}
+TestIndirectValues4(1, 2, 3);
+
+
+function TestForOf() {
+  var i = 0;
+  for (var value of arguments) {
+    assertEquals(arguments[i++], value);
+  }
+
+  assertEquals(arguments.length, i);
+}
+TestForOf(1, 2, 3, 4, 5);
+
+
+function TestAssignmentToIterator() {
+  var i = 0;
+  arguments[Symbol.iterator] = [].entries;
+  for (var entry of arguments) {
+    assertEquals([i, arguments[i]], entry);
+    i++;
+  }
+
+  assertEquals(arguments.length, i);
+}
+TestAssignmentToIterator(1, 2, 3, 4, 5);
+
+
+function TestArgumentsMutation() {
+  var i = 0;
+  for (var x of arguments) {
+    assertEquals(arguments[i], x);
+    arguments[i+1] *= 2;
+    i++;
+  }
+
+  assertEquals(arguments.length, i);
+}
+TestArgumentsMutation(1, 2, 3, 4, 5);
+
+
+function TestSloppyArgumentsAliasing(a0, a1, a2, a3, a4) {
+  var i = 0;
+  for (var x of arguments) {
+    assertEquals(arguments[i], x);
+    a0 = a1; a1 = a2; a3 = a4;
+    i++;
+  }
+
+  assertEquals(arguments.length, i);
+}
+TestSloppyArgumentsAliasing(1, 2, 3, 4, 5);
+
+
+function TestStrictArgumentsAliasing(a0, a1, a2, a3, a4) {
+  "use strict";
+  var i = 0;
+  for (var x of arguments) {
+    a0 = a1; a1 = a2; a3 = a4;
+    assertEquals(arguments[i], x);
+    i++;
+  }
+
+  assertEquals(arguments.length, i);
+}
+TestStrictArgumentsAliasing(1, 2, 3, 4, 5);
+
+
+function TestArgumentsAsProto() {
+  "use strict";
+
+  var o = {__proto__:arguments};
+  assertSame([].values, o[Symbol.iterator]);
+  // Make o dict-mode.
+  %OptimizeObjectForAddingMultipleProperties(o, 0);
+  assertFalse(o.hasOwnProperty(Symbol.iterator));
+  assertSame([].values, o[Symbol.iterator]);
+  o[Symbol.iterator] = 10;
+  assertTrue(o.hasOwnProperty(Symbol.iterator));
+  assertEquals(10, o[Symbol.iterator]);
+  assertSame([].values, arguments[Symbol.iterator]);
+
+  // Frozen o.
+  o = Object.freeze({__proto__:arguments});
+  assertSame([].values, o[Symbol.iterator]);
+  assertFalse(o.hasOwnProperty(Symbol.iterator));
+  assertSame([].values, o[Symbol.iterator]);
+  // This should throw, but currently it doesn't, because
+  // ExecutableAccessorInfo callbacks don't see the current strict mode.
+  // See note in accessors.cc:SetPropertyOnInstanceIfInherited.
+  o[Symbol.iterator] = 10;
+  assertFalse(o.hasOwnProperty(Symbol.iterator));
+  assertEquals([].values, o[Symbol.iterator]);
+  assertSame([].values, arguments[Symbol.iterator]);
+}
+TestArgumentsAsProto();
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 3dafda6..2183c31 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -97,8 +97,6 @@
   'deserialize-reference': [PASS, NO_VARIANTS],
 
   # Support for %GetFrameDetails is missing and requires checkpoints.
-  'debug-backtrace-text': [PASS, NO_VARIANTS],
-  'debug-break-inline': [PASS, NO_VARIANTS],
   'debug-evaluate-bool-constructor': [PASS, NO_VARIANTS],
   'debug-evaluate-closure': [PASS, NO_VARIANTS],
   'debug-evaluate-const': [PASS, NO_VARIANTS],
@@ -162,6 +160,7 @@
   'es6/iteration-semantics': [PASS, NO_VARIANTS],
   'es6/string-iterator': [PASS, NO_VARIANTS],
   'es6/typed-array-iterator': [PASS, NO_VARIANTS],
+  'es6/arguments-iterator': [PASS, NO_VARIANTS],
 
   ##############################################################################
   # Too slow in debug mode with --stress-opt mode.
diff --git a/test/test262-es6/test262-es6.status b/test/test262-es6/test262-es6.status
index ceac845..73f4477 100644
--- a/test/test262-es6/test262-es6.status
+++ b/test/test262-es6/test262-es6.status
@@ -38,51 +38,7 @@
   '11.2.3_b': [FAIL],
   '12.2.3_b': [FAIL],
 
-  ###################### NEEDS INVESTIGATION (2014) #######################
-
-  # Cause unknown.
-  'bug_596_1': [FAIL],
-
-  # New ES6 Array functions.
-  'S22.1.2.1_T1': [FAIL],
-  'S22.1.2.1_T2': [FAIL],
-  'S22.1.2.3_T1': [FAIL],
-  'S22.1.2.3_T2': [FAIL],
-  'S22.1.3.6_T1': [FAIL],
-
-  # New ES6 function String.prototype.contains, unimplemented in v8.
-  'String.prototype.contains_FailBadLocation': [FAIL],
-  'String.prototype.contains_FailLocation': [FAIL],
-  'String.prototype.contains_FailMissingLetter': [FAIL],
-  'String.prototype.contains_Success': [FAIL],
-  'String.prototype.contains_SuccessNoLocation': [FAIL],
-  'String.prototype.contains_lengthProp': [FAIL],
-
-  # New ES6 function String.prototype.endsWith, unimplemented in v8.
-  'String.prototype.endsWith_Fail': [FAIL],
-  'String.prototype.endsWith_Fail_2': [FAIL],
-  'String.prototype.endsWith_Success': [FAIL],
-  'String.prototype.endsWith_Success_2': [FAIL],
-  'String.prototype.endsWith_Success_3': [FAIL],
-  'String.prototype.endsWith_Success_4': [FAIL],
-
-  # New ES6 function Array.prototype.find, unimplemented in v8.
-  'Array.prototype.find_callable-predicate': [FAIL],
-  'Array.prototype.find_empty-array-undefined': [FAIL],
-  'Array.prototype.find_length-property': [FAIL],
-  'Array.prototype.find_modify-after-start': [FAIL],
-  'Array.prototype.find_non-returning-predicate': [FAIL],
-  'Array.prototype.find_predicate-arguments': [FAIL],
-  'Array.prototype.find_push-after-start': [FAIL],
-  'Array.prototype.find_remove-after-start': [FAIL],
-  'Array.prototype.find_return-found-value': [FAIL],
-  'Array.prototype.find_skip-empty': [FAIL],
-  'Array.prototype.find_this-defined': [FAIL],
-  'Array.prototype.find_this-is-object': [FAIL],
-  'Array.prototype.find_this-undefined': [FAIL],
-
-  # This negative test fails for the wrong reason.
-  #'Array.prototype.find_noncallable-predicate': [FAIL],
+  ###################### NEEDS INVESTIGATION #######################
 
   # Possibly same cause as S8.5_A2.1, below: floating-point tests.
   'S15.8.2.16_A7': [PASS, FAIL_OK],
@@ -94,6 +50,40 @@
   # https://code.google.com/p/v8/issues/detail?id=705
   '12.6.4-2': [PASS, FAIL_OK],
 
+  ###################### MISSING ES6 FEATURES #######################
+
+  # Array.from
+  'S22.1.2.1_T1': [FAIL],
+  'S22.1.2.1_T2': [FAIL],
+
+  # Direct proxies
+  'Array.prototype.find_callable-predicate': [FAIL],
+
+  ######################## OBSOLETED BY ES6 ###########################
+
+  # ES6 allows duplicate properties
+  # TODO(arv): Reactivate when check removal has relanded.
+  # '11.1.5-4-4-a-1-s': [FAIL],
+  # '11.1.5_4-4-b-1': [FAIL],
+  # '11.1.5_4-4-b-2': [FAIL],
+  # '11.1.5_4-4-c-1': [FAIL],
+  # '11.1.5_4-4-c-2': [FAIL],
+  # '11.1.5_4-4-d-1': [FAIL],
+  # '11.1.5_4-4-d-2': [FAIL],
+  # '11.1.5_4-4-d-3': [FAIL],
+  # '11.1.5_4-4-d-4': [FAIL],
+
+  # ES6 allows block-local functions.
+  'Sbp_A1_T1': [FAIL],
+  'Sbp_A2_T1': [FAIL],
+  'Sbp_A2_T2': [FAIL],
+  'Sbp_A3_T1': [FAIL],
+  'Sbp_A3_T2': [FAIL],
+  'Sbp_A4_T1': [FAIL],
+  'Sbp_A4_T2': [FAIL],
+  'Sbp_A5_T1': [PASS], # Test is broken (strict reference to unbound variable)
+  'Sbp_A5_T2': [FAIL],
+
   ######################## NEEDS INVESTIGATION ###########################
 
   # These test failures are specific to the intl402 suite and need investigation
@@ -133,17 +123,6 @@
   'S8.5_A2.1': [PASS, FAIL_OK],
   'S8.5_A2.2': [PASS, FAIL_OK],
 
-  # ES6 allows duplicate properties
-  '11.1.5-4-4-a-1-s': [FAIL],
-  '11.1.5_4-4-b-1': [FAIL],
-  '11.1.5_4-4-b-2': [FAIL],
-  '11.1.5_4-4-c-1': [FAIL],
-  '11.1.5_4-4-c-2': [FAIL],
-  '11.1.5_4-4-d-1': [FAIL],
-  '11.1.5_4-4-d-2': [FAIL],
-  '11.1.5_4-4-d-3': [FAIL],
-  '11.1.5_4-4-d-4': [FAIL],
-
   ############################ INVALID TESTS #############################
 
   # The reference value calculated by Test262 is incorrect if you run these
@@ -157,6 +136,10 @@
   'S15.9.3.1_A5_T5': [PASS, FAIL_OK],
   'S15.9.3.1_A5_T6': [PASS, FAIL_OK],
 
+  # Test makes unjustified assumptions about the number of calls to SortCompare.
+  # Test262 Bug: https://bugs.ecmascript.org/show_bug.cgi?id=596
+  'bug_596_1': [PASS, FAIL_OK],
+
   ############################ SKIPPED TESTS #############################
 
   # These tests take a looong time to run in debug mode.
diff --git a/test/test262-es6/testcfg.py b/test/test262-es6/testcfg.py
index 5231f38..7107f95 100644
--- a/test/test262-es6/testcfg.py
+++ b/test/test262-es6/testcfg.py
@@ -79,7 +79,7 @@
 
   def GetFlagsForTestCase(self, testcase, context):
     return (testcase.flags + context.mode_flags + self.harness +
-            self.GetIncludesForTest(testcase) +
+            self.GetIncludesForTest(testcase) + ["--harmony"] +
             [os.path.join(self.testroot, testcase.path + ".js")])
 
   def LoadParseTestRecord(self):
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index f6279a1..052b83e 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -603,6 +603,8 @@
         '../../src/ic/access-compiler.h',
         '../../src/ic/call-optimization.cc',
         '../../src/ic/call-optimization.h',
+        '../../src/ic/handler-compiler.cc',
+        '../../src/ic/handler-compiler.h',
         '../../src/ic/ic-inl.h',
         '../../src/ic/ic.cc',
         '../../src/ic/ic.h',
@@ -794,6 +796,7 @@
             '../../src/compiler/arm/instruction-selector-arm.cc',
             '../../src/compiler/arm/linkage-arm.cc',
             '../../src/ic/arm/access-compiler-arm.cc',
+            '../../src/ic/arm/handler-compiler-arm.cc',
             '../../src/ic/arm/ic-arm.cc',
             '../../src/ic/arm/ic-compiler-arm.cc',
             '../../src/ic/arm/stub-cache-arm.cc',
@@ -848,6 +851,7 @@
             '../../src/compiler/arm64/instruction-selector-arm64.cc',
             '../../src/compiler/arm64/linkage-arm64.cc',
             '../../src/ic/arm64/access-compiler-arm64.cc',
+            '../../src/ic/arm64/handler-compiler-arm64.cc',
             '../../src/ic/arm64/ic-arm64.cc',
             '../../src/ic/arm64/ic-compiler-arm64.cc',
             '../../src/ic/arm64/stub-cache-arm64.cc',
@@ -885,6 +889,7 @@
             '../../src/compiler/ia32/instruction-selector-ia32.cc',
             '../../src/compiler/ia32/linkage-ia32.cc',
             '../../src/ic/ia32/access-compiler-ia32.cc',
+            '../../src/ic/ia32/handler-compiler-ia32.cc',
             '../../src/ic/ia32/ic-ia32.cc',
             '../../src/ic/ia32/ic-compiler-ia32.cc',
             '../../src/ic/ia32/stub-cache-ia32.cc',
@@ -907,7 +912,6 @@
             '../../src/x87/frames-x87.cc',
             '../../src/x87/frames-x87.h',
             '../../src/x87/full-codegen-x87.cc',
-            '../../src/x87/ic-x87.cc',
             '../../src/x87/lithium-codegen-x87.cc',
             '../../src/x87/lithium-codegen-x87.h',
             '../../src/x87/lithium-gap-resolver-x87.cc',
@@ -918,7 +922,10 @@
             '../../src/x87/macro-assembler-x87.h',
             '../../src/x87/regexp-macro-assembler-x87.cc',
             '../../src/x87/regexp-macro-assembler-x87.h',
-            '../../src/x87/stub-cache-x87.cc',
+            '../../src/ic/x87/access-compiler-x87.cc',
+            '../../src/ic/x87/ic-x87.cc',
+            '../../src/ic/x87/ic-compiler-x87.cc',
+            '../../src/ic/x87/stub-cache-x87.cc',
           ],
         }],
         ['v8_target_arch=="mips" or v8_target_arch=="mipsel"', {
@@ -940,7 +947,6 @@
             '../../src/mips/frames-mips.cc',
             '../../src/mips/frames-mips.h',
             '../../src/mips/full-codegen-mips.cc',
-            '../../src/mips/ic-mips.cc',
             '../../src/mips/lithium-codegen-mips.cc',
             '../../src/mips/lithium-codegen-mips.h',
             '../../src/mips/lithium-gap-resolver-mips.cc',
@@ -952,7 +958,11 @@
             '../../src/mips/regexp-macro-assembler-mips.cc',
             '../../src/mips/regexp-macro-assembler-mips.h',
             '../../src/mips/simulator-mips.cc',
-            '../../src/mips/stub-cache-mips.cc',
+            '../../src/ic/mips/access-compiler-mips.cc',
+            '../../src/ic/mips/handler-compiler-mips.cc',
+            '../../src/ic/mips/ic-mips.cc',
+            '../../src/ic/mips/ic-compiler-mips.cc',
+            '../../src/ic/mips/stub-cache-mips.cc',
           ],
         }],
         ['v8_target_arch=="mips64el"', {
@@ -974,7 +984,6 @@
             '../../src/mips64/frames-mips64.cc',
             '../../src/mips64/frames-mips64.h',
             '../../src/mips64/full-codegen-mips64.cc',
-            '../../src/mips64/ic-mips64.cc',
             '../../src/mips64/lithium-codegen-mips64.cc',
             '../../src/mips64/lithium-codegen-mips64.h',
             '../../src/mips64/lithium-gap-resolver-mips64.cc',
@@ -986,7 +995,11 @@
             '../../src/mips64/regexp-macro-assembler-mips64.cc',
             '../../src/mips64/regexp-macro-assembler-mips64.h',
             '../../src/mips64/simulator-mips64.cc',
-            '../../src/mips64/stub-cache-mips64.cc',
+            '../../src/ic/mips64/access-compiler-mips64.cc',
+            '../../src/ic/mips64/handler-compiler-mips64.cc',
+            '../../src/ic/mips64/ic-mips64.cc',
+            '../../src/ic/mips64/ic-compiler-mips64.cc',
+            '../../src/ic/mips64/stub-cache-mips64.cc',
           ],
         }],
         ['v8_target_arch=="x64" or v8_target_arch=="x32"', {
@@ -1021,6 +1034,7 @@
             '../../src/compiler/x64/instruction-selector-x64.cc',
             '../../src/compiler/x64/linkage-x64.cc',
             '../../src/ic/x64/access-compiler-x64.cc',
+            '../../src/ic/x64/handler-compiler-x64.cc',
             '../../src/ic/x64/ic-x64.cc',
             '../../src/ic/x64/ic-compiler-x64.cc',
             '../../src/ic/x64/stub-cache-x64.cc',
diff --git a/tools/push-to-trunk/git_recipes.py b/tools/push-to-trunk/git_recipes.py
index 6ffb2da..1cbd8f5 100644
--- a/tools/push-to-trunk/git_recipes.py
+++ b/tools/push-to-trunk/git_recipes.py
@@ -28,6 +28,9 @@
 
 import re
 
+SHA1_RE = re.compile('^[a-fA-F0-9]{40}$')
+GIT_SVN_ID_RE = re.compile('^git-svn-id: .*@([0-9]+) .*$')
+
 
 class GitFailedException(Exception):
   pass
@@ -185,6 +188,20 @@
   def GitPull(self):
     self.Git("pull")
 
+  def GitFetchOrigin(self):
+    self.Git("fetch origin")
+
+  def GitConvertToSVNRevision(self, git_hash):
+    result = self.Git(MakeArgs(["rev-list", "-n", "1", git_hash]))
+    if not result or not SHA1_RE.match(result):
+      raise GitFailedException("Git hash %s is unknown." % git_hash)
+    log = self.GitLog(n=1, format="%B", git_hash=git_hash)
+    for line in reversed(log.splitlines()):
+      match = GIT_SVN_ID_RE.match(line.strip())
+      if match:
+        return match.group(1)
+    raise GitFailedException("Couldn't convert %s to SVN." % git_hash)
+
   def GitSVNFetch(self):
     self.Git("svn fetch")
 
diff --git a/tools/push-to-trunk/releases.py b/tools/push-to-trunk/releases.py
index 586cbc1..239189e 100755
--- a/tools/push-to-trunk/releases.py
+++ b/tools/push-to-trunk/releases.py
@@ -47,10 +47,10 @@
 
 # Expression with three versions (historical) for extracting the v8 revision
 # from the chromium DEPS file.
-DEPS_RE = re.compile(r'^\s*(?:"v8_revision": "'
-                      '|\(Var\("googlecode_url"\) % "v8"\) \+ "\/trunk@'
-                      '|"http\:\/\/v8\.googlecode\.com\/svn\/trunk@)'
-                      '([0-9]+)".*$', re.M)
+DEPS_RE = re.compile(r"""^\s*(?:["']v8_revision["']: ["']"""
+                     """|\(Var\("googlecode_url"\) % "v8"\) \+ "\/trunk@"""
+                     """|"http\:\/\/v8\.googlecode\.com\/svn\/trunk@)"""
+                     """([^"']+)["'].*$""", re.M)
 
 # Expression to pick tag and revision for bleeding edge tags. To be used with
 # output of 'svn log'.
@@ -374,6 +374,18 @@
     self.GitCreateBranch(self.Config(BRANCHNAME))
 
 
+def ConvertToCommitNumber(step, revision):
+  # Simple check for git hashes.
+  if revision.isdigit() and len(revision) < 8:
+    return revision
+  try:
+    # TODO(machenbach): Add cwd to git calls.
+    os.chdir(os.path.join(step["chrome_path"], "v8"))
+    return step.GitConvertToSVNRevision(revision)
+  finally:
+    os.chdir(step["chrome_path"])
+
+
 class RetrieveChromiumV8Releases(Step):
   MESSAGE = "Retrieve V8 releases from Chromium DEPS."
   REQUIRES = "chrome_path"
@@ -387,6 +399,14 @@
       print "No releases detected. Skipping chromium history."
       return True
 
+    # Update v8 checkout in chromium.
+    try:
+      # TODO(machenbach): Add cwd to git calls.
+      os.chdir(os.path.join(self["chrome_path"], "v8"))
+      self.GitFetchOrigin()
+    finally:
+      os.chdir(self["chrome_path"])
+
     oldest_v8_rev = int(releases[-1]["revision"])
 
     cr_releases = []
@@ -401,7 +421,7 @@
         if match:
           cr_rev = GetCommitPositionNumber(self, git_hash)
           if cr_rev:
-            v8_rev = match.group(1)
+            v8_rev = ConvertToCommitNumber(self, match.group(1))
             cr_releases.append([cr_rev, v8_rev])
 
           # Stop after reaching beyond the last v8 revision we want to update.
@@ -458,7 +478,7 @@
         deps = FileToText(self.Config(DEPS_FILE))
         match = DEPS_RE.search(deps)
         if match:
-          v8_rev = match.group(1)
+          v8_rev = ConvertToCommitNumber(self, match.group(1))
           cr_branches.append([str(branch), v8_rev])
 
           # Stop after reaching beyond the last v8 revision we want to update.
diff --git a/tools/push-to-trunk/test_scripts.py b/tools/push-to-trunk/test_scripts.py
index 7a40985..4b1f638 100644
--- a/tools/push-to-trunk/test_scripts.py
+++ b/tools/push-to-trunk/test_scripts.py
@@ -1214,6 +1214,11 @@
 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b
 
 """
+    c_v8_22624_log = """V8 CL.
+
+git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123
+
+"""
     json_output = self.MakeEmptyTempFile()
     csv_output = self.MakeEmptyTempFile()
     TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
@@ -1222,6 +1227,8 @@
     TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
     if not os.path.exists(TEST_CONFIG[CHROMIUM]):
       os.makedirs(TEST_CONFIG[CHROMIUM])
+    if not os.path.exists(os.path.join(TEST_CONFIG[CHROMIUM], "v8")):
+      os.makedirs(os.path.join(TEST_CONFIG[CHROMIUM], "v8"))
     def WriteDEPS(revision):
       TextToFile("Line\n   \"v8_revision\": \"%s\",\n  line\n" % revision,
                  TEST_CONFIG[DEPS_FILE])
@@ -1290,12 +1297,17 @@
       Git("checkout -f master", ""),
       Git("pull", ""),
       Git("checkout -b %s" % TEST_CONFIG[BRANCHNAME], ""),
+      Git("fetch origin", ""),
       Git("log --format=%H --grep=\"V8\"", "c_hash1\nc_hash2\nc_hash3\n"),
       Git("diff --name-only c_hash1 c_hash1^", ""),
       Git("diff --name-only c_hash2 c_hash2^", TEST_CONFIG[DEPS_FILE]),
       Git("checkout -f c_hash2 -- %s" % TEST_CONFIG[DEPS_FILE], "",
-          cb=ResetDEPS(22624)),
+          cb=ResetDEPS("0123456789012345678901234567890123456789")),
       Git("log -1 --format=%B c_hash2", c_hash2_commit_log),
+      Git("rev-list -n 1 0123456789012345678901234567890123456789",
+          "0123456789012345678901234567890123456789"),
+      Git("log -1 --format=%B 0123456789012345678901234567890123456789",
+          c_v8_22624_log),
       Git("diff --name-only c_hash3 c_hash3^", TEST_CONFIG[DEPS_FILE]),
       Git("checkout -f c_hash3 -- %s" % TEST_CONFIG[DEPS_FILE], "",
           cb=ResetDEPS(345)),
diff --git a/tools/run_benchmarks.py b/tools/run_benchmarks.py
index d6e9145..b74f358 100755
--- a/tools/run_benchmarks.py
+++ b/tools/run_benchmarks.py
@@ -113,6 +113,8 @@
                    "x64",
                    "arm64"]
 
+GENERIC_RESULTS_RE = re.compile(
+    r"^Trace\(([^\)]+)\), Result\(([^\)]+)\), StdDev\(([^\)]+)\)$")
 
 class Results(object):
   """Place holder for result traces."""
@@ -249,7 +251,7 @@
   """
   @property
   def main(self):
-    return self._suite["main"]
+    return self._suite.get("main", "")
 
   def ChangeCWD(self, suite_path):
     """Changes the cwd to to path defined in the current graph.
@@ -289,6 +291,33 @@
     return self.GetResults()
 
 
+class RunnableGeneric(Runnable):
+  """Represents a runnable benchmark suite definition with generic traces."""
+  def __init__(self, suite, parent, arch):
+    super(RunnableGeneric, self).__init__(suite, parent, arch)
+
+  def Run(self, runner):
+    """Iterates over several runs and handles the output."""
+    traces = {}
+    for stdout in runner():
+      for line in stdout.strip().splitlines():
+        match = GENERIC_RESULTS_RE.match(line)
+        if match:
+          trace = match.group(1)
+          result = match.group(2)
+          stddev = match.group(3)
+          trace_result = traces.setdefault(trace, Results([{
+            "graphs": self.graphs + [trace],
+            "units": self.units,
+            "results": [],
+            "stddev": "",
+          }], []))
+          trace_result.traces[0]["results"].append(result)
+          trace_result.traces[0]["stddev"] = stddev
+
+    return reduce(lambda r, t: r + t, traces.itervalues(), Results())
+
+
 def MakeGraph(suite, arch, parent):
   """Factory method for making graph objects."""
   if isinstance(parent, Runnable):
@@ -302,6 +331,10 @@
     else:
       # This graph has no subbenchmarks, it's a leaf.
       return RunnableTrace(suite, parent, arch)
+  elif suite.get("generic"):
+    # This is a generic suite definition. It is either a runnable executable
+    # or has a main js file.
+    return RunnableGeneric(suite, parent, arch)
   elif suite.get("benchmarks"):
     # This is neither a leaf nor a runnable.
     return Graph(suite, parent, arch)
diff --git a/tools/unittests/run_benchmarks_test.py b/tools/unittests/run_benchmarks_test.py
index 37a816e..0545220 100644
--- a/tools/unittests/run_benchmarks_test.py
+++ b/tools/unittests/run_benchmarks_test.py
@@ -68,6 +68,15 @@
   ]
 }
 
+V8_GENERIC_JSON = {
+  "path": ["."],
+  "binary": "cc",
+  "flags": ["--flag"],
+  "generic": True,
+  "run_count": 1,
+  "units": "ms",
+}
+
 Output = namedtuple("Output", "stdout, stderr")
 
 class BenchmarksTest(unittest.TestCase):
@@ -295,3 +304,17 @@
     self._VerifyErrors(
         ["Regexp \"^Richards: (.+)$\" didn't match for benchmark Richards."])
     self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
+
+  def testOneRunGeneric(self):
+    test_input = dict(V8_GENERIC_JSON)
+    self._WriteTestInput(test_input)
+    self._MockCommand(["."], [
+      "Trace(Test1), Result(1.234), StdDev(0.23)\n"
+      "Trace(Test2), Result(10657567), StdDev(106)\n"])
+    self.assertEquals(0, self._CallMain())
+    self._VerifyResults("test", "ms", [
+      {"name": "Test1", "results": ["1.234"], "stddev": "0.23"},
+      {"name": "Test2", "results": ["10657567"], "stddev": "106"},
+    ])
+    self._VerifyErrors([])
+    self._VerifyMock(path.join("out", "x64.release", "cc"), "--flag", "")