Reviewers: ulan,

Message:
PTAL

Description:
Tag normal as handlers, and make code handler-specific.

BUG=

Please review this at https://chromiumcodereview.appspot.com/25049003/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+61, -36 lines):
  M src/builtins.h
  M src/builtins.cc
  M src/ic.cc
  M src/objects.h
  M src/objects.cc


Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index 454cf46685b9663ab0b57b3b6070dde80a09007e..637aeca12b6dfb7925d78d092907d8bf024d7101 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1655,8 +1655,19 @@ void Builtins::InitBuiltinFunctionTable() {
functions->extra_args = NO_EXTRA_ARGUMENTS; \
     ++functions;

+#define DEF_FUNCTION_PTR_H(aname, kind, extra) \ + functions->generator = FUNCTION_ADDR(Generate_##aname); \ + functions->c_code = NULL; \ + functions->s_name = #aname; \ + functions->name = k##aname; \ + functions->flags = Code::ComputeFlags( \ + Code::HANDLER, MONOMORPHIC, extra, Code::NORMAL, Code::kind); \ + functions->extra_args = NO_EXTRA_ARGUMENTS; \
+    ++functions;
+
   BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
   BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
+  BUILTIN_LIST_H(DEF_FUNCTION_PTR_H)
   BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)

 #undef DEF_FUNCTION_PTR_C
@@ -1781,8 +1792,15 @@ Handle<Code> Builtins::name() { \
       reinterpret_cast<Code**>(builtin_address(k##name));   \
   return Handle<Code>(code_address);                        \
 }
+#define DEFINE_BUILTIN_ACCESSOR_H(name, kind, extra)        \
+Handle<Code> Builtins::name() {                             \
+  Code** code_address =                                     \
+      reinterpret_cast<Code**>(builtin_address(k##name));   \
+  return Handle<Code>(code_address);                        \
+}
 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
+BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
 #undef DEFINE_BUILTIN_ACCESSOR_C
 #undef DEFINE_BUILTIN_ACCESSOR_A
Index: src/builtins.h
diff --git a/src/builtins.h b/src/builtins.h
index 612f85a36a6a11557090e6bc97e3735318d94778..ffb15eb5d613a54ba2727e488ae1ccf4c1dbc36f 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -115,8 +115,6 @@ enum BuiltinExtraArguments {
                                     Code::kNoExtraICState)              \
   V(KeyedLoadIC_MissForceGeneric,   BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
-  V(KeyedLoadIC_Slow,               HANDLER, MONOMORPHIC,               \
-                                    Code::kNoExtraICState)              \
   V(StoreIC_Miss,                   BUILTIN, UNINITIALIZED,             \
                                     Code::kNoExtraICState)              \
   V(StoreIC_Slow,                   BUILTIN, UNINITIALIZED,             \
@@ -131,14 +129,10 @@ enum BuiltinExtraArguments {
                                     Code::kNoExtraICState)              \
   V(LoadIC_PreMonomorphic,          LOAD_IC, PREMONOMORPHIC,            \
                                     Code::kNoExtraICState)              \
-  V(LoadIC_Normal,                  LOAD_IC, MONOMORPHIC,               \
-                                    Code::kNoExtraICState)              \
   V(LoadIC_Megamorphic,             LOAD_IC, MEGAMORPHIC,               \
                                     Code::kNoExtraICState)              \
   V(LoadIC_Getter_ForDeopt,         LOAD_IC, MONOMORPHIC,               \
                                     Code::kNoExtraICState)              \
-  V(LoadIC_Slow,                    HANDLER, MONOMORPHIC,               \
-                                    Code::kNoExtraICState)              \
                                                                         \
   V(KeyedLoadIC_Initialize,         KEYED_LOAD_IC, UNINITIALIZED,       \
                                     Code::kNoExtraICState)              \
@@ -157,8 +151,6 @@ enum BuiltinExtraArguments {
                                     Code::kNoExtraICState)              \
   V(StoreIC_PreMonomorphic,         STORE_IC, PREMONOMORPHIC,           \
                                     Code::kNoExtraICState)              \
-  V(StoreIC_Normal,                 STORE_IC, MONOMORPHIC,              \
-                                    Code::kNoExtraICState)              \
   V(StoreIC_Megamorphic,            STORE_IC, MEGAMORPHIC,              \
                                     Code::kNoExtraICState)              \
   V(StoreIC_Generic,                STORE_IC, GENERIC,                  \
@@ -171,8 +163,6 @@ enum BuiltinExtraArguments {
                                     kStrictMode)                        \
   V(StoreIC_PreMonomorphic_Strict,  STORE_IC, PREMONOMORPHIC,           \
                                     kStrictMode)                        \
-  V(StoreIC_Normal_Strict,          STORE_IC, MONOMORPHIC,              \
-                                    kStrictMode)                        \
   V(StoreIC_Megamorphic_Strict,     STORE_IC, MEGAMORPHIC,              \
                                     kStrictMode)                        \
   V(StoreIC_GlobalProxy_Strict,     STORE_IC, GENERIC,                  \
@@ -220,6 +210,14 @@ enum BuiltinExtraArguments {
                                     Code::kNoExtraICState)              \
   CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, V)

+// Define list of builtin handlers implemented in assembly.
+#define BUILTIN_LIST_H(V)                                                 \
+  V(LoadIC_Slow,                    LOAD_IC, Code::kNoExtraICState)       \
+  V(KeyedLoadIC_Slow,               KEYED_LOAD_IC, Code::kNoExtraICState) \
+  V(LoadIC_Normal,                  LOAD_IC, Code::kNoExtraICState)       \
+  V(StoreIC_Normal,                 STORE_IC, Code::kNoExtraICState)      \
+  V(StoreIC_Normal_Strict,          STORE_IC, kStrictMode)
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
 // Define list of builtins used by the debugger implemented in assembly.
#define BUILTIN_LIST_DEBUG_A(V) \
@@ -307,8 +305,10 @@ class Builtins {
   enum Name {
 #define DEF_ENUM_C(name, ignore) k##name,
 #define DEF_ENUM_A(name, kind, state, extra) k##name,
+#define DEF_ENUM_H(name, kind, extra) k##name,
     BUILTIN_LIST_C(DEF_ENUM_C)
     BUILTIN_LIST_A(DEF_ENUM_A)
+    BUILTIN_LIST_H(DEF_ENUM_H)
     BUILTIN_LIST_DEBUG_A(DEF_ENUM_A)
 #undef DEF_ENUM_C
 #undef DEF_ENUM_A
@@ -332,8 +332,10 @@ class Builtins {
 #define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name();
 #define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
   Handle<Code> name();
+#define DECLARE_BUILTIN_ACCESSOR_H(name, kind, extra) Handle<Code> name();
   BUILTIN_LIST_C(DECLARE_BUILTIN_ACCESSOR_C)
   BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A)
+  BUILTIN_LIST_H(DECLARE_BUILTIN_ACCESSOR_H)
   BUILTIN_LIST_DEBUG_A(DECLARE_BUILTIN_ACCESSOR_A)
 #undef DECLARE_BUILTIN_ACCESSOR_C
 #undef DECLARE_BUILTIN_ACCESSOR_A
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index 579e268baddc13aa2b103ad7c846bed3d7ee9369..bde51af9e3a4e6ab63e2323f6efc5ce0a5e5088a 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -219,13 +219,14 @@ static bool TryRemoveInvalidPrototypeDependentStub(Code* target,
     map->RemoveFromCodeCache(String::cast(name), target, index);
// For loads and stores, handlers are stored in addition to the ICs on the
     // map. Remove those, too.
-    if ((target->is_load_stub() || target->is_keyed_load_stub() ||
-         target->is_store_stub() || target->is_keyed_store_stub()) &&
-        target->type() != Code::NORMAL) {
-      Code* handler = target->FindFirstCode();
-      index = map->IndexInCodeCache(name, handler);
-      if (index >= 0) {
-        map->RemoveFromCodeCache(String::cast(name), handler, index);
+    if (target->is_load_stub() || target->is_keyed_load_stub() ||
+        target->is_store_stub() || target->is_keyed_store_stub()) {
+      Code* handler = target->FindFirstHandler();
+      if (handler != NULL) {
+        index = map->IndexInCodeCache(name, handler);
+        if (index >= 0) {
+          map->RemoveFromCodeCache(String::cast(name), handler, index);
+        }
       }
     }
     return true;
@@ -1000,10 +1001,6 @@ bool IC::UpdatePolymorphicIC(State state,
                              Handle<Code> code,
                              StrictModeFlag strict_mode) {
   if (code->kind() != Code::HANDLER) return false;
-  if (target()->ic_state() == MONOMORPHIC &&
-      target()->type() == Code::NORMAL) {
-    return false;
-  }

   MapHandleList receiver_maps;
   CodeHandleList handlers;
@@ -1038,7 +1035,10 @@ bool IC::UpdatePolymorphicIC(State state,
     if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) {
       return false;
     }
-    target()->FindAllCode(&handlers, receiver_maps.length());
+
+    if (!target()->FindHandlers(&handlers, receiver_maps.length())) {
+      return false;
+    }
   }

   number_of_valid_maps++;
@@ -1126,7 +1126,7 @@ void IC::CopyICToMegamorphicCache(Handle<String> name) {
   {
     DisallowHeapAllocation no_gc;
     target()->FindAllMaps(&receiver_maps);
-    target()->FindAllCode(&handlers, receiver_maps.length());
+    if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
   }
   for (int i = 0; i < receiver_maps.length(); i++) {
     UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
@@ -1170,7 +1170,7 @@ void IC::PatchCache(State state,
           bool is_same_handler = false;
           {
             DisallowHeapAllocation no_allocation;
-            Code* old_handler = target()->FindFirstCode();
+            Code* old_handler = target()->FindFirstHandler();
             is_same_handler = old_handler == *code;
           }
           if (is_same_handler
@@ -1182,9 +1182,7 @@ void IC::PatchCache(State state,
             break;
           }

-          if (target()->type() != Code::NORMAL) {
-            CopyICToMegamorphicCache(name);
-          }
+          CopyICToMegamorphicCache(name);
         }

         UpdateMegamorphicCache(receiver->map(), *name, *code);
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index e70346590e1af1bf09485a63910896e3f68efab6..9ddb6ff497e414313707d583793e696977518f3f 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -10297,31 +10297,35 @@ void Code::ReplaceFirstMap(Map* replace_with) {
 }


-Code* Code::FindFirstCode() {
+Code* Code::FindFirstHandler() {
   ASSERT(is_inline_cache_stub());
   DisallowHeapAllocation no_allocation;
   int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
     RelocInfo* info = it.rinfo();
-    return Code::GetCodeFromTargetAddress(info->target_address());
+    Code* code = Code::GetCodeFromTargetAddress(info->target_address());
+    if (code->kind() == Code::HANDLER) return code;
   }
   return NULL;
 }


-void Code::FindAllCode(CodeHandleList* code_list, int length) {
+bool Code::FindHandlers(CodeHandleList* code_list, int length) {
   ASSERT(is_inline_cache_stub());
   DisallowHeapAllocation no_allocation;
   int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
   int i = 0;
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
-    if (i++ == length) return;
+    if (i == length) return true;
     RelocInfo* info = it.rinfo();
     Code* code = Code::GetCodeFromTargetAddress(info->target_address());
-    ASSERT(code->kind() == Code::HANDLER);
+    // IC stubs with handlers never contain non-handler code objects before
+    // handler targets.
+    if (code->kind() != Code::HANDLER) break;
     code_list->Add(Handle<Code>(code));
+    i++;
   }
-  UNREACHABLE();
+  return i == length;
 }


Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 0e065e67852d0368a5f8db95fb60e303a88b9471..8a48116f99f77e76726ec5cd8f47a604b754bd12 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4998,9 +4998,12 @@ class Code: public HeapObject {
   void FindAllMaps(MapHandleList* maps);
   void ReplaceFirstMap(Map* replace);

-  // Find the first code in an IC stub.
-  Code* FindFirstCode();
-  void FindAllCode(CodeHandleList* code_list, int length);
+  // Find the first handler in an IC stub.
+  Code* FindFirstHandler();
+
+ // Find |length| handlers and put them into |code_list|. Returns false if not
+  // enough handlers can be found.
+  MUST_USE_RESULT bool FindHandlers(CodeHandleList* code_list, int length);

   // Find the first name in an IC stub.
   Name* FindFirstName();


--
--
v8-dev mailing list
v8-dev@googlegroups.com
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 v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to