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
parent 94bb378e
...@@ -2049,12 +2049,23 @@ Condition CompareIC::ComputeCondition(Token::Value op) { ...@@ -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<Object> x, Handle<Object> y) { void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
HandleScope scope; HandleScope scope;
Handle<Code> rewritten; Handle<Code> rewritten;
State previous_state = GetState(); State previous_state = GetState();
State state = TargetState(previous_state, x, y); State state = TargetState(previous_state, HasInlinedSmiCode(address()), x, y);
if (state == GENERIC) { if (state == GENERIC) {
CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS); CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS);
rewritten = stub.GetCode(); rewritten = stub.GetCode();
......
...@@ -2133,13 +2133,16 @@ const char* CompareIC::GetStateName(State state) { ...@@ -2133,13 +2133,16 @@ const char* CompareIC::GetStateName(State state) {
CompareIC::State CompareIC::TargetState(State state, CompareIC::State CompareIC::TargetState(State state,
bool has_inlined_smi_code,
Handle<Object> x, Handle<Object> x,
Handle<Object> y) { Handle<Object> y) {
if (state != UNINITIALIZED) return GENERIC; if (!has_inlined_smi_code && state != UNINITIALIZED) return GENERIC;
if (x->IsSmi() && y->IsSmi()) return SMIS; if (state == UNINITIALIZED && x->IsSmi() && y->IsSmi()) return SMIS;
if (x->IsNumber() && y->IsNumber()) return HEAP_NUMBERS; 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 (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; return GENERIC;
} }
......
...@@ -582,7 +582,10 @@ class CompareIC: public IC { ...@@ -582,7 +582,10 @@ class CompareIC: public IC {
static const char* GetStateName(State state); static const char* GetStateName(State state);
private: private:
State TargetState(State state, Handle<Object> x, Handle<Object> y); State TargetState(State state,
bool has_inlined_smi_code,
Handle<Object> x,
Handle<Object> y);
bool strict() const { return op_ == Token::EQ_STRICT; } bool strict() const { return op_ == Token::EQ_STRICT; }
Condition GetCondition() const { return ComputeCondition(op_); } Condition GetCondition() const { return ComputeCondition(op_); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment