Land Vitaly's change to fix compare IC performance.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 13 Dec 2010 10:05:19 +0000 (10:05 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 13 Dec 2010 10:05:19 +0000 (10:05 +0000)
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
src/ic.cc
src/ic.h

index fdcb1f5..d713601 100644 (file)
@@ -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) {
   HandleScope scope;
   Handle<Code> 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();
index b485a01..645c6fd 100644 (file)
--- 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<Object> x,
                                         Handle<Object> 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;
 }
 
index ec35c6a..7dfb02f 100644 (file)
--- 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<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; }
   Condition GetCondition() const { return ComputeCondition(op_); }