From 2938ef4e45e6aaaf0f4b9359cb4200f8797dfaf7 Mon Sep 17 00:00:00 2001
From: machenbach <machenbach@chromium.org>
Date: Mon, 11 Apr 2016 04:34:40 -0700
Subject: [PATCH] Revert of Turn StoreIC::Megamorphic into a builtin, get rid
 of the non-monomorphic-cache (patchset #5 id:80001 of
 https://codereview.chromium.org/1864703003/ )

Reason for revert:
[Sheriff] Check during mksnapshot:
https://build.chromium.org/p/client.v8/builders/V8%20Linux%20ASAN%20mipsel%20-%20debug%20builder/builds/5950/steps/compile/logs/stdio

Original issue's description:
> Turn StoreIC::Megamorphic into a builtin, get rid of the non-monomorphic-cache
>
> BUG=
>
> Committed: https://crrev.com/8764f87a3399ba433a4ce6f32161181c713af95c
> Cr-Commit-Position: refs/heads/master@{#35376}

TBR=mvstanton@chromium.org,hpayer@chromium.org,verwaest@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=

Review URL: https://codereview.chromium.org/1875033003

Cr-Commit-Position: refs/heads/master@{#35379}
---
 src/builtins.cc                 |  8 -----
 src/builtins.h                  |  5 +--
 src/heap/heap.cc                |  5 +++
 src/heap/heap.h                 |  6 ++++
 src/ic/arm/ic-arm.cc            |  2 +-
 src/ic/arm64/ic-arm64.cc        |  6 ++--
 src/ic/ic-compiler.cc           | 63 ++++++++++++++++++++++++++++++---
 src/ic/ic-compiler.h            | 44 ++++++++++++++++++++---
 src/ic/ic.cc                    | 18 +++++-----
 src/ic/ic.h                     |  7 ++++
 src/snapshot/code-serializer.cc |  8 ++++-
 11 files changed, 137 insertions(+), 35 deletions(-)

diff --git a/src/builtins.cc b/src/builtins.cc
index 5456cd5b4f..7173e54504 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -4667,14 +4667,6 @@ static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
   NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
 }
 
-static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
-  StoreIC::GenerateMegamorphic(masm);
-}
-
-static void Generate_StoreIC_Megamorphic_Strict(MacroAssembler* masm) {
-  StoreIC::GenerateMegamorphic(masm);
-}
-
 
 static void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) {
   KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY);
diff --git a/src/builtins.h b/src/builtins.h
index 75761edfae..294929a290 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -247,11 +247,8 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
   V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC,                            \
     StoreICState::kStrictModeState)                                            \
                                                                                \
-  V(StoreIC_Megamorphic, STORE_IC, MEGAMORPHIC, kNoExtraICState)               \
-  V(StoreIC_Megamorphic_Strict, STORE_IC, MEGAMORPHIC,                         \
-    StoreICState::kStrictModeState)                                            \
-                                                                               \
   V(KeyedStoreIC_Megamorphic, KEYED_STORE_IC, MEGAMORPHIC, kNoExtraICState)    \
+                                                                               \
   V(KeyedStoreIC_Megamorphic_Strict, KEYED_STORE_IC, MEGAMORPHIC,              \
     StoreICState::kStrictModeState)                                            \
                                                                                \
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 592215b483..1c6d9f62ab 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -2691,6 +2691,10 @@ void Heap::CreateInitialObjects() {
   // expanding the dictionary during bootstrapping.
   set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
 
+  // Create the non_monomorphic_cache used in stub-cache.cc. The initial size
+  // is set to avoid expanding the dictionary during bootstrapping.
+  set_non_monomorphic_cache(*UnseededNumberDictionary::New(isolate(), 64));
+
   set_instanceof_cache_function(Smi::FromInt(0));
   set_instanceof_cache_map(Smi::FromInt(0));
   set_instanceof_cache_answer(Smi::FromInt(0));
@@ -2893,6 +2897,7 @@ bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
     case kInstanceofCacheMapRootIndex:
     case kInstanceofCacheAnswerRootIndex:
     case kCodeStubsRootIndex:
+    case kNonMonomorphicCacheRootIndex:
     case kEmptyScriptRootIndex:
     case kSymbolRegistryRootIndex:
     case kScriptListRootIndex:
diff --git a/src/heap/heap.h b/src/heap/heap.h
index ab121873ed..59d7dfcf00 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -162,6 +162,7 @@ using v8::MemoryPressureLevel;
   V(HeapNumber, minus_infinity_value, MinusInfinityValue)                      \
   V(JSObject, message_listeners, MessageListeners)                             \
   V(UnseededNumberDictionary, code_stubs, CodeStubs)                           \
+  V(UnseededNumberDictionary, non_monomorphic_cache, NonMonomorphicCache)      \
   V(Code, js_entry_code, JsEntryCode)                                          \
   V(Code, js_construct_entry_code, JsConstructEntryCode)                       \
   V(FixedArray, natives_source_cache, NativesSourceCache)                      \
@@ -976,6 +977,11 @@ class Heap {
     roots_[kCodeStubsRootIndex] = value;
   }
 
+  // Sets the non_monomorphic_cache_ (only used when expanding the dictionary).
+  void SetRootNonMonomorphicCache(UnseededNumberDictionary* value) {
+    roots_[kNonMonomorphicCacheRootIndex] = value;
+  }
+
   void SetRootMaterializedObjects(FixedArray* objects) {
     roots_[kMaterializedObjectsRootIndex] = objects;
   }
diff --git a/src/ic/arm/ic-arm.cc b/src/ic/arm/ic-arm.cc
index 1563837699..76488aa090 100644
--- a/src/ic/arm/ic-arm.cc
+++ b/src/ic/arm/ic-arm.cc
@@ -747,7 +747,7 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
       Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(Code::STORE_IC));
 
   masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, flags,
-                                               receiver, name, r5, r6, r7, r8);
+                                               receiver, name, r3, r4, r5, r6);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
diff --git a/src/ic/arm64/ic-arm64.cc b/src/ic/arm64/ic-arm64.cc
index eb52fe8cd1..40082bbbec 100644
--- a/src/ic/arm64/ic-arm64.cc
+++ b/src/ic/arm64/ic-arm64.cc
@@ -729,14 +729,14 @@ void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   Register receiver = StoreDescriptor::ReceiverRegister();
   Register name = StoreDescriptor::NameRegister();
-  DCHECK(!AreAliased(receiver, name, StoreDescriptor::ValueRegister(), x5, x6,
-                     x7, x8));
+  DCHECK(!AreAliased(receiver, name, StoreDescriptor::ValueRegister(), x3, x4,
+                     x5, x6));
 
   // Probe the stub cache.
   Code::Flags flags =
       Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(Code::STORE_IC));
   masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, flags,
-                                               receiver, name, x5, x6, x7, x8);
+                                               receiver, name, x3, x4, x5, x6);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc
index 3c2619d0e6..dbdb59589c 100644
--- a/src/ic/ic-compiler.cc
+++ b/src/ic/ic-compiler.cc
@@ -43,35 +43,90 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
   return stub;
 }
 
+
 Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
-    Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
+    Handle<Map> receiver_map, LanguageMode language_mode,
+    KeyedAccessStoreMode store_mode) {
   Isolate* isolate = receiver_map->GetIsolate();
+  ExtraICState extra_state =
+      KeyedStoreIC::ComputeExtraICState(language_mode, store_mode);
 
   DCHECK(store_mode == STANDARD_STORE ||
          store_mode == STORE_AND_GROW_NO_TRANSITION ||
          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
          store_mode == STORE_NO_TRANSITION_HANDLE_COW);
 
-  PropertyICCompiler compiler(isolate);
+  PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
   Handle<Code> code =
       compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
   return code;
 }
 
+
+static void FillCache(Isolate* isolate, Handle<Code> code) {
+  Handle<UnseededNumberDictionary> dictionary = UnseededNumberDictionary::Set(
+      isolate->factory()->non_monomorphic_cache(), code->flags(), code);
+  isolate->heap()->SetRootNonMonomorphicCache(*dictionary);
+}
+
+
+Handle<Code> PropertyICCompiler::ComputeStore(Isolate* isolate,
+                                              InlineCacheState ic_state,
+                                              ExtraICState extra_state) {
+  DCHECK_EQ(MEGAMORPHIC, ic_state);
+  Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, ic_state, extra_state);
+  Handle<UnseededNumberDictionary> cache =
+      isolate->factory()->non_monomorphic_cache();
+  int entry = cache->FindEntry(isolate, flags);
+  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
+
+  PropertyICCompiler compiler(isolate, Code::STORE_IC);
+  Handle<Code> code = compiler.CompileStoreMegamorphic(flags);
+
+  FillCache(isolate, code);
+  return code;
+}
+
+
 void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
     MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
-    CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
+    CodeHandleList* handlers, KeyedAccessStoreMode store_mode,
+    LanguageMode language_mode) {
   Isolate* isolate = receiver_maps->at(0)->GetIsolate();
   DCHECK(store_mode == STANDARD_STORE ||
          store_mode == STORE_AND_GROW_NO_TRANSITION ||
          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
          store_mode == STORE_NO_TRANSITION_HANDLE_COW);
-  PropertyICCompiler compiler(isolate);
+  ExtraICState extra_state =
+      KeyedStoreIC::ComputeExtraICState(language_mode, store_mode);
+  PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
   compiler.CompileKeyedStorePolymorphicHandlers(
       receiver_maps, transitioned_maps, handlers, store_mode);
 }
 
 
+Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) {
+  StoreIC::GenerateMegamorphic(masm());
+  Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
+  PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG,
+                                     AbstractCode::cast(*code), 0));
+  return code;
+}
+
+Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Handle<Name> name,
+                                         InlineCacheState state) {
+  Code::Flags flags =
+      Code::ComputeFlags(kind, state, extra_ic_state_, cache_holder());
+  Handle<Code> code = GetCodeWithFlags(flags, name);
+  PROFILE(isolate(),
+          CodeCreateEvent(log_kind(code), AbstractCode::cast(*code), *name));
+#ifdef DEBUG
+  code->VerifyEmbeddedObjects();
+#endif
+  return code;
+}
+
+
 void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
     MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
     CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
diff --git a/src/ic/ic-compiler.h b/src/ic/ic-compiler.h
index 9d8884fb8a..415aad5e6d 100644
--- a/src/ic/ic-compiler.h
+++ b/src/ic/ic-compiler.h
@@ -13,15 +13,21 @@ namespace internal {
 
 class PropertyICCompiler : public PropertyAccessCompiler {
  public:
+  // Named
+  static Handle<Code> ComputeStore(Isolate* isolate, InlineCacheState ic_state,
+                                   ExtraICState extra_state);
+
   // Keyed
   static Handle<Code> ComputeKeyedLoadMonomorphicHandler(
       Handle<Map> receiver_map, ExtraICState extra_ic_state);
 
   static Handle<Code> ComputeKeyedStoreMonomorphicHandler(
-      Handle<Map> receiver_map, KeyedAccessStoreMode store_mode);
+      Handle<Map> receiver_map, LanguageMode language_mode,
+      KeyedAccessStoreMode store_mode);
   static void ComputeKeyedStorePolymorphicHandlers(
       MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
-      CodeHandleList* handlers, KeyedAccessStoreMode store_mode);
+      CodeHandleList* handlers, KeyedAccessStoreMode store_mode,
+      LanguageMode language_mode);
 
   // Helpers
   // TODO(verwaest): Move all uses of these helpers to the PropertyICCompiler
@@ -31,9 +37,13 @@ class PropertyICCompiler : public PropertyAccessCompiler {
 
 
  private:
-  explicit PropertyICCompiler(Isolate* isolate)
-      : PropertyAccessCompiler(isolate, Code::KEYED_STORE_IC,
-                               kCacheOnReceiver) {}
+  PropertyICCompiler(Isolate* isolate, Code::Kind kind,
+                     ExtraICState extra_ic_state = kNoExtraICState,
+                     CacheHolderFlag cache_holder = kCacheOnReceiver)
+      : PropertyAccessCompiler(isolate, kind, cache_holder),
+        extra_ic_state_(extra_ic_state) {}
+
+  Handle<Code> CompileStoreMegamorphic(Code::Flags flags);
 
   Handle<Code> CompileKeyedStoreMonomorphicHandler(
       Handle<Map> receiver_map, KeyedAccessStoreMode store_mode);
@@ -41,6 +51,30 @@ class PropertyICCompiler : public PropertyAccessCompiler {
                                             MapHandleList* transitioned_maps,
                                             CodeHandleList* handlers,
                                             KeyedAccessStoreMode store_mode);
+
+  Handle<Code> GetCode(Code::Kind kind, Handle<Name> name,
+                       InlineCacheState state = MONOMORPHIC);
+
+  Logger::LogEventsAndTags log_kind(Handle<Code> code) {
+    if (kind() == Code::LOAD_IC) {
+      return code->ic_state() == MONOMORPHIC ? Logger::LOAD_IC_TAG
+                                             : Logger::LOAD_POLYMORPHIC_IC_TAG;
+    } else if (kind() == Code::KEYED_LOAD_IC) {
+      return code->ic_state() == MONOMORPHIC
+                 ? Logger::KEYED_LOAD_IC_TAG
+                 : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
+    } else if (kind() == Code::STORE_IC) {
+      return code->ic_state() == MONOMORPHIC ? Logger::STORE_IC_TAG
+                                             : Logger::STORE_POLYMORPHIC_IC_TAG;
+    } else {
+      DCHECK_EQ(Code::KEYED_STORE_IC, kind());
+      return code->ic_state() == MONOMORPHIC
+                 ? Logger::KEYED_STORE_IC_TAG
+                 : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
+    }
+  }
+
+  const ExtraICState extra_ic_state_;
 };
 
 
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 37fbf44843..17614fa4ec 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -1431,9 +1431,8 @@ Handle<Code> StoreIC::initialize_stub_in_optimized_code(
     return stub.GetCode();
   }
 
-  return is_strict(language_mode)
-             ? isolate->builtins()->StoreIC_Megamorphic_Strict()
-             : isolate->builtins()->StoreIC_Megamorphic();
+  return PropertyICCompiler::ComputeStore(isolate, initialization_state,
+                                          ComputeExtraICState(language_mode));
 }
 
 Handle<Code> StoreIC::slow_stub() const {
@@ -1632,8 +1631,8 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
         ComputeTransitionedMap(receiver_map, store_mode);
     store_mode = GetNonTransitioningStoreMode(store_mode);
     Handle<Code> handler =
-        PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(monomorphic_map,
-                                                                store_mode);
+        PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+            monomorphic_map, language_mode(), store_mode);
     return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler);
   }
 
@@ -1659,7 +1658,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
       store_mode = GetNonTransitioningStoreMode(store_mode);
       Handle<Code> handler =
           PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
-              transitioned_receiver_map, store_mode);
+              transitioned_receiver_map, language_mode(), store_mode);
       ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler);
       return;
     }
@@ -1672,8 +1671,8 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
       // grow at the end of the array, handle OOB accesses or copy COW arrays
       // and still stay MONOMORPHIC.
       Handle<Code> handler =
-          PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(receiver_map,
-                                                                  store_mode);
+          PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+              receiver_map, language_mode(), store_mode);
       return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
     }
   }
@@ -1734,7 +1733,8 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
   MapHandleList transitioned_maps(target_receiver_maps.length());
   CodeHandleList handlers(target_receiver_maps.length());
   PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
-      &target_receiver_maps, &transitioned_maps, &handlers, store_mode);
+      &target_receiver_maps, &transitioned_maps, &handlers, store_mode,
+      language_mode());
   ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers);
 }
 
diff --git a/src/ic/ic.h b/src/ic/ic.h
index b77ceb6a58..99695b5b34 100644
--- a/src/ic/ic.h
+++ b/src/ic/ic.h
@@ -353,6 +353,13 @@ class KeyedLoadIC : public LoadIC {
   static void GenerateRuntimeGetProperty(MacroAssembler* masm);
   static void GenerateMegamorphic(MacroAssembler* masm);
 
+  // Bit mask to be tested against bit field for the cases when
+  // generic stub should go into slow case.
+  // Access check is necessary explicitly since generic stub does not perform
+  // map checks.
+  static const int kSlowCaseBitFieldMask =
+      (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
+
   static Handle<Code> initialize_stub_in_optimized_code(
       Isolate* isolate, State initialization_state, ExtraICState extra_state);
   static Handle<Code> ChooseMegamorphicStub(Isolate* isolate,
diff --git a/src/snapshot/code-serializer.cc b/src/snapshot/code-serializer.cc
index 0a8db40a47..84a08c103d 100644
--- a/src/snapshot/code-serializer.cc
+++ b/src/snapshot/code-serializer.cc
@@ -177,7 +177,13 @@ void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code,
       return;
     }
   }
-  UNREACHABLE();
+  // The IC may also just be a piece of code kept in the non_monomorphic_cache.
+  // In that case, just serialize as a normal code object.
+  if (FLAG_trace_serializer) {
+    PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind()));
+  }
+  DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC);
+  SerializeGeneric(ic, how_to_code, where_to_point);
 }
 
 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) {