Removed static type inference and add a dynamic test for string addition.
authorlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 24 Jun 2009 12:46:00 +0000 (12:46 +0000)
committerlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 24 Jun 2009 12:46:00 +0000 (12:46 +0000)
The complexity of static type inference never really paid off, and as an
analysis it didn't fit well with codegen frame propagation.

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

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

12 files changed:
src/arm/virtual-frame-arm.h
src/frame-element.h
src/ia32/codegen-ia32.cc
src/ia32/virtual-frame-ia32.cc
src/ia32/virtual-frame-ia32.h
src/jump-target.cc
src/register-allocator.cc
src/register-allocator.h
src/virtual-frame.cc
src/x64/codegen-x64.cc
src/x64/virtual-frame-x64.cc
src/x64/virtual-frame-x64.h

index ebebd53..2f36f10 100644 (file)
@@ -359,14 +359,14 @@ class VirtualFrame : public ZoneObject {
   void EmitPush(Register reg);
 
   // Push an element on the virtual frame.
-  void Push(Register reg, StaticType static_type = StaticType());
+  void Push(Register reg);
   void Push(Handle<Object> value);
   void Push(Smi* value) { Push(Handle<Object>(value)); }
 
   // Pushing a result invalidates it (its contents become owned by the frame).
   void Push(Result* result) {
     if (result->is_register()) {
-      Push(result->reg(), result->static_type());
+      Push(result->reg());
     } else {
       ASSERT(result->is_constant());
       Push(result->handle());
index d16eb48..666aabb 100644 (file)
@@ -54,8 +54,7 @@ class FrameElement BASE_EMBEDDED {
 
   // The default constructor creates an invalid frame element.
   FrameElement() {
-    value_ = StaticTypeField::encode(StaticType::UNKNOWN_TYPE)
-        | TypeField::encode(INVALID)
+    value_ = TypeField::encode(INVALID)
         | CopiedField::encode(false)
         | SyncedField::encode(false)
         | DataField::encode(0);
@@ -75,9 +74,8 @@ class FrameElement BASE_EMBEDDED {
 
   // Factory function to construct an in-register frame element.
   static FrameElement RegisterElement(Register reg,
-                                      SyncFlag is_synced,
-                                      StaticType static_type = StaticType()) {
-    return FrameElement(REGISTER, reg, is_synced, static_type);
+                                      SyncFlag is_synced) {
+    return FrameElement(REGISTER, reg, is_synced);
   }
 
   // Factory function to construct a frame element whose value is known at
@@ -143,15 +141,6 @@ class FrameElement BASE_EMBEDDED {
     return DataField::decode(value_);
   }
 
-  StaticType static_type() {
-    return StaticType(StaticTypeField::decode(value_));
-  }
-
-  void set_static_type(StaticType static_type) {
-    value_ = value_ & ~StaticTypeField::mask();
-    value_ = value_ | StaticTypeField::encode(static_type.static_type_);
-  }
-
   bool Equals(FrameElement other) {
     uint32_t masked_difference = (value_ ^ other.value_) & ~CopiedField::mask();
     if (!masked_difference) {
@@ -184,13 +173,8 @@ class FrameElement BASE_EMBEDDED {
     if (!other->is_valid()) return other;
 
     if (!SameLocation(other)) return NULL;
-    // If either is unsynced, the result is.  The result static type is
-    // the merge of the static types.  It's safe to set it on one of the
-    // frame elements, and harmless too (because we are only going to
-    // merge the reaching frames and will ensure that the types are
-    // coherent, and changing the static type does not emit code).
+    // If either is unsynced, the result is.
     FrameElement* result = is_synced() ? other : this;
-    result->set_static_type(static_type().merge(other->static_type()));
     return result;
   }
 
@@ -205,16 +189,7 @@ class FrameElement BASE_EMBEDDED {
 
   // Used to construct memory and register elements.
   FrameElement(Type type, Register reg, SyncFlag is_synced) {
-    value_ = StaticTypeField::encode(StaticType::UNKNOWN_TYPE)
-        | TypeField::encode(type)
-        | CopiedField::encode(false)
-        | SyncedField::encode(is_synced != NOT_SYNCED)
-        | DataField::encode(reg.code_ > 0 ? reg.code_ : 0);
-  }
-
-  FrameElement(Type type, Register reg, SyncFlag is_synced, StaticType stype) {
-    value_ = StaticTypeField::encode(stype.static_type_)
-        | TypeField::encode(type)
+    value_ = TypeField::encode(type)
         | CopiedField::encode(false)
         | SyncedField::encode(is_synced != NOT_SYNCED)
         | DataField::encode(reg.code_ > 0 ? reg.code_ : 0);
@@ -222,8 +197,7 @@ class FrameElement BASE_EMBEDDED {
 
   // Used to construct constant elements.
   FrameElement(Handle<Object> value, SyncFlag is_synced) {
-    value_ = StaticTypeField::encode(StaticType::TypeOf(*value).static_type_)
-        | TypeField::encode(CONSTANT)
+    value_ = TypeField::encode(CONSTANT)
         | CopiedField::encode(false)
         | SyncedField::encode(is_synced != NOT_SYNCED)
         | DataField::encode(ConstantList()->length());
@@ -248,14 +222,13 @@ class FrameElement BASE_EMBEDDED {
     value_ = value_ | DataField::encode(new_reg.code_);
   }
 
-  // Encode static type, type, copied, synced and data in one 32 bit integer.
+  // Encode type, copied, synced and data in one 32 bit integer.
   uint32_t value_;
 
-  class StaticTypeField: public BitField<StaticType::StaticTypeEnum, 0, 3> {};
-  class TypeField: public BitField<Type, 3, 3> {};
-  class CopiedField: public BitField<uint32_t, 6, 1> {};
-  class SyncedField: public BitField<uint32_t, 7, 1> {};
-  class DataField: public BitField<uint32_t, 8, 32 - 9> {};
+  class TypeField: public BitField<Type, 0, 3> {};
+  class CopiedField: public BitField<uint32_t, 3, 1> {};
+  class SyncedField: public BitField<uint32_t, 4, 1> {};
+  class DataField: public BitField<uint32_t, 5, 32 - 6> {};
 
   friend class VirtualFrame;
 };
index 0228be9..970a4ea 100644 (file)
@@ -919,15 +919,15 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
   Result left = frame_->Pop();
 
   if (op == Token::ADD) {
-    bool left_is_string = left.static_type().is_jsstring();
-    bool right_is_string = right.static_type().is_jsstring();
+    bool left_is_string = left.is_constant() && left.handle()->IsString();
+    bool right_is_string = right.is_constant() && right.handle()->IsString();
     if (left_is_string || right_is_string) {
       frame_->Push(&left);
       frame_->Push(&right);
       Result answer;
       if (left_is_string) {
         if (right_is_string) {
-          // TODO(lrn): if (left.is_constant() && right.is_constant())
+          // TODO(lrn): if both are constant strings
           // -- do a compile time cons, if allocation during codegen is allowed.
           answer = frame_->CallRuntime(Runtime::kStringAdd, 2);
         } else {
@@ -938,7 +938,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
         answer =
           frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2);
       }
-      answer.set_static_type(StaticType::jsstring());
       frame_->Push(&answer);
       return;
     }
@@ -6854,9 +6853,45 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
   // result.
   __ bind(&call_runtime);
   switch (op_) {
-    case Token::ADD:
+    case Token::ADD: {
+      // Test for string arguments before calling runtime.
+      Label not_strings, both_strings, not_string1, string1;
+      Result answer;
+      __ mov(eax, Operand(esp, 2 * kPointerSize));  // First argument.
+      __ mov(edx, Operand(esp, 1 * kPointerSize));  // Second argument.
+      __ test(eax, Immediate(kSmiTagMask));
+      __ j(zero, &not_string1);
+      __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, eax);
+      __ j(above_equal, &not_string1);
+
+      // First argument is a a string, test second.
+      __ test(edx, Immediate(kSmiTagMask));
+      __ j(zero, &string1);
+      __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, edx);
+      __ j(above_equal, &string1);
+
+      // First and second argument are strings.
+      __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2);
+
+      // Only first argument is a string.
+      __ bind(&string1);
+      __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_FUNCTION);
+
+      // First argument was not a string, test second.
+      __ bind(&not_string1);
+      __ test(edx, Immediate(kSmiTagMask));
+      __ j(zero, &not_strings);
+      __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, edx);
+      __ j(above_equal, &not_strings);
+
+      // Only second argument is a string.
+      __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_FUNCTION);
+
+      __ bind(&not_strings);
+      // Neither argument is a string.
       __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
       break;
+    }
     case Token::SUB:
       __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
       break;
index 53cdd5a..0854636 100644 (file)
@@ -218,10 +218,7 @@ void VirtualFrame::MakeMergable() {
           }
         }
       }
-      // No need to set the copied flag---there are no copies.
-
-      // Backwards jump targets can never know the type of a value.
-      elements_[i].set_static_type(StaticType::unknown());
+      // No need to set the copied flag --- there are no copies.
     } else {
       // Clear the copy flag of non-constant, non-copy elements.
       // They cannot be copied because copies are not allowed.
@@ -999,7 +996,6 @@ Result VirtualFrame::Pop() {
     if (element.is_memory()) {
       Result temp = cgen()->allocator()->Allocate();
       ASSERT(temp.is_valid());
-      temp.set_static_type(element.static_type());
       __ pop(temp.reg());
       return temp;
     }
@@ -1031,12 +1027,11 @@ Result VirtualFrame::Pop() {
         FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED);
     // Preserve the copy flag on the element.
     if (element.is_copied()) new_element.set_copied();
-    new_element.set_static_type(element.static_type());
     elements_[index] = new_element;
     __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
-    return Result(temp.reg(), element.static_type());
+    return Result(temp.reg());
   } else if (element.is_register()) {
-    return Result(element.reg(), element.static_type());
+    return Result(element.reg());
   } else {
     ASSERT(element.is_constant());
     return Result(element.handle());
index b69b800..314ea73 100644 (file)
@@ -43,7 +43,7 @@ namespace internal {
 // as random access to the expression stack elements, locals, and
 // parameters.
 
-class VirtualFrame : public ZoneObject {
+class VirtualFrame: public ZoneObject {
  public:
   // A utility class to introduce a scope where the virtual frame is
   // expected to remain spilled.  The constructor spills the code
@@ -65,7 +65,7 @@ class VirtualFrame : public ZoneObject {
    private:
     bool previous_state_;
 
-    CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
+    CodeGenerator* cgen() {return CodeGeneratorScope::Current();}
   };
 
   // An illegal index into the virtual frame.
@@ -78,6 +78,7 @@ class VirtualFrame : public ZoneObject {
   explicit VirtualFrame(VirtualFrame* original);
 
   CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
+
   MacroAssembler* masm() { return cgen()->masm(); }
 
   // Create a duplicate of an existing valid frame element.
@@ -87,9 +88,7 @@ class VirtualFrame : public ZoneObject {
   int element_count() { return elements_.length(); }
 
   // The height of the virtual expression stack.
-  int height() {
-    return element_count() - expression_base_index();
-  }
+  int height() { return element_count() - expression_base_index(); }
 
   int register_location(int num) {
     ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters);
@@ -255,7 +254,9 @@ class VirtualFrame : public ZoneObject {
   void PushReceiverSlotAddress();
 
   // Push the function on top of the frame.
-  void PushFunction() { PushFrameSlotAt(function_index()); }
+  void PushFunction() {
+    PushFrameSlotAt(function_index());
+  }
 
   // Save the value of the esi register to the context frame slot.
   void SaveContextRegister();
@@ -290,7 +291,9 @@ class VirtualFrame : public ZoneObject {
   }
 
   // The receiver frame slot.
-  Operand Receiver() { return ParameterAt(-1); }
+  Operand Receiver() {
+    return ParameterAt(-1);
+  }
 
   // Push a try-catch or try-finally handler on top of the virtual frame.
   void PushTryHandler(HandlerType type);
@@ -320,9 +323,7 @@ class VirtualFrame : public ZoneObject {
 
   // Invoke builtin given the number of arguments it expects on (and
   // removes from) the stack.
-  Result InvokeBuiltin(Builtins::JavaScript id,
-                       InvokeFlag flag,
-                       int arg_count);
+  Result InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, int arg_count);
 
   // Call load IC.  Name and receiver are found on top of the frame.
   // Receiver is not dropped.
@@ -357,10 +358,14 @@ class VirtualFrame : public ZoneObject {
   void Drop(int count);
 
   // Drop one element.
-  void Drop() { Drop(1); }
+  void Drop() {
+    Drop(1);
+  }
 
   // Duplicate the top element of the frame.
-  void Dup() { PushFrameSlotAt(element_count() - 1); }
+  void Dup() {
+    PushFrameSlotAt(element_count() - 1);
+  }
 
   // Pop an element from the top of the expression stack.  Returns a
   // Result, which may be a constant or a register.
@@ -378,15 +383,17 @@ class VirtualFrame : public ZoneObject {
   void EmitPush(Immediate immediate);
 
   // Push an element on the virtual frame.
-  void Push(Register reg, StaticType static_type = StaticType());
+  void Push(Register reg);
   void Push(Handle<Object> value);
-  void Push(Smi* value) { Push(Handle<Object>(value)); }
+  void Push(Smi* value) {
+    Push(Handle<Object> (value));
+  }
 
   // Pushing a result invalidates it (its contents become owned by the
   // frame).
   void Push(Result* result) {
     if (result->is_register()) {
-      Push(result->reg(), result->static_type());
+      Push(result->reg());
     } else {
       ASSERT(result->is_constant());
       Push(result->handle());
@@ -418,32 +425,48 @@ class VirtualFrame : public ZoneObject {
   int register_locations_[RegisterAllocator::kNumRegisters];
 
   // The number of frame-allocated locals and parameters respectively.
-  int parameter_count() { return cgen()->scope()->num_parameters(); }
-  int local_count() { return cgen()->scope()->num_stack_slots(); }
+  int parameter_count() {
+    return cgen()->scope()->num_parameters();
+  }
+  int local_count() {
+    return cgen()->scope()->num_stack_slots();
+  }
 
   // The index of the element that is at the processor's frame pointer
   // (the ebp register).  The parameters, receiver, and return address
   // are below the frame pointer.
-  int frame_pointer() { return parameter_count() + 2; }
+  int frame_pointer() {
+    return parameter_count() + 2;
+  }
 
   // The index of the first parameter.  The receiver lies below the first
   // parameter.
-  int param0_index() { return 1; }
+  int param0_index() {
+    return 1;
+  }
 
   // The index of the context slot in the frame.  It is immediately
   // above the frame pointer.
-  int context_index() { return frame_pointer() + 1; }
+  int context_index() {
+    return frame_pointer() + 1;
+  }
 
   // The index of the function slot in the frame.  It is above the frame
   // pointer and the context slot.
-  int function_index() { return frame_pointer() + 2; }
+  int function_index() {
+    return frame_pointer() + 2;
+  }
 
   // The index of the first local.  Between the frame pointer and the
   // locals lie the context and the function.
-  int local0_index() { return frame_pointer() + 3; }
+  int local0_index() {
+    return frame_pointer() + 3;
+  }
 
   // The index of the base of the expression stack.
-  int expression_base_index() { return local0_index() + local_count(); }
+  int expression_base_index() {
+    return local0_index() + local_count();
+  }
 
   // Convert a frame index into a frame pointer relative offset into the
   // actual stack.
@@ -547,7 +570,6 @@ class VirtualFrame : public ZoneObject {
   friend class JumpTarget;
 };
 
-
 } }  // namespace v8::internal
 
 #endif  // V8_IA32_VIRTUAL_FRAME_IA32_H_
index a9d7770..8168dd0 100644 (file)
@@ -81,17 +81,12 @@ void JumpTarget::ComputeEntryFrame() {
   // frame.
   for (int i = 0; i < length; i++) {
     FrameElement element = initial_frame->elements_[i];
-    // We do not allow copies or constants in bidirectional frames.  All
-    // elements above the water mark on bidirectional frames have
-    // unknown static types.
+    // We do not allow copies or constants in bidirectional frames.
     if (direction_ == BIDIRECTIONAL) {
       if (element.is_constant() || element.is_copy()) {
         elements.Add(NULL);
         continue;
       }
-      // It's safe to change the static type on the initial frame
-      // element, see comment in JumpTarget::Combine.
-      initial_frame->elements_[i].set_static_type(StaticType::unknown());
     }
     elements.Add(&initial_frame->elements_[i]);
   }
@@ -142,18 +137,12 @@ void JumpTarget::ComputeEntryFrame() {
   for (int i = length - 1; i >= 0; i--) {
     if (elements[i] == NULL) {
       // Loop over all the reaching frames to check whether the element
-      // is synced on all frames, to count the registers it occupies,
-      // and to compute a merged static type.
+      // is synced on all frames and to count the registers it occupies.
       bool is_synced = true;
       RegisterFile candidate_registers;
       int best_count = kMinInt;
       int best_reg_num = RegisterAllocator::kInvalidRegister;
 
-      StaticType type;  // Initially invalid.
-      if (direction_ != BIDIRECTIONAL) {
-        type = reaching_frames_[0]->elements_[i].static_type();
-      }
-
       for (int j = 0; j < reaching_frames_.length(); j++) {
         FrameElement element = reaching_frames_[j]->elements_[i];
         is_synced = is_synced && element.is_synced();
@@ -167,7 +156,6 @@ void JumpTarget::ComputeEntryFrame() {
             best_reg_num = num;
           }
         }
-        type = type.merge(element.static_type());
       }
 
       // If the value is synced on all frames, put it in memory.  This
@@ -175,7 +163,6 @@ void JumpTarget::ComputeEntryFrame() {
       // memory-to-register move when the value is needed later.
       if (is_synced) {
         // Already recorded as a memory element.
-        entry_frame_->elements_[i].set_static_type(type);
         continue;
       }
 
@@ -190,20 +177,15 @@ void JumpTarget::ComputeEntryFrame() {
         }
       }
 
-      if (best_reg_num == RegisterAllocator::kInvalidRegister) {
-        // If there was no register found, the element is already
-        // recorded as in memory.
-        entry_frame_->elements_[i].set_static_type(type);
-      } else {
+      if (best_reg_num != RegisterAllocator::kInvalidRegister) {
         // If there was a register choice, use it.  Preserve the copied
-        // flag on the element.  Set the static type as computed.
+        // flag on the element.
         bool is_copied = entry_frame_->elements_[i].is_copied();
         Register reg = RegisterAllocator::ToRegister(best_reg_num);
         entry_frame_->elements_[i] =
             FrameElement::RegisterElement(reg,
                                           FrameElement::NOT_SYNCED);
         if (is_copied) entry_frame_->elements_[i].set_copied();
-        entry_frame_->elements_[i].set_static_type(type);
         entry_frame_->set_register_location(reg, i);
       }
     }
index 2599232..d1b08bb 100644 (file)
@@ -40,18 +40,7 @@ namespace internal {
 Result::Result(Register reg) {
   ASSERT(reg.is_valid() && !RegisterAllocator::IsReserved(reg));
   CodeGeneratorScope::Current()->allocator()->Use(reg);
-  value_ = StaticTypeField::encode(StaticType::UNKNOWN_TYPE)
-      | TypeField::encode(REGISTER)
-      | DataField::encode(reg.code_);
-}
-
-
-Result::Result(Register reg, StaticType type) {
-  ASSERT(reg.is_valid() && !RegisterAllocator::IsReserved(reg));
-  CodeGeneratorScope::Current()->allocator()->Use(reg);
-  value_ = StaticTypeField::encode(type.static_type_)
-      | TypeField::encode(REGISTER)
-      | DataField::encode(reg.code_);
+  value_ = TypeField::encode(REGISTER) | DataField::encode(reg.code_);
 }
 
 
index c539191..f7167d9 100644 (file)
@@ -45,80 +45,6 @@ namespace internal {
 
 
 // -------------------------------------------------------------------------
-// StaticType
-//
-// StaticType represent the type of an expression or a word at runtime.
-// The types are ordered by knowledge, so that if a value can come about
-// in more than one way, and there are different static types inferred
-// for the different ways, the types can be combined to a type that we
-// are still certain of (possibly just "unknown").
-
-class StaticType BASE_EMBEDDED {
- public:
-  StaticType() : static_type_(UNKNOWN_TYPE) {}
-
-  static StaticType unknown() { return StaticType(); }
-  static StaticType smi() { return StaticType(SMI_TYPE); }
-  static StaticType jsstring() { return StaticType(STRING_TYPE); }
-  static StaticType heap_object() { return StaticType(HEAP_OBJECT_TYPE); }
-
-  // Accessors
-  bool is_unknown() { return static_type_ == UNKNOWN_TYPE; }
-  bool is_smi() { return static_type_ == SMI_TYPE; }
-  bool is_heap_object() { return (static_type_ & HEAP_OBJECT_TYPE) != 0; }
-  bool is_jsstring() { return static_type_ == STRING_TYPE; }
-
-  bool operator==(StaticType other) const {
-    return static_type_ == other.static_type_;
-  }
-
-  // Find the best approximating type for a value.
-  // The argument must not be NULL.
-  static StaticType TypeOf(Object* object) {
-    // Remember to make the most specific tests first. A string is also a heap
-    // object, so test for string-ness first.
-    if (object->IsSmi()) return smi();
-    if (object->IsString()) return jsstring();
-    if (object->IsHeapObject()) return heap_object();
-    return unknown();
-  }
-
-  // Merges two static types to a type that combines the knowledge
-  // of both. If there is no way to combine (e.g., being a string *and*
-  // being a smi), the resulting type is unknown.
-  StaticType merge(StaticType other) {
-    StaticType x(
-        static_cast<StaticTypeEnum>(static_type_ & other.static_type_));
-    return x;
-  }
-
- private:
-  enum StaticTypeEnum {
-    // Numbers are chosen so that least upper bound of the following
-    // partial order is implemented by bitwise "and":
-    //
-    //    string
-    //       |
-    //    heap-object    smi
-    //           \       /
-    //            unknown
-    //
-    UNKNOWN_TYPE     = 0x00,
-    SMI_TYPE         = 0x01,
-    HEAP_OBJECT_TYPE = 0x02,
-    STRING_TYPE      = 0x04 | HEAP_OBJECT_TYPE
-  };
-  explicit StaticType(StaticTypeEnum static_type) : static_type_(static_type) {}
-
-  // StaticTypeEnum static_type_;
-  StaticTypeEnum static_type_;
-
-  friend class FrameElement;
-  friend class Result;
-};
-
-
-// -------------------------------------------------------------------------
 // Results
 //
 // Results encapsulate the compile-time values manipulated by the code
@@ -138,13 +64,9 @@ class Result BASE_EMBEDDED {
   // Construct a register Result.
   explicit Result(Register reg);
 
-  // Construct a register Result with a known static type.
-  Result(Register reg, StaticType static_type);
-
   // Construct a Result whose value is a compile-time constant.
   explicit Result(Handle<Object> value) {
-    value_ = StaticTypeField::encode(StaticType::TypeOf(*value).static_type_)
-        | TypeField::encode(CONSTANT)
+    value_ = TypeField::encode(CONSTANT)
         | DataField::encode(ConstantList()->length());
     ConstantList()->Add(value);
   }
@@ -182,15 +104,6 @@ class Result BASE_EMBEDDED {
 
   inline void Unuse();
 
-  StaticType static_type() const {
-    return StaticType(StaticTypeField::decode(value_));
-  }
-
-  void set_static_type(StaticType type) {
-    value_ = value_ & ~StaticTypeField::mask();
-    value_ = value_ | StaticTypeField::encode(type.static_type_);
-  }
-
   Type type() const { return TypeField::decode(value_); }
 
   void invalidate() { value_ = TypeField::encode(INVALID); }
@@ -225,9 +138,8 @@ class Result BASE_EMBEDDED {
  private:
   uint32_t value_;
 
-  class StaticTypeField: public BitField<StaticType::StaticTypeEnum, 0, 3> {};
-  class TypeField: public BitField<Type, 3, 2> {};
-  class DataField: public BitField<uint32_t, 5, 32 - 6> {};
+  class TypeField: public BitField<Type, 0, 2> {};
+  class DataField: public BitField<uint32_t, 2, 32 - 3> {};
 
   inline void CopyTo(Result* destination) const;
 
index 39dbf17..44e5fae 100644 (file)
@@ -73,7 +73,6 @@ FrameElement VirtualFrame::CopyElementAt(int index) {
     case FrameElement::MEMORY:  // Fall through.
     case FrameElement::REGISTER:
       // All copies are backed by memory or register locations.
-      result.set_static_type(target.static_type());
       result.set_type(FrameElement::COPY);
       result.clear_copied();
       result.clear_sync();
@@ -153,7 +152,6 @@ void VirtualFrame::SpillElementAt(int index) {
   if (elements_[index].is_register()) {
     Unuse(elements_[index].reg());
   }
-  new_element.set_static_type(elements_[index].static_type());
   elements_[index] = new_element;
 }
 
@@ -211,9 +209,6 @@ void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) {
       ASSERT(source.is_valid());
       elements_[i].clear_sync();
     }
-    // No code needs to be generated to change the static type of an
-    // element.
-    elements_[i].set_static_type(target.static_type());
   }
 }
 
@@ -246,11 +241,8 @@ void VirtualFrame::PrepareForCall(int spilled_args, int dropped_args) {
 void VirtualFrame::PrepareForReturn() {
   // Spill all locals. This is necessary to make sure all locals have
   // the right value when breaking at the return site in the debugger.
-  // Set their static type to unknown so that they will match the known
-  // return frame.
   for (int i = 0; i < expression_base_index(); i++) {
     SpillElementAt(i);
-    elements_[i].set_static_type(StaticType::unknown());
   }
 }
 
@@ -283,7 +275,6 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
       // register element, or the new element at frame_index, must be made
       // a copy.
       int i = register_location(value->reg());
-      ASSERT(value->static_type() == elements_[i].static_type());
 
       if (i < frame_index) {
         // The register FrameElement is lower in the frame than the new copy.
@@ -310,8 +301,7 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
       Use(value->reg(), frame_index);
       elements_[frame_index] =
           FrameElement::RegisterElement(value->reg(),
-                                        FrameElement::NOT_SYNCED,
-                                        value->static_type());
+                                        FrameElement::NOT_SYNCED);
     }
   } else {
     ASSERT(value->is_constant());
@@ -328,18 +318,16 @@ void VirtualFrame::PushFrameSlotAt(int index) {
 }
 
 
-void VirtualFrame::Push(Register reg, StaticType static_type) {
+void VirtualFrame::Push(Register reg) {
   if (is_used(reg)) {
     int index = register_location(reg);
     FrameElement element = CopyElementAt(index);
-    ASSERT(static_type.merge(element.static_type()) == element.static_type());
     elements_.Add(element);
   } else {
     Use(reg, element_count());
     FrameElement element =
         FrameElement::RegisterElement(reg,
-                                      FrameElement::NOT_SYNCED,
-                                      static_type);
+                                      FrameElement::NOT_SYNCED);
     elements_.Add(element);
   }
 }
index 53e5f72..95c0f73 100644 (file)
@@ -2368,15 +2368,15 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
   Result left = frame_->Pop();
 
   if (op == Token::ADD) {
-    bool left_is_string = left.static_type().is_jsstring();
-    bool right_is_string = right.static_type().is_jsstring();
+    bool left_is_string = left.is_constant() && left.handle()->IsString();
+    bool right_is_string = right.is_constant() && right.handle()->IsString();
     if (left_is_string || right_is_string) {
       frame_->Push(&left);
       frame_->Push(&right);
       Result answer;
       if (left_is_string) {
         if (right_is_string) {
-          // TODO(lrn): if (left.is_constant() && right.is_constant())
+          // TODO(lrn): if both are constant strings
           // -- do a compile time cons, if allocation during codegen is allowed.
           answer = frame_->CallRuntime(Runtime::kStringAdd, 2);
         } else {
@@ -2387,7 +2387,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
         answer =
           frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2);
       }
-      answer.set_static_type(StaticType::jsstring());
       frame_->Push(&answer);
       return;
     }
index e0b16e6..f86e75f 100644 (file)
@@ -432,8 +432,7 @@ void VirtualFrame::MakeMergable() {
           }
         }
       }
-      // No need to set the copied flag---there are no copies.
-      elements_[i].set_static_type(StaticType::unknown());
+      // No need to set the copied flag --- there are no copies.
     } else {
       // Clear the copy flag of non-constant, non-copy elements.
       // They cannot be copied because copies are not allowed.
@@ -651,7 +650,6 @@ Result VirtualFrame::Pop() {
     if (element.is_memory()) {
       Result temp = cgen()->allocator()->Allocate();
       ASSERT(temp.is_valid());
-      temp.set_static_type(element.static_type());
       __ pop(temp.reg());
       return temp;
     }
@@ -683,12 +681,11 @@ Result VirtualFrame::Pop() {
         FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED);
     // Preserve the copy flag on the element.
     if (element.is_copied()) new_element.set_copied();
-    new_element.set_static_type(element.static_type());
     elements_[index] = new_element;
     __ movq(temp.reg(), Operand(rbp, fp_relative(index)));
-    return Result(temp.reg(), element.static_type());
+    return Result(temp.reg());
   } else if (element.is_register()) {
-    return Result(element.reg(), element.static_type());
+    return Result(element.reg());
   } else {
     ASSERT(element.is_constant());
     return Result(element.handle());
index d0aa26f..b7d5a31 100644 (file)
@@ -378,7 +378,7 @@ class VirtualFrame : public ZoneObject {
   void EmitPush(Immediate immediate);
 
   // Push an element on the virtual frame.
-  void Push(Register reg, StaticType static_type = StaticType());
+  void Push(Register reg);
   void Push(Handle<Object> value);
   void Push(Smi* value) { Push(Handle<Object>(value)); }
 
@@ -386,7 +386,7 @@ class VirtualFrame : public ZoneObject {
   // frame).
   void Push(Result* result) {
     if (result->is_register()) {
-      Push(result->reg(), result->static_type());
+      Push(result->reg());
     } else {
       ASSERT(result->is_constant());
       Push(result->handle());