Revision: 24529
Author:   [email protected]
Date:     Fri Oct 10 13:27:52 2014 UTC
Log:      Fix type feedback for name-keyed stores

BUG=chromium:422212
LOG=n
[email protected]

Review URL: https://codereview.chromium.org/648703002
https://code.google.com/p/v8/source/detail?r=24529

Modified:
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ic/ic-compiler.cc
 /branches/bleeding_edge/src/ic/ic-compiler.h
 /branches/bleeding_edge/src/ic/ic.h
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/type-info.cc
 /branches/bleeding_edge/src/type-info.h
 /branches/bleeding_edge/src/typing.cc

=======================================
--- /branches/bleeding_edge/src/ast.h   Fri Oct 10 13:22:10 2014 UTC
+++ /branches/bleeding_edge/src/ast.h   Fri Oct 10 13:27:52 2014 UTC
@@ -376,6 +376,10 @@
     UNREACHABLE();
     return STANDARD_STORE;
   }
+  virtual IcCheckType GetKeyType() {
+    UNREACHABLE();
+    return ELEMENT;
+  }

   // TODO(rossberg): this should move to its own AST node eventually.
   virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
@@ -2097,10 +2101,12 @@
   virtual SmallMapList* GetReceiverTypes() OVERRIDE {
     return &receiver_types_;
   }
+  virtual IcCheckType GetKeyType() OVERRIDE { return key_type_; }
   virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
     return store_mode_;
   }
   Type* type() const { return type_; }
+  void set_key_type(IcCheckType type) { key_type_ = type; }
   void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
   void set_type(Type* type) { type_ = type; }

@@ -2127,6 +2133,7 @@
  private:
   Token::Value op_;
   bool is_prefix_ : 1;
+  IcCheckType key_type_ : 1;
   KeyedAccessStoreMode store_mode_ : 5;  // Windows treats as signed,
                                          // must have extra bit.
   Type* type_;
@@ -2239,10 +2246,12 @@
   virtual SmallMapList* GetReceiverTypes() OVERRIDE {
     return &receiver_types_;
   }
+  virtual IcCheckType GetKeyType() OVERRIDE { return key_type_; }
   virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
     return store_mode_;
   }
   void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
+  void set_key_type(IcCheckType key_type) { key_type_ = key_type; }
   void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }

  protected:
@@ -2267,6 +2276,7 @@
   Expression* value_;
   BinaryOperation* binary_operation_;
   bool is_uninitialized_ : 1;
+  IcCheckType key_type_ : 1;
   KeyedAccessStoreMode store_mode_ : 5;  // Windows treats as signed,
                                          // must have extra bit.
   SmallMapList receiver_types_;
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Mon Oct  6 13:15:23 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Oct 10 13:27:52 2014 UTC
@@ -7174,8 +7174,14 @@
   bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());

   bool force_generic = false;
-  if (access_type == STORE &&
-      (monomorphic || (types != NULL && !types->is_empty()))) {
+  if (access_type == STORE && expr->GetKeyType() == PROPERTY) {
+ // Non-Generic accesses assume that elements are being accessed, and will
+    // deopt for non-index keys, which the IC knows will occur.
+ // TODO(jkummerow): Consider adding proper support for property accesses.
+    force_generic = true;
+    monomorphic = false;
+  } else if (access_type == STORE &&
+             (monomorphic || (types != NULL && !types->is_empty()))) {
// Stores can't be mono/polymorphic if their prototype chain has dictionary
     // elements. However a receiver map that has dictionary elements itself
// should be left to normal mono/poly behavior (the other maps may benefit
=======================================
--- /branches/bleeding_edge/src/ic/ic-compiler.cc Mon Sep 22 13:23:27 2014 UTC +++ /branches/bleeding_edge/src/ic/ic-compiler.cc Fri Oct 10 13:27:52 2014 UTC
@@ -57,6 +57,13 @@

   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));
+  }

   Handle<Code> ic;
   // There are multiple string maps that all use the same prototype. That
@@ -67,13 +74,6 @@
     ic = Find(name, stub_holder, kind, extra_ic_state, flag);
     if (!ic.is_null()) return ic;
   }
-
-#ifdef DEBUG
-  if (kind == Code::KEYED_STORE_IC) {
-    DCHECK(STANDARD_STORE ==
-           KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
-  }
-#endif

   PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag);
   ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
=======================================
--- /branches/bleeding_edge/src/ic/ic-compiler.h Mon Sep 8 12:51:29 2014 UTC +++ /branches/bleeding_edge/src/ic/ic-compiler.h Fri Oct 10 13:27:52 2014 UTC
@@ -11,9 +11,6 @@
 namespace internal {


-enum IcCheckType { ELEMENT, PROPERTY };
-
-
 class PropertyICCompiler : public PropertyAccessCompiler {
  public:
   // Finds the Code object stored in the Heap::non_monomorphic_cache().
=======================================
--- /branches/bleeding_edge/src/ic/ic.h Fri Oct 10 09:49:43 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.h Fri Oct 10 13:27:52 2014 UTC
@@ -542,6 +542,8 @@
   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) |
@@ -552,6 +554,10 @@
       ExtraICState extra_state) {
     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());
=======================================
--- /branches/bleeding_edge/src/objects.h       Fri Oct 10 10:51:34 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Fri Oct 10 13:27:52 2014 UTC
@@ -230,6 +230,9 @@
   return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
       store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT;
 }
+
+
+enum IcCheckType { ELEMENT, PROPERTY };


 // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
=======================================
--- /branches/bleeding_edge/src/type-info.cc    Fri Oct 10 13:22:10 2014 UTC
+++ /branches/bleeding_edge/src/type-info.cc    Fri Oct 10 13:27:52 2014 UTC
@@ -101,16 +101,21 @@
 }


-KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
-    TypeFeedbackId ast_id) {
+void TypeFeedbackOracle::GetStoreModeAndKeyType(
+    TypeFeedbackId ast_id, KeyedAccessStoreMode* store_mode,
+    IcCheckType* key_type) {
   Handle<Object> maybe_code = GetInfo(ast_id);
   if (maybe_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(maybe_code);
     if (code->kind() == Code::KEYED_STORE_IC) {
-      return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state());
+      ExtraICState extra_ic_state = code->extra_ic_state();
+      *store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state);
+      *key_type = KeyedStoreIC::GetKeyType(extra_ic_state);
+      return;
     }
   }
-  return STANDARD_STORE;
+  *store_mode = STANDARD_STORE;
+  *key_type = ELEMENT;
 }


@@ -274,10 +279,10 @@

 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes(
     TypeFeedbackId id, SmallMapList* receiver_types,
-    KeyedAccessStoreMode* store_mode) {
+    KeyedAccessStoreMode* store_mode, IcCheckType* key_type) {
   receiver_types->Clear();
   CollectReceiverTypes(id, receiver_types);
-  *store_mode = GetStoreMode(id);
+  GetStoreModeAndKeyType(id, store_mode, key_type);
 }


=======================================
--- /branches/bleeding_edge/src/type-info.h     Fri Oct 10 13:22:10 2014 UTC
+++ /branches/bleeding_edge/src/type-info.h     Fri Oct 10 13:27:52 2014 UTC
@@ -36,7 +36,9 @@
   // be possible.
   byte ForInType(FeedbackVectorSlot feedback_vector_slot);

-  KeyedAccessStoreMode GetStoreMode(TypeFeedbackId id);
+  void GetStoreModeAndKeyType(TypeFeedbackId id,
+                              KeyedAccessStoreMode* store_mode,
+                              IcCheckType* key_type);

   void PropertyReceiverTypes(TypeFeedbackId id, Handle<String> name,
                              SmallMapList* receiver_types);
@@ -48,7 +50,8 @@
                                SmallMapList* receiver_types);
   void KeyedAssignmentReceiverTypes(TypeFeedbackId id,
                                     SmallMapList* receiver_types,
-                                    KeyedAccessStoreMode* store_mode);
+                                    KeyedAccessStoreMode* store_mode,
+                                    IcCheckType* key_type);
   void CountReceiverTypes(TypeFeedbackId id,
                           SmallMapList* receiver_types);

=======================================
--- /branches/bleeding_edge/src/typing.cc       Tue Sep 30 10:29:32 2014 UTC
+++ /branches/bleeding_edge/src/typing.cc       Fri Oct 10 13:27:52 2014 UTC
@@ -444,9 +444,11 @@
oracle()->AssignmentReceiverTypes(id, name, expr->GetReceiverTypes());
       } else {
         KeyedAccessStoreMode store_mode;
-        oracle()->KeyedAssignmentReceiverTypes(
-            id, expr->GetReceiverTypes(), &store_mode);
+        IcCheckType key_type;
+ oracle()->KeyedAssignmentReceiverTypes(id, expr->GetReceiverTypes(),
+                                               &store_mode, &key_type);
         expr->set_store_mode(store_mode);
+        expr->set_key_type(key_type);
       }
     }
   }
@@ -587,7 +589,11 @@
 void AstTyper::VisitCountOperation(CountOperation* expr) {
   // Collect type feedback.
   TypeFeedbackId store_id = expr->CountStoreFeedbackId();
-  expr->set_store_mode(oracle()->GetStoreMode(store_id));
+  KeyedAccessStoreMode store_mode;
+  IcCheckType key_type;
+  oracle()->GetStoreModeAndKeyType(store_id, &store_mode, &key_type);
+  expr->set_store_mode(store_mode);
+  expr->set_key_type(key_type);
   oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes());
   expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId()));
   // TODO(rossberg): merge the count type with the generic expression type.

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to