Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc
index e087acf..ae4b2a5 100644
--- a/src/ic/ic-compiler.cc
+++ b/src/ic/ic-compiler.cc
@@ -2,11 +2,11 @@
 // 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/ic-compiler.h"
 
 #include "src/ic/handler-compiler.h"
 #include "src/ic/ic-inl.h"
-#include "src/ic/ic-compiler.h"
+#include "src/profiler/cpu-profiler.h"
 
 
 namespace v8 {
@@ -25,92 +25,26 @@
 }
 
 
-bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
-  for (int i = 0; i < types->length(); ++i) {
-    if (types->at(i)->Is(HeapType::Number())) return true;
+bool PropertyICCompiler::IncludesNumberMap(MapHandleList* maps) {
+  for (int i = 0; i < maps->length(); ++i) {
+    if (maps->at(i)->instance_type() == HEAP_NUMBER_TYPE) 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);
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeMonomorphic(
-    Code::Kind kind, Handle<Name> name, Handle<HeapType> type,
-    Handle<Code> handler, ExtraICState extra_ic_state) {
-  Isolate* isolate = name->GetIsolate();
-  if (handler.is_identical_to(isolate->builtins()->LoadIC_Normal()) ||
-      handler.is_identical_to(isolate->builtins()->StoreIC_Normal())) {
-    name = isolate->factory()->normal_ic_symbol();
-  }
-
-  CacheHolderFlag flag;
-  Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag);
-  if (kind == Code::KEYED_STORE_IC) {
-    // Always set the "property" bit.
-    extra_ic_state =
-        KeyedStoreIC::IcCheckTypeField::update(extra_ic_state, PROPERTY);
-    DCHECK(STANDARD_STORE ==
-           KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
-  } else if (kind == Code::KEYED_LOAD_IC) {
-    extra_ic_state = KeyedLoadIC::IcCheckTypeField::update(extra_ic_state,
-                                                           PROPERTY);
-  }
-
-  Handle<Code> ic;
-  // There are multiple string maps that all use the same prototype. That
-  // prototype cannot hold multiple handlers, one for each of the string maps,
-  // for a single name. Hence, turn off caching of the IC.
-  bool can_be_cached = !type->Is(HeapType::String());
-  if (can_be_cached) {
-    ic = Find(name, stub_holder, kind, extra_ic_state, flag);
-    if (!ic.is_null()) return ic;
-  }
-
-  PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag);
-  ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
-
-  if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
-  return ic;
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
-    Handle<Map> receiver_map) {
-  Isolate* isolate = receiver_map->GetIsolate();
-  DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
-  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
-  Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string();
-
-  Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
-
-  Handle<Code> stub = ComputeKeyedLoadMonomorphicHandler(receiver_map);
-  PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
-  Handle<Code> code =
-      compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub,
-                                  isolate->factory()->empty_string(), ELEMENT);
-
-  Map::UpdateCodeCache(receiver_map, name, code);
-  return code;
-}
-
-
 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
-    Handle<Map> receiver_map) {
+    Handle<Map> receiver_map, ExtraICState extra_ic_state) {
   Isolate* isolate = receiver_map->GetIsolate();
+  bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
   ElementsKind elements_kind = receiver_map->elements_kind();
+
+  // No need to check for an elements-free prototype chain here, the generated
+  // stub code needs to check that dynamically anyway.
+  bool convert_hole_to_undefined =
+      is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
+      *receiver_map == isolate->get_initial_js_array_map(elements_kind) &&
+      !(is_strong(LoadICState::GetLanguageMode(extra_ic_state)));
   Handle<Code> stub;
   if (receiver_map->has_indexed_interceptor()) {
     stub = LoadIndexedInterceptorStub(isolate).GetCode();
@@ -120,43 +54,32 @@
   } else if (receiver_map->has_sloppy_arguments_elements()) {
     stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
   } else if (receiver_map->has_fast_elements() ||
-             receiver_map->has_external_array_elements() ||
              receiver_map->has_fixed_typed_array_elements()) {
-    stub = LoadFastElementStub(isolate,
-                               receiver_map->instance_type() == JS_ARRAY_TYPE,
-                               elements_kind).GetCode();
+    stub = LoadFastElementStub(isolate, is_js_array, elements_kind,
+                               convert_hole_to_undefined).GetCode();
   } else {
-    stub = LoadDictionaryElementStub(isolate).GetCode();
+    stub = LoadDictionaryElementStub(isolate, LoadICState(extra_ic_state))
+               .GetCode();
   }
   return stub;
 }
 
 
-Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphic(
-    Handle<Map> receiver_map, StrictMode strict_mode,
+Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+    Handle<Map> receiver_map, LanguageMode language_mode,
     KeyedAccessStoreMode store_mode) {
   Isolate* isolate = receiver_map->GetIsolate();
   ExtraICState extra_state =
-      KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
-  Code::Flags flags =
-      Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, 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);
 
-  Handle<String> name = isolate->factory()->KeyedStoreMonomorphic_string();
-  Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
-
   PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
   Handle<Code> code =
-      compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode);
-
-  Map::UpdateCodeCache(receiver_map, name, code);
-  DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) ==
-         store_mode);
+      compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
   return code;
 }
 
@@ -178,30 +101,7 @@
 static void FillCache(Isolate* isolate, Handle<Code> code) {
   Handle<UnseededNumberDictionary> dictionary = UnseededNumberDictionary::Set(
       isolate->factory()->non_monomorphic_cache(), code->flags(), code);
-  isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate,
-                                             InlineCacheState ic_state,
-                                             ExtraICState extra_state) {
-  Code::Flags flags = Code::ComputeFlags(Code::LOAD_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::LOAD_IC);
-  Handle<Code> code;
-  if (ic_state == UNINITIALIZED) {
-    code = compiler.CompileLoadInitialize(flags);
-  } else if (ic_state == PREMONOMORPHIC) {
-    code = compiler.CompileLoadPreMonomorphic(flags);
-  } else {
-    UNREACHABLE();
-  }
-  FillCache(isolate, code);
-  return code;
+  isolate->heap()->SetRootNonMonomorphicCache(*dictionary);
 }
 
 
@@ -256,69 +156,20 @@
 }
 
 
-// TODO(verwaest): Change this method so it takes in a TypeHandleList.
-Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
-    MapHandleList* receiver_maps) {
-  Isolate* isolate = receiver_maps->at(0)->GetIsolate();
-  DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
-  Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
-  Handle<PolymorphicCodeCache> cache =
-      isolate->factory()->polymorphic_code_cache();
-  Handle<Object> probe = cache->Lookup(receiver_maps, flags);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
-
-  TypeHandleList types(receiver_maps->length());
-  for (int i = 0; i < receiver_maps->length(); i++) {
-    types.Add(HeapType::Class(receiver_maps->at(i), isolate));
-  }
-  CodeHandleList handlers(receiver_maps->length());
-  ElementHandlerCompiler compiler(isolate);
-  compiler.CompileElementHandlers(receiver_maps, &handlers);
-  PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
-  Handle<Code> code = ic_compiler.CompilePolymorphic(
-      &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL,
-      ELEMENT);
-
-  isolate->counters()->keyed_load_polymorphic_stubs()->Increment();
-
-  PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
-  return code;
-}
-
-
-Handle<Code> PropertyICCompiler::ComputePolymorphic(
-    Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers,
-    int valid_types, Handle<Name> name, ExtraICState extra_ic_state) {
-  Handle<Code> handler = handlers->at(0);
-  Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL;
-  DCHECK(kind == Code::LOAD_IC || kind == Code::STORE_IC);
-  PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state);
-  return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY);
-}
-
-
-Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
-    MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
-    StrictMode strict_mode) {
+void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
+    MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
+    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);
-  Handle<PolymorphicCodeCache> cache =
-      isolate->factory()->polymorphic_code_cache();
   ExtraICState extra_state =
-      KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
-  Code::Flags flags =
-      Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
-  Handle<Object> probe = cache->Lookup(receiver_maps, flags);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
-
+      KeyedStoreIC::ComputeExtraICState(language_mode, store_mode);
   PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
-  Handle<Code> code =
-      compiler.CompileKeyedStorePolymorphic(receiver_maps, store_mode);
-  PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
-  return code;
+  compiler.CompileKeyedStorePolymorphicHandlers(
+      receiver_maps, transitioned_maps, handlers, store_mode);
 }
 
 
@@ -330,15 +181,6 @@
 }
 
 
-Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
-  LoadIC::GeneratePreMonomorphic(masm());
-  Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic");
-  PROFILE(isolate(),
-          CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0));
-  return code;
-}
-
-
 Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) {
   StoreIC::GenerateInitialize(masm());
   Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize");
@@ -358,8 +200,8 @@
 
 Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
   ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
-  StrictMode strict_mode = StoreIC::GetStrictMode(extra_state);
-  GenerateRuntimeSetProperty(masm(), strict_mode);
+  LanguageMode language_mode = StoreICState::GetLanguageMode(extra_state);
+  GenerateRuntimeSetProperty(masm(), language_mode);
   Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric");
   PROFILE(isolate(), CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
   return code;
@@ -381,20 +223,21 @@
       Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder());
   Handle<Code> code = GetCodeWithFlags(flags, name);
   PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
+#ifdef DEBUG
+  code->VerifyEmbeddedObjects();
+#endif
   return code;
 }
 
 
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
-    MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
-  // Collect MONOMORPHIC stubs for all |receiver_maps|.
-  CodeHandleList handlers(receiver_maps->length());
-  MapHandleList transitioned_maps(receiver_maps->length());
+void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
+    MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
+    CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
   for (int i = 0; i < receiver_maps->length(); ++i) {
     Handle<Map> receiver_map(receiver_maps->at(i));
     Handle<Code> cached_stub;
     Handle<Map> transitioned_map =
-        receiver_map->FindTransitionedMap(receiver_maps);
+        Map::FindTransitionedMap(receiver_map, receiver_maps);
 
     // TODO(mvstanton): The code below is doing pessimistic elements
     // transitions. I would like to stop doing that and rely on Allocation Site
@@ -409,46 +252,54 @@
                                          transitioned_map->elements_kind(),
                                          is_js_array, store_mode).GetCode();
     } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
+      // TODO(mvstanton): Consider embedding store_mode in the state of the slow
+      // keyed store ic for uniformity.
       cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
     } else {
-      if (receiver_map->has_fast_elements() ||
-          receiver_map->has_external_array_elements() ||
-          receiver_map->has_fixed_typed_array_elements()) {
+      if (IsSloppyArgumentsElements(elements_kind)) {
+        cached_stub =
+            KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
+      } else if (receiver_map->has_fast_elements() ||
+                 receiver_map->has_fixed_typed_array_elements()) {
         cached_stub = StoreFastElementStub(isolate(), is_js_array,
                                            elements_kind, store_mode).GetCode();
       } else {
-        cached_stub = StoreElementStub(isolate(), elements_kind).GetCode();
+        cached_stub =
+            StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
       }
     }
     DCHECK(!cached_stub.is_null());
-    handlers.Add(cached_stub);
-    transitioned_maps.Add(transitioned_map);
+    handlers->Add(cached_stub);
+    transitioned_maps->Add(transitioned_map);
   }
-
-  Handle<Code> code = CompileKeyedStorePolymorphic(receiver_maps, &handlers,
-                                                   &transitioned_maps);
-  isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
-  PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0));
-  return code;
 }
 
 
 #define __ ACCESS_MASM(masm())
 
 
-Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
+Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler(
     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()) {
+  if (receiver_map->has_sloppy_arguments_elements()) {
+    stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
+  } else if (receiver_map->has_fast_elements() ||
+             receiver_map->has_fixed_typed_array_elements()) {
     stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
                                 store_mode).GetCode();
   } else {
-    stub = StoreElementStub(isolate(), elements_kind).GetCode();
+    stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
   }
+  return stub;
+}
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
+    Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
+  Handle<Code> stub =
+      CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
 
   Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
 
@@ -462,5 +313,5 @@
 
 
 #undef __
-}
-}  // namespace v8::internal
+}  // namespace internal
+}  // namespace v8