Revision: 15344
Author:   [email protected]
Date:     Wed Jun 26 10:37:55 2013
Log:      Avoid Unnecessary Smi Checks

BUG=
[email protected]

Review URL: https://codereview.chromium.org/16026023
http://code.google.com/p/v8/source/detail?r=15344

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.h
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/hydrogen.h
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.h
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Wed Jun 26 01:43:27 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Wed Jun 26 10:37:55 2013
@@ -2000,7 +2000,7 @@
 }


-LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
+LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
   return AssignEnvironment(new(zone()) LCheckNonSmi(value));
 }
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Wed Jun 26 01:43:27 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Wed Jun 26 10:37:55 2013
@@ -2421,6 +2421,7 @@
   LOperand* value() { return inputs_[0]; }

   DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
+  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
 };


=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Jun 26 09:17:12 2013 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Jun 26 10:37:55 2013
@@ -1880,10 +1880,12 @@
   Register map = ToRegister(instr->temp());
   Label done;

-  // If the object is a smi return the object.
-  __ SmiTst(input);
-  __ Move(result, input, eq);
-  __ b(eq, &done);
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    // If the object is a smi return the object.
+    __ SmiTst(input);
+    __ Move(result, input, eq);
+    __ b(eq, &done);
+  }

   // If the object is not a value type, return the object.
   __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
@@ -2438,8 +2440,11 @@

 Condition LCodeGen::EmitIsString(Register input,
                                  Register temp1,
-                                 Label* is_not_string) {
-  __ JumpIfSmi(input, is_not_string);
+                                 Label* is_not_string,
+ SmiCheck check_needed = INLINE_SMI_CHECK) {
+  if (check_needed == INLINE_SMI_CHECK) {
+    __ JumpIfSmi(input, is_not_string);
+  }
   __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE);

   return lt;
@@ -2450,8 +2455,11 @@
   Register reg = ToRegister(instr->value());
   Register temp1 = ToRegister(instr->temp());

+  SmiCheck check_needed =
+      instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
   Condition true_cond =
-      EmitIsString(reg, temp1, instr->FalseLabel(chunk_));
+      EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed);

   EmitBranch(instr, true_cond);
 }
@@ -2468,7 +2476,9 @@
   Register input = ToRegister(instr->value());
   Register temp = ToRegister(instr->temp());

-  __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }
   __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset));
   __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
   __ tst(temp, Operand(1 << Map::kIsUndetectable));
@@ -2534,7 +2544,9 @@
   Register scratch = scratch0();
   Register input = ToRegister(instr->value());

-  __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }

__ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
   EmitBranch(instr, BranchCondition(instr->hydrogen()));
@@ -2969,9 +2981,9 @@

   __ str(value, target);
   if (instr->hydrogen()->NeedsWriteBarrier()) {
-    HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
-        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+        instr->hydrogen()->value()->IsHeapObject()
+            ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     __ RecordWriteContextSlot(context,
                               target.offset(),
                               value,
@@ -4209,9 +4221,9 @@
   // Do the store.
   Register value = ToRegister(instr->value());
   ASSERT(!object.is(value));
-  HType type = instr->hydrogen()->value()->type();
   SmiCheck check_needed =
-      type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+      instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
   if (access.IsInobject()) {
     __ str(value, FieldMemOperand(object, offset));
     if (instr->hydrogen()->NeedsWriteBarrier()) {
@@ -4420,9 +4432,9 @@
   __ str(value, FieldMemOperand(store_base, offset));

   if (instr->hydrogen()->NeedsWriteBarrier()) {
-    HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
-        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+        instr->hydrogen()->value()->IsHeapObject()
+            ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
     __ add(key, store_base, Operand(offset - kHeapObjectTag));
     __ RecordWrite(elements,
@@ -5144,9 +5156,11 @@


 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
-  LOperand* input = instr->value();
-  __ SmiTst(ToRegister(input));
-  DeoptimizeIf(eq, instr->environment());
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    LOperand* input = instr->value();
+    __ SmiTst(ToRegister(input));
+    DeoptimizeIf(eq, instr->environment());
+  }
 }


=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Thu Jun 20 04:50:50 2013 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Wed Jun 26 10:37:55 2013
@@ -349,7 +349,8 @@
   // true and false label should be made, to optimize fallthrough.
   Condition EmitIsString(Register input,
                          Register temp1,
-                         Label* is_not_string);
+                         Label* is_not_string,
+                         SmiCheck check_needed);

   // Emits optimized code for %_IsConstructCall().
   // Caller should branch on equal condition.
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Jun 24 07:34:07 2013 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Jun 26 10:37:55 2013
@@ -3065,9 +3065,8 @@
 }


-HType HCheckNonSmi::CalculateInferredType() {
-  // TODO(kasperl): Is there any way to signal that this isn't a smi?
-  return HType::Tagged();
+HType HCheckHeapObject::CalculateInferredType() {
+  return HType::NonPrimitive();
 }


@@ -3736,7 +3735,7 @@
 }


-void HCheckNonSmi::Verify() {
+void HCheckHeapObject::Verify() {
   HInstruction::Verify();
   ASSERT(HasNoUses());
 }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Jun 24 07:34:07 2013 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Jun 26 10:37:55 2013
@@ -89,9 +89,9 @@
   V(CallStub)                                  \
   V(Change)                                    \
   V(CheckFunction)                             \
+  V(CheckHeapObject)                           \
   V(CheckInstanceType)                         \
   V(CheckMaps)                                 \
-  V(CheckNonSmi)                               \
   V(CheckPrototypeMaps)                        \
   V(ClampToUint8)                              \
   V(ClassOfTestAndBranch)                      \
@@ -434,7 +434,7 @@

   bool IsHeapObject() const {
     ASSERT(type_ != kUninitialized);
-    return IsHeapNumber() || IsString() || IsNonPrimitive();
+    return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive();
   }

   static HType TypeFromValue(Handle<Object> value);
@@ -917,6 +917,10 @@
     ASSERT(new_type.IsSubtypeOf(type_));
     type_ = new_type;
   }
+
+  bool IsHeapObject() {
+    return representation_.IsHeapObject() || type_.IsHeapObject();
+  }

   // An operation needs to override this function iff:
   //   1) it can produce an int32 output.
@@ -2948,9 +2952,9 @@
 };


-class HCheckNonSmi: public HUnaryOperation {
+class HCheckHeapObject: public HUnaryOperation {
  public:
-  explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
+  explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
   }
@@ -2967,17 +2971,13 @@

   virtual HValue* Canonicalize() {
     HType value_type = value()->type();
-    if (!value_type.IsUninitialized() &&
-        (value_type.IsHeapNumber() ||
-         value_type.IsString() ||
-         value_type.IsBoolean() ||
-         value_type.IsNonPrimitive())) {
+    if (!value_type.IsUninitialized() && value_type.IsHeapObject()) {
       return NULL;
     }
     return this;
   }

-  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
+  DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)

  protected:
   virtual bool DataEquals(HValue* other) { return true; }
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Wed Jun 26 02:51:57 2013
+++ /branches/bleeding_edge/src/hydrogen.cc     Wed Jun 26 10:37:55 2013
@@ -1024,9 +1024,9 @@
 }


-HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) {
+HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
   if (obj->type().IsHeapObject()) return obj;
-  HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj);
+  HCheckHeapObject* check = new(zone()) HCheckHeapObject(obj);
   AddInstruction(check);
   return check;
 }
@@ -1703,7 +1703,7 @@
     if_nil.Then();
     if_nil.Else();
     if (type->NumClasses() == 1) {
-      BuildCheckNonSmi(value);
+      BuildCheckHeapObject(value);
// For ICs, the map checked below is a sentinel map that gets replaced by // the monomorphic map when the code is used as a template to generate a
       // new IC. For optimized functions, there is no sentinel map, the map
@@ -6158,14 +6158,14 @@


 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
-  BuildCheckNonSmi(object);
+  BuildCheckHeapObject(object);
   AddInstruction(HCheckMaps::New(object, map, zone()));
 }


 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
                                                          Handle<Map> map) {
-  BuildCheckNonSmi(object);
+  BuildCheckHeapObject(object);
   AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
 }

@@ -6334,7 +6334,7 @@
   if (count != types->length()) return NULL;

   // Everything matched; can use monomorphic load.
-  BuildCheckNonSmi(object);
+  BuildCheckHeapObject(object);
   AddInstruction(HCheckMaps::New(object, types, zone()));
   return BuildLoadNamedField(object, access, representation);
 }
@@ -6349,7 +6349,7 @@
       expr, object, types, name);
   if (instr == NULL) {
     // Something did not match; must use a polymorphic load.
-    BuildCheckNonSmi(object);
+    BuildCheckHeapObject(object);
     HValue* context = environment()->LookupContext();
     instr = new(zone()) HLoadNamedFieldPolymorphic(
         context, object, types, name, zone());
@@ -6405,7 +6405,7 @@
   if (count != types->length()) return false;

   // Everything matched; can use monomorphic store.
-  BuildCheckNonSmi(object);
+  BuildCheckHeapObject(object);
   AddInstruction(HCheckMaps::New(object, types, zone()));
   HInstruction* store;
   CHECK_ALIVE_OR_RETURN(
@@ -6444,7 +6444,7 @@
     LookupResult lookup(isolate());
     if (ComputeLoadStoreField(map, name, &lookup, true)) {
       if (count == 0) {
-        BuildCheckNonSmi(object);
+        BuildCheckHeapObject(object);
         join = graph()->CreateBasicBlock();
       }
       ++count;
@@ -7178,7 +7178,7 @@
     KeyedAccessStoreMode store_mode,
     bool* has_side_effects) {
   *has_side_effects = false;
-  BuildCheckNonSmi(object);
+  BuildCheckHeapObject(object);
   SmallMapList* maps = prop->GetReceiverTypes();
   bool todo_external_array = false;

@@ -7403,7 +7403,7 @@
                        : BuildLoadKeyedGeneric(obj, key);
       AddInstruction(instr);
     } else {
-      BuildCheckNonSmi(obj);
+      BuildCheckHeapObject(obj);
       instr = BuildMonomorphicElementAccess(
           obj, key, val, NULL, map, is_store, expr->GetStoreMode());
     }
@@ -7535,7 +7535,7 @@
   HInstruction* instr = NULL;
   if (expr->IsStringLength()) {
     HValue* string = Pop();
-    BuildCheckNonSmi(string);
+    BuildCheckHeapObject(string);
     AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
     instr = HStringLength::New(zone(), string);
   } else if (expr->IsStringAccess()) {
@@ -7550,7 +7550,7 @@

   } else if (expr->IsFunctionPrototype()) {
     HValue* function = Pop();
-    BuildCheckNonSmi(function);
+    BuildCheckHeapObject(function);
     instr = new(zone()) HLoadFunctionPrototype(function);

   } else if (expr->key()->IsPropertyName()) {
@@ -7724,7 +7724,7 @@
         empty_smi_block->Goto(number_block);
         set_current_block(not_smi_block);
       } else {
-        BuildCheckNonSmi(receiver);
+        BuildCheckHeapObject(receiver);
       }
     }
     HBasicBlock* if_true = graph()->CreateBasicBlock();
@@ -9335,7 +9335,7 @@
       return new(zone()) HConstant(s->Get(i));
     }
   }
-  BuildCheckNonSmi(string);
+  BuildCheckHeapObject(string);
   AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
   HInstruction* length = HStringLength::New(zone(), string);
   AddInstruction(length);
@@ -9426,9 +9426,9 @@
   switch (expr->op()) {
     case Token::ADD:
if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
-        BuildCheckNonSmi(left);
+        BuildCheckHeapObject(left);
         AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
-        BuildCheckNonSmi(right);
+        BuildCheckHeapObject(right);
         AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
         instr = HStringAdd::New(zone(), context, left, right);
       } else {
@@ -9845,9 +9845,9 @@
           result->set_position(expr->position());
           return ast_context()->ReturnControl(result, expr->id());
         } else {
-          BuildCheckNonSmi(left);
+          BuildCheckHeapObject(left);
AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
-          BuildCheckNonSmi(right);
+          BuildCheckHeapObject(right);
AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
           HCompareObjectEqAndBranch* result =
               new(zone()) HCompareObjectEqAndBranch(left, right);
@@ -9860,9 +9860,9 @@
     }
   } else if (combined_type->Is(Type::InternalizedString()) &&
              Token::IsEqualityOp(op)) {
-    BuildCheckNonSmi(left);
+    BuildCheckHeapObject(left);
AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone()));
-    BuildCheckNonSmi(right);
+    BuildCheckHeapObject(right);
AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone()));
     HCompareObjectEqAndBranch* result =
         new(zone()) HCompareObjectEqAndBranch(left, right);
=======================================
--- /branches/bleeding_edge/src/hydrogen.h      Tue Jun 25 05:22:26 2013
+++ /branches/bleeding_edge/src/hydrogen.h      Wed Jun 26 10:37:55 2013
@@ -1012,7 +1012,7 @@
   HBasicBlock* CreateBasicBlock(HEnvironment* env);
   HBasicBlock* CreateLoopHeaderBlock();

-  HValue* BuildCheckNonSmi(HValue* object);
+  HValue* BuildCheckHeapObject(HValue* object);
   HValue* BuildCheckMap(HValue* obj, Handle<Map> map);

   // Building common constructs
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Jun 26 09:17:12 2013 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Jun 26 10:37:55 2013
@@ -1810,8 +1810,11 @@
   ASSERT(input.is(result));

   Label done;
-  // If the object is a smi return the object.
-  __ JumpIfSmi(input, &done, Label::kNear);
+
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    // If the object is a smi return the object.
+    __ JumpIfSmi(input, &done, Label::kNear);
+  }

   // If the object is not a value type, return the object.
   __ CmpObjectType(input, JS_VALUE_TYPE, map);
@@ -2364,8 +2367,11 @@

 Condition LCodeGen::EmitIsString(Register input,
                                  Register temp1,
-                                 Label* is_not_string) {
-  __ JumpIfSmi(input, is_not_string);
+                                 Label* is_not_string,
+ SmiCheck check_needed = INLINE_SMI_CHECK) {
+  if (check_needed == INLINE_SMI_CHECK) {
+    __ JumpIfSmi(input, is_not_string);
+  }

   Condition cond = masm_->IsObjectStringType(input, temp1, temp1);

@@ -2377,7 +2383,12 @@
   Register reg = ToRegister(instr->value());
   Register temp = ToRegister(instr->temp());

-  Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_));
+  SmiCheck check_needed =
+      instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+
+  Condition true_cond = EmitIsString(
+      reg, temp, instr->FalseLabel(chunk_), check_needed);

   EmitBranch(instr, true_cond);
 }
@@ -2395,8 +2406,10 @@
   Register input = ToRegister(instr->value());
   Register temp = ToRegister(instr->temp());

-  STATIC_ASSERT(kSmiTag == 0);
-  __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    STATIC_ASSERT(kSmiTag == 0);
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }
   __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
   __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
             1 << Map::kIsUndetectable);
@@ -2461,7 +2474,9 @@
   Register input = ToRegister(instr->value());
   Register temp = ToRegister(instr->temp());

-  __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }

   __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
   EmitBranch(instr, BranchCondition(instr->hydrogen()));
@@ -2898,9 +2913,9 @@

   __ mov(target, value);
   if (instr->hydrogen()->NeedsWriteBarrier()) {
-    HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
-        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+        instr->hydrogen()->value()->IsHeapObject()
+            ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     Register temp = ToRegister(instr->temp());
     int offset = Context::SlotOffset(instr->slot_index());
     __ RecordWriteContextSlot(context,
@@ -4269,9 +4284,9 @@
   }

   // Do the store.
-  HType type = instr->hydrogen()->value()->type();
   SmiCheck check_needed =
-      type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+      instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;

   Register write_register = object;
   if (!access.IsInobject()) {
@@ -4508,9 +4523,9 @@
     ASSERT(instr->value()->IsRegister());
     Register value = ToRegister(instr->value());
     ASSERT(!instr->key()->IsConstantOperand());
-    HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
-        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+        instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
     __ lea(key, operand);
     __ RecordWrite(elements,
@@ -5652,9 +5667,11 @@


 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
-  LOperand* input = instr->value();
-  __ test(ToOperand(input), Immediate(kSmiTagMask));
-  DeoptimizeIf(zero, instr->environment());
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    LOperand* input = instr->value();
+    __ test(ToOperand(input), Immediate(kSmiTagMask));
+    DeoptimizeIf(zero, instr->environment());
+  }
 }


=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Thu Jun 20 04:50:50 2013 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Wed Jun 26 10:37:55 2013
@@ -357,7 +357,8 @@
   // true and false label should be made, to optimize fallthrough.
   Condition EmitIsString(Register input,
                          Register temp1,
-                         Label* is_not_string);
+                         Label* is_not_string,
+                         SmiCheck check_needed);

   // Emits optimized code for %_IsConstructCall().
   // Caller should branch on equal condition.
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Jun 26 05:03:22 2013 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Jun 26 10:37:55 2013
@@ -2040,7 +2040,7 @@
 }


-LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
+LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
   LOperand* value = UseAtStart(instr->value());
   return AssignEnvironment(new(zone()) LCheckNonSmi(value));
 }
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Wed Jun 26 05:03:22 2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Wed Jun 26 10:37:55 2013
@@ -895,6 +895,7 @@
   LOperand* temp() { return temps_[0]; }

   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)

   virtual void PrintDataTo(StringStream* stream);
 };
@@ -927,6 +928,7 @@

   DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
                                "is-undetectable-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)

   virtual void PrintDataTo(StringStream* stream);
 };
@@ -2570,6 +2572,7 @@
   LOperand* value() { return inputs_[0]; }

   DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
+  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
 };


=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jun 26 09:17:12 2013 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jun 26 10:37:55 2013
@@ -1586,8 +1586,11 @@
   Register result = ToRegister(instr->result());
   ASSERT(input.is(result));
   Label done;
-  // If the object is a smi return the object.
-  __ JumpIfSmi(input, &done, Label::kNear);
+
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    // If the object is a smi return the object.
+    __ JumpIfSmi(input, &done, Label::kNear);
+  }

   // If the object is not a value type, return the object.
   __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister);
@@ -2151,8 +2154,12 @@

 Condition LCodeGen::EmitIsString(Register input,
                                  Register temp1,
-                                 Label* is_not_string) {
-  __ JumpIfSmi(input, is_not_string);
+                                 Label* is_not_string,
+ SmiCheck check_needed = INLINE_SMI_CHECK) {
+  if (check_needed == INLINE_SMI_CHECK) {
+    __ JumpIfSmi(input, is_not_string);
+  }
+
   Condition cond =  masm_->IsObjectStringType(input, temp1, temp1);

   return cond;
@@ -2163,7 +2170,12 @@
   Register reg = ToRegister(instr->value());
   Register temp = ToRegister(instr->temp());

-  Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_));
+  SmiCheck check_needed =
+      instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+
+  Condition true_cond = EmitIsString(
+      reg, temp, instr->FalseLabel(chunk_), check_needed);

   EmitBranch(instr, true_cond);
 }
@@ -2186,7 +2198,9 @@
   Register input = ToRegister(instr->value());
   Register temp = ToRegister(instr->temp());

-  __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }
   __ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
   __ testb(FieldOperand(temp, Map::kBitFieldOffset),
            Immediate(1 << Map::kIsUndetectable));
@@ -2230,7 +2244,9 @@
void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
   Register input = ToRegister(instr->value());

-  __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }

   __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
   EmitBranch(instr, BranchCondition(instr->hydrogen()));
@@ -2640,9 +2656,9 @@
   __ movq(target, value);

   if (instr->hydrogen()->NeedsWriteBarrier()) {
-    HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
-        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+      instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     int offset = Context::SlotOffset(instr->slot_index());
     Register scratch = ToRegister(instr->temp());
     __ RecordWriteContextSlot(context,
@@ -3965,9 +3981,9 @@
   }

   // Do the store.
-  HType type = instr->hydrogen()->value()->type();
   SmiCheck check_needed =
-      type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+      instr->hydrogen()->value()->IsHeapObject()
+          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;

   Register write_register = object;
   if (!access.IsInobject()) {
@@ -4206,9 +4222,9 @@
     ASSERT(instr->value()->IsRegister());
     Register value = ToRegister(instr->value());
     ASSERT(!instr->key()->IsConstantOperand());
-    HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
-        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+        instr->hydrogen()->value()->IsHeapObject()
+            ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
     Register key_reg(ToRegister(key));
     __ lea(key_reg, operand);
@@ -4874,9 +4890,11 @@


 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
-  LOperand* input = instr->value();
-  Condition cc = masm()->CheckSmi(ToRegister(input));
-  DeoptimizeIf(cc, instr->environment());
+  if (!instr->hydrogen()->value()->IsHeapObject()) {
+    LOperand* input = instr->value();
+    Condition cc = masm()->CheckSmi(ToRegister(input));
+    DeoptimizeIf(cc, instr->environment());
+  }
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Thu Jun 20 04:50:50 2013 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Wed Jun 26 10:37:55 2013
@@ -312,7 +312,8 @@
   // true and false label should be made, to optimize fallthrough.
   Condition EmitIsString(Register input,
                          Register temp1,
-                         Label* is_not_string);
+                         Label* is_not_string,
+                         SmiCheck check_needed);

   // Emits optimized code for %_IsConstructCall().
   // Caller should branch on equal condition.
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Wed Jun 26 01:43:27 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Wed Jun 26 10:37:55 2013
@@ -1913,7 +1913,7 @@
 }


-LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
+LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
   return AssignEnvironment(new(zone()) LCheckNonSmi(value));
 }
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Wed Jun 26 01:43:27 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Wed Jun 26 10:37:55 2013
@@ -2379,6 +2379,7 @@
   LOperand* value() { return inputs_[0]; }

   DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
+  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
 };


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to