Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index cd9095be129998145233d06c3d794f241f24355f..de26d6c77bb41408a91a2020e01dc13d45654518 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<Address*>(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<Address*>(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<Object>(0), args.at<String>(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<Object>(0), args.at<Object>(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<Object>(0), args.at<Object>(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<Object>(0), |