Use type info for count operation in Crankshaft.
authorwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Apr 2011 09:21:18 +0000 (09:21 +0000)
committerwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Apr 2011 09:21:18 +0000 (09:21 +0000)
BUG=
TEST=

Review URL: http://codereview.chromium.org/6880276

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7717 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen.cc
src/hydrogen.h
src/type-info.cc
src/type-info.h

index 27b8a26..ef7e363 100644 (file)
@@ -4653,12 +4653,18 @@ void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
 }
 
 
-HInstruction* HGraphBuilder::BuildIncrement(HValue* value, bool increment) {
+HInstruction* HGraphBuilder::BuildIncrement(HValue* value,
+                                            bool increment,
+                                            CountOperation* expr) {
   HConstant* delta = increment
       ? graph_->GetConstant1()
       : graph_->GetConstantMinus1();
   HInstruction* instr = new(zone()) HAdd(value, delta);
-  AssumeRepresentation(instr,  Representation::Integer32());
+  Representation rep = ToRepresentation(oracle()->IncrementType(expr));
+  if (rep.IsTagged()) {
+    rep = Representation::Integer32();
+  }
+  AssumeRepresentation(instr, rep);
   return instr;
 }
 
@@ -4681,7 +4687,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
     // element for postfix operations in a non-effect context.
     bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
     HValue* before = has_extra ? Top() : Pop();
-    HInstruction* after = BuildIncrement(before, inc);
+    HInstruction* after = BuildIncrement(before, inc, expr);
     AddInstruction(after);
     Push(after);
 
@@ -4733,7 +4739,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
       HValue* before = Pop();
       // There is no deoptimization to after the increment, so we don't need
       // to simulate the expression stack after this instruction.
-      HInstruction* after = BuildIncrement(before, inc);
+      HInstruction* after = BuildIncrement(before, inc, expr);
       AddInstruction(after);
 
       HInstruction* store = BuildStoreNamed(obj, after, prop);
@@ -4769,7 +4775,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
       HValue* before = Pop();
       // There is no deoptimization to after the increment, so we don't need
       // to simulate the expression stack after this instruction.
-      HInstruction* after = BuildIncrement(before, inc);
+      HInstruction* after = BuildIncrement(before, inc, expr);
       AddInstruction(after);
 
       expr->RecordTypeFeedback(oracle());
index 32bf6d4..a7dba01 100644 (file)
@@ -831,7 +831,9 @@ class HGraphBuilder: public AstVisitor {
   HInstruction* BuildBinaryOperation(BinaryOperation* expr,
                                      HValue* left,
                                      HValue* right);
-  HInstruction* BuildIncrement(HValue* value, bool increment);
+  HInstruction* BuildIncrement(HValue* value,
+                               bool increment,
+                               CountOperation* expr);
   HLoadNamedField* BuildLoadNamedField(HValue* object,
                                        Property* expr,
                                        Handle<Map> type,
index e924197..f0def1c 100644 (file)
@@ -334,6 +334,35 @@ TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) {
 }
 
 
+TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
+  Handle<Object> object = GetInfo(expr->CountId());
+  TypeInfo unknown = TypeInfo::Unknown();
+  if (!object->IsCode()) return unknown;
+  Handle<Code> code = Handle<Code>::cast(object);
+  if (!code->is_type_recording_binary_op_stub()) return unknown;
+
+  TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
+      code->type_recording_binary_op_type());
+  switch (type) {
+    case TRBinaryOpIC::UNINITIALIZED:
+    case TRBinaryOpIC::SMI:
+      return TypeInfo::Smi();
+    case TRBinaryOpIC::INT32:
+      return TypeInfo::Integer32();
+    case TRBinaryOpIC::HEAP_NUMBER:
+      return TypeInfo::Double();
+    case TRBinaryOpIC::BOTH_STRING:
+    case TRBinaryOpIC::STRING:
+    case TRBinaryOpIC::GENERIC:
+      return unknown;
+    default:
+      return unknown;
+  }
+  UNREACHABLE();
+  return unknown;
+}
+
+
 ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
                                                       Handle<String> name,
                                                       Code::Flags flags) {
index 4518049..a715bc7 100644 (file)
@@ -231,6 +231,7 @@ class UnaryOperation;
 class BinaryOperation;
 class Call;
 class CompareOperation;
+class CountOperation;
 class CompilationInfo;
 class Property;
 class CaseClause;
@@ -263,6 +264,7 @@ class TypeFeedbackOracle BASE_EMBEDDED {
   TypeInfo BinaryType(BinaryOperation* expr);
   TypeInfo CompareType(CompareOperation* expr);
   TypeInfo SwitchType(CaseClause* clause);
+  TypeInfo IncrementType(CountOperation* expr);
 
  private:
   ZoneMapList* CollectReceiverTypes(unsigned ast_id,