Migrate BinaryOpICs and UnaryOpICs to new type rep
authorjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 14 Jun 2013 17:02:39 +0000 (17:02 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 14 Jun 2013 17:02:39 +0000 (17:02 +0000)
R=rossberg@chromium.org

Review URL: https://codereview.chromium.org/16957004

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

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

index 0ebbd35be886cdef66de2bb459226000d41750a3..bf607d255c15dbeda52c16146d2c97fa30a1fe8b 100644 (file)
@@ -663,12 +663,13 @@ void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
 
 
 void UnaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
-  type_ = oracle->UnaryType(this);
+  type_ = oracle->UnaryType(UnaryOperationFeedbackId());
 }
 
 
 void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
-  oracle->BinaryType(this, &left_type_, &right_type_, &result_type_,
+  oracle->BinaryType(BinaryOperationFeedbackId(),
+                     &left_type_, &right_type_, &result_type_,
                      &has_fixed_right_arg_, &fixed_right_arg_value_);
 }
 
index b7ada60665869ca575a5180d934fe689238d9750..b07456b8f789ed9f03d6aa8b82a2409bf0fe004b 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1837,7 +1837,7 @@ class UnaryOperation: public Expression {
 
   TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); }
   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
-  TypeInfo type() const { return type_; }
+  Handle<Type> type() const { return type_; }
 
  protected:
   UnaryOperation(Isolate* isolate,
@@ -1858,7 +1858,7 @@ class UnaryOperation: public Expression {
   Expression* expression_;
   int pos_;
 
-  TypeInfo type_;
+  Handle<Type> type_;
 
   // For unary not (Token::NOT), the AST ids where true and false will
   // actually be materialized, respectively.
@@ -1882,9 +1882,9 @@ class BinaryOperation: public Expression {
 
   TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
-  TypeInfo left_type() const { return left_type_; }
-  TypeInfo right_type() const { return right_type_; }
-  TypeInfo result_type() const { return result_type_; }
+  Handle<Type> left_type() const { return left_type_; }
+  Handle<Type> right_type() const { return right_type_; }
+  Handle<Type> result_type() const { return result_type_; }
   bool has_fixed_right_arg() const { return has_fixed_right_arg_; }
   int fixed_right_arg_value() const { return fixed_right_arg_value_; }
 
@@ -1909,9 +1909,9 @@ class BinaryOperation: public Expression {
   Expression* right_;
   int pos_;
 
-  TypeInfo left_type_;
-  TypeInfo right_type_;
-  TypeInfo result_type_;
+  Handle<Type> left_type_;
+  Handle<Type> right_type_;
+  Handle<Type> result_type_;
   bool has_fixed_right_arg_;
   int fixed_right_arg_value_;
 
index fad06548ba9e89559a87fdb9c1e5fbee6dfb0226..66b040743746e500ef935bc00f12153124578945 100644 (file)
@@ -9106,11 +9106,11 @@ void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
   HValue* context = environment()->LookupContext();
   HInstruction* instr =
       HMul::New(zone(), context, value, graph()->GetConstantMinus1());
-  TypeInfo info = expr->type();
-  Representation rep = ToRepresentation(info);
-  if (info.IsUninitialized()) {
+  Handle<Type> type = expr->type();
+  Representation rep = ToRepresentation(type);
+  if (type->Is(Type::None())) {
     AddSoftDeoptimize();
-    info = TypeInfo::Unknown();
+    type = handle(Type::Any(), isolate());
   }
   if (instr->IsBinaryOperation()) {
     HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep);
@@ -9123,8 +9123,8 @@ void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) {
   CHECK_ALIVE(VisitForValue(expr->expression()));
   HValue* value = Pop();
-  TypeInfo info = expr->type();
-  if (info.IsUninitialized()) {
+  Handle<Type> info = expr->type();
+  if (info->Is(Type::None())) {
     AddSoftDeoptimize();
   }
   HInstruction* instr = new(zone()) HBitNot(value);
@@ -9486,24 +9486,26 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
     HValue* left,
     HValue* right) {
   HValue* context = environment()->LookupContext();
-  TypeInfo left_info = expr->left_type();
-  TypeInfo right_info = expr->right_type();
-  TypeInfo result_info = expr->result_type();
+  Handle<Type> left_type = expr->left_type();
+  Handle<Type> right_type = expr->right_type();
+  Handle<Type> result_type = expr->result_type();
   bool has_fixed_right_arg = expr->has_fixed_right_arg();
   int fixed_right_arg_value = expr->fixed_right_arg_value();
-  Representation left_rep = ToRepresentation(left_info);
-  Representation right_rep = ToRepresentation(right_info);
-  Representation result_rep = ToRepresentation(result_info);
-  if (left_info.IsUninitialized()) {
-    // Can't have initialized one but not the other.
-    ASSERT(right_info.IsUninitialized());
+  Representation left_rep = ToRepresentation(left_type);
+  Representation right_rep = ToRepresentation(right_type);
+  Representation result_rep = ToRepresentation(result_type);
+  if (left_type->Is(Type::None())) {
+    AddSoftDeoptimize();
+    left_type = handle(Type::Any(), isolate());
+  }
+  if (right_type->Is(Type::None())) {
     AddSoftDeoptimize();
-    left_info = right_info = TypeInfo::Unknown();
+    right_type = handle(Type::Any(), isolate());
   }
   HInstruction* instr = NULL;
   switch (expr->op()) {
     case Token::ADD:
-      if (left_info.IsString() && right_info.IsString()) {
+      if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
         BuildCheckNonSmi(left);
         AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
         BuildCheckNonSmi(right);
@@ -9536,7 +9538,8 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
       break;
     case Token::BIT_OR: {
       HValue* operand, *shift_amount;
-      if (left_info.IsInteger32() && right_info.IsInteger32() &&
+      if (left_type->Is(Type::Integer32()) &&
+          right_type->Is(Type::Integer32()) &&
           MatchRotateRight(left, right, &operand, &shift_amount)) {
         instr = new(zone()) HRor(context, operand, shift_amount);
       } else {
index fc776eeadb68b6a6867065530ce93a02d4d27bb5..d6e35a7c47ccd16f2a8027ee7e762103db6d8a00 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -2420,17 +2420,34 @@ const char* UnaryOpIC::GetName(TypeInfo type_info) {
 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
   switch (type_info) {
     case UNINITIALIZED:
-      return ::v8::internal::UNINITIALIZED;
+      return v8::internal::UNINITIALIZED;
     case SMI:
     case NUMBER:
       return MONOMORPHIC;
     case GENERIC:
-      return ::v8::internal::GENERIC;
+      return v8::internal::GENERIC;
   }
   UNREACHABLE();
-  return ::v8::internal::UNINITIALIZED;
+  return v8::internal::UNINITIALIZED;
 }
 
+
+Handle<Type> UnaryOpIC::TypeInfoToType(TypeInfo type_info, Isolate* isolate) {
+  switch (type_info) {
+    case UNINITIALIZED:
+      return handle(Type::None(), isolate);
+    case SMI:
+      return handle(Type::Integer31(), isolate);
+    case NUMBER:
+      return handle(Type::Number(), isolate);
+    case GENERIC:
+      return handle(Type::Any(), isolate);
+  }
+  UNREACHABLE();
+  return handle(Type::Any(), isolate);
+}
+
+
 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) {
   v8::internal::TypeInfo operand_type =
       v8::internal::TypeInfo::FromValue(operand);
@@ -2501,6 +2518,46 @@ BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) {
 }
 
 
+Handle<Type> BinaryOpIC::TypeInfoToType(BinaryOpIC::TypeInfo binary_type,
+                                        Isolate* isolate) {
+  switch (binary_type) {
+    case UNINITIALIZED:
+      return handle(Type::None(), isolate);
+    case SMI:
+      return handle(Type::Integer31(), isolate);
+    case INT32:
+      return handle(Type::Integer32(), isolate);
+    case NUMBER:
+      return handle(Type::Number(), isolate);
+    case ODDBALL:
+      return handle(Type::Optional(
+          handle(Type::Union(
+              handle(Type::Number(), isolate),
+              handle(Type::String(), isolate)), isolate)), isolate);
+    case STRING:
+      return handle(Type::String(), isolate);
+    case GENERIC:
+      return handle(Type::Any(), isolate);
+  }
+  UNREACHABLE();
+  return handle(Type::Any(), isolate);
+}
+
+
+void BinaryOpIC::StubInfoToType(int minor_key,
+                                Handle<Type>* left,
+                                Handle<Type>* right,
+                                Handle<Type>* result,
+                                Isolate* isolate) {
+  TypeInfo left_typeinfo, right_typeinfo, result_typeinfo;
+  BinaryOpStub::decode_types_from_minor_key(
+      minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo);
+  *left = TypeInfoToType(left_typeinfo, isolate);
+  *right = TypeInfoToType(right_typeinfo, isolate);
+  *result = TypeInfoToType(result_typeinfo, isolate);
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
   ASSERT(args.length() == 4);
 
@@ -2814,45 +2871,60 @@ Handle<Type> CompareIC::StateToType(
 }
 
 
-static CompareIC::State InputState(CompareIC::State old_state,
-                                   Handle<Object> value) {
+void CompareIC::StubInfoToType(int stub_minor_key,
+                               Handle<Type>* left_type,
+                               Handle<Type>* right_type,
+                               Handle<Type>* overall_type,
+                               Handle<Map> map,
+                               Isolate* isolate) {
+  State left_state, right_state, handler_state;
+  ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
+                                &handler_state, NULL);
+  *left_type = StateToType(isolate, left_state);
+  *right_type = StateToType(isolate, right_state);
+  *overall_type = StateToType(isolate, handler_state, map);
+}
+
+
+CompareIC::State CompareIC::NewInputState(State old_state,
+                                          Handle<Object> value) {
   switch (old_state) {
-    case CompareIC::UNINITIALIZED:
-      if (value->IsSmi()) return CompareIC::SMI;
-      if (value->IsHeapNumber()) return CompareIC::NUMBER;
-      if (value->IsInternalizedString()) return CompareIC::INTERNALIZED_STRING;
-      if (value->IsString()) return CompareIC::STRING;
-      if (value->IsSymbol()) return CompareIC::UNIQUE_NAME;
-      if (value->IsJSObject()) return CompareIC::OBJECT;
+    case UNINITIALIZED:
+      if (value->IsSmi()) return SMI;
+      if (value->IsHeapNumber()) return NUMBER;
+      if (value->IsInternalizedString()) return INTERNALIZED_STRING;
+      if (value->IsString()) return STRING;
+      if (value->IsSymbol()) return UNIQUE_NAME;
+      if (value->IsJSObject()) return OBJECT;
       break;
-    case CompareIC::SMI:
-      if (value->IsSmi()) return CompareIC::SMI;
-      if (value->IsHeapNumber()) return CompareIC::NUMBER;
+    case SMI:
+      if (value->IsSmi()) return SMI;
+      if (value->IsHeapNumber()) return NUMBER;
       break;
-    case CompareIC::NUMBER:
-      if (value->IsNumber()) return CompareIC::NUMBER;
+    case NUMBER:
+      if (value->IsNumber()) return NUMBER;
       break;
-    case CompareIC::INTERNALIZED_STRING:
-      if (value->IsInternalizedString()) return CompareIC::INTERNALIZED_STRING;
-      if (value->IsString()) return CompareIC::STRING;
-      if (value->IsSymbol()) return CompareIC::UNIQUE_NAME;
+    case INTERNALIZED_STRING:
+      if (value->IsInternalizedString()) return INTERNALIZED_STRING;
+      if (value->IsString()) return STRING;
+      if (value->IsSymbol()) return UNIQUE_NAME;
       break;
-    case CompareIC::STRING:
-      if (value->IsString()) return CompareIC::STRING;
+    case STRING:
+      if (value->IsString()) return STRING;
       break;
-    case CompareIC::UNIQUE_NAME:
-      if (value->IsUniqueName()) return CompareIC::UNIQUE_NAME;
+    case UNIQUE_NAME:
+      if (value->IsUniqueName()) return UNIQUE_NAME;
       break;
-    case CompareIC::OBJECT:
-      if (value->IsJSObject()) return CompareIC::OBJECT;
+    case OBJECT:
+      if (value->IsJSObject()) return OBJECT;
       break;
-    case CompareIC::GENERIC:
+    case GENERIC:
       break;
-    case CompareIC::KNOWN_OBJECT:
+    case KNOWN_OBJECT:
       UNREACHABLE();
       break;
   }
-  return CompareIC::GENERIC;
+  return GENERIC;
 }
 
 
@@ -2925,8 +2997,8 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
   State previous_left, previous_right, previous_state;
   ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
                                 &previous_right, &previous_state, NULL);
-  State new_left = InputState(previous_left, x);
-  State new_right = InputState(previous_right, y);
+  State new_left = NewInputState(previous_left, x);
+  State new_right = NewInputState(previous_right, y);
   State state = TargetState(previous_state, previous_left, previous_right,
                             HasInlinedSmiCode(address()), x, y);
   ICCompareStub stub(op_, new_left, new_right, state);
index e6e88176c876536dda258c0a4e624f007688f183..829c6b1547666c708e41f15c36a7dcc49f4211ee 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -690,6 +690,8 @@ class UnaryOpIC: public IC {
     GENERIC
   };
 
+  static Handle<Type> TypeInfoToType(TypeInfo info, Isolate* isolate);
+
   explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
 
   void patch(Code* code);
@@ -717,6 +719,12 @@ class BinaryOpIC: public IC {
     GENERIC
   };
 
+  static void StubInfoToType(int minor_key,
+                             Handle<Type>* left,
+                             Handle<Type>* right,
+                             Handle<Type>* result,
+                             Isolate* isolate);
+
   explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
 
   void patch(Code* code);
@@ -724,6 +732,9 @@ class BinaryOpIC: public IC {
   static const char* GetName(TypeInfo type_info);
 
   static State ToState(TypeInfo type_info);
+
+ private:
+  static Handle<Type> TypeInfoToType(TypeInfo binary_type, Isolate* isolate);
 };
 
 
@@ -747,8 +758,18 @@ class CompareIC: public IC {
     GENERIC
   };
 
-  static Handle<Type> StateToType(
-      Isolate* isolate, State state, Handle<Map> map = Handle<Map>());
+  static State NewInputState(State old_state, Handle<Object> value);
+
+  static Handle<Type> StateToType(Isolate* isolate,
+                                  State state,
+                                  Handle<Map> map = Handle<Map>());
+
+  static void StubInfoToType(int stub_minor_key,
+                             Handle<Type>* left_type,
+                             Handle<Type>* right_type,
+                             Handle<Type>* overall_type,
+                             Handle<Map> map,
+                             Isolate* isolate);
 
   CompareIC(Isolate* isolate, Token::Value op)
       : IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
index 769354781d8ee2291228cfd18bbce31784c95c64..c5bdc9bec9dc3f11bf86e878e17fa2589115af90 100644 (file)
@@ -363,12 +363,8 @@ void TypeFeedbackOracle::CompareTypes(TypeFeedbackId id,
 
   if (code->is_compare_ic_stub()) {
     int stub_minor_key = code->stub_info();
-    CompareIC::State left_state, right_state, handler_state;
-    ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
-                                  &handler_state, NULL);
-    *left_type = CompareIC::StateToType(isolate_, left_state);
-    *right_type = CompareIC::StateToType(isolate_, right_state);
-    *overall_type = CompareIC::StateToType(isolate_, handler_state, map);
+    CompareIC::StubInfoToType(
+        stub_minor_key, left_type, right_type, overall_type, map, isolate());
   } else if (code->is_compare_nil_ic_stub()) {
     CompareNilICStub::State state(code->compare_nil_state());
     *compare_nil_type = CompareNilICStub::StateToType(isolate_, state, map);
@@ -376,70 +372,34 @@ void TypeFeedbackOracle::CompareTypes(TypeFeedbackId id,
 }
 
 
-TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
-  Handle<Object> object = GetInfo(expr->UnaryOperationFeedbackId());
-  TypeInfo unknown = TypeInfo::Unknown();
-  if (!object->IsCode()) return unknown;
+Handle<Type> TypeFeedbackOracle::UnaryType(TypeFeedbackId id) {
+  Handle<Object> object = GetInfo(id);
+  if (!object->IsCode()) return handle(Type::Any(), isolate());
   Handle<Code> code = Handle<Code>::cast(object);
   ASSERT(code->is_unary_op_stub());
-  UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>(
-      code->unary_op_type());
-  switch (type) {
-    case UnaryOpIC::SMI:
-      return TypeInfo::Smi();
-    case UnaryOpIC::NUMBER:
-      return TypeInfo::Double();
-    default:
-      return unknown;
-  }
+  return UnaryOpIC::TypeInfoToType(
+      static_cast<UnaryOpIC::TypeInfo>(code->unary_op_type()), isolate());
 }
 
 
-static TypeInfo TypeFromBinaryOpType(BinaryOpIC::TypeInfo binary_type) {
-  switch (binary_type) {
-    // Uninitialized means never executed.
-    case BinaryOpIC::UNINITIALIZED:  return TypeInfo::Uninitialized();
-    case BinaryOpIC::SMI:            return TypeInfo::Smi();
-    case BinaryOpIC::INT32:          return TypeInfo::Integer32();
-    case BinaryOpIC::NUMBER:         return TypeInfo::Double();
-    case BinaryOpIC::ODDBALL:        return TypeInfo::Unknown();
-    case BinaryOpIC::STRING:         return TypeInfo::String();
-    case BinaryOpIC::GENERIC:        return TypeInfo::Unknown();
-  }
-  UNREACHABLE();
-  return TypeInfo::Unknown();
-}
-
-
-void TypeFeedbackOracle::BinaryType(BinaryOperation* expr,
-                                    TypeInfo* left,
-                                    TypeInfo* right,
-                                    TypeInfo* result,
+void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
+                                    Handle<Type>* left,
+                                    Handle<Type>* right,
+                                    Handle<Type>* result,
                                     bool* has_fixed_right_arg,
                                     int* fixed_right_arg_value) {
-  Handle<Object> object = GetInfo(expr->BinaryOperationFeedbackId());
-  TypeInfo unknown = TypeInfo::Unknown();
-  if (!object->IsCode()) {
-    *left = *right = *result = unknown;
-    return;
-  }
+  Handle<Object> object = GetInfo(id);
+  *left = *right = *result = handle(Type::Any(), isolate_);
+  if (!object->IsCode()) return;
   Handle<Code> code = Handle<Code>::cast(object);
-  if (code->is_binary_op_stub()) {
-    int minor_key = code->stub_info();
-    BinaryOpIC::TypeInfo left_type, right_type, result_type;
-    BinaryOpStub::decode_types_from_minor_key(
-        minor_key, &left_type, &right_type, &result_type);
-    *left = TypeFromBinaryOpType(left_type);
-    *right = TypeFromBinaryOpType(right_type);
-    *result = TypeFromBinaryOpType(result_type);
-    *has_fixed_right_arg =
-        BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(minor_key);
-    *fixed_right_arg_value =
-        BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(minor_key);
-    return;
-  }
-  // Not a binary op stub.
-  *left = *right = *result = unknown;
+  if (!code->is_binary_op_stub()) return;
+
+  int minor_key = code->stub_info();
+  BinaryOpIC::StubInfoToType(minor_key, left, right, result, isolate());
+  *has_fixed_right_arg =
+      BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(minor_key);
+  *fixed_right_arg_value =
+      BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(minor_key);
 }
 
 
index 1262b3177c888b85f3d32b8fdf30bebc4f6d7023..3c2b83114ce4898898257ec9939ddb7ad5026418 100644 (file)
@@ -220,7 +220,6 @@ enum StringStubFeedback {
 // Forward declarations.
 // TODO(rossberg): these should all go away eventually.
 class Assignment;
-class BinaryOperation;
 class Call;
 class CallNew;
 class CaseClause;
@@ -231,7 +230,6 @@ class ForInStatement;
 class ICStub;
 class Property;
 class SmallMapList;
-class UnaryOperation;
 class ObjectLiteral;
 class ObjectLiteralProperty;
 
@@ -296,11 +294,11 @@ class TypeFeedbackOracle: public ZoneObject {
   byte ToBooleanTypes(TypeFeedbackId id);
 
   // Get type information for arithmetic operations and compares.
-  TypeInfo UnaryType(UnaryOperation* expr);
-  void BinaryType(BinaryOperation* expr,
-                  TypeInfo* left,
-                  TypeInfo* right,
-                  TypeInfo* result,
+  Handle<Type> UnaryType(TypeFeedbackId id);
+  void BinaryType(TypeFeedbackId id,
+                  Handle<Type>* left,
+                  Handle<Type>* right,
+                  Handle<Type>* result,
                   bool* has_fixed_right_arg,
                   int* fixed_right_arg_value);