From f7bae62cd38a0c140c53d034372be766a9f9af8a Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Wed, 30 Jan 2013 14:25:34 +0000 Subject: [PATCH] Fix gbemu preformance regression R=yangguo@chromium.org Review URL: https://codereview.chromium.org/12084063 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13557 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 2 +- src/ia32/code-stubs-ia32.cc | 2 +- src/ic.cc | 43 ++++++++++++++++++++++++++++--------- src/ic.h | 6 ++++-- src/x64/code-stubs-x64.cc | 2 +- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index d0b4d1eb10..1236e31784 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -45,7 +45,7 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( descriptor->register_param_count_ = 2; descriptor->register_params_ = registers; descriptor->deoptimization_handler_ = - FUNCTION_ADDR(KeyedLoadIC_Miss); + FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); } diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 25ff1d5039..2c6b0a5f3d 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -48,7 +48,7 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( descriptor->register_param_count_ = 2; descriptor->register_params_ = registers; descriptor->deoptimization_handler_ = - FUNCTION_ADDR(KeyedLoadIC_Miss); + FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); } diff --git a/src/ic.cc b/src/ic.cc index cd9095be12..de26d6c77b 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -111,16 +111,30 @@ void IC::TraceIC(const char* type, ASSERT((TraceIC(type, name, old_state, new_target), true)) IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { - ASSERT(isolate == Isolate::Current()); + // To improve the performance of the (much used) IC code, we unfold a few + // levels of the stack frame iteration code. This yields a ~35% speedup when + // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. + const Address entry = + Isolate::c_entry_fp(isolate->thread_local_top()); + Address* pc_address = + reinterpret_cast(entry + ExitFrameConstants::kCallerPCOffset); + Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); + // If there's another JavaScript frame on the stack or a + // StubFailureTrampoline, we need to look one frame further down the stack to + // find the frame pointer and the return address stack slot. + if (depth == EXTRA_CALL_FRAME) { + const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; + pc_address = reinterpret_cast(fp + kCallerPCOffset); + fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); + } +#ifdef DEBUG StackFrameIterator it; for (int i = 0; i < depth + 1; i++) it.Advance(); - // Skip StubFailureTrampolineFrames - if (it.frame()->is_stub_failure_trampoline()) { - it.Advance(); - } StackFrame* frame = it.frame(); - fp_ = frame->fp(); - pc_address_ = frame->pc_address(); + ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); +#endif + fp_ = fp; + pc_address_ = pc_address; } @@ -1876,7 +1890,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { HandleScope scope(isolate); ASSERT(args.length() == 2); - LoadIC ic(isolate); + LoadIC ic(IC::NO_EXTRA_FRAME, isolate); IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); return ic.Load(state, args.at(0), args.at(1)); } @@ -1886,7 +1900,16 @@ RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { HandleScope scope(isolate); ASSERT(args.length() == 2); - KeyedLoadIC ic(isolate); + KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); + IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); + return ic.Load(state, args.at(0), args.at(1), MISS); +} + + +RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { + HandleScope scope(isolate); + ASSERT(args.length() == 2); + KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); return ic.Load(state, args.at(0), args.at(1), MISS); } @@ -1895,7 +1918,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) { HandleScope scope(isolate); ASSERT(args.length() == 2); - KeyedLoadIC ic(isolate); + KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); return ic.Load(state, args.at(0), diff --git a/src/ic.h b/src/ic.h index ea6aa057df..cb316407c0 100644 --- a/src/ic.h +++ b/src/ic.h @@ -342,7 +342,7 @@ class KeyedCallIC: public CallICBase { class LoadIC: public IC { public: - explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { + explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) { ASSERT(target()->is_load_stub() || target()->is_keyed_load_stub()); } @@ -404,7 +404,8 @@ enum ICMissMode { class KeyedLoadIC: public LoadIC { public: - explicit KeyedLoadIC(Isolate* isolate) : LoadIC(isolate) { + explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate) + : LoadIC(depth, isolate) { ASSERT(target()->is_keyed_load_stub()); } @@ -813,6 +814,7 @@ enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; void PatchInlinedSmiCode(Address address, InlinedSmiCheck check); DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss); +DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure); } } // namespace v8::internal diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 109fcfcd40..2d3f7c6431 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -45,7 +45,7 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( descriptor->register_param_count_ = 2; descriptor->register_params_ = registers; descriptor->deoptimization_handler_ = - FUNCTION_ADDR(KeyedLoadIC_Miss); + FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); }