lithium.h revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
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
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_CRANKSHAFT_LITHIUM_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_CRANKSHAFT_LITHIUM_H_
79fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <set>
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bailout-reason.h"
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/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  }
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool TooManyParameters(int num_parameters) {
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int parameter_limit = -LUnallocated::kMinFixedSlotIndex;
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return num_parameters + 1 > parameter_limit;
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool TooManyParametersOrStackSlots(int num_parameters,
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            int num_stack_slots) {
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int locals_limit = LUnallocated::kMaxFixedSlotIndex;
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return num_parameters + 1 + num_stack_slots > locals_limit;
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
2671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LMoveOperands final BASE_EMBEDDED {
2701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
2711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LMoveOperands(LOperand* source, LOperand* destination)
2721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      : source_(source), destination_(destination) {
2731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* source() const { return source_; }
2761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void set_source(LOperand* operand) { source_ = operand; }
2771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* destination() const { return destination_; }
2791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void set_destination(LOperand* operand) { destination_ = operand; }
2801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // The gap resolver marks moves as "in-progress" by clearing the
2821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // destination (but not the source).
2831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsPending() const {
2841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return destination_ == NULL && source_ != NULL;
2851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // True if this move a move into the given destination operand.
2881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool Blocks(LOperand* operand) const {
2891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return !IsEliminated() && source()->Equals(operand);
2901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // A move is redundant if it's been eliminated, if its source and
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // destination are the same, or if its destination is unneeded or constant.
2941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsRedundant() const {
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsEliminated() || source_->Equals(destination_) || IsIgnored() ||
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           (destination_ != NULL && destination_->IsConstantOperand());
2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsIgnored() const {
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return destination_ != NULL && destination_->IsIgnored();
3011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // We clear both operands to indicate move that's been eliminated.
3041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Eliminate() { source_ = destination_ = NULL; }
3051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsEliminated() const {
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(source_ != NULL || destination_ == NULL);
3071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return source_ == NULL;
3081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
3091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
3111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* source_;
3121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LOperand* destination_;
3131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
3141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <LOperand::Kind kOperandKind, int kNumCachedOperands>
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LSubKindOperand final : public LOperand {
3181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LSubKindOperand* Create(int index, Zone* zone) {
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 0);
3211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (index < kNumCachedOperands) return &cache[index];
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) LSubKindOperand(index);
3231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
3241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LSubKindOperand* cast(LOperand* op) {
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(op->kind() == kOperandKind);
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<LSubKindOperand*>(op);
3281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
3291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void SetUpCache();
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void TearDownCache();
3321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LSubKindOperand* cache;
3351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LSubKindOperand() : LOperand() { }
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LSubKindOperand(int index) : LOperand(kOperandKind, index) { }
3381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
3391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS(name, type, number)   \
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef LSubKindOperand<LOperand::type, number> L##name;
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLITHIUM_OPERAND_LIST(LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS)
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS
3451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LParallelMove final : public ZoneObject {
348b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public:
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LParallelMove(Zone* zone) : move_operands_(4, zone) { }
350b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddMove(LOperand* from, LOperand* to, Zone* zone) {
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    move_operands_.Add(LMoveOperands(from, to), zone);
353b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
354b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
355b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool IsRedundant() const;
356b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<LMoveOperands>* move_operands() { return &move_operands_; }
3589fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
359b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void PrintDataTo(StringStream* stream) const;
360b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
361b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private:
362b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ZoneList<LMoveOperands> move_operands_;
363b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch};
364b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
365b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LPointerMap final : public ZoneObject {
367086aeeaae12517475c22695a200be45495516549Ben Murdoch public:
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LPointerMap(Zone* zone)
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : pointer_operands_(8, zone),
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        untagged_operands_(0, zone),
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        lithium_position_(-1) { }
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const ZoneList<LOperand*>* GetNormalizedOperands() {
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = 0; i < untagged_operands_.length(); ++i) {
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RemovePointer(untagged_operands_[i]);
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    untagged_operands_.Clear();
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return &pointer_operands_;
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
380b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int lithium_position() const { return lithium_position_; }
381b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
382b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void set_lithium_position(int pos) {
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(lithium_position_ == -1);
384b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    lithium_position_ = pos;
385b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
386b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordPointer(LOperand* op, Zone* zone);
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RemovePointer(LOperand* op);
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordUntagged(LOperand* op, Zone* zone);
390b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void PrintTo(StringStream* stream);
3919fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
392086aeeaae12517475c22695a200be45495516549Ben Murdoch private:
393b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ZoneList<LOperand*> pointer_operands_;
3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<LOperand*> untagged_operands_;
395b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int lithium_position_;
396086aeeaae12517475c22695a200be45495516549Ben Murdoch};
397086aeeaae12517475c22695a200be45495516549Ben Murdoch
398086aeeaae12517475c22695a200be45495516549Ben Murdoch
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LEnvironment final : public ZoneObject {
400b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public:
401b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LEnvironment(Handle<JSFunction> closure,
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               FrameType frame_type,
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               BailoutId ast_id,
404b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch               int parameter_count,
405b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch               int argument_count,
406b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch               int value_count,
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               LEnvironment* outer,
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               HEnterInlined* entry,
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               Zone* zone)
410b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      : closure_(closure),
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        frame_type_(frame_type),
412b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        arguments_stack_height_(argument_count),
413b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
414b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        translation_index_(-1),
415b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        ast_id_(ast_id),
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        translation_size_(value_count),
417b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        parameter_count_(parameter_count),
4182b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch        pc_offset_(-1),
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        values_(value_count, zone),
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        is_tagged_(value_count, zone),
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        is_uint32_(value_count, zone),
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object_mapping_(0, zone),
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        outer_(outer),
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        entry_(entry),
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        zone_(zone),
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        has_been_used_(false) { }
427b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
428b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Handle<JSFunction> closure() const { return closure_; }
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type() const { return frame_type_; }
430b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int arguments_stack_height() const { return arguments_stack_height_; }
431b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int deoptimization_index() const { return deoptimization_index_; }
432b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int translation_index() const { return translation_index_; }
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id() const { return ast_id_; }
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int translation_size() const { return translation_size_; }
435b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int parameter_count() const { return parameter_count_; }
4362b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  int pc_offset() const { return pc_offset_; }
437b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  const ZoneList<LOperand*>* values() const { return &values_; }
438b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LEnvironment* outer() const { return outer_; }
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry() { return entry_; }
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_been_used() const { return has_been_used_; }
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_has_been_used() { has_been_used_ = true; }
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddValue(LOperand* operand,
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Representation representation,
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                bool is_uint32) {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.Add(operand, zone());
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (representation.IsSmiOrTagged()) {
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!is_uint32);
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_tagged_.Add(values_.length() - 1, zone());
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
453b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_uint32) {
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_uint32_.Add(values_.length() - 1, zone());
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
457b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
458b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
459b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool HasTaggedValueAt(int index) const {
4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return is_tagged_.Contains(index);
461b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
462b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasUint32ValueAt(int index) const {
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return is_uint32_.Contains(index);
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddNewObject(int length, bool is_arguments) {
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t encoded = LengthOrDupeField::encode(length) |
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       IsArgumentsField::encode(is_arguments) |
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       IsDuplicateField::encode(false);
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object_mapping_.Add(encoded, zone());
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddDuplicateObject(int dupe_of) {
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t encoded = LengthOrDupeField::encode(dupe_of) |
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       IsDuplicateField::encode(true);
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object_mapping_.Add(encoded, zone());
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int ObjectDuplicateOfAt(int index) {
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(ObjectIsDuplicateAt(index));
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LengthOrDupeField::decode(object_mapping_[index]);
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int ObjectLengthAt(int index) {
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!ObjectIsDuplicateAt(index));
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LengthOrDupeField::decode(object_mapping_[index]);
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ObjectIsArgumentsAt(int index) {
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!ObjectIsDuplicateAt(index));
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsArgumentsField::decode(object_mapping_[index]);
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ObjectIsDuplicateAt(int index) {
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsDuplicateField::decode(object_mapping_[index]);
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4992b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  void Register(int deoptimization_index,
5002b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                int translation_index,
5012b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch                int pc_offset) {
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!HasBeenRegistered());
503b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    deoptimization_index_ = deoptimization_index;
504b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    translation_index_ = translation_index;
5052b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch    pc_offset_ = pc_offset;
506b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
507b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool HasBeenRegistered() const {
508b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex;
509b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
510b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
511b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void PrintTo(StringStream* stream);
512b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Marker value indicating a de-materialized object.
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LOperand* materialization_marker() { return NULL; }
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Encoding used for the object_mapping map below.
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class LengthOrDupeField : public BitField<int,   0, 30> { };
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class IsArgumentsField  : public BitField<bool, 30,  1> { };
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class IsDuplicateField  : public BitField<bool, 31,  1> { };
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
521b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private:
522b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  Handle<JSFunction> closure_;
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type_;
524b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int arguments_stack_height_;
525b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int deoptimization_index_;
526b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int translation_index_;
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id_;
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int translation_size_;
529b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int parameter_count_;
5302b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  int pc_offset_;
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Value array: [parameters] [locals] [expression stack] [de-materialized].
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //              |>--------- translation_size ---------<|
534b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  ZoneList<LOperand*> values_;
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GrowableBitVector is_tagged_;
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GrowableBitVector is_uint32_;
537b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Map with encoded information about materialization_marker operands.
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<uint32_t> object_mapping_;
540b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
541b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  LEnvironment* outer_;
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry_;
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_been_used_;
545b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch};
546b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Iterates over the non-null, non-constant operands in an environment.
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ShallowIterator final BASE_EMBEDDED {
5501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
5511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  explicit ShallowIterator(LEnvironment* env)
5521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      : env_(env),
5531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        limit_(env != NULL ? env->values()->length() : 0),
5541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        current_(0) {
5553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
5561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool Done() { return current_ >= limit_; }
5591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LOperand* Current() {
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!Done());
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(env_->values()->at(current_) != NULL);
5631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return env_->values()->at(current_);
5641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Advance() {
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!Done());
5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ++current_;
5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
5701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LEnvironment* env() { return env_; }
5731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
5753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool ShouldSkip(LOperand* op) {
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return op == NULL || op->IsConstantOperand();
577e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
578e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Skip until something interesting, beginning with and including current_.
5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void SkipUninteresting() {
5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    while (current_ < limit_ && ShouldSkip(env_->values()->at(current_))) {
5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ++current_;
5831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LEnvironment* env_;
5871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int limit_;
5881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int current_;
5891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
5901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Iterator for non-null, non-constant operands incl. outer environments.
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DeepIterator final BASE_EMBEDDED {
5941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
5951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  explicit DeepIterator(LEnvironment* env)
5963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : current_iterator_(env) {
5973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
5981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool Done() { return current_iterator_.Done(); }
6013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LOperand* Current() {
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!current_iterator_.Done());
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(current_iterator_.Current() != NULL);
6053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return current_iterator_.Current();
6061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
6071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Advance() {
6093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    current_iterator_.Advance();
6103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SkipUninteresting();
6111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
6121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
6143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void SkipUninteresting() {
6153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    while (current_iterator_.env() != NULL && current_iterator_.Done()) {
6163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      current_iterator_ = ShallowIterator(current_iterator_.env()->outer());
6173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
6181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
6191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  ShallowIterator current_iterator_;
6211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
6221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
623257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LPlatformChunk;
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LGap;
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LLabel;
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Superclass providing data and behavior common to all the
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// arch-specific LPlatformChunk classes.
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LChunk : public ZoneObject {
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static LChunk* NewChunk(HGraph* graph);
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddInstruction(LInstruction* instruction, HBasicBlock* block);
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LConstantOperand* DefineConstantOperand(HConstant* constant);
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* LookupConstant(LConstantOperand* operand) const;
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int ParameterAt(int index);
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int GetParameterStackSlot(int index) const;
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int spill_slot_count() const { return spill_slot_count_; }
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info() const { return info_; }
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph() const { return graph_; }
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return graph_->isolate(); }
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddGapMove(int index, LOperand* from, LOperand* to);
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LGap* GetGapAt(int index) const;
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsGapAt(int index) const;
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int NearestGapPos(int index) const;
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkEmptyBlocks();
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LLabel* GetLabel(int block_id) const;
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int LookupDestination(int block_id) const;
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label* GetAssemblyLabel(int block_id) const;
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const ZoneList<Handle<SharedFunctionInfo>>& inlined_functions() const {
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return inlined_functions_;
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AddInlinedFunction(Handle<SharedFunctionInfo> closure) {
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    inlined_functions_.Add(closure, zone());
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddDeprecationDependency(Handle<Map> map) {
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!map->is_deprecated());
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!map->CanBeDeprecated()) return;
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!info_->IsStub());
668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    deprecation_dependencies_.Add(map, zone());
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
670257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddStabilityDependency(Handle<Map> map) {
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(map->is_stable());
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!map->CanTransition()) return;
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!info_->IsStub());
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    stability_dependencies_.Add(map, zone());
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return info_->zone(); }
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> Codegen();
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_allocated_double_registers(BitVector* allocated_registers);
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector* allocated_double_registers() {
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return allocated_double_registers_;
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LChunk(CompilationInfo* info, HGraph* graph);
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int spill_slot_count_;
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CommitDependencies(Handle<Code> code) const;
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info_;
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* const graph_;
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector* allocated_double_registers_;
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<LInstruction*> instructions_;
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<LPointerMap*> pointer_maps_;
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Handle<SharedFunctionInfo>> inlined_functions_;
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Handle<Map>> deprecation_dependencies_;
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Handle<Map>> stability_dependencies_;
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LChunkBuilderBase BASE_EMBEDDED {
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LChunkBuilderBase(CompilationInfo* info, HGraph* graph)
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : argument_count_(0),
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        chunk_(NULL),
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        info_(info),
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        graph_(graph),
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        status_(UNUSED),
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        zone_(graph->zone()) {}
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~LChunkBuilderBase() { }
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Abort(BailoutReason reason);
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Retry(BailoutReason reason);
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Status { UNUSED, BUILDING, DONE, ABORTED };
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPlatformChunk* chunk() const { return chunk_; }
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info() const { return info_; }
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph() const { return graph_; }
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int argument_count() const { return argument_count_; }
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return graph_->isolate(); }
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap() const { return isolate()->heap(); }
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_unused() const { return status_ == UNUSED; }
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_building() const { return status_ == BUILDING; }
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_done() const { return status_ == DONE; }
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_aborted() const { return status_ == ABORTED; }
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // An input operand in register, stack slot or a constant operand.
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Will not be moved to a register even if one is freely available.
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) = 0;
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int* argument_index_accumulator,
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ZoneList<HValue*>* objects_to_materialize);
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddObjectToMaterialize(HValue* value,
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              ZoneList<HValue*>* objects_to_materialize,
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              LEnvironment* result);
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int argument_count_;
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPlatformChunk* chunk_;
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info_;
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* const graph_;
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Status status_;
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint StackSlotOffset(int index);
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum NumberUntagDMode {
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NUMBER_CANDIDATE_IS_SMI,
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NUMBER_CANDIDATE_IS_ANY_TAGGED
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LPhase : public CompilationPhase {
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPhase(const char* name, LChunk* chunk)
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : CompilationPhase(name, chunk->info()),
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        chunk_(chunk) { }
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~LPhase();
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LChunk* chunk_;
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(LPhase);
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A register-allocator view of a Lithium instruction. It contains the id of
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the output operand and a list of input operand uses.
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum RegisterKind {
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNALLOCATED_REGISTERS,
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GENERAL_REGISTERS,
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DOUBLE_REGISTERS
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Iterator for non-null temp operands.
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TempIterator BASE_EMBEDDED {
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline explicit TempIterator(LInstruction* instr);
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Done();
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline LOperand* Current();
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Advance();
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void SkipUninteresting();
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* instr_;
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int limit_;
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int current_;
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Iterator for non-constant input operands.
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass InputIterator BASE_EMBEDDED {
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline explicit InputIterator(LInstruction* instr);
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Done();
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline LOperand* Current();
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Advance();
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void SkipUninteresting();
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstruction* instr_;
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int limit_;
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int current_;
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UseIterator BASE_EMBEDDED {
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline explicit UseIterator(LInstruction* instr);
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Done();
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline LOperand* Current();
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Advance();
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InputIterator input_iterator_;
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeepIterator env_iterator_;
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
834257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LInstruction;
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LCodeGen;
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
839086aeeaae12517475c22695a200be45495516549Ben Murdoch
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_CRANKSHAFT_LITHIUM_H_
841