From f80379f3fb6493cd05c5e0efbbbee38a8011a1c7 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Mon, 21 Jan 2013 17:17:02 +0000 Subject: [PATCH] Migrate ArrayLength (Keyed|Named)LoadIC to CodeStub Review URL: https://chromiumcodereview.appspot.com/11938013 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13458 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 29 +++++++++++++++++++ src/arm/ic-arm.cc | 15 ---------- src/arm/stub-cache-arm.cc | 21 -------------- src/ast.cc | 3 +- src/builtins.cc | 5 ---- src/builtins.h | 2 -- src/code-stubs.h | 15 ++++++++++ src/ia32/code-stubs-ia32.cc | 19 +++++++++++++ src/ia32/ic-ia32.cc | 14 ---------- src/ia32/stub-cache-ia32.cc | 26 ----------------- src/ic.cc | 56 +++++++++++++++---------------------- src/stub-cache.cc | 17 ----------- src/stub-cache.h | 5 ---- src/x64/code-stubs-x64.cc | 27 ++++++++++++++++++ src/x64/ic-x64.cc | 14 ---------- src/x64/stub-cache-x64.cc | 26 ----------------- 16 files changed, 115 insertions(+), 179 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 415f8bc4e7..3998a9f3fa 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -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; diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc index c9b7cb9b00..d9ca491f4c 100644 --- a/src/arm/ic-arm.cc +++ b/src/arm/ic-arm.cc @@ -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 diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 236e9087d3..fc69530f5f 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -3207,27 +3207,6 @@ Handle KeyedLoadStubCompiler::CompileLoadInterceptor( } -Handle KeyedLoadStubCompiler::CompileLoadArrayLength( - Handle 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 KeyedLoadStubCompiler::CompileLoadFunctionPrototype( Handle name) { // ----------- S t a t e ------------- diff --git a/src/ast.cc b/src/ast.cc index f7c667fbc1..b89da9d886 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -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; diff --git a/src/builtins.cc b/src/builtins.cc index 4f373dd0f1..cd94d1d8e7 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -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); } diff --git a/src/builtins.h b/src/builtins.h index 619006a758..bad92f4137 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -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, \ diff --git a/src/code-stubs.h b/src/code-stubs.h index 7e2ebe4d52..f906a3acf6 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -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) diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index cfeecf1981..afea534e27 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -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 diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc index e5c14574e2..f011e09233 100644 --- a/src/ia32/ic-ia32.cc +++ b/src/ia32/ic-ia32.cc @@ -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 diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index d500abd17c..fe18647645 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -3315,32 +3315,6 @@ Handle KeyedLoadStubCompiler::CompileLoadInterceptor( } -Handle KeyedLoadStubCompiler::CompileLoadArrayLength( - Handle 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 KeyedLoadStubCompiler::CompileLoadFunctionPrototype( Handle name) { // ----------- S t a t e ------------- diff --git a/src/ic.cc b/src/ic.cc index b6738658ef..09a918f0a5 100644 --- 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 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 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 array = Handle::cast(object); - Handle 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()) && diff --git a/src/stub-cache.cc b/src/stub-cache.cc index ba681ca9f8..fa1c820bf5 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -348,23 +348,6 @@ Handle StubCache::ComputeKeyedLoadCallback( } -Handle StubCache::ComputeKeyedLoadArrayLength(Handle name, - Handle receiver) { - Code::Flags flags = - Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS); - Handle probe(receiver->map()->FindInCodeCache(*name, flags), - isolate_); - if (probe->IsCode()) return Handle::cast(probe); - - KeyedLoadStubCompiler compiler(isolate_); - Handle 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 StubCache::ComputeKeyedLoadFunctionPrototype( Handle name, Handle receiver) { diff --git a/src/stub-cache.h b/src/stub-cache.h index 555d660760..0468e7492b 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -133,9 +133,6 @@ class StubCache { Handle receiver, Handle holder); - Handle ComputeKeyedLoadArrayLength(Handle name, - Handle receiver); - Handle ComputeKeyedLoadFunctionPrototype(Handle name, Handle receiver); @@ -667,8 +664,6 @@ class KeyedLoadStubCompiler: public StubCompiler { Handle holder, Handle name); - Handle CompileLoadArrayLength(Handle name); - Handle CompileLoadFunctionPrototype(Handle name); Handle CompileLoadElement(Handle receiver_map); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index e557285a48..3b1ae11de2 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -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; diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc index f903f87196..f30db79683 100644 --- a/src/x64/ic-x64.cc +++ b/src/x64/ic-x64.cc @@ -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 diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 1b65dd05ed..5259d7f5f7 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -3128,32 +3128,6 @@ Handle KeyedLoadStubCompiler::CompileLoadInterceptor( } -Handle KeyedLoadStubCompiler::CompileLoadArrayLength( - Handle 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 KeyedLoadStubCompiler::CompileLoadFunctionPrototype( Handle name) { // ----------- S t a t e -------------