From b50b98421c77688fd8ee8e11cde75c8269f8221a Mon Sep 17 00:00:00 2001 From: "fschneider@chromium.org" Date: Mon, 13 Dec 2010 10:05:19 +0000 Subject: [PATCH] Land Vitaly's change to fix compare IC performance. Original change: http://codereview.chromium.org/5733004/ When we have inlined smi code can transition to heap number state before going to the generic state. Without inlined smi code the behaviour is unchanged. Review URL: http://codereview.chromium.org/5689005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5975 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/ic-ia32.cc | 13 ++++++++++++- src/ic.cc | 11 +++++++---- src/ic.h | 5 ++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc index fdcb1f5..d713601 100644 --- a/src/ia32/ic-ia32.cc +++ b/src/ia32/ic-ia32.cc @@ -2049,12 +2049,23 @@ Condition CompareIC::ComputeCondition(Token::Value op) { } +static bool HasInlinedSmiCode(Address address) { + // The address of the instruction following the call. + Address test_instruction_address = + address + Assembler::kCallTargetAddressOffset; + + // If the instruction following the call is not a test al, nothing + // was inlined. + return *test_instruction_address == Assembler::kTestAlByte; +} + + void CompareIC::UpdateCaches(Handle x, Handle y) { HandleScope scope; Handle rewritten; State previous_state = GetState(); - State state = TargetState(previous_state, x, y); + State state = TargetState(previous_state, HasInlinedSmiCode(address()), x, y); if (state == GENERIC) { CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS); rewritten = stub.GetCode(); diff --git a/src/ic.cc b/src/ic.cc index b485a01..645c6fd 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -2133,13 +2133,16 @@ const char* CompareIC::GetStateName(State state) { CompareIC::State CompareIC::TargetState(State state, + bool has_inlined_smi_code, Handle x, Handle y) { - if (state != UNINITIALIZED) return GENERIC; - if (x->IsSmi() && y->IsSmi()) return SMIS; - if (x->IsNumber() && y->IsNumber()) return HEAP_NUMBERS; + if (!has_inlined_smi_code && state != UNINITIALIZED) return GENERIC; + if (state == UNINITIALIZED && x->IsSmi() && y->IsSmi()) return SMIS; + if ((state == UNINITIALIZED || (state == SMIS && has_inlined_smi_code)) && + x->IsNumber() && y->IsNumber()) return HEAP_NUMBERS; if (op_ != Token::EQ && op_ != Token::EQ_STRICT) return GENERIC; - if (x->IsJSObject() && y->IsJSObject()) return OBJECTS; + if (state == UNINITIALIZED && + x->IsJSObject() && y->IsJSObject()) return OBJECTS; return GENERIC; } diff --git a/src/ic.h b/src/ic.h index ec35c6a..7dfb02f 100644 --- a/src/ic.h +++ b/src/ic.h @@ -582,7 +582,10 @@ class CompareIC: public IC { static const char* GetStateName(State state); private: - State TargetState(State state, Handle x, Handle y); + State TargetState(State state, + bool has_inlined_smi_code, + Handle x, + Handle y); bool strict() const { return op_ == Token::EQ_STRICT; } Condition GetCondition() const { return ComputeCondition(op_); } -- 2.7.4