Migrate ArrayLength (Keyed|Named)LoadIC to CodeStub
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Jan 2013 17:17:02 +0000 (17:17 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Jan 2013 17:17:02 +0000 (17:17 +0000)
Review URL: https://chromiumcodereview.appspot.com/11938013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13458 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

16 files changed:
src/arm/code-stubs-arm.cc
src/arm/ic-arm.cc
src/arm/stub-cache-arm.cc
src/ast.cc
src/builtins.cc
src/builtins.h
src/code-stubs.h
src/ia32/code-stubs-ia32.cc
src/ia32/ic-ia32.cc
src/ia32/stub-cache-ia32.cc
src/ic.cc
src/stub-cache.cc
src/stub-cache.h
src/x64/code-stubs-x64.cc
src/x64/ic-x64.cc
src/x64/stub-cache-x64.cc

index 415f8bc..3998a9f 100644 (file)
@@ -4503,6 +4503,35 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
 }
 
 
+void ArrayLengthStub::Generate(MacroAssembler* masm) {
+  Label miss;
+  Register receiver;
+  if (kind() == Code::KEYED_LOAD_IC) {
+    // ----------- S t a t e -------------
+    //  -- lr    : return address
+    //  -- r0    : key
+    //  -- r1    : receiver
+    // -----------------------------------
+    __ cmp(r0, Operand(masm->isolate()->factory()->length_symbol()));
+    __ b(ne, &miss);
+    receiver = r1;
+  } else {
+    ASSERT(kind() == Code::LOAD_IC);
+    // ----------- S t a t e -------------
+    //  -- r2    : name
+    //  -- lr    : return address
+    //  -- r0    : receiver
+    //  -- sp[0] : receiver
+    // -----------------------------------
+    receiver = r0;
+  }
+
+  StubCompiler::GenerateLoadArrayLength(masm, receiver, r3, &miss);
+  __ bind(&miss);
+  StubCompiler::GenerateLoadMiss(masm, kind());
+}
+
+
 void StringLengthStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver;
index c9b7cb9..d9ca491 100644 (file)
@@ -213,21 +213,6 @@ static void GenerateDictionaryStore(MacroAssembler* masm,
 }
 
 
-void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- r2    : name
-  //  -- lr    : return address
-  //  -- r0    : receiver
-  //  -- sp[0] : receiver
-  // -----------------------------------
-  Label miss;
-
-  StubCompiler::GenerateLoadArrayLength(masm, r0, r3, &miss);
-  __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
-}
-
-
 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r2    : name
index 236e908..fc69530 100644 (file)
@@ -3207,27 +3207,6 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
 }
 
 
-Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
-    Handle<String> name) {
-  // ----------- S t a t e -------------
-  //  -- lr    : return address
-  //  -- r0    : key
-  //  -- r1    : receiver
-  // -----------------------------------
-  Label miss;
-
-  // Check the key is the cached one.
-  __ cmp(r0, Operand(name));
-  __ b(ne, &miss);
-
-  GenerateLoadArrayLength(masm(), r1, r2, &miss);
-  __ bind(&miss);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  return GetCode(Code::CALLBACKS, name);
-}
-
-
 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
     Handle<String> name) {
   // ----------- S t a t e -------------
index f7c667f..b89da9d 100644 (file)
@@ -413,8 +413,9 @@ void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle,
   is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
   receiver_types_.Clear();
   if (key()->IsPropertyName()) {
+    ArrayLengthStub array_stub(Code::LOAD_IC);
     StringLengthStub string_stub(Code::LOAD_IC, false);
-    if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
+    if (oracle->LoadIsStub(this, &array_stub)) {
       is_array_length_ = true;
     } else if (oracle->LoadIsStub(this, &string_stub)) {
       is_string_length_ = true;
index 4f373dd..cd94d1d 100644 (file)
@@ -1453,11 +1453,6 @@ BUILTIN(HandleApiCallAsConstructor) {
 }
 
 
-static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) {
-  LoadIC::GenerateArrayLength(masm);
-}
-
-
 static void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) {
   LoadIC::GenerateFunctionPrototype(masm);
 }
index 619006a..bad92f4 100644 (file)
@@ -134,8 +134,6 @@ enum BuiltinExtraArguments {
                                     Code::kNoExtraICState)              \
   V(LoadIC_Normal,                  LOAD_IC, MONOMORPHIC,               \
                                     Code::kNoExtraICState)              \
-  V(LoadIC_ArrayLength,             LOAD_IC, MONOMORPHIC,               \
-                                    Code::kNoExtraICState)              \
   V(LoadIC_FunctionPrototype,       LOAD_IC, MONOMORPHIC,               \
                                     Code::kNoExtraICState)              \
   V(LoadIC_Megamorphic,             LOAD_IC, MEGAMORPHIC,               \
index 7e2ebe4..f906a3a 100644 (file)
@@ -47,6 +47,7 @@ namespace internal {
   V(Compare)                             \
   V(CompareIC)                           \
   V(MathPow)                             \
+  V(ArrayLength)                         \
   V(StringLength)                        \
   V(RecordWrite)                         \
   V(StoreBufferOverflow)                 \
@@ -557,11 +558,25 @@ class ICStub: public PlatformCodeStub {
   }
   Code::Kind kind() { return kind_; }
 
+  virtual int MinorKey() {
+    return KindBits::encode(kind_);
+  }
+
  private:
   Code::Kind kind_;
 };
 
 
+class ArrayLengthStub: public ICStub {
+ public:
+  explicit ArrayLengthStub(Code::Kind kind) : ICStub(kind) { }
+  virtual void Generate(MacroAssembler* masm);
+
+ private:
+  virtual CodeStub::Major MajorKey() { return ArrayLength; }
+};
+
+
 class StringLengthStub: public ICStub {
  public:
   StringLengthStub(Code::Kind kind, bool support_wrapper)
index cfeecf1..afea534 100644 (file)
@@ -3259,6 +3259,25 @@ void MathPowStub::Generate(MacroAssembler* masm) {
 }
 
 
+void ArrayLengthStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- ecx    : name
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  if (kind() == Code::KEYED_LOAD_IC) {
+    __ cmp(ecx, Immediate(masm->isolate()->factory()->length_symbol()));
+    __ j(not_equal, &miss);
+  }
+
+  StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
+  __ bind(&miss);
+  StubCompiler::GenerateLoadMiss(masm, kind());
+}
+
+
 void StringLengthStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- ecx    : name
index e5c1457..f011e09 100644 (file)
@@ -216,20 +216,6 @@ static void GenerateDictionaryStore(MacroAssembler* masm,
 }
 
 
-void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
-  __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
-}
-
-
 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- ecx    : name
index d500abd..fe18647 100644 (file)
@@ -3315,32 +3315,6 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
 }
 
 
-Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
-    Handle<String> name) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->keyed_load_array_length(), 1);
-
-  // Check that the name has not changed.
-  __ cmp(ecx, Immediate(name));
-  __ j(not_equal, &miss);
-
-  GenerateLoadArrayLength(masm(), edx, eax, &miss);
-  __ bind(&miss);
-  __ DecrementCounter(counters->keyed_load_array_length(), 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
-}
-
-
 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
     Handle<String> name) {
   // ----------- S t a t e -------------
index b673865..09a918f 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -868,6 +868,29 @@ bool IC::HandleLoad(State state,
     *result = Smi::FromInt(String::cast(*string)->length());
     return true;
   }
+
+  // Use specialized code for getting the length of arrays.
+  if (object->IsJSArray() && name->Equals(isolate()->heap()->length_symbol())) {
+    Handle<Code> stub;
+    if (state == UNINITIALIZED) {
+      stub = pre_monomorphic_stub();
+    } else if (state == PREMONOMORPHIC) {
+      ArrayLengthStub array_length_stub(kind());
+      stub = array_length_stub.GetCode();
+    } else if (state != MEGAMORPHIC) {
+      ASSERT(state != GENERIC);
+      stub = megamorphic_stub();
+    }
+    if (!stub.is_null()) {
+      set_target(*stub);
+#ifdef DEBUG
+      if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
+#endif
+    }
+    *result = JSArray::cast(*object)->length();
+    return true;
+  }
+
   return false;
 }
 
@@ -887,27 +910,6 @@ MaybeObject* LoadIC::Load(State state,
       return result;
     }
 
-    // Use specialized code for getting the length of arrays.
-    if (object->IsJSArray() &&
-        name->Equals(isolate()->heap()->length_symbol())) {
-      Handle<Code> stub;
-      if (state == UNINITIALIZED) {
-        stub = pre_monomorphic_stub();
-      } else if (state == PREMONOMORPHIC) {
-        stub = isolate()->builtins()->LoadIC_ArrayLength();
-      } else if (state != MEGAMORPHIC) {
-        ASSERT(state != GENERIC);
-        stub = megamorphic_stub();
-      }
-      if (!stub.is_null()) {
-        set_target(*stub);
-#ifdef DEBUG
-        if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
-#endif
-      }
-      return JSArray::cast(*object)->length();
-    }
-
     // Use specialized code for getting prototype of functions.
     if (object->IsJSFunction() &&
         name->Equals(isolate()->heap()->prototype_symbol()) &&
@@ -1175,18 +1177,6 @@ MaybeObject* KeyedLoadIC::Load(State state,
       }
 
       // TODO(1073): don't ignore the current stub state.
-      // Use specialized code for getting the length of arrays.
-      if (object->IsJSArray() &&
-          name->Equals(isolate()->heap()->length_symbol())) {
-        Handle<JSArray> array = Handle<JSArray>::cast(object);
-        Handle<Code> code =
-            isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array);
-        ASSERT(!code.is_null());
-        set_target(*code);
-        TRACE_IC("KeyedLoadIC", name, state, target());
-        return array->length();
-      }
-
       // Use specialized code for getting prototype of functions.
       if (object->IsJSFunction() &&
           name->Equals(isolate()->heap()->prototype_symbol()) &&
index ba681ca..fa1c820 100644 (file)
@@ -348,23 +348,6 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
 }
 
 
-Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
-                                                    Handle<JSArray> receiver) {
-  Code::Flags flags =
-      Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
-  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
-                       isolate_);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
-
-  KeyedLoadStubCompiler compiler(isolate_);
-  Handle<Code> code = compiler.CompileLoadArrayLength(name);
-  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
-  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
-  JSObject::UpdateMapCodeCache(receiver, name, code);
-  return code;
-}
-
-
 Handle<Code> StubCache::ComputeKeyedLoadFunctionPrototype(
     Handle<String> name,
     Handle<JSFunction> receiver) {
index 555d660..0468e74 100644 (file)
@@ -133,9 +133,6 @@ class StubCache {
                                            Handle<JSObject> receiver,
                                            Handle<JSObject> holder);
 
-  Handle<Code> ComputeKeyedLoadArrayLength(Handle<String> name,
-                                           Handle<JSArray> receiver);
-
   Handle<Code> ComputeKeyedLoadFunctionPrototype(Handle<String> name,
                                                  Handle<JSFunction> receiver);
 
@@ -667,8 +664,6 @@ class KeyedLoadStubCompiler: public StubCompiler {
                                       Handle<JSObject> holder,
                                       Handle<String> name);
 
-  Handle<Code> CompileLoadArrayLength(Handle<String> name);
-
   Handle<Code> CompileLoadFunctionPrototype(Handle<String> name);
 
   Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
index e557285..3b1ae11 100644 (file)
@@ -2360,6 +2360,33 @@ void MathPowStub::Generate(MacroAssembler* masm) {
 }
 
 
+void ArrayLengthStub::Generate(MacroAssembler* masm) {
+  Label miss;
+  Register receiver;
+  if (kind() == Code::KEYED_LOAD_IC) {
+    // ----------- S t a t e -------------
+    //  -- rax    : key
+    //  -- rdx    : receiver
+    //  -- rsp[0] : return address
+    // -----------------------------------
+    __ Cmp(rax, masm->isolate()->factory()->length_symbol());
+    receiver = rdx;
+  } else {
+    ASSERT(kind() == Code::LOAD_IC);
+    // ----------- S t a t e -------------
+    //  -- rax    : receiver
+    //  -- rcx    : name
+    //  -- rsp[0] : return address
+    // -----------------------------------
+    receiver = rax;
+  }
+
+  StubCompiler::GenerateLoadArrayLength(masm, receiver, r8, &miss);
+  __ bind(&miss);
+  StubCompiler::GenerateLoadMiss(masm, kind());
+}
+
+
 void StringLengthStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver;
index f903f87..f30db79 100644 (file)
@@ -224,20 +224,6 @@ static void GenerateDictionaryStore(MacroAssembler* masm,
 }
 
 
-void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
-  __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
-}
-
-
 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : receiver
index 1b65dd0..5259d7f 100644 (file)
@@ -3128,32 +3128,6 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
 }
 
 
-Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
-    Handle<String> name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->keyed_load_array_length(), 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rax, name);
-  __ j(not_equal, &miss);
-
-  GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
-  __ bind(&miss);
-  __ DecrementCounter(counters->keyed_load_array_length(), 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
-}
-
-
 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
     Handle<String> name) {
   // ----------- S t a t e -------------