13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
49fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5086aeeaae12517475c22695a200be45495516549Ben Murdoch#ifndef V8_LITHIUM_H_
6086aeeaae12517475c22695a200be45495516549Ben Murdoch#define V8_LITHIUM_H_
79fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <set>
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bailout-reason.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/safepoint-table.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/zone-allocator.h"
159fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
16086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace v8 {
17086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace internal {
189fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_OPERAND_LIST(V)               \
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ConstantOperand, CONSTANT_OPERAND,  128)  \
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StackSlot,       STACK_SLOT,        128)  \
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128)  \
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Register,        REGISTER,          16)   \
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DoubleRegister,  DOUBLE_REGISTER,   16)
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LOperand : public ZoneObject {
271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  enum Kind {
291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    INVALID,
301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    UNALLOCATED,
311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CONSTANT_OPERAND,
321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    STACK_SLOT,
331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    DOUBLE_STACK_SLOT,
341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    REGISTER,
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DOUBLE_REGISTER
361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  };
371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand() : value_(KindField::encode(INVALID)) { }
391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Kind kind() const { return KindField::decode(value_); }
411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int index() const { return static_cast<int>(value_) >> kKindFieldWidth; }
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_OPERAND_PREDICATE(name, type, number) \
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Is##name() const { return kind() == type; }
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_PREDICATE)
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LITHIUM_OPERAND_PREDICATE(Ignored, INVALID, 0)
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef LITHIUM_OPERAND_PREDICATE
481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool Equals(LOperand* other) const { return value_ == other->value_; }
491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void PrintTo(StringStream* stream);
511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void ConvertTo(Kind kind, int index) {
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kind == REGISTER) DCHECK(index >= 0);
531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    value_ = KindField::encode(kind);
541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    value_ |= index << kKindFieldWidth;
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this->index() == index);
561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Calls SetUpCache()/TearDownCache() for each subclass.
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void SetUpCaches();
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void TearDownCaches();
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kKindFieldWidth = 3;
641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  class KindField : public BitField<Kind, 0, kKindFieldWidth> { };
651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand(Kind kind, int index) { ConvertTo(kind, index); }
671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  unsigned value_;
691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LUnallocated : public LOperand {
731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum BasicPolicy {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FIXED_SLOT,
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXTENDED_POLICY
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum ExtendedPolicy {
801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    NONE,
811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    ANY,
821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    FIXED_REGISTER,
831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    FIXED_DOUBLE_REGISTER,
841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    MUST_HAVE_REGISTER,
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MUST_HAVE_DOUBLE_REGISTER,
861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    WRITABLE_REGISTER,
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SAME_AS_FIRST_INPUT
881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  };
891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Lifetime of operand inside the instruction.
911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  enum Lifetime {
921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // USED_AT_START operand is guaranteed to be live only at
931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // instruction start. Register allocator is free to assign the same register
941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // to some other operand used inside instruction (i.e. temporary or
951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // output).
961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    USED_AT_START,
971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // USED_AT_END operand is treated as live until the end of
991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // instruction. This means that register allocator will not reuse it's
1001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // register for any other operand inside instruction.
1011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    USED_AT_END
1021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  };
1031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LUnallocated(ExtendedPolicy policy) : LOperand(UNALLOCATED, 0) {
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= ExtendedPolicyField::encode(policy);
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= LifetimeField::encode(USED_AT_END);
1081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LUnallocated(BasicPolicy policy, int index) : LOperand(UNALLOCATED, 0) {
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(policy == FIXED_SLOT);
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(policy);
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= index << FixedSlotIndexField::kShift;
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this->fixed_slot_index() == index);
1151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LUnallocated(ExtendedPolicy policy, int index) : LOperand(UNALLOCATED, 0) {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER);
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= ExtendedPolicyField::encode(policy);
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= LifetimeField::encode(USED_AT_END);
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= FixedRegisterField::encode(index);
1231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LUnallocated(ExtendedPolicy policy, Lifetime lifetime)
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : LOperand(UNALLOCATED, 0) {
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= ExtendedPolicyField::encode(policy);
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= LifetimeField::encode(lifetime);
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LUnallocated* CopyUnconstrained(Zone* zone) {
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LUnallocated* result = new(zone) LUnallocated(ANY);
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->set_virtual_register(virtual_register());
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LUnallocated* cast(LOperand* op) {
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(op->IsUnallocated());
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<LUnallocated*>(op);
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The encoding used for LUnallocated operands depends on the policy that is
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // stored within the operand. The FIXED_SLOT policy uses a compact encoding
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // because it accommodates a larger pay-load.
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For FIXED_SLOT policy:
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //     +------------------------------------------+
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //     |       slot_index      |  vreg  | 0 | 001 |
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //     +------------------------------------------+
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all other (extended) policies:
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //     +------------------------------------------+
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //     |  reg_index  | L | PPP |  vreg  | 1 | 001 |    L ... Lifetime
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //     +------------------------------------------+    P ... Policy
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The slot index is a signed value which requires us to decode it manually
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instead of using the BitField utility class.
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The superclass has a KindField.
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kKindFieldWidth == 3);
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // BitFields for all unallocated operands.
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class BasicPolicyField     : public BitField<BasicPolicy,     3,  1> {};
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class VirtualRegisterField : public BitField<unsigned,        4, 18> {};
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // BitFields specific to BasicPolicy::FIXED_SLOT.
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class FixedSlotIndexField  : public BitField<int,            22, 10> {};
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // BitFields specific to BasicPolicy::EXTENDED_POLICY.
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class ExtendedPolicyField  : public BitField<ExtendedPolicy, 22,  3> {};
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class LifetimeField        : public BitField<Lifetime,       25,  1> {};
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class FixedRegisterField   : public BitField<int,            26,  6> {};
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1;
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize;
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1;
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1));
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Predicates for the operand policy.
1811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool HasAnyPolicy() const {
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == ANY;
1841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool HasFixedPolicy() const {
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == FIXED_SLOT ||
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == FIXED_REGISTER ||
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == FIXED_DOUBLE_REGISTER;
1891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool HasRegisterPolicy() const {
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY && (
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == WRITABLE_REGISTER ||
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == MUST_HAVE_REGISTER);
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasDoubleRegisterPolicy() const {
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == MUST_HAVE_DOUBLE_REGISTER;
1981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool HasSameAsInputPolicy() const {
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == SAME_AS_FIRST_INPUT;
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasFixedSlotPolicy() const {
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == FIXED_SLOT;
2051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasFixedRegisterPolicy() const {
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == FIXED_REGISTER;
2091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasFixedDoubleRegisterPolicy() const {
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == FIXED_DOUBLE_REGISTER;
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasWritableRegisterPolicy() const {
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extended_policy() == WRITABLE_REGISTER;
2171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [basic_policy]: Distinguish between FIXED_SLOT and all other policies.
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BasicPolicy basic_policy() const {
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return BasicPolicyField::decode(value_);
2221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy.
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExtendedPolicy extended_policy() const {
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(basic_policy() == EXTENDED_POLICY);
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ExtendedPolicyField::decode(value_);
2281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [fixed_slot_index]: Only for FIXED_SLOT.
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int fixed_slot_index() const {
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasFixedSlotPolicy());
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<int>(value_) >> FixedSlotIndexField::kShift;
2341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER.
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int fixed_register_index() const {
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy());
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return FixedRegisterField::decode(value_);
2401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [virtual_register]: The virtual register ID for this operand.
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int virtual_register() const {
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return VirtualRegisterField::decode(value_);
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_virtual_register(unsigned id) {
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ = VirtualRegisterField::update(value_, id);
2481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [lifetime]: Only for non-FIXED_SLOT.
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsUsedAtStart() {
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(basic_policy() == EXTENDED_POLICY);
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LifetimeField::decode(value_) == USED_AT_START;
2541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
2561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LMoveOperands FINAL BASE_EMBEDDED {
2591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
2601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LMoveOperands(LOperand* source, LOperand* destination)
2611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      : source_(source), destination_(destination) {
2621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* source() const { return source_; }
2651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void set_source(LOperand* operand) { source_ = operand; }
2661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* destination() const { return destination_; }
2681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void set_destination(LOperand* operand) { destination_ = operand; }
2691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // The gap resolver marks moves as "in-progress" by clearing the
2711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // destination (but not the source).
2721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsPending() const {
2731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return destination_ == NULL && source_ != NULL;
2741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // True if this move a move into the given destination operand.
2771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool Blocks(LOperand* operand) const {
2781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return !IsEliminated() && source()->Equals(operand);
2791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // A move is redundant if it's been eliminated, if its source and
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // destination are the same, or if its destination is unneeded or constant.
2831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsRedundant() const {
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsEliminated() || source_->Equals(destination_) || IsIgnored() ||
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           (destination_ != NULL && destination_->IsConstantOperand());
2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsIgnored() const {
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return destination_ != NULL && destination_->IsIgnored();
2901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // We clear both operands to indicate move that's been eliminated.
2931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Eliminate() { source_ = destination_ = NULL; }
2941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsEliminated() const {
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(source_ != NULL || destination_ == NULL);
2961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return source_ == NULL;
2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* source_;
3011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* destination_;
3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
3031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<LOperand::Kind kOperandKind, int kNumCachedOperands>
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LSubKindOperand FINAL : public LOperand {
3071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LSubKindOperand* Create(int index, Zone* zone) {
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 0);
3101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (index < kNumCachedOperands) return &cache[index];
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) LSubKindOperand(index);
3121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
3131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LSubKindOperand* cast(LOperand* op) {
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(op->kind() == kOperandKind);
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<LSubKindOperand*>(op);
3171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
3181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void SetUpCache();
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void TearDownCache();
3211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LSubKindOperand* cache;
3241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LSubKindOperand() : LOperand() { }
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LSubKindOperand(int index) : LOperand(kOperandKind, index) { }
3271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
3281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS(name, type, number)   \
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef LSubKindOperand<LOperand::type, number> L##name;
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLITHIUM_OPERAND_LIST(LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS)
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS
3341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LParallelMove FINAL : public ZoneObject {
337b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public:
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LParallelMove(Zone* zone) : move_operands_(4, zone) { }
339b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddMove(LOperand* from, LOperand* to, Zone* zone) {
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    move_operands_.Add(LMoveOperands(from, to), zone);
342b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
343b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
344b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool IsRedundant() const;
345b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<LMoveOperands>* move_operands() { return &move_operands_; }
3479fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
348b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void PrintDataTo(StringStream* stream) const;
349b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
350b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private:
351b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ZoneList<LMoveOperands> move_operands_;
352b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch};
353b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
354b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LPointerMap FINAL : public ZoneObject {
356086aeeaae12517475c22695a200be45495516549Ben Murdoch public:
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LPointerMap(Zone* zone)
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : pointer_operands_(8, zone),
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        untagged_operands_(0, zone),
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        lithium_position_(-1) { }
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const ZoneList<LOperand*>* GetNormalizedOperands() {
3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = 0; i < untagged_operands_.length(); ++i) {
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RemovePointer(untagged_operands_[i]);
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    untagged_operands_.Clear();
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return &pointer_operands_;
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
369b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int lithium_position() const { return lithium_position_; }
370b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
371b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void set_lithium_position(int pos) {
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(lithium_position_ == -1);
373b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    lithium_position_ = pos;
374b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
375b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordPointer(LOperand* op, Zone* zone);
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RemovePointer(LOperand* op);
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordUntagged(LOperand* op, Zone* zone);
379b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void PrintTo(StringStream* stream);
3809fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
381086aeeaae12517475c22695a200be45495516549Ben Murdoch private:
382b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ZoneList<LOperand*> pointer_operands_;
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<LOperand*> untagged_operands_;
384b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int lithium_position_;
385086aeeaae12517475c22695a200be45495516549Ben Murdoch};
386086aeeaae12517475c22695a200be45495516549Ben Murdoch
387086aeeaae12517475c22695a200be45495516549Ben Murdoch
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LEnvironment FINAL : public ZoneObject {
389b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public:
390b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LEnvironment(Handle<JSFunction> closure,
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               FrameType frame_type,
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               BailoutId ast_id,
393b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch               int parameter_count,
394b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch               int argument_count,
395b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch               int value_count,
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               LEnvironment* outer,
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               HEnterInlined* entry,
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               Zone* zone)
399b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      : closure_(closure),
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        frame_type_(frame_type),
401b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        arguments_stack_height_(argument_count),
402b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
403b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        translation_index_(-1),
404b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        ast_id_(ast_id),
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        translation_size_(value_count),
406b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        parameter_count_(parameter_count),
4072b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch        pc_offset_(-1),
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        values_(value_count, zone),
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        is_tagged_(value_count, zone),
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        is_uint32_(value_count, zone),
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object_mapping_(0, zone),
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        outer_(outer),
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        entry_(entry),
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        zone_(zone),
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        has_been_used_(false) { }
416b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
417b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Handle<JSFunction> closure() const { return closure_; }
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type() const { return frame_type_; }
419b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int arguments_stack_height() const { return arguments_stack_height_; }
420b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int deoptimization_index() const { return deoptimization_index_; }
421b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int translation_index() const { return translation_index_; }
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id() const { return ast_id_; }
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int translation_size() const { return translation_size_; }
424b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int parameter_count() const { return parameter_count_; }
4252b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  int pc_offset() const { return pc_offset_; }
426b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  const ZoneList<LOperand*>* values() const { return &values_; }
427b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LEnvironment* outer() const { return outer_; }
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry() { return entry_; }
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_been_used() const { return has_been_used_; }
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_has_been_used() { has_been_used_ = true; }
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddValue(LOperand* operand,
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Representation representation,
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                bool is_uint32) {
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.Add(operand, zone());
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (representation.IsSmiOrTagged()) {
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!is_uint32);
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_tagged_.Add(values_.length() - 1, zone());
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
442b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_uint32) {
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_uint32_.Add(values_.length() - 1, zone());
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
446b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
447b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
448b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool HasTaggedValueAt(int index) const {
4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return is_tagged_.Contains(index);
450b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
451b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasUint32ValueAt(int index) const {
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return is_uint32_.Contains(index);
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddNewObject(int length, bool is_arguments) {
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t encoded = LengthOrDupeField::encode(length) |
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       IsArgumentsField::encode(is_arguments) |
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       IsDuplicateField::encode(false);
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object_mapping_.Add(encoded, zone());
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddDuplicateObject(int dupe_of) {
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t encoded = LengthOrDupeField::encode(dupe_of) |
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       IsDuplicateField::encode(true);
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object_mapping_.Add(encoded, zone());
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int ObjectDuplicateOfAt(int index) {
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(ObjectIsDuplicateAt(index));
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LengthOrDupeField::decode(object_mapping_[index]);
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int ObjectLengthAt(int index) {
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!ObjectIsDuplicateAt(index));
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LengthOrDupeField::decode(object_mapping_[index]);
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ObjectIsArgumentsAt(int index) {
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!ObjectIsDuplicateAt(index));
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsArgumentsField::decode(object_mapping_[index]);
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ObjectIsDuplicateAt(int index) {
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsDuplicateField::decode(object_mapping_[index]);
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4882b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void Register(int deoptimization_index,
4892b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                int translation_index,
4902b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                int pc_offset) {
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!HasBeenRegistered());
492b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    deoptimization_index_ = deoptimization_index;
493b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    translation_index_ = translation_index;
4942b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch    pc_offset_ = pc_offset;
495b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
496b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool HasBeenRegistered() const {
497b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex;
498b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
499b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
500b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void PrintTo(StringStream* stream);
501b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Marker value indicating a de-materialized object.
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LOperand* materialization_marker() { return NULL; }
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Encoding used for the object_mapping map below.
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class LengthOrDupeField : public BitField<int,   0, 30> { };
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class IsArgumentsField  : public BitField<bool, 30,  1> { };
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class IsDuplicateField  : public BitField<bool, 31,  1> { };
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
510b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private:
511b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Handle<JSFunction> closure_;
5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type_;
513b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int arguments_stack_height_;
514b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int deoptimization_index_;
515b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int translation_index_;
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id_;
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int translation_size_;
518b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int parameter_count_;
5192b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  int pc_offset_;
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Value array: [parameters] [locals] [expression stack] [de-materialized].
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //              |>--------- translation_size ---------<|
523b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ZoneList<LOperand*> values_;
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GrowableBitVector is_tagged_;
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GrowableBitVector is_uint32_;
526b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Map with encoded information about materialization_marker operands.
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<uint32_t> object_mapping_;
529b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
530b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LEnvironment* outer_;
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry_;
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_been_used_;
534b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch};
535b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Iterates over the non-null, non-constant operands in an environment.
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ShallowIterator FINAL BASE_EMBEDDED {
5391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
5401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  explicit ShallowIterator(LEnvironment* env)
5411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      : env_(env),
5421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        limit_(env != NULL ? env->values()->length() : 0),
5431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        current_(0) {
5443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
5451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool Done() { return current_ >= limit_; }
5481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LOperand* Current() {
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!Done());
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(env_->values()->at(current_) != NULL);
5521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return env_->values()->at(current_);
5531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Advance() {
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!Done());
5573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ++current_;
5583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
5591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LEnvironment* env() { return env_; }
5621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
5643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool ShouldSkip(LOperand* op) {
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return op == NULL || op->IsConstantOperand();
566e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
567e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Skip until something interesting, beginning with and including current_.
5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void SkipUninteresting() {
5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    while (current_ < limit_ && ShouldSkip(env_->values()->at(current_))) {
5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ++current_;
5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LEnvironment* env_;
5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int limit_;
5771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int current_;
5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
5791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Iterator for non-null, non-constant operands incl. outer environments.
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DeepIterator FINAL BASE_EMBEDDED {
5831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  explicit DeepIterator(LEnvironment* env)
5853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : current_iterator_(env) {
5863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
5871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool Done() { return current_iterator_.Done(); }
5903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LOperand* Current() {
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!current_iterator_.Done());
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(current_iterator_.Current() != NULL);
5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return current_iterator_.Current();
5951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Advance() {
5983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    current_iterator_.Advance();
5993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
6011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
6033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void SkipUninteresting() {
6043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    while (current_iterator_.env() != NULL && current_iterator_.Done()) {
6053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      current_iterator_ = ShallowIterator(current_iterator_.env()->outer());
6063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
6071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
6081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  ShallowIterator current_iterator_;
6101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
6111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
612257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LPlatformChunk;
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LGap;
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LLabel;
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Superclass providing data and behavior common to all the
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// arch-specific LPlatformChunk classes.
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LChunk : public ZoneObject {
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LChunk* NewChunk(HGraph* graph);
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddInstruction(LInstruction* instruction, HBasicBlock* block);
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LConstantOperand* DefineConstantOperand(HConstant* constant);
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* LookupConstant(LConstantOperand* operand) const;
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int ParameterAt(int index);
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int GetParameterStackSlot(int index) const;
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int spill_slot_count() const { return spill_slot_count_; }
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info() const { return info_; }
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph() const { return graph_; }
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return graph_->isolate(); }
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddGapMove(int index, LOperand* from, LOperand* to);
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LGap* GetGapAt(int index) const;
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsGapAt(int index) const;
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int NearestGapPos(int index) const;
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkEmptyBlocks();
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LLabel* GetLabel(int block_id) const;
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int LookupDestination(int block_id) const;
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label* GetAssemblyLabel(int block_id) const;
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<Handle<JSFunction> >* inlined_closures() const {
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return &inlined_closures_;
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddInlinedClosure(Handle<JSFunction> closure) {
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    inlined_closures_.Add(closure, zone());
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddDeprecationDependency(Handle<Map> map) {
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!map->is_deprecated());
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!map->CanBeDeprecated()) return;
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!info_->IsStub());
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deprecation_dependencies_.insert(map);
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
659257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddStabilityDependency(Handle<Map> map) {
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(map->is_stable());
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!map->CanTransition()) return;
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!info_->IsStub());
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stability_dependencies_.insert(map);
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return info_->zone(); }
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> Codegen();
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_allocated_double_registers(BitVector* allocated_registers);
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector* allocated_double_registers() {
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return allocated_double_registers_;
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LChunk(CompilationInfo* info, HGraph* graph);
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int spill_slot_count_;
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef std::less<Handle<Map> > MapLess;
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef zone_allocator<Handle<Map> > MapAllocator;
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef std::set<Handle<Map>, MapLess, MapAllocator> MapSet;
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CommitDependencies(Handle<Code> code) const;
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info_;
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* const graph_;
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector* allocated_double_registers_;
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<LInstruction*> instructions_;
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<LPointerMap*> pointer_maps_;
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Handle<JSFunction> > inlined_closures_;
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapSet deprecation_dependencies_;
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapSet stability_dependencies_;
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LChunkBuilderBase BASE_EMBEDDED {
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LChunkBuilderBase(CompilationInfo* info, HGraph* graph)
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : argument_count_(0),
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        chunk_(NULL),
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        info_(info),
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        graph_(graph),
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        status_(UNUSED),
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        zone_(graph->zone()) {}
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~LChunkBuilderBase() { }
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Abort(BailoutReason reason);
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Retry(BailoutReason reason);
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Status { UNUSED, BUILDING, DONE, ABORTED };
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPlatformChunk* chunk() const { return chunk_; }
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info() const { return info_; }
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph() const { return graph_; }
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int argument_count() const { return argument_count_; }
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return graph_->isolate(); }
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap() const { return isolate()->heap(); }
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_unused() const { return status_ == UNUSED; }
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_building() const { return status_ == BUILDING; }
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_done() const { return status_ == DONE; }
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_aborted() const { return status_ == ABORTED; }
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // An input operand in register, stack slot or a constant operand.
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Will not be moved to a register even if one is freely available.
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) = 0;
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int* argument_index_accumulator,
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ZoneList<HValue*>* objects_to_materialize);
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddObjectToMaterialize(HValue* value,
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              ZoneList<HValue*>* objects_to_materialize,
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              LEnvironment* result);
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int argument_count_;
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPlatformChunk* chunk_;
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info_;
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* const graph_;
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Status status_;
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint StackSlotOffset(int index);
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum NumberUntagDMode {
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NUMBER_CANDIDATE_IS_SMI,
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NUMBER_CANDIDATE_IS_ANY_TAGGED
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LPhase : public CompilationPhase {
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPhase(const char* name, LChunk* chunk)
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : CompilationPhase(name, chunk->info()),
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        chunk_(chunk) { }
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~LPhase();
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LChunk* chunk_;
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(LPhase);
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A register-allocator view of a Lithium instruction. It contains the id of
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the output operand and a list of input operand uses.
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum RegisterKind {
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNALLOCATED_REGISTERS,
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GENERAL_REGISTERS,
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DOUBLE_REGISTERS
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Iterator for non-null temp operands.
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TempIterator BASE_EMBEDDED {
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline explicit TempIterator(LInstruction* instr);
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Done();
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline LOperand* Current();
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Advance();
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void SkipUninteresting();
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* instr_;
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int limit_;
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int current_;
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Iterator for non-constant input operands.
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass InputIterator BASE_EMBEDDED {
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline explicit InputIterator(LInstruction* instr);
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Done();
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline LOperand* Current();
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Advance();
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void SkipUninteresting();
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* instr_;
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int limit_;
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int current_;
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UseIterator BASE_EMBEDDED {
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline explicit UseIterator(LInstruction* instr);
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Done();
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline LOperand* Current();
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Advance();
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InputIterator input_iterator_;
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeepIterator env_iterator_;
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
827257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LInstruction;
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LCodeGen;
830086aeeaae12517475c22695a200be45495516549Ben Murdoch} }  // namespace v8::internal
831086aeeaae12517475c22695a200be45495516549Ben Murdoch
832086aeeaae12517475c22695a200be45495516549Ben Murdoch#endif  // V8_LITHIUM_H_
833