Update V8 to version 4.1.0.21

This is a cherry-pick of all commits up to and including the
4.1.0.21 cherry-pick in Chromium.

Original commit message:

Version 4.1.0.21 (cherry-pick)

Merged 206e9136bde0f2b5ae8cb77afbb1e7833e5bd412

Unlink pages from the space page list after evacuation.

BUG=430201
LOG=N
R=jkummerow@chromium.org

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

Cr-Commit-Position: refs/branch-heads/4.1@{#22}
Cr-Branched-From: 2e08d2a7aa9d65d269d8c57aba82eb38a8cb0a18-refs/heads/candidates@{#25353}

---

FPIIM-449

Change-Id: I8c23c7bbb70772b4858fe8a47b64fa97ee0d1f8c
diff --git a/src/ic/ic.h b/src/ic/ic.h
index d86d2b7..541fa0c 100644
--- a/src/ic/ic.h
+++ b/src/ic/ic.h
@@ -21,7 +21,6 @@
   ICU(CallIC_Customization_Miss)       \
   ICU(StoreIC_Miss)                    \
   ICU(StoreIC_Slow)                    \
-  ICU(SharedStoreIC_ExtendStorage)     \
   ICU(KeyedStoreIC_Miss)               \
   ICU(KeyedStoreIC_Slow)               \
   /* Utilities for IC stubs. */        \
@@ -60,7 +59,8 @@
 
   // Construct the IC structure with the given number of extra
   // JavaScript frames on the stack.
-  IC(FrameDepth depth, Isolate* isolate);
+  IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL,
+     bool for_queries_only = false);
   virtual ~IC() {}
 
   State state() const { return state_; }
@@ -72,17 +72,10 @@
   bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name);
   void MarkPrototypeFailure(Handle<Object> name) {
     DCHECK(IsNameCompatibleWithPrototypeFailure(name));
+    old_state_ = state_;
     state_ = PROTOTYPE_FAILURE;
   }
 
-  // If the stub contains weak maps then this function adds the stub to
-  // the dependent code array of each weak map.
-  static void RegisterWeakMapDependency(Handle<Code> stub);
-
-  // This function is called when a weak map in the stub is dying,
-  // invalidates the stub by setting maps in it to undefined.
-  static void InvalidateMaps(Code* stub);
-
   // Clear the inline cache to initial state.
   static void Clear(Isolate* isolate, Address address,
                     ConstantPoolArray* constant_pool);
@@ -114,6 +107,11 @@
     return state == UNINITIALIZED || state == PREMONOMORPHIC;
   }
 
+  static bool IsCleared(FeedbackNexus* nexus) {
+    InlineCacheState state = nexus->StateFromFeedback();
+    return state == UNINITIALIZED || state == PREMONOMORPHIC;
+  }
+
   // Utility functions to convert maps to types and back. There are two special
   // cases:
   // - The heap_number_map is used as a marker which includes heap numbers as
@@ -127,6 +125,12 @@
   static Handle<HeapType> CurrentTypeOf(Handle<Object> object,
                                         Isolate* isolate);
 
+  static bool ICUseVector(Code::Kind kind) {
+    return (FLAG_vector_ics &&
+            (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC)) ||
+           kind == Code::CALL_IC;
+  }
+
  protected:
   // Get the call-site target; used for determining the state.
   Handle<Code> target() const { return target_; }
@@ -146,6 +150,22 @@
   inline void set_target(Code* code);
   bool is_target_set() { return target_set_; }
 
+  bool UseVector() const {
+    bool use = ICUseVector(kind());
+    // If we are supposed to use the nexus, verify the nexus is non-null.
+    DCHECK(!use || nexus_ != NULL);
+    return use;
+  }
+
+  // Configure for most states.
+  void ConfigureVectorState(IC::State new_state);
+  // Configure the vector for MONOMORPHIC.
+  void ConfigureVectorState(Handle<Name> name, Handle<HeapType> type,
+                            Handle<Code> handler);
+  // Configure the vector for POLYMORPHIC.
+  void ConfigureVectorState(Handle<Name> name, TypeHandleList* types,
+                            CodeHandleList* handlers);
+
   char TransitionMarkFromState(IC::State state);
   void TraceIC(const char* type, Handle<Object> name);
   void TraceIC(const char* type, Handle<Object> name, State old_state,
@@ -163,6 +183,10 @@
   static void OnTypeFeedbackChanged(Isolate* isolate, Address address,
                                     State old_state, State new_state,
                                     bool target_remains_ic_stub);
+  // As a vector-based IC, type feedback must be updated differently.
+  static void OnTypeFeedbackChanged(Isolate* isolate, Code* host,
+                                    TypeFeedbackVector* vector, State old_state,
+                                    State new_state);
   static void PostPatching(Address address, Code* target, Code* old_target);
 
   // Compute the handler either by compiling or by retrieving a cached version.
@@ -224,9 +248,22 @@
     return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
   }
 
- protected:
   inline void UpdateTarget();
 
+  Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); }
+  FeedbackVectorICSlot slot() const { return nexus()->slot(); }
+  State saved_state() const {
+    return state() == PROTOTYPE_FAILURE ? old_state_ : state();
+  }
+
+  template <class NexusClass>
+  NexusClass* casted_nexus() {
+    return static_cast<NexusClass*>(nexus_);
+  }
+  FeedbackNexus* nexus() const { return nexus_; }
+
+  inline Code* get_host();
+
  private:
   inline Code* raw_target() const;
   inline ConstantPoolArray* constant_pool() const;
@@ -235,11 +272,15 @@
   void FindTargetMaps() {
     if (target_maps_set_) return;
     target_maps_set_ = true;
-    if (state_ == MONOMORPHIC) {
-      Map* map = target_->FindFirstMap();
-      if (map != NULL) target_maps_.Add(handle(map));
-    } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
-      target_->FindAllMaps(&target_maps_);
+    if (UseVector()) {
+      nexus()->ExtractMaps(&target_maps_);
+    } else {
+      if (state_ == MONOMORPHIC) {
+        Map* map = target_->FindFirstMap();
+        if (map != NULL) target_maps_.Add(handle(map));
+      } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
+        target_->FindAllMaps(&target_maps_);
+      }
     }
   }
 
@@ -261,6 +302,7 @@
   // The original code target that missed.
   Handle<Code> target_;
   bool target_set_;
+  State old_state_;  // For saving if we marked as prototype failure.
   State state_;
   Code::Kind kind_;
   Handle<HeapType> receiver_type_;
@@ -270,6 +312,8 @@
   MapHandleList target_maps_;
   bool target_maps_set_;
 
+  FeedbackNexus* nexus_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
 };
 
@@ -293,29 +337,24 @@
 
 class CallIC : public IC {
  public:
-  explicit CallIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
+  CallIC(Isolate* isolate, CallICNexus* nexus)
+      : IC(EXTRA_CALL_FRAME, isolate, nexus) {
+    DCHECK(nexus != NULL);
+  }
 
-  void PatchMegamorphic(Handle<Object> function,
-                        Handle<TypeFeedbackVector> vector, Handle<Smi> slot);
+  void PatchMegamorphic(Handle<Object> function);
 
-  void HandleMiss(Handle<Object> receiver, Handle<Object> function,
-                  Handle<TypeFeedbackVector> vector, Handle<Smi> slot);
+  void HandleMiss(Handle<Object> receiver, Handle<Object> function);
 
   // Returns true if a custom handler was installed.
   bool DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
-                       Handle<TypeFeedbackVector> vector, Handle<Smi> slot,
-                       const CallICState& state);
+                       const CallICState& callic_state);
 
   // Code generator routines.
   static Handle<Code> initialize_stub(Isolate* isolate, int argc,
                                       CallICState::CallType call_type);
 
-  static void Clear(Isolate* isolate, Address address, Code* target,
-                    ConstantPoolArray* constant_pool);
-
- private:
-  inline IC::State FeedbackToState(Handle<TypeFeedbackVector> vector,
-                                   Handle<Smi> slot) const;
+  static void Clear(Isolate* isolate, Code* host, CallICNexus* nexus);
 };
 
 
@@ -329,7 +368,18 @@
     return LoadICState::GetContextualMode(extra_ic_state());
   }
 
-  explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
+  LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
+      : IC(depth, isolate, nexus) {
+    DCHECK(!FLAG_vector_ics || nexus != NULL);
+    DCHECK(IsLoadStub());
+  }
+
+  // TODO(mvstanton): The for_queries_only is because we have a case where we
+  // construct an IC only to gather the contextual mode, and we don't have
+  // vector/slot information. for_queries_only is a temporary hack to enable the
+  // strong DCHECK protection around vector/slot.
+  LoadIC(FrameDepth depth, Isolate* isolate, bool for_queries_only)
+      : IC(depth, isolate, NULL, for_queries_only) {
     DCHECK(IsLoadStub());
   }
 
@@ -355,10 +405,14 @@
 
   static Handle<Code> initialize_stub(Isolate* isolate,
                                       ExtraICState extra_state);
+  static Handle<Code> initialize_stub_in_optimized_code(
+      Isolate* isolate, ExtraICState extra_state);
 
   MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
                                            Handle<Name> name);
 
+  static void Clear(Isolate* isolate, Code* host, LoadICNexus* nexus);
+
  protected:
   inline void set_target(Code* code);
 
@@ -371,7 +425,7 @@
     }
   }
 
-  virtual Handle<Code> megamorphic_stub() OVERRIDE;
+  Handle<Code> megamorphic_stub() OVERRIDE;
 
   // Update the inline cache and the global stub cache based on the
   // lookup result.
@@ -379,7 +433,7 @@
 
   virtual Handle<Code> CompileHandler(LookupIterator* lookup,
                                       Handle<Object> unused,
-                                      CacheHolderFlag cache_holder);
+                                      CacheHolderFlag cache_holder) OVERRIDE;
 
  private:
   virtual Handle<Code> pre_monomorphic_stub() const;
@@ -397,8 +451,23 @@
 
 class KeyedLoadIC : public LoadIC {
  public:
-  explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate)
-      : LoadIC(depth, isolate) {
+  // ExtraICState bits (building on IC)
+  class IcCheckTypeField : public BitField<IcCheckType, 1, 1> {};
+
+  static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
+                                          IcCheckType key_type) {
+    return LoadICState(contextual_mode).GetExtraICState() |
+           IcCheckTypeField::encode(key_type);
+  }
+
+  static IcCheckType GetKeyType(ExtraICState extra_state) {
+    return IcCheckTypeField::decode(extra_state);
+  }
+
+  KeyedLoadIC(FrameDepth depth, Isolate* isolate,
+              KeyedLoadICNexus* nexus = NULL)
+      : LoadIC(depth, isolate, nexus) {
+    DCHECK(!FLAG_vector_ics || nexus != NULL);
     DCHECK(target()->is_keyed_load_stub());
   }
 
@@ -413,7 +482,6 @@
     GenerateMiss(masm);
   }
   static void GenerateGeneric(MacroAssembler* masm);
-  static void GenerateString(MacroAssembler* masm);
 
   // Bit mask to be tested against bit field for the cases when
   // generic stub should go into slow case.
@@ -422,20 +490,22 @@
   static const int kSlowCaseBitFieldMask =
       (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
 
+  static Handle<Code> initialize_stub(Isolate* isolate);
+  static Handle<Code> initialize_stub_in_optimized_code(Isolate* isolate);
   static Handle<Code> generic_stub(Isolate* isolate);
   static Handle<Code> pre_monomorphic_stub(Isolate* isolate);
 
+  static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus);
+
  protected:
-  Handle<Code> LoadElementStub(Handle<JSObject> receiver);
+  // receiver is HeapObject because it could be a String or a JSObject
+  Handle<Code> LoadElementStub(Handle<HeapObject> receiver);
   virtual Handle<Code> pre_monomorphic_stub() const {
     return pre_monomorphic_stub(isolate());
   }
 
  private:
   Handle<Code> generic_stub() const { return generic_stub(isolate()); }
-  Handle<Code> string_stub() {
-    return isolate()->builtins()->KeyedLoadIC_String();
-  }
 
   static void Clear(Isolate* isolate, Address address, Code* target,
                     ConstantPoolArray* constant_pool);
@@ -489,7 +559,7 @@
                       JSReceiver::StoreFromKeyed store_mode);
 
  protected:
-  virtual Handle<Code> megamorphic_stub() OVERRIDE;
+  Handle<Code> megamorphic_stub() OVERRIDE;
 
   // Stub accessors.
   Handle<Code> generic_stub() const;
@@ -509,7 +579,7 @@
                     JSReceiver::StoreFromKeyed store_mode);
   virtual Handle<Code> CompileHandler(LookupIterator* lookup,
                                       Handle<Object> value,
-                                      CacheHolderFlag cache_holder);
+                                      CacheHolderFlag cache_holder) OVERRIDE;
 
  private:
   inline void set_target(Code* code);
@@ -534,10 +604,13 @@
   class ExtraICStateKeyedAccessStoreMode
       : public BitField<KeyedAccessStoreMode, 2, 4> {};  // NOLINT
 
+  class IcCheckTypeField : public BitField<IcCheckType, 6, 1> {};
+
   static ExtraICState ComputeExtraICState(StrictMode flag,
                                           KeyedAccessStoreMode mode) {
     return StrictModeState::encode(flag) |
-           ExtraICStateKeyedAccessStoreMode::encode(mode);
+           ExtraICStateKeyedAccessStoreMode::encode(mode) |
+           IcCheckTypeField::encode(ELEMENT);
   }
 
   static KeyedAccessStoreMode GetKeyedAccessStoreMode(
@@ -545,6 +618,10 @@
     return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
   }
 
+  static IcCheckType GetKeyType(ExtraICState extra_state) {
+    return IcCheckTypeField::decode(extra_state);
+  }
+
   KeyedStoreIC(FrameDepth depth, Isolate* isolate) : StoreIC(depth, isolate) {
     DCHECK(target()->is_keyed_store_stub());
   }
@@ -560,6 +637,7 @@
   }
   static void GenerateMiss(MacroAssembler* masm);
   static void GenerateSlow(MacroAssembler* masm);
+  static void GenerateMegamorphic(MacroAssembler* masm, StrictMode strict_mode);
   static void GenerateGeneric(MacroAssembler* masm, StrictMode strict_mode);
   static void GenerateSloppyArguments(MacroAssembler* masm);
 
@@ -681,8 +759,7 @@
 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite);
 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss);
 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss);
-DECLARE_RUNTIME_FUNCTION(VectorLoadIC_MissFromStubFailure);
-DECLARE_RUNTIME_FUNCTION(VectorKeyedLoadIC_MissFromStubFailure);
+DECLARE_RUNTIME_FUNCTION(LoadIC_MissFromStubFailure);
 
 // Support functions for callbacks handlers.
 DECLARE_RUNTIME_FUNCTION(StoreCallbackProperty);