diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 3e26b52..dca2167 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -4,6 +4,9 @@
 
 #include "src/code-stub-assembler.h"
 #include "src/code-factory.h"
+#include "src/frames-inl.h"
+#include "src/frames.h"
+#include "src/ic/stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -22,6 +25,18 @@
                                      const char* name)
     : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {}
 
+void CodeStubAssembler::Assert(Node* condition) {
+#if defined(DEBUG)
+  Label ok(this);
+  Comment("[ Assert");
+  GotoIf(condition, &ok);
+  DebugBreak();
+  Goto(&ok);
+  Bind(&ok);
+  Comment("] Assert");
+#endif
+}
+
 Node* CodeStubAssembler::BooleanMapConstant() {
   return HeapConstant(isolate()->factory()->boolean_map());
 }
@@ -46,6 +61,14 @@
   return LoadRoot(Heap::kUndefinedValueRootIndex);
 }
 
+Node* CodeStubAssembler::TheHoleConstant() {
+  return LoadRoot(Heap::kTheHoleValueRootIndex);
+}
+
+Node* CodeStubAssembler::HashSeed() {
+  return SmiToWord32(LoadRoot(Heap::kHashSeedRootIndex));
+}
+
 Node* CodeStubAssembler::StaleRegisterConstant() {
   return LoadRoot(Heap::kStaleRegisterRootIndex);
 }
@@ -450,6 +473,17 @@
   return InnerAllocate(previous, IntPtrConstant(offset));
 }
 
+compiler::Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) {
+  Node* frame_pointer = LoadFramePointer();
+  return Load(rep, frame_pointer, IntPtrConstant(offset));
+}
+
+compiler::Node* CodeStubAssembler::LoadFromParentFrame(int offset,
+                                                       MachineType rep) {
+  Node* frame_pointer = LoadParentFramePointer();
+  return Load(rep, frame_pointer, IntPtrConstant(offset));
+}
+
 Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset,
                                           MachineType rep) {
   return Load(rep, buffer, IntPtrConstant(offset));
@@ -460,9 +494,14 @@
   return Load(rep, object, IntPtrConstant(offset - kHeapObjectTag));
 }
 
+Node* CodeStubAssembler::LoadObjectField(Node* object, Node* offset,
+                                         MachineType rep) {
+  return Load(rep, object, IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)));
+}
+
 Node* CodeStubAssembler::LoadHeapNumberValue(Node* object) {
-  return Load(MachineType::Float64(), object,
-              IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag));
+  return LoadObjectField(object, HeapNumber::kValueOffset,
+                         MachineType::Float64());
 }
 
 Node* CodeStubAssembler::LoadMap(Node* object) {
@@ -473,6 +512,15 @@
   return LoadMapInstanceType(LoadMap(object));
 }
 
+void CodeStubAssembler::AssertInstanceType(Node* object,
+                                           InstanceType instance_type) {
+  Assert(Word32Equal(LoadInstanceType(object), Int32Constant(instance_type)));
+}
+
+Node* CodeStubAssembler::LoadProperties(Node* object) {
+  return LoadObjectField(object, JSObject::kPropertiesOffset);
+}
+
 Node* CodeStubAssembler::LoadElements(Node* object) {
   return LoadObjectField(object, JSObject::kElementsOffset);
 }
@@ -482,23 +530,19 @@
 }
 
 Node* CodeStubAssembler::LoadMapBitField(Node* map) {
-  return Load(MachineType::Uint8(), map,
-              IntPtrConstant(Map::kBitFieldOffset - kHeapObjectTag));
+  return LoadObjectField(map, Map::kBitFieldOffset, MachineType::Uint8());
 }
 
 Node* CodeStubAssembler::LoadMapBitField2(Node* map) {
-  return Load(MachineType::Uint8(), map,
-              IntPtrConstant(Map::kBitField2Offset - kHeapObjectTag));
+  return LoadObjectField(map, Map::kBitField2Offset, MachineType::Uint8());
 }
 
 Node* CodeStubAssembler::LoadMapBitField3(Node* map) {
-  return Load(MachineType::Uint32(), map,
-              IntPtrConstant(Map::kBitField3Offset - kHeapObjectTag));
+  return LoadObjectField(map, Map::kBitField3Offset, MachineType::Uint32());
 }
 
 Node* CodeStubAssembler::LoadMapInstanceType(Node* map) {
-  return Load(MachineType::Uint8(), map,
-              IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag));
+  return LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint8());
 }
 
 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
@@ -509,9 +553,49 @@
   return LoadObjectField(map, Map::kPrototypeOffset);
 }
 
-Node* CodeStubAssembler::LoadNameHash(Node* name) {
-  return Load(MachineType::Uint32(), name,
-              IntPtrConstant(Name::kHashFieldOffset - kHeapObjectTag));
+Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
+  return LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8());
+}
+
+Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) {
+  // See Map::GetInObjectProperties() for details.
+  STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
+  Assert(Int32GreaterThanOrEqual(LoadMapInstanceType(map),
+                                 Int32Constant(FIRST_JS_OBJECT_TYPE)));
+  return LoadObjectField(
+      map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset,
+      MachineType::Uint8());
+}
+
+Node* CodeStubAssembler::LoadNameHashField(Node* name) {
+  return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32());
+}
+
+Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) {
+  Node* hash_field = LoadNameHashField(name);
+  if (if_hash_not_computed != nullptr) {
+    GotoIf(WordEqual(
+               Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
+               Int32Constant(0)),
+           if_hash_not_computed);
+  }
+  return Word32Shr(hash_field, Int32Constant(Name::kHashShift));
+}
+
+Node* CodeStubAssembler::LoadStringLength(Node* object) {
+  return LoadObjectField(object, String::kLengthOffset);
+}
+
+Node* CodeStubAssembler::LoadJSValueValue(Node* object) {
+  return LoadObjectField(object, JSValue::kValueOffset);
+}
+
+Node* CodeStubAssembler::LoadWeakCellValue(Node* weak_cell, Label* if_cleared) {
+  Node* value = LoadObjectField(weak_cell, WeakCell::kValueOffset);
+  if (if_cleared != nullptr) {
+    GotoIf(WordEqual(value, IntPtrConstant(0)), if_cleared);
+  }
+  return value;
 }
 
 Node* CodeStubAssembler::AllocateUninitializedFixedArray(Node* length) {
@@ -537,9 +621,14 @@
   return Load(MachineType::AnyTagged(), object, offset);
 }
 
-Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
-  return Load(MachineType::Uint8(), map,
-              IntPtrConstant(Map::kInstanceSizeOffset - kHeapObjectTag));
+Node* CodeStubAssembler::LoadFixedDoubleArrayElement(
+    Node* object, Node* index_node, MachineType machine_type,
+    int additional_offset, ParameterMode parameter_mode) {
+  int32_t header_size =
+      FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag;
+  Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS,
+                                        parameter_mode, header_size);
+  return Load(machine_type, object, offset);
 }
 
 Node* CodeStubAssembler::LoadNativeContext(Node* context) {
@@ -620,21 +709,107 @@
   StoreMapNoWriteBarrier(result, LoadRoot(Heap::kOneByteStringMapRootIndex));
   StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
                                  SmiConstant(Smi::FromInt(length)));
-  StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot,
-                                 IntPtrConstant(String::kEmptyHashField));
+  StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset,
+                                 IntPtrConstant(String::kEmptyHashField),
+                                 MachineRepresentation::kWord32);
   return result;
 }
 
+Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length) {
+  Variable var_result(this, MachineRepresentation::kTagged);
+
+  // Compute the SeqOneByteString size and check if it fits into new space.
+  Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred),
+      if_join(this);
+  Node* size = WordAnd(
+      IntPtrAdd(
+          IntPtrAdd(length, IntPtrConstant(SeqOneByteString::kHeaderSize)),
+          IntPtrConstant(kObjectAlignmentMask)),
+      IntPtrConstant(~kObjectAlignmentMask));
+  Branch(IntPtrLessThanOrEqual(size,
+                               IntPtrConstant(Page::kMaxRegularHeapObjectSize)),
+         &if_sizeissmall, &if_notsizeissmall);
+
+  Bind(&if_sizeissmall);
+  {
+    // Just allocate the SeqOneByteString in new space.
+    Node* result = Allocate(size);
+    StoreMapNoWriteBarrier(result, LoadRoot(Heap::kOneByteStringMapRootIndex));
+    StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
+                                   SmiFromWord(length));
+    StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset,
+                                   IntPtrConstant(String::kEmptyHashField),
+                                   MachineRepresentation::kWord32);
+    var_result.Bind(result);
+    Goto(&if_join);
+  }
+
+  Bind(&if_notsizeissmall);
+  {
+    // We might need to allocate in large object space, go to the runtime.
+    Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context,
+                               SmiFromWord(length));
+    var_result.Bind(result);
+    Goto(&if_join);
+  }
+
+  Bind(&if_join);
+  return var_result.value();
+}
+
 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length) {
   Node* result = Allocate(SeqTwoByteString::SizeFor(length));
   StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex));
   StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
                                  SmiConstant(Smi::FromInt(length)));
-  StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot,
-                                 IntPtrConstant(String::kEmptyHashField));
+  StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset,
+                                 IntPtrConstant(String::kEmptyHashField),
+                                 MachineRepresentation::kWord32);
   return result;
 }
 
+Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length) {
+  Variable var_result(this, MachineRepresentation::kTagged);
+
+  // Compute the SeqTwoByteString size and check if it fits into new space.
+  Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred),
+      if_join(this);
+  Node* size = WordAnd(
+      IntPtrAdd(IntPtrAdd(WordShl(length, 1),
+                          IntPtrConstant(SeqTwoByteString::kHeaderSize)),
+                IntPtrConstant(kObjectAlignmentMask)),
+      IntPtrConstant(~kObjectAlignmentMask));
+  Branch(IntPtrLessThanOrEqual(size,
+                               IntPtrConstant(Page::kMaxRegularHeapObjectSize)),
+         &if_sizeissmall, &if_notsizeissmall);
+
+  Bind(&if_sizeissmall);
+  {
+    // Just allocate the SeqTwoByteString in new space.
+    Node* result = Allocate(size);
+    StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex));
+    StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
+                                   SmiFromWord(length));
+    StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset,
+                                   IntPtrConstant(String::kEmptyHashField),
+                                   MachineRepresentation::kWord32);
+    var_result.Bind(result);
+    Goto(&if_join);
+  }
+
+  Bind(&if_notsizeissmall);
+  {
+    // We might need to allocate in large object space, go to the runtime.
+    Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context,
+                               SmiFromWord(length));
+    var_result.Bind(result);
+    Goto(&if_join);
+  }
+
+  Bind(&if_join);
+  return var_result.value();
+}
+
 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map,
                                          Node* capacity_node, Node* length_node,
                                          compiler::Node* allocation_site,
@@ -643,6 +818,8 @@
   int base_size = JSArray::kSize + FixedArray::kHeaderSize;
   int elements_offset = JSArray::kSize;
 
+  Comment("begin allocation of JSArray");
+
   if (allocation_site != nullptr) {
     base_size += AllocationMemento::kSize;
     elements_offset += AllocationMemento::kSize;
@@ -714,8 +891,49 @@
       }
     }
   } else {
-    // TODO(danno): Add a loop for initialization
-    UNIMPLEMENTED();
+    Variable current(this, MachineRepresentation::kTagged);
+    Label test(this);
+    Label decrement(this, &current);
+    Label done(this);
+    Node* limit = IntPtrAdd(elements, IntPtrConstant(first_element_offset));
+    current.Bind(
+        IntPtrAdd(limit, ElementOffsetFromIndex(capacity_node, kind, mode, 0)));
+
+    Branch(WordEqual(current.value(), limit), &done, &decrement);
+
+    Bind(&decrement);
+    current.Bind(IntPtrSub(
+        current.value(),
+        Int32Constant(IsFastDoubleElementsKind(kind) ? kDoubleSize
+                                                     : kPointerSize)));
+    if (is_double) {
+      // Don't use doubles to store the hole double, since manipulating the
+      // signaling NaN used for the hole in C++, e.g. with bit_cast, will
+      // change its value on ia32 (the x87 stack is used to return values
+      // and stores to the stack silently clear the signalling bit).
+      //
+      // TODO(danno): When we have a Float32/Float64 wrapper class that
+      // preserves double bits during manipulation, remove this code/change
+      // this to an indexed Float64 store.
+      if (Is64()) {
+        StoreNoWriteBarrier(MachineRepresentation::kWord64, current.value(),
+                            double_hole);
+      } else {
+        StoreNoWriteBarrier(MachineRepresentation::kWord32, current.value(),
+                            double_hole);
+        StoreNoWriteBarrier(
+            MachineRepresentation::kWord32,
+            IntPtrAdd(current.value(), Int32Constant(kPointerSize)),
+            double_hole);
+      }
+    } else {
+      StoreNoWriteBarrier(MachineRepresentation::kTagged, current.value(),
+                          hole);
+    }
+    Node* compare = WordNotEqual(current.value(), limit);
+    Branch(compare, &decrement, &done);
+
+    Bind(&done);
   }
 
   return array;
@@ -1256,19 +1474,46 @@
                    Int32Constant(shift));
 }
 
+void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) {
+  if (FLAG_native_code_counters && counter->Enabled()) {
+    Node* counter_address = ExternalConstant(ExternalReference(counter));
+    StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address,
+                        Int32Constant(value));
+  }
+}
+
+void CodeStubAssembler::IncrementCounter(StatsCounter* counter, int delta) {
+  DCHECK(delta > 0);
+  if (FLAG_native_code_counters && counter->Enabled()) {
+    Node* counter_address = ExternalConstant(ExternalReference(counter));
+    Node* value = Load(MachineType::Int32(), counter_address);
+    value = Int32Add(value, Int32Constant(delta));
+    StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value);
+  }
+}
+
+void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) {
+  DCHECK(delta > 0);
+  if (FLAG_native_code_counters && counter->Enabled()) {
+    Node* counter_address = ExternalConstant(ExternalReference(counter));
+    Node* value = Load(MachineType::Int32(), counter_address);
+    value = Int32Sub(value, Int32Constant(delta));
+    StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value);
+  }
+}
+
 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
                                   Variable* var_index, Label* if_keyisunique,
-                                  Label* call_runtime) {
+                                  Label* if_bailout) {
   DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep());
+  Comment("TryToName");
 
   Label if_keyissmi(this), if_keyisnotsmi(this);
   Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi);
   Bind(&if_keyissmi);
   {
     // Negative smi keys are named properties. Handle in the runtime.
-    Label if_keyispositive(this);
-    Branch(WordIsPositiveSmi(key), &if_keyispositive, call_runtime);
-    Bind(&if_keyispositive);
+    GotoUnless(WordIsPositiveSmi(key), if_bailout);
 
     var_index->Bind(SmiToWord32(key));
     Goto(if_keyisindex);
@@ -1277,125 +1522,659 @@
   Bind(&if_keyisnotsmi);
 
   Node* key_instance_type = LoadInstanceType(key);
-  Label if_keyisnotsymbol(this);
-  Branch(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)),
-         if_keyisunique, &if_keyisnotsymbol);
-  Bind(&if_keyisnotsymbol);
-  {
-    Label if_keyisinternalized(this);
-    Node* bits =
-        WordAnd(key_instance_type,
-                Int32Constant(kIsNotStringMask | kIsNotInternalizedMask));
-    Branch(Word32Equal(bits, Int32Constant(kStringTag | kInternalizedTag)),
-           &if_keyisinternalized, call_runtime);
-    Bind(&if_keyisinternalized);
+  // Symbols are unique.
+  GotoIf(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)),
+         if_keyisunique);
 
-    // Check whether the key is an array index passed in as string. Handle
-    // uniform with smi keys if so.
-    // TODO(verwaest): Also support non-internalized strings.
-    Node* hash = LoadNameHash(key);
-    Node* bit =
-        Word32And(hash, Int32Constant(internal::Name::kIsNotArrayIndexMask));
-    Label if_isarrayindex(this);
-    Branch(Word32Equal(bit, Int32Constant(0)), &if_isarrayindex,
-           if_keyisunique);
-    Bind(&if_isarrayindex);
-    var_index->Bind(BitFieldDecode<internal::Name::ArrayIndexValueBits>(hash));
-    Goto(if_keyisindex);
-  }
+  Label if_keyisinternalized(this);
+  Node* bits =
+      WordAnd(key_instance_type,
+              Int32Constant(kIsNotStringMask | kIsNotInternalizedMask));
+  Branch(Word32Equal(bits, Int32Constant(kStringTag | kInternalizedTag)),
+         &if_keyisinternalized, if_bailout);
+  Bind(&if_keyisinternalized);
+
+  // Check whether the key is an array index passed in as string. Handle
+  // uniform with smi keys if so.
+  // TODO(verwaest): Also support non-internalized strings.
+  Node* hash = LoadNameHashField(key);
+  Node* bit = Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask));
+  GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_keyisunique);
+  // Key is an index. Check if it is small enough to be encoded in the
+  // hash_field. Handle too big array index in runtime.
+  bit = Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
+  GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_bailout);
+  var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash));
+  Goto(if_keyisindex);
 }
 
-void CodeStubAssembler::TryLookupProperty(Node* object, Node* map,
-                                          Node* instance_type, Node* name,
-                                          Label* if_found, Label* if_not_found,
-                                          Label* call_runtime) {
-  {
-    Label if_objectissimple(this);
-    Branch(Int32LessThanOrEqual(instance_type,
-                                Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
-           call_runtime, &if_objectissimple);
-    Bind(&if_objectissimple);
+template <typename Dictionary>
+Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
+  Node* entry_index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize));
+  return Int32Add(entry_index,
+                  Int32Constant(Dictionary::kElementsStartIndex + field_index));
+}
+
+template <typename Dictionary>
+void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
+                                             Node* unique_name, Label* if_found,
+                                             Variable* var_name_index,
+                                             Label* if_not_found,
+                                             int inlined_probes) {
+  DCHECK_EQ(MachineRepresentation::kWord32, var_name_index->rep());
+  Comment("NameDictionaryLookup");
+
+  Node* capacity = SmiToWord32(LoadFixedArrayElement(
+      dictionary, Int32Constant(Dictionary::kCapacityIndex)));
+  Node* mask = Int32Sub(capacity, Int32Constant(1));
+  Node* hash = LoadNameHash(unique_name);
+
+  // See Dictionary::FirstProbe().
+  Node* count = Int32Constant(0);
+  Node* entry = Word32And(hash, mask);
+
+  for (int i = 0; i < inlined_probes; i++) {
+    Node* index = EntryToIndex<Dictionary>(entry);
+    var_name_index->Bind(index);
+
+    Node* current = LoadFixedArrayElement(dictionary, index);
+    GotoIf(WordEqual(current, unique_name), if_found);
+
+    // See Dictionary::NextProbe().
+    count = Int32Constant(i + 1);
+    entry = Word32And(Int32Add(entry, count), mask);
   }
 
-  // TODO(verwaest): Perform a dictonary lookup on slow-mode receivers.
-  Node* bit_field3 = LoadMapBitField3(map);
-  Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3);
-  Label if_isfastmap(this);
-  Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, call_runtime);
-  Bind(&if_isfastmap);
-  Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3);
-  // Bail out to the runtime for large numbers of own descriptors. The stub only
-  // does linear search, which becomes too expensive in that case.
-  {
-    static const int32_t kMaxLinear = 210;
-    Label above_max(this), below_max(this);
-    Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxLinear)), &below_max,
-           call_runtime);
-    Bind(&below_max);
-  }
-  Node* descriptors = LoadMapDescriptors(map);
+  Node* undefined = UndefinedConstant();
 
-  Variable var_descriptor(this, MachineRepresentation::kWord32);
-  Label loop(this, &var_descriptor);
-  var_descriptor.Bind(Int32Constant(0));
+  Variable var_count(this, MachineRepresentation::kWord32);
+  Variable var_entry(this, MachineRepresentation::kWord32);
+  Variable* loop_vars[] = {&var_count, &var_entry, var_name_index};
+  Label loop(this, 3, loop_vars);
+  var_count.Bind(count);
+  var_entry.Bind(entry);
   Goto(&loop);
   Bind(&loop);
   {
-    Node* index = var_descriptor.value();
-    Node* offset = Int32Constant(DescriptorArray::ToKeyIndex(0));
-    Node* factor = Int32Constant(DescriptorArray::kDescriptorSize);
-    Label if_notdone(this);
-    Branch(Word32Equal(index, nof), if_not_found, &if_notdone);
-    Bind(&if_notdone);
+    Node* count = var_count.value();
+    Node* entry = var_entry.value();
+
+    Node* index = EntryToIndex<Dictionary>(entry);
+    var_name_index->Bind(index);
+
+    Node* current = LoadFixedArrayElement(dictionary, index);
+    GotoIf(WordEqual(current, undefined), if_not_found);
+    GotoIf(WordEqual(current, unique_name), if_found);
+
+    // See Dictionary::NextProbe().
+    count = Int32Add(count, Int32Constant(1));
+    entry = Word32And(Int32Add(entry, count), mask);
+
+    var_count.Bind(count);
+    var_entry.Bind(entry);
+    Goto(&loop);
+  }
+}
+
+// Instantiate template methods to workaround GCC compilation issue.
+template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>(
+    Node*, Node*, Label*, Variable*, Label*, int);
+template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
+    Node*, Node*, Label*, Variable*, Label*, int);
+
+Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
+  // See v8::internal::ComputeIntegerHash()
+  Node* hash = key;
+  hash = Word32Xor(hash, seed);
+  hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)),
+                  Word32Shl(hash, Int32Constant(15)));
+  hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
+  hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2)));
+  hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4)));
+  hash = Int32Mul(hash, Int32Constant(2057));
+  hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16)));
+  return Word32And(hash, Int32Constant(0x3fffffff));
+}
+
+template <typename Dictionary>
+void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key,
+                                               Label* if_found,
+                                               Variable* var_entry,
+                                               Label* if_not_found) {
+  DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep());
+  Comment("NumberDictionaryLookup");
+
+  Node* capacity = SmiToWord32(LoadFixedArrayElement(
+      dictionary, Int32Constant(Dictionary::kCapacityIndex)));
+  Node* mask = Int32Sub(capacity, Int32Constant(1));
+
+  Node* seed;
+  if (Dictionary::ShapeT::UsesSeed) {
+    seed = HashSeed();
+  } else {
+    seed = Int32Constant(kZeroHashSeed);
+  }
+  Node* hash = ComputeIntegerHash(key, seed);
+  Node* key_as_float64 = ChangeUint32ToFloat64(key);
+
+  // See Dictionary::FirstProbe().
+  Node* count = Int32Constant(0);
+  Node* entry = Word32And(hash, mask);
+
+  Node* undefined = UndefinedConstant();
+  Node* the_hole = TheHoleConstant();
+
+  Variable var_count(this, MachineRepresentation::kWord32);
+  Variable* loop_vars[] = {&var_count, var_entry};
+  Label loop(this, 2, loop_vars);
+  var_count.Bind(count);
+  var_entry->Bind(entry);
+  Goto(&loop);
+  Bind(&loop);
+  {
+    Node* count = var_count.value();
+    Node* entry = var_entry->value();
+
+    Node* index = EntryToIndex<Dictionary>(entry);
+    Node* current = LoadFixedArrayElement(dictionary, index);
+    GotoIf(WordEqual(current, undefined), if_not_found);
+    Label next_probe(this);
     {
-      Node* array_index = Int32Add(offset, Int32Mul(index, factor));
-      Node* current = LoadFixedArrayElement(descriptors, array_index);
-      Label if_unequal(this);
-      Branch(WordEqual(current, name), if_found, &if_unequal);
-      Bind(&if_unequal);
+      Label if_currentissmi(this), if_currentisnotsmi(this);
+      Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi);
+      Bind(&if_currentissmi);
+      {
+        Node* current_value = SmiToWord32(current);
+        Branch(Word32Equal(current_value, key), if_found, &next_probe);
+      }
+      Bind(&if_currentisnotsmi);
+      {
+        GotoIf(WordEqual(current, the_hole), &next_probe);
+        // Current must be the Number.
+        Node* current_value = LoadHeapNumberValue(current);
+        Branch(Float64Equal(current_value, key_as_float64), if_found,
+               &next_probe);
+      }
+    }
+
+    Bind(&next_probe);
+    // See Dictionary::NextProbe().
+    count = Int32Add(count, Int32Constant(1));
+    entry = Word32And(Int32Add(entry, count), mask);
+
+    var_count.Bind(count);
+    var_entry->Bind(entry);
+    Goto(&loop);
+  }
+}
+
+void CodeStubAssembler::TryLookupProperty(
+    Node* object, Node* map, Node* instance_type, Node* unique_name,
+    Label* if_found_fast, Label* if_found_dict, Label* if_found_global,
+    Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found,
+    Label* if_bailout) {
+  DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep());
+  DCHECK_EQ(MachineRepresentation::kWord32, var_name_index->rep());
+
+  Label if_objectisspecial(this);
+  STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
+  GotoIf(Int32LessThanOrEqual(instance_type,
+                              Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
+         &if_objectisspecial);
+
+  Node* bit_field = LoadMapBitField(map);
+  Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
+                             1 << Map::kIsAccessCheckNeeded);
+  Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0)));
+
+  Node* bit_field3 = LoadMapBitField3(map);
+  Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3);
+  Label if_isfastmap(this), if_isslowmap(this);
+  Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap);
+  Bind(&if_isfastmap);
+  {
+    Comment("DescriptorArrayLookup");
+    Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3);
+    // Bail out to the runtime for large numbers of own descriptors. The stub
+    // only does linear search, which becomes too expensive in that case.
+    {
+      static const int32_t kMaxLinear = 210;
+      GotoIf(Int32GreaterThan(nof, Int32Constant(kMaxLinear)), if_bailout);
+    }
+    Node* descriptors = LoadMapDescriptors(map);
+    var_meta_storage->Bind(descriptors);
+
+    Variable var_descriptor(this, MachineRepresentation::kWord32);
+    Label loop(this, &var_descriptor);
+    var_descriptor.Bind(Int32Constant(0));
+    Goto(&loop);
+    Bind(&loop);
+    {
+      Node* index = var_descriptor.value();
+      Node* name_offset = Int32Constant(DescriptorArray::ToKeyIndex(0));
+      Node* factor = Int32Constant(DescriptorArray::kDescriptorSize);
+      GotoIf(Word32Equal(index, nof), if_not_found);
+
+      Node* name_index = Int32Add(name_offset, Int32Mul(index, factor));
+      Node* name = LoadFixedArrayElement(descriptors, name_index);
+
+      var_name_index->Bind(name_index);
+      GotoIf(WordEqual(name, unique_name), if_found_fast);
 
       var_descriptor.Bind(Int32Add(index, Int32Constant(1)));
       Goto(&loop);
     }
   }
+  Bind(&if_isslowmap);
+  {
+    Node* dictionary = LoadProperties(object);
+    var_meta_storage->Bind(dictionary);
+
+    NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict,
+                                         var_name_index, if_not_found);
+  }
+  Bind(&if_objectisspecial);
+  {
+    // Handle global object here and other special objects in runtime.
+    GotoUnless(Word32Equal(instance_type, Int32Constant(JS_GLOBAL_OBJECT_TYPE)),
+               if_bailout);
+
+    // Handle interceptors and access checks in runtime.
+    Node* bit_field = LoadMapBitField(map);
+    Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
+                               1 << Map::kIsAccessCheckNeeded);
+    GotoIf(Word32NotEqual(Word32And(bit_field, mask), Int32Constant(0)),
+           if_bailout);
+
+    Node* dictionary = LoadProperties(object);
+    var_meta_storage->Bind(dictionary);
+
+    NameDictionaryLookup<GlobalDictionary>(
+        dictionary, unique_name, if_found_global, var_name_index, if_not_found);
+  }
+}
+
+void CodeStubAssembler::TryHasOwnProperty(compiler::Node* object,
+                                          compiler::Node* map,
+                                          compiler::Node* instance_type,
+                                          compiler::Node* unique_name,
+                                          Label* if_found, Label* if_not_found,
+                                          Label* if_bailout) {
+  Comment("TryHasOwnProperty");
+  Variable var_meta_storage(this, MachineRepresentation::kTagged);
+  Variable var_name_index(this, MachineRepresentation::kWord32);
+
+  Label if_found_global(this);
+  TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found,
+                    &if_found_global, &var_meta_storage, &var_name_index,
+                    if_not_found, if_bailout);
+  Bind(&if_found_global);
+  {
+    Variable var_value(this, MachineRepresentation::kTagged);
+    Variable var_details(this, MachineRepresentation::kWord32);
+    // Check if the property cell is not deleted.
+    LoadPropertyFromGlobalDictionary(var_meta_storage.value(),
+                                     var_name_index.value(), &var_value,
+                                     &var_details, if_not_found);
+    Goto(if_found);
+  }
+}
+
+void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
+                                                   Node* descriptors,
+                                                   Node* name_index,
+                                                   Variable* var_details,
+                                                   Variable* var_value) {
+  DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep());
+  DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
+  Comment("[ LoadPropertyFromFastObject");
+
+  const int name_to_details_offset =
+      (DescriptorArray::kDescriptorDetails - DescriptorArray::kDescriptorKey) *
+      kPointerSize;
+  const int name_to_value_offset =
+      (DescriptorArray::kDescriptorValue - DescriptorArray::kDescriptorKey) *
+      kPointerSize;
+
+  Node* details = SmiToWord32(
+      LoadFixedArrayElement(descriptors, name_index, name_to_details_offset));
+  var_details->Bind(details);
+
+  Node* location = BitFieldDecode<PropertyDetails::LocationField>(details);
+
+  Label if_in_field(this), if_in_descriptor(this), done(this);
+  Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field,
+         &if_in_descriptor);
+  Bind(&if_in_field);
+  {
+    Node* field_index =
+        BitFieldDecode<PropertyDetails::FieldIndexField>(details);
+    Node* representation =
+        BitFieldDecode<PropertyDetails::RepresentationField>(details);
+
+    Node* inobject_properties = LoadMapInobjectProperties(map);
+
+    Label if_inobject(this), if_backing_store(this);
+    Variable var_double_value(this, MachineRepresentation::kFloat64);
+    Label rebox_double(this, &var_double_value);
+    BranchIfInt32LessThan(field_index, inobject_properties, &if_inobject,
+                          &if_backing_store);
+    Bind(&if_inobject);
+    {
+      Comment("if_inobject");
+      Node* field_offset = ChangeInt32ToIntPtr(
+          Int32Mul(Int32Sub(LoadMapInstanceSize(map),
+                            Int32Sub(inobject_properties, field_index)),
+                   Int32Constant(kPointerSize)));
+
+      Label if_double(this), if_tagged(this);
+      BranchIfWord32NotEqual(representation,
+                             Int32Constant(Representation::kDouble), &if_tagged,
+                             &if_double);
+      Bind(&if_tagged);
+      {
+        var_value->Bind(LoadObjectField(object, field_offset));
+        Goto(&done);
+      }
+      Bind(&if_double);
+      {
+        if (FLAG_unbox_double_fields) {
+          var_double_value.Bind(
+              LoadObjectField(object, field_offset, MachineType::Float64()));
+        } else {
+          Node* mutable_heap_number = LoadObjectField(object, field_offset);
+          var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
+        }
+        Goto(&rebox_double);
+      }
+    }
+    Bind(&if_backing_store);
+    {
+      Comment("if_backing_store");
+      Node* properties = LoadProperties(object);
+      field_index = Int32Sub(field_index, inobject_properties);
+      Node* value = LoadFixedArrayElement(properties, field_index);
+
+      Label if_double(this), if_tagged(this);
+      BranchIfWord32NotEqual(representation,
+                             Int32Constant(Representation::kDouble), &if_tagged,
+                             &if_double);
+      Bind(&if_tagged);
+      {
+        var_value->Bind(value);
+        Goto(&done);
+      }
+      Bind(&if_double);
+      {
+        var_double_value.Bind(LoadHeapNumberValue(value));
+        Goto(&rebox_double);
+      }
+    }
+    Bind(&rebox_double);
+    {
+      Comment("rebox_double");
+      Node* heap_number = AllocateHeapNumber();
+      StoreHeapNumberValue(heap_number, var_double_value.value());
+      var_value->Bind(heap_number);
+      Goto(&done);
+    }
+  }
+  Bind(&if_in_descriptor);
+  {
+    Node* value =
+        LoadFixedArrayElement(descriptors, name_index, name_to_value_offset);
+    var_value->Bind(value);
+    Goto(&done);
+  }
+  Bind(&done);
+
+  Comment("] LoadPropertyFromFastObject");
+}
+
+void CodeStubAssembler::LoadPropertyFromNameDictionary(Node* dictionary,
+                                                       Node* name_index,
+                                                       Variable* var_details,
+                                                       Variable* var_value) {
+  Comment("LoadPropertyFromNameDictionary");
+
+  const int name_to_details_offset =
+      (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) *
+      kPointerSize;
+  const int name_to_value_offset =
+      (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) *
+      kPointerSize;
+
+  Node* details = SmiToWord32(
+      LoadFixedArrayElement(dictionary, name_index, name_to_details_offset));
+
+  var_details->Bind(details);
+  var_value->Bind(
+      LoadFixedArrayElement(dictionary, name_index, name_to_value_offset));
+
+  Comment("] LoadPropertyFromNameDictionary");
+}
+
+void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary,
+                                                         Node* name_index,
+                                                         Variable* var_details,
+                                                         Variable* var_value,
+                                                         Label* if_deleted) {
+  Comment("[ LoadPropertyFromGlobalDictionary");
+
+  const int name_to_value_offset =
+      (GlobalDictionary::kEntryValueIndex - GlobalDictionary::kEntryKeyIndex) *
+      kPointerSize;
+
+  Node* property_cell =
+      LoadFixedArrayElement(dictionary, name_index, name_to_value_offset);
+
+  Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset);
+  GotoIf(WordEqual(value, TheHoleConstant()), if_deleted);
+
+  var_value->Bind(value);
+
+  Node* details =
+      SmiToWord32(LoadObjectField(property_cell, PropertyCell::kDetailsOffset));
+  var_details->Bind(details);
+
+  Comment("] LoadPropertyFromGlobalDictionary");
+}
+
+void CodeStubAssembler::TryGetOwnProperty(
+    Node* context, Node* receiver, Node* object, Node* map, Node* instance_type,
+    Node* unique_name, Label* if_found_value, Variable* var_value,
+    Label* if_not_found, Label* if_bailout) {
+  DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
+  Comment("TryGetOwnProperty");
+
+  Variable var_meta_storage(this, MachineRepresentation::kTagged);
+  Variable var_entry(this, MachineRepresentation::kWord32);
+
+  Label if_found_fast(this), if_found_dict(this), if_found_global(this);
+
+  Variable var_details(this, MachineRepresentation::kWord32);
+  Variable* vars[] = {var_value, &var_details};
+  Label if_found(this, 2, vars);
+
+  TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast,
+                    &if_found_dict, &if_found_global, &var_meta_storage,
+                    &var_entry, if_not_found, if_bailout);
+  Bind(&if_found_fast);
+  {
+    Node* descriptors = var_meta_storage.value();
+    Node* name_index = var_entry.value();
+
+    LoadPropertyFromFastObject(object, map, descriptors, name_index,
+                               &var_details, var_value);
+    Goto(&if_found);
+  }
+  Bind(&if_found_dict);
+  {
+    Node* dictionary = var_meta_storage.value();
+    Node* entry = var_entry.value();
+    LoadPropertyFromNameDictionary(dictionary, entry, &var_details, var_value);
+    Goto(&if_found);
+  }
+  Bind(&if_found_global);
+  {
+    Node* dictionary = var_meta_storage.value();
+    Node* entry = var_entry.value();
+
+    LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value,
+                                     if_not_found);
+    Goto(&if_found);
+  }
+  // Here we have details and value which could be an accessor.
+  Bind(&if_found);
+  {
+    Node* details = var_details.value();
+    Node* kind = BitFieldDecode<PropertyDetails::KindField>(details);
+
+    Label if_accessor(this);
+    Branch(Word32Equal(kind, Int32Constant(kData)), if_found_value,
+           &if_accessor);
+    Bind(&if_accessor);
+    {
+      Node* accessor_pair = var_value->value();
+      GotoIf(Word32Equal(LoadInstanceType(accessor_pair),
+                         Int32Constant(ACCESSOR_INFO_TYPE)),
+             if_bailout);
+      AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE);
+      Node* getter =
+          LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
+      Node* getter_map = LoadMap(getter);
+      Node* instance_type = LoadMapInstanceType(getter_map);
+      // FunctionTemplateInfo getters are not supported yet.
+      GotoIf(Word32Equal(instance_type,
+                         Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)),
+             if_bailout);
+
+      // Return undefined if the {getter} is not callable.
+      var_value->Bind(UndefinedConstant());
+      GotoIf(Word32Equal(Word32And(LoadMapBitField(getter_map),
+                                   Int32Constant(1 << Map::kIsCallable)),
+                         Int32Constant(0)),
+             if_found_value);
+
+      // Call the accessor.
+      Callable callable = CodeFactory::Call(isolate());
+      Node* result = CallJS(callable, context, getter, receiver);
+      var_value->Bind(result);
+      Goto(if_found_value);
+    }
+  }
 }
 
 void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
                                          Node* instance_type, Node* index,
                                          Label* if_found, Label* if_not_found,
-                                         Label* call_runtime) {
-  {
-    Label if_objectissimple(this);
-    Branch(Int32LessThanOrEqual(instance_type,
-                                Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
-           call_runtime, &if_objectissimple);
-    Bind(&if_objectissimple);
-  }
+                                         Label* if_bailout) {
+  // Handle special objects in runtime.
+  GotoIf(Int32LessThanOrEqual(instance_type,
+                              Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
+         if_bailout);
 
   Node* bit_field2 = LoadMapBitField2(map);
   Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2);
 
   // TODO(verwaest): Support other elements kinds as well.
-  Label if_isobjectorsmi(this);
-  Branch(
-      Int32LessThanOrEqual(elements_kind, Int32Constant(FAST_HOLEY_ELEMENTS)),
-      &if_isobjectorsmi, call_runtime);
+  Label if_isobjectorsmi(this), if_isdouble(this), if_isdictionary(this),
+      if_isfaststringwrapper(this), if_isslowstringwrapper(this);
+  // clang-format off
+  int32_t values[] = {
+      // Handled by {if_isobjectorsmi}.
+      FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
+          FAST_HOLEY_ELEMENTS,
+      // Handled by {if_isdouble}.
+      FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
+      // Handled by {if_isdictionary}.
+      DICTIONARY_ELEMENTS,
+      // Handled by {if_isfaststringwrapper}.
+      FAST_STRING_WRAPPER_ELEMENTS,
+      // Handled by {if_isslowstringwrapper}.
+      SLOW_STRING_WRAPPER_ELEMENTS,
+      // Handled by {if_not_found}.
+      NO_ELEMENTS,
+  };
+  Label* labels[] = {
+      &if_isobjectorsmi, &if_isobjectorsmi, &if_isobjectorsmi,
+          &if_isobjectorsmi,
+      &if_isdouble, &if_isdouble,
+      &if_isdictionary,
+      &if_isfaststringwrapper,
+      &if_isslowstringwrapper,
+      if_not_found,
+  };
+  // clang-format on
+  STATIC_ASSERT(arraysize(values) == arraysize(labels));
+  Switch(elements_kind, if_bailout, values, labels, arraysize(values));
+
   Bind(&if_isobjectorsmi);
   {
     Node* elements = LoadElements(object);
     Node* length = LoadFixedArrayBaseLength(elements);
 
-    Label if_iskeyinrange(this);
-    Branch(Int32LessThan(index, SmiToWord32(length)), &if_iskeyinrange,
-           if_not_found);
+    GotoIf(Int32GreaterThanOrEqual(index, SmiToWord32(length)), if_not_found);
 
-    Bind(&if_iskeyinrange);
     Node* element = LoadFixedArrayElement(elements, index);
-    Node* the_hole = LoadRoot(Heap::kTheHoleValueRootIndex);
+    Node* the_hole = TheHoleConstant();
     Branch(WordEqual(element, the_hole), if_not_found, if_found);
   }
+  Bind(&if_isdouble);
+  {
+    Node* elements = LoadElements(object);
+    Node* length = LoadFixedArrayBaseLength(elements);
+
+    GotoIf(Int32GreaterThanOrEqual(index, SmiToWord32(length)), if_not_found);
+
+    if (kPointerSize == kDoubleSize) {
+      Node* element =
+          LoadFixedDoubleArrayElement(elements, index, MachineType::Uint64());
+      Node* the_hole = Int64Constant(kHoleNanInt64);
+      Branch(Word64Equal(element, the_hole), if_not_found, if_found);
+    } else {
+      Node* element_upper =
+          LoadFixedDoubleArrayElement(elements, index, MachineType::Uint32(),
+                                      kIeeeDoubleExponentWordOffset);
+      Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
+             if_not_found, if_found);
+    }
+  }
+  Bind(&if_isdictionary);
+  {
+    Variable var_entry(this, MachineRepresentation::kWord32);
+    Node* elements = LoadElements(object);
+    NumberDictionaryLookup<SeededNumberDictionary>(elements, index, if_found,
+                                                   &var_entry, if_not_found);
+  }
+  Bind(&if_isfaststringwrapper);
+  {
+    AssertInstanceType(object, JS_VALUE_TYPE);
+    Node* string = LoadJSValueValue(object);
+    Assert(Int32LessThan(LoadInstanceType(string),
+                         Int32Constant(FIRST_NONSTRING_TYPE)));
+    Node* length = LoadStringLength(string);
+    GotoIf(Int32LessThan(index, SmiToWord32(length)), if_found);
+    Goto(&if_isobjectorsmi);
+  }
+  Bind(&if_isslowstringwrapper);
+  {
+    AssertInstanceType(object, JS_VALUE_TYPE);
+    Node* string = LoadJSValueValue(object);
+    Assert(Int32LessThan(LoadInstanceType(string),
+                         Int32Constant(FIRST_NONSTRING_TYPE)));
+    Node* length = LoadStringLength(string);
+    GotoIf(Int32LessThan(index, SmiToWord32(length)), if_found);
+    Goto(&if_isdictionary);
+  }
 }
 
+// Instantiate template methods to workaround GCC compilation issue.
+template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>(
+    Node*, Node*, Label*, Variable*, Label*);
+template void CodeStubAssembler::NumberDictionaryLookup<
+    UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*);
+
 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
                                              Node* object) {
   Variable var_result(this, MachineRepresentation::kTagged);
@@ -1500,8 +2279,8 @@
 
     // Check the current {object} prototype.
     Node* object_prototype = LoadMapPrototype(object_map);
-    GotoIf(WordEqual(object_prototype, callable_prototype), &return_true);
     GotoIf(WordEqual(object_prototype, NullConstant()), &return_false);
+    GotoIf(WordEqual(object_prototype, callable_prototype), &return_true);
 
     // Continue with the prototype.
     var_object_map.Bind(LoadMap(object_prototype));
@@ -1568,5 +2347,331 @@
           : WordShr(index_node, IntPtrConstant(-element_size_shift)));
 }
 
+compiler::Node* CodeStubAssembler::LoadTypeFeedbackVectorForStub() {
+  Node* function =
+      LoadFromParentFrame(JavaScriptFrameConstants::kFunctionOffset);
+  Node* literals = LoadObjectField(function, JSFunction::kLiteralsOffset);
+  return LoadObjectField(literals, LiteralsArray::kFeedbackVectorOffset);
+}
+
+compiler::Node* CodeStubAssembler::LoadReceiverMap(compiler::Node* receiver) {
+  Variable var_receiver_map(this, MachineRepresentation::kTagged);
+  // TODO(ishell): defer blocks when it works.
+  Label load_smi_map(this /*, Label::kDeferred*/), load_receiver_map(this),
+      if_result(this);
+
+  Branch(WordIsSmi(receiver), &load_smi_map, &load_receiver_map);
+  Bind(&load_smi_map);
+  {
+    var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex));
+    Goto(&if_result);
+  }
+  Bind(&load_receiver_map);
+  {
+    var_receiver_map.Bind(LoadMap(receiver));
+    Goto(&if_result);
+  }
+  Bind(&if_result);
+  return var_receiver_map.value();
+}
+
+compiler::Node* CodeStubAssembler::TryMonomorphicCase(
+    const LoadICParameters* p, compiler::Node* receiver_map, Label* if_handler,
+    Variable* var_handler, Label* if_miss) {
+  DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
+
+  // TODO(ishell): add helper class that hides offset computations for a series
+  // of loads.
+  int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag;
+  Node* offset = ElementOffsetFromIndex(p->slot, FAST_HOLEY_ELEMENTS,
+                                        SMI_PARAMETERS, header_size);
+  Node* feedback = Load(MachineType::AnyTagged(), p->vector, offset);
+
+  // Try to quickly handle the monomorphic case without knowing for sure
+  // if we have a weak cell in feedback. We do know it's safe to look
+  // at WeakCell::kValueOffset.
+  GotoUnless(WordEqual(receiver_map, LoadWeakCellValue(feedback)), if_miss);
+
+  Node* handler = Load(MachineType::AnyTagged(), p->vector,
+                       IntPtrAdd(offset, IntPtrConstant(kPointerSize)));
+
+  var_handler->Bind(handler);
+  Goto(if_handler);
+  return feedback;
+}
+
+void CodeStubAssembler::HandlePolymorphicCase(
+    const LoadICParameters* p, compiler::Node* receiver_map,
+    compiler::Node* feedback, Label* if_handler, Variable* var_handler,
+    Label* if_miss, int unroll_count) {
+  DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
+
+  // Iterate {feedback} array.
+  const int kEntrySize = 2;
+
+  for (int i = 0; i < unroll_count; i++) {
+    Label next_entry(this);
+    Node* cached_map = LoadWeakCellValue(
+        LoadFixedArrayElement(feedback, Int32Constant(i * kEntrySize)));
+    GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry);
+
+    // Found, now call handler.
+    Node* handler =
+        LoadFixedArrayElement(feedback, Int32Constant(i * kEntrySize + 1));
+    var_handler->Bind(handler);
+    Goto(if_handler);
+
+    Bind(&next_entry);
+  }
+  Node* length = SmiToWord32(LoadFixedArrayBaseLength(feedback));
+
+  // Loop from {unroll_count}*kEntrySize to {length}.
+  Variable var_index(this, MachineRepresentation::kWord32);
+  Label loop(this, &var_index);
+  var_index.Bind(Int32Constant(unroll_count * kEntrySize));
+  Goto(&loop);
+  Bind(&loop);
+  {
+    Node* index = var_index.value();
+    GotoIf(Int32GreaterThanOrEqual(index, length), if_miss);
+
+    Node* cached_map =
+        LoadWeakCellValue(LoadFixedArrayElement(feedback, index));
+
+    Label next_entry(this);
+    GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry);
+
+    // Found, now call handler.
+    Node* handler = LoadFixedArrayElement(feedback, index, kPointerSize);
+    var_handler->Bind(handler);
+    Goto(if_handler);
+
+    Bind(&next_entry);
+    var_index.Bind(Int32Add(index, Int32Constant(kEntrySize)));
+    Goto(&loop);
+  }
+}
+
+compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name,
+                                                          Code::Flags flags,
+                                                          compiler::Node* map) {
+  // See v8::internal::StubCache::PrimaryOffset().
+  STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift);
+  // Compute the hash of the name (use entire hash field).
+  Node* hash_field = LoadNameHashField(name);
+  Assert(WordEqual(
+      Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
+      Int32Constant(0)));
+
+  // Using only the low bits in 64-bit mode is unlikely to increase the
+  // risk of collision even if the heap is spread over an area larger than
+  // 4Gb (and not at all if it isn't).
+  Node* hash = Int32Add(hash_field, map);
+  // We always set the in_loop bit to zero when generating the lookup code
+  // so do it here too so the hash codes match.
+  uint32_t iflags =
+      (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
+  // Base the offset on a simple combination of name, flags, and map.
+  hash = Word32Xor(hash, Int32Constant(iflags));
+  uint32_t mask = (StubCache::kPrimaryTableSize - 1)
+                  << StubCache::kCacheIndexShift;
+  return Word32And(hash, Int32Constant(mask));
+}
+
+compiler::Node* CodeStubAssembler::StubCacheSecondaryOffset(
+    compiler::Node* name, Code::Flags flags, compiler::Node* seed) {
+  // See v8::internal::StubCache::SecondaryOffset().
+
+  // Use the seed from the primary cache in the secondary cache.
+  Node* hash = Int32Sub(seed, name);
+  // We always set the in_loop bit to zero when generating the lookup code
+  // so do it here too so the hash codes match.
+  uint32_t iflags =
+      (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
+  hash = Int32Add(hash, Int32Constant(iflags));
+  int32_t mask = (StubCache::kSecondaryTableSize - 1)
+                 << StubCache::kCacheIndexShift;
+  return Word32And(hash, Int32Constant(mask));
+}
+
+enum CodeStubAssembler::StubCacheTable : int {
+  kPrimary = static_cast<int>(StubCache::kPrimary),
+  kSecondary = static_cast<int>(StubCache::kSecondary)
+};
+
+void CodeStubAssembler::TryProbeStubCacheTable(
+    StubCache* stub_cache, StubCacheTable table_id,
+    compiler::Node* entry_offset, compiler::Node* name, Code::Flags flags,
+    compiler::Node* map, Label* if_handler, Variable* var_handler,
+    Label* if_miss) {
+  StubCache::Table table = static_cast<StubCache::Table>(table_id);
+#ifdef DEBUG
+  if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
+    Goto(if_miss);
+    return;
+  } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
+    Goto(if_miss);
+    return;
+  }
+#endif
+  // The {table_offset} holds the entry offset times four (due to masking
+  // and shifting optimizations).
+  const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift;
+  entry_offset = Int32Mul(entry_offset, Int32Constant(kMultiplier));
+
+  // Check that the key in the entry matches the name.
+  Node* key_base =
+      ExternalConstant(ExternalReference(stub_cache->key_reference(table)));
+  Node* entry_key = Load(MachineType::Pointer(), key_base, entry_offset);
+  GotoIf(WordNotEqual(name, entry_key), if_miss);
+
+  // Get the map entry from the cache.
+  DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() -
+                                  stub_cache->key_reference(table).address());
+  Node* entry_map =
+      Load(MachineType::Pointer(), key_base,
+           Int32Add(entry_offset, Int32Constant(kPointerSize * 2)));
+  GotoIf(WordNotEqual(map, entry_map), if_miss);
+
+  // Check that the flags match what we're looking for.
+  DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() -
+                              stub_cache->key_reference(table).address());
+  Node* code = Load(MachineType::Pointer(), key_base,
+                    Int32Add(entry_offset, Int32Constant(kPointerSize)));
+
+  Node* code_flags =
+      LoadObjectField(code, Code::kFlagsOffset, MachineType::Uint32());
+  GotoIf(Word32NotEqual(Int32Constant(flags),
+                        Word32And(code_flags,
+                                  Int32Constant(~Code::kFlagsNotUsedInLookup))),
+         if_miss);
+
+  // We found the handler.
+  var_handler->Bind(code);
+  Goto(if_handler);
+}
+
+void CodeStubAssembler::TryProbeStubCache(
+    StubCache* stub_cache, Code::Flags flags, compiler::Node* receiver,
+    compiler::Node* name, Label* if_handler, Variable* var_handler,
+    Label* if_miss) {
+  Label try_secondary(this), miss(this);
+
+  Counters* counters = isolate()->counters();
+  IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
+
+  // Check that the {receiver} isn't a smi.
+  GotoIf(WordIsSmi(receiver), &miss);
+
+  Node* receiver_map = LoadMap(receiver);
+
+  // Probe the primary table.
+  Node* primary_offset = StubCachePrimaryOffset(name, flags, receiver_map);
+  TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, flags,
+                         receiver_map, if_handler, var_handler, &try_secondary);
+
+  Bind(&try_secondary);
+  {
+    // Probe the secondary table.
+    Node* secondary_offset =
+        StubCacheSecondaryOffset(name, flags, primary_offset);
+    TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name,
+                           flags, receiver_map, if_handler, var_handler, &miss);
+  }
+
+  Bind(&miss);
+  {
+    IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
+    Goto(if_miss);
+  }
+}
+
+void CodeStubAssembler::LoadIC(const LoadICParameters* p) {
+  Variable var_handler(this, MachineRepresentation::kTagged);
+  // TODO(ishell): defer blocks when it works.
+  Label if_handler(this, &var_handler), try_polymorphic(this),
+      try_megamorphic(this /*, Label::kDeferred*/),
+      miss(this /*, Label::kDeferred*/);
+
+  Node* receiver_map = LoadReceiverMap(p->receiver);
+
+  // Check monomorphic case.
+  Node* feedback = TryMonomorphicCase(p, receiver_map, &if_handler,
+                                      &var_handler, &try_polymorphic);
+  Bind(&if_handler);
+  {
+    LoadWithVectorDescriptor descriptor(isolate());
+    TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
+                 p->name, p->slot, p->vector);
+  }
+
+  Bind(&try_polymorphic);
+  {
+    // Check polymorphic case.
+    GotoUnless(
+        WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
+        &try_megamorphic);
+    HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler,
+                          &miss, 2);
+  }
+
+  Bind(&try_megamorphic);
+  {
+    // Check megamorphic case.
+    GotoUnless(
+        WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
+        &miss);
+
+    Code::Flags code_flags =
+        Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(Code::LOAD_IC));
+
+    TryProbeStubCache(isolate()->stub_cache(), code_flags, p->receiver, p->name,
+                      &if_handler, &var_handler, &miss);
+  }
+  Bind(&miss);
+  {
+    TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name,
+                    p->slot, p->vector);
+  }
+}
+
+void CodeStubAssembler::LoadGlobalIC(const LoadICParameters* p) {
+  Label try_handler(this), miss(this);
+  Node* weak_cell =
+      LoadFixedArrayElement(p->vector, p->slot, 0, SMI_PARAMETERS);
+  AssertInstanceType(weak_cell, WEAK_CELL_TYPE);
+
+  // Load value or try handler case if the {weak_cell} is cleared.
+  Node* property_cell = LoadWeakCellValue(weak_cell, &try_handler);
+  AssertInstanceType(property_cell, PROPERTY_CELL_TYPE);
+
+  Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset);
+  GotoIf(WordEqual(value, TheHoleConstant()), &miss);
+  Return(value);
+
+  Bind(&try_handler);
+  {
+    Node* handler =
+        LoadFixedArrayElement(p->vector, p->slot, kPointerSize, SMI_PARAMETERS);
+    GotoIf(WordEqual(handler, LoadRoot(Heap::kuninitialized_symbolRootIndex)),
+           &miss);
+
+    // In this case {handler} must be a Code object.
+    AssertInstanceType(handler, CODE_TYPE);
+    LoadWithVectorDescriptor descriptor(isolate());
+    Node* native_context = LoadNativeContext(p->context);
+    Node* receiver = LoadFixedArrayElement(
+        native_context, Int32Constant(Context::EXTENSION_INDEX));
+    Node* fake_name = IntPtrConstant(0);
+    TailCallStub(descriptor, handler, p->context, receiver, fake_name, p->slot,
+                 p->vector);
+  }
+  Bind(&miss);
+  {
+    TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot,
+                    p->vector);
+  }
+}
+
 }  // namespace internal
 }  // namespace v8
