Upstream version 10.39.233.0
[platform/framework/web/crosswalk.git] / src / v8 / src / lithium.h
index 8aeebe6..d2e4ff1 100644 (file)
@@ -8,6 +8,7 @@
 #include <set>
 
 #include "src/allocation.h"
+#include "src/bailout-reason.h"
 #include "src/hydrogen.h"
 #include "src/safepoint-table.h"
 #include "src/zone-allocator.h"
 namespace v8 {
 namespace internal {
 
-#define LITHIUM_OPERAND_LIST(V)               \
-  V(ConstantOperand, CONSTANT_OPERAND,  128)  \
-  V(StackSlot,       STACK_SLOT,        128)  \
-  V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128)  \
-  V(Register,        REGISTER,          16)   \
-  V(DoubleRegister,  DOUBLE_REGISTER,   16)
-
+#define LITHIUM_OPERAND_LIST(V)                     \
+  V(ConstantOperand,    CONSTANT_OPERAND,     128)  \
+  V(StackSlot,          STACK_SLOT,           128)  \
+  V(DoubleStackSlot,    DOUBLE_STACK_SLOT,    128)  \
+  V(Float32x4StackSlot, FLOAT32x4_STACK_SLOT, 128)  \
+  V(Float64x2StackSlot, FLOAT64x2_STACK_SLOT, 128)  \
+  V(Int32x4StackSlot,   INT32x4_STACK_SLOT,   128)  \
+  V(Register,           REGISTER,             16)   \
+  V(DoubleRegister,     DOUBLE_REGISTER,      16)   \
+  V(Float32x4Register,  FLOAT32x4_REGISTER,   16)   \
+  V(Float64x2Register,  FLOAT64x2_REGISTER,   16)   \
+  V(Int32x4Register,    INT32x4_REGISTER,     16)
 
 class LOperand : public ZoneObject {
  public:
@@ -31,8 +37,14 @@ class LOperand : public ZoneObject {
     CONSTANT_OPERAND,
     STACK_SLOT,
     DOUBLE_STACK_SLOT,
+    FLOAT32x4_STACK_SLOT,
+    FLOAT64x2_STACK_SLOT,
+    INT32x4_STACK_SLOT,
     REGISTER,
-    DOUBLE_REGISTER
+    DOUBLE_REGISTER,
+    FLOAT32x4_REGISTER,
+    FLOAT64x2_REGISTER,
+    INT32x4_REGISTER
   };
 
   LOperand() : value_(KindField::encode(INVALID)) { }
@@ -45,13 +57,26 @@ class LOperand : public ZoneObject {
   LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
   LITHIUM_OPERAND_PREDICATE(Ignored, INVALID, 0)
 #undef LITHIUM_OPERAND_PREDICATE
-  bool Equals(LOperand* other) const { return value_ == other->value_; }
+  bool IsSIMD128Register() const {
+    return kind() == FLOAT32x4_REGISTER || kind() == FLOAT64x2_REGISTER ||
+           kind() == INT32x4_REGISTER;
+  }
+  bool IsSIMD128StackSlot() const {
+    return kind() == FLOAT32x4_STACK_SLOT || kind() == FLOAT64x2_STACK_SLOT ||
+           kind() == INT32x4_STACK_SLOT;
+  }
+  bool Equals(LOperand* other) const {
+    return value_ == other->value_ || (index() == other->index() &&
+        ((IsSIMD128Register() && other->IsSIMD128Register()) ||
+         (IsSIMD128StackSlot() && other->IsSIMD128StackSlot())));
+  }
 
   void PrintTo(StringStream* stream);
   void ConvertTo(Kind kind, int index) {
+    if (kind == REGISTER) DCHECK(index >= 0);
     value_ = KindField::encode(kind);
     value_ |= index << kKindFieldWidth;
-    ASSERT(this->index() == index);
+    DCHECK(this->index() == index);
   }
 
   // Calls SetUpCache()/TearDownCache() for each subclass.
@@ -59,7 +84,7 @@ class LOperand : public ZoneObject {
   static void TearDownCaches();
 
  protected:
-  static const int kKindFieldWidth = 3;
+  static const int kKindFieldWidth = 4;
   class KindField : public BitField<Kind, 0, kKindFieldWidth> { };
 
   LOperand(Kind kind, int index) { ConvertTo(kind, index); }
@@ -107,14 +132,14 @@ class LUnallocated : public LOperand {
   }
 
   LUnallocated(BasicPolicy policy, int index) : LOperand(UNALLOCATED, 0) {
-    ASSERT(policy == FIXED_SLOT);
+    DCHECK(policy == FIXED_SLOT);
     value_ |= BasicPolicyField::encode(policy);
     value_ |= index << FixedSlotIndexField::kShift;
-    ASSERT(this->fixed_slot_index() == index);
+    DCHECK(this->fixed_slot_index() == index);
   }
 
   LUnallocated(ExtendedPolicy policy, int index) : LOperand(UNALLOCATED, 0) {
-    ASSERT(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER);
+    DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER);
     value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
     value_ |= ExtendedPolicyField::encode(policy);
     value_ |= LifetimeField::encode(USED_AT_END);
@@ -135,7 +160,7 @@ class LUnallocated : public LOperand {
   }
 
   static LUnallocated* cast(LOperand* op) {
-    ASSERT(op->IsUnallocated());
+    DCHECK(op->IsUnallocated());
     return reinterpret_cast<LUnallocated*>(op);
   }
 
@@ -144,32 +169,32 @@ class LUnallocated : public LOperand {
   // because it accommodates a larger pay-load.
   //
   // For FIXED_SLOT policy:
-  //     +------------------------------------------+
-  //     |       slot_index      |  vreg  | 0 | 001 |
-  //     +------------------------------------------+
+  //     +-------------------------------------------+
+  //     |       slot_index      |  vreg  | 0 | 0001 |
+  //     +-------------------------------------------+
   //
   // For all other (extended) policies:
-  //     +------------------------------------------+
-  //     |  reg_index  | L | PPP |  vreg  | 1 | 001 |    L ... Lifetime
-  //     +------------------------------------------+    P ... Policy
+  //     +-------------------------------------------+
+  //     |  reg_index  | L | PPP |  vreg  | 1 | 0001 |    L ... Lifetime
+  //     +-------------------------------------------+    P ... Policy
   //
   // The slot index is a signed value which requires us to decode it manually
   // instead of using the BitField utility class.
 
   // The superclass has a KindField.
-  STATIC_ASSERT(kKindFieldWidth == 3);
+  STATIC_ASSERT(kKindFieldWidth == 4);
 
   // BitFields for all unallocated operands.
-  class BasicPolicyField     : public BitField<BasicPolicy,     3,  1> {};
-  class VirtualRegisterField : public BitField<unsigned,        4, 18> {};
+  class BasicPolicyField     : public BitField<BasicPolicy,     4,  1> {};
+  class VirtualRegisterField : public BitField<unsigned,        5, 18> {};
 
   // BitFields specific to BasicPolicy::FIXED_SLOT.
-  class FixedSlotIndexField  : public BitField<int,            22, 10> {};
+  class FixedSlotIndexField  : public BitField<int,            23,  9> {};
 
   // BitFields specific to BasicPolicy::EXTENDED_POLICY.
-  class ExtendedPolicyField  : public BitField<ExtendedPolicy, 22,  3> {};
-  class LifetimeField        : public BitField<Lifetime,       25,  1> {};
-  class FixedRegisterField   : public BitField<int,            26,  6> {};
+  class ExtendedPolicyField  : public BitField<ExtendedPolicy, 23,  3> {};
+  class LifetimeField        : public BitField<Lifetime,       26,  1> {};
+  class FixedRegisterField   : public BitField<int,            27,  5> {};
 
   static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1;
   static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize;
@@ -222,19 +247,19 @@ class LUnallocated : public LOperand {
 
   // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy.
   ExtendedPolicy extended_policy() const {
-    ASSERT(basic_policy() == EXTENDED_POLICY);
+    DCHECK(basic_policy() == EXTENDED_POLICY);
     return ExtendedPolicyField::decode(value_);
   }
 
   // [fixed_slot_index]: Only for FIXED_SLOT.
   int fixed_slot_index() const {
-    ASSERT(HasFixedSlotPolicy());
+    DCHECK(HasFixedSlotPolicy());
     return static_cast<int>(value_) >> FixedSlotIndexField::kShift;
   }
 
   // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER.
   int fixed_register_index() const {
-    ASSERT(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy());
+    DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy());
     return FixedRegisterField::decode(value_);
   }
 
@@ -248,13 +273,13 @@ class LUnallocated : public LOperand {
 
   // [lifetime]: Only for non-FIXED_SLOT.
   bool IsUsedAtStart() {
-    ASSERT(basic_policy() == EXTENDED_POLICY);
+    DCHECK(basic_policy() == EXTENDED_POLICY);
     return LifetimeField::decode(value_) == USED_AT_START;
   }
 };
 
 
-class LMoveOperands V8_FINAL BASE_EMBEDDED {
+class LMoveOperands FINAL BASE_EMBEDDED {
  public:
   LMoveOperands(LOperand* source, LOperand* destination)
       : source_(source), destination_(destination) {
@@ -278,9 +303,10 @@ class LMoveOperands V8_FINAL BASE_EMBEDDED {
   }
 
   // A move is redundant if it's been eliminated, if its source and
-  // destination are the same, or if its destination is unneeded.
+  // destination are the same, or if its destination is unneeded or constant.
   bool IsRedundant() const {
-    return IsEliminated() || source_->Equals(destination_) || IsIgnored();
+    return IsEliminated() || source_->Equals(destination_) || IsIgnored() ||
+           (destination_ != NULL && destination_->IsConstantOperand());
   }
 
   bool IsIgnored() const {
@@ -290,7 +316,7 @@ class LMoveOperands V8_FINAL BASE_EMBEDDED {
   // We clear both operands to indicate move that's been eliminated.
   void Eliminate() { source_ = destination_ = NULL; }
   bool IsEliminated() const {
-    ASSERT(source_ != NULL || destination_ == NULL);
+    DCHECK(source_ != NULL || destination_ == NULL);
     return source_ == NULL;
   }
 
@@ -301,16 +327,16 @@ class LMoveOperands V8_FINAL BASE_EMBEDDED {
 
 
 template<LOperand::Kind kOperandKind, int kNumCachedOperands>
-class LSubKindOperand V8_FINAL : public LOperand {
+class LSubKindOperand FINAL : public LOperand {
  public:
   static LSubKindOperand* Create(int index, Zone* zone) {
-    ASSERT(index >= 0);
+    DCHECK(index >= 0);
     if (index < kNumCachedOperands) return &cache[index];
     return new(zone) LSubKindOperand(index);
   }
 
   static LSubKindOperand* cast(LOperand* op) {
-    ASSERT(op->kind() == kOperandKind);
+    DCHECK(op->kind() == kOperandKind);
     return reinterpret_cast<LSubKindOperand*>(op);
   }
 
@@ -331,7 +357,7 @@ LITHIUM_OPERAND_LIST(LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS)
 #undef LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS
 
 
-class LParallelMove V8_FINAL : public ZoneObject {
+class LParallelMove FINAL : public ZoneObject {
  public:
   explicit LParallelMove(Zone* zone) : move_operands_(4, zone) { }
 
@@ -341,9 +367,7 @@ class LParallelMove V8_FINAL : public ZoneObject {
 
   bool IsRedundant() const;
 
-  const ZoneList<LMoveOperands>* move_operands() const {
-    return &move_operands_;
-  }
+  ZoneList<LMoveOperands>* move_operands() { return &move_operands_; }
 
   void PrintDataTo(StringStream* stream) const;
 
@@ -352,7 +376,7 @@ class LParallelMove V8_FINAL : public ZoneObject {
 };
 
 
-class LPointerMap V8_FINAL : public ZoneObject {
+class LPointerMap FINAL : public ZoneObject {
  public:
   explicit LPointerMap(Zone* zone)
       : pointer_operands_(8, zone),
@@ -369,7 +393,7 @@ class LPointerMap V8_FINAL : public ZoneObject {
   int lithium_position() const { return lithium_position_; }
 
   void set_lithium_position(int pos) {
-    ASSERT(lithium_position_ == -1);
+    DCHECK(lithium_position_ == -1);
     lithium_position_ = pos;
   }
 
@@ -385,7 +409,7 @@ class LPointerMap V8_FINAL : public ZoneObject {
 };
 
 
-class LEnvironment V8_FINAL : public ZoneObject {
+class LEnvironment FINAL : public ZoneObject {
  public:
   LEnvironment(Handle<JSFunction> closure,
                FrameType frame_type,
@@ -436,7 +460,7 @@ class LEnvironment V8_FINAL : public ZoneObject {
                 bool is_uint32) {
     values_.Add(operand, zone());
     if (representation.IsSmiOrTagged()) {
-      ASSERT(!is_uint32);
+      DCHECK(!is_uint32);
       is_tagged_.Add(values_.length() - 1, zone());
     }
 
@@ -467,17 +491,17 @@ class LEnvironment V8_FINAL : public ZoneObject {
   }
 
   int ObjectDuplicateOfAt(int index) {
-    ASSERT(ObjectIsDuplicateAt(index));
+    DCHECK(ObjectIsDuplicateAt(index));
     return LengthOrDupeField::decode(object_mapping_[index]);
   }
 
   int ObjectLengthAt(int index) {
-    ASSERT(!ObjectIsDuplicateAt(index));
+    DCHECK(!ObjectIsDuplicateAt(index));
     return LengthOrDupeField::decode(object_mapping_[index]);
   }
 
   bool ObjectIsArgumentsAt(int index) {
-    ASSERT(!ObjectIsDuplicateAt(index));
+    DCHECK(!ObjectIsDuplicateAt(index));
     return IsArgumentsField::decode(object_mapping_[index]);
   }
 
@@ -488,7 +512,7 @@ class LEnvironment V8_FINAL : public ZoneObject {
   void Register(int deoptimization_index,
                 int translation_index,
                 int pc_offset) {
-    ASSERT(!HasBeenRegistered());
+    DCHECK(!HasBeenRegistered());
     deoptimization_index_ = deoptimization_index;
     translation_index_ = translation_index;
     pc_offset_ = pc_offset;
@@ -535,7 +559,7 @@ class LEnvironment V8_FINAL : public ZoneObject {
 
 
 // Iterates over the non-null, non-constant operands in an environment.
-class ShallowIterator V8_FINAL BASE_EMBEDDED {
+class ShallowIterator FINAL BASE_EMBEDDED {
  public:
   explicit ShallowIterator(LEnvironment* env)
       : env_(env),
@@ -547,13 +571,13 @@ class ShallowIterator V8_FINAL BASE_EMBEDDED {
   bool Done() { return current_ >= limit_; }
 
   LOperand* Current() {
-    ASSERT(!Done());
-    ASSERT(env_->values()->at(current_) != NULL);
+    DCHECK(!Done());
+    DCHECK(env_->values()->at(current_) != NULL);
     return env_->values()->at(current_);
   }
 
   void Advance() {
-    ASSERT(!Done());
+    DCHECK(!Done());
     ++current_;
     SkipUninteresting();
   }
@@ -579,7 +603,7 @@ class ShallowIterator V8_FINAL BASE_EMBEDDED {
 
 
 // Iterator for non-null, non-constant operands incl. outer environments.
-class DeepIterator V8_FINAL BASE_EMBEDDED {
+class DeepIterator FINAL BASE_EMBEDDED {
  public:
   explicit DeepIterator(LEnvironment* env)
       : current_iterator_(env) {
@@ -589,8 +613,8 @@ class DeepIterator V8_FINAL BASE_EMBEDDED {
   bool Done() { return current_iterator_.Done(); }
 
   LOperand* Current() {
-    ASSERT(!current_iterator_.Done());
-    ASSERT(current_iterator_.Current() != NULL);
+    DCHECK(!current_iterator_.Done());
+    DCHECK(current_iterator_.Current() != NULL);
     return current_iterator_.Current();
   }
 
@@ -651,16 +675,16 @@ class LChunk : public ZoneObject {
   }
 
   void AddDeprecationDependency(Handle<Map> map) {
-    ASSERT(!map->is_deprecated());
+    DCHECK(!map->is_deprecated());
     if (!map->CanBeDeprecated()) return;
-    ASSERT(!info_->IsStub());
+    DCHECK(!info_->IsStub());
     deprecation_dependencies_.insert(map);
   }
 
   void AddStabilityDependency(Handle<Map> map) {
-    ASSERT(map->is_stable());
+    DCHECK(map->is_stable());
     if (!map->CanTransition()) return;
-    ASSERT(!info_->IsStub());
+    DCHECK(!info_->IsStub());
     stability_dependencies_.insert(map);
   }
 
@@ -698,13 +722,34 @@ class LChunk : public ZoneObject {
 
 class LChunkBuilderBase BASE_EMBEDDED {
  public:
-  explicit LChunkBuilderBase(Zone* zone)
+  explicit LChunkBuilderBase(CompilationInfo* info, HGraph* graph)
       : argument_count_(0),
-        zone_(zone) { }
+        chunk_(NULL),
+        info_(info),
+        graph_(graph),
+        status_(UNUSED),
+        zone_(graph->zone()) {}
 
   virtual ~LChunkBuilderBase() { }
 
+  void Abort(BailoutReason reason);
+  void Retry(BailoutReason reason);
+
  protected:
+  enum Status { UNUSED, BUILDING, DONE, ABORTED };
+
+  LPlatformChunk* chunk() const { return chunk_; }
+  CompilationInfo* info() const { return info_; }
+  HGraph* graph() const { return graph_; }
+  int argument_count() const { return argument_count_; }
+  Isolate* isolate() const { return graph_->isolate(); }
+  Heap* heap() const { return isolate()->heap(); }
+
+  bool is_unused() const { return status_ == UNUSED; }
+  bool is_building() const { return status_ == BUILDING; }
+  bool is_done() const { return status_ == DONE; }
+  bool is_aborted() const { return status_ == ABORTED; }
+
   // An input operand in register, stack slot or a constant operand.
   // Will not be moved to a register even if one is freely available.
   virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) = 0;
@@ -719,6 +764,10 @@ class LChunkBuilderBase BASE_EMBEDDED {
   Zone* zone() const { return zone_; }
 
   int argument_count_;
+  LPlatformChunk* chunk_;
+  CompilationInfo* info_;
+  HGraph* const graph_;
+  Status status_;
 
  private:
   Zone* zone_;
@@ -747,6 +796,63 @@ class LPhase : public CompilationPhase {
 };
 
 
+// A register-allocator view of a Lithium instruction. It contains the id of
+// the output operand and a list of input operand uses.
+enum RegisterKind {
+  UNALLOCATED_REGISTERS,
+  GENERAL_REGISTERS,
+  DOUBLE_REGISTERS,
+  FLOAT32x4_REGISTERS,
+  FLOAT64x2_REGISTERS,
+  INT32x4_REGISTERS
+};
+
+// Iterator for non-null temp operands.
+class TempIterator BASE_EMBEDDED {
+ public:
+  inline explicit TempIterator(LInstruction* instr);
+  inline bool Done();
+  inline LOperand* Current();
+  inline void Advance();
+
+ private:
+  inline void SkipUninteresting();
+  LInstruction* instr_;
+  int limit_;
+  int current_;
+};
+
+
+// Iterator for non-constant input operands.
+class InputIterator BASE_EMBEDDED {
+ public:
+  inline explicit InputIterator(LInstruction* instr);
+  inline bool Done();
+  inline LOperand* Current();
+  inline void Advance();
+
+ private:
+  inline void SkipUninteresting();
+  LInstruction* instr_;
+  int limit_;
+  int current_;
+};
+
+
+class UseIterator BASE_EMBEDDED {
+ public:
+  inline explicit UseIterator(LInstruction* instr);
+  inline bool Done();
+  inline LOperand* Current();
+  inline void Advance();
+
+ private:
+  InputIterator input_iterator_;
+  DeepIterator env_iterator_;
+};
+
+class LInstruction;
+class LCodeGen;
 } }  // namespace v8::internal
 
 #endif  // V8_LITHIUM_H_