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" 121b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#include "src/crankshaft/compilation-phase.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/safepoint-table.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/zone-allocator.h" 169fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 17086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace v8 { 18086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace internal { 199fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_OPERAND_LIST(V) \ 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(ConstantOperand, CONSTANT_OPERAND, 128) \ 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(StackSlot, STACK_SLOT, 128) \ 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(Register, REGISTER, 16) \ 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V(DoubleRegister, DOUBLE_REGISTER, 16) 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LOperand : public ZoneObject { 281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum Kind { 301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block INVALID, 311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block UNALLOCATED, 321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CONSTANT_OPERAND, 331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block STACK_SLOT, 341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DOUBLE_STACK_SLOT, 351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block REGISTER, 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DOUBLE_REGISTER 371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LOperand() : value_(KindField::encode(INVALID)) { } 401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Kind kind() const { return KindField::decode(value_); } 421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_OPERAND_PREDICATE(name, type, number) \ 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool Is##name() const { return kind() == type; } 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_PREDICATE) 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LITHIUM_OPERAND_PREDICATE(Ignored, INVALID, 0) 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef LITHIUM_OPERAND_PREDICATE 491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool Equals(LOperand* other) const { return value_ == other->value_; } 501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void PrintTo(StringStream* stream); 521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void ConvertTo(Kind kind, int index) { 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kind == REGISTER) DCHECK(index >= 0); 541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block value_ = KindField::encode(kind); 551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block value_ |= index << kKindFieldWidth; 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(this->index() == index); 571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calls SetUpCache()/TearDownCache() for each subclass. 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void SetUpCaches(); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void TearDownCaches(); 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected: 641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kKindFieldWidth = 3; 651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block class KindField : public BitField<Kind, 0, kKindFieldWidth> { }; 661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LOperand(Kind kind, int index) { ConvertTo(kind, index); } 681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block unsigned value_; 701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LUnallocated : public LOperand { 741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum BasicPolicy { 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FIXED_SLOT, 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EXTENDED_POLICY 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum ExtendedPolicy { 811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block NONE, 821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ANY, 831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block FIXED_REGISTER, 841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block FIXED_DOUBLE_REGISTER, 851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block MUST_HAVE_REGISTER, 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MUST_HAVE_DOUBLE_REGISTER, 871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WRITABLE_REGISTER, 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SAME_AS_FIRST_INPUT 891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Lifetime of operand inside the instruction. 921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum Lifetime { 931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // USED_AT_START operand is guaranteed to be live only at 941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // instruction start. Register allocator is free to assign the same register 951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // to some other operand used inside instruction (i.e. temporary or 961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // output). 971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block USED_AT_START, 981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // USED_AT_END operand is treated as live until the end of 1001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // instruction. This means that register allocator will not reuse it's 1011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // register for any other operand inside instruction. 1021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block USED_AT_END 1031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 1041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit LUnallocated(ExtendedPolicy policy) : LOperand(UNALLOCATED, 0) { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= ExtendedPolicyField::encode(policy); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= LifetimeField::encode(USED_AT_END); 1091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LUnallocated(BasicPolicy policy, int index) : LOperand(UNALLOCATED, 0) { 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(policy == FIXED_SLOT); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= BasicPolicyField::encode(policy); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= index << FixedSlotIndexField::kShift; 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(this->fixed_slot_index() == index); 1161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LUnallocated(ExtendedPolicy policy, int index) : LOperand(UNALLOCATED, 0) { 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= ExtendedPolicyField::encode(policy); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= LifetimeField::encode(USED_AT_END); 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= FixedRegisterField::encode(index); 1241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LUnallocated(ExtendedPolicy policy, Lifetime lifetime) 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : LOperand(UNALLOCATED, 0) { 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= ExtendedPolicyField::encode(policy); 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ |= LifetimeField::encode(lifetime); 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LUnallocated* CopyUnconstrained(Zone* zone) { 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LUnallocated* result = new(zone) LUnallocated(ANY); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_virtual_register(virtual_register()); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static LUnallocated* cast(LOperand* op) { 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(op->IsUnallocated()); 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<LUnallocated*>(op); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The encoding used for LUnallocated operands depends on the policy that is 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stored within the operand. The FIXED_SLOT policy uses a compact encoding 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // because it accommodates a larger pay-load. 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For FIXED_SLOT policy: 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // +------------------------------------------+ 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // | slot_index | vreg | 0 | 001 | 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // +------------------------------------------+ 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For all other (extended) policies: 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // +------------------------------------------+ 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // | reg_index | L | PPP | vreg | 1 | 001 | L ... Lifetime 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // +------------------------------------------+ P ... Policy 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The slot index is a signed value which requires us to decode it manually 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instead of using the BitField utility class. 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The superclass has a KindField. 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kKindFieldWidth == 3); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // BitFields for all unallocated operands. 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class BasicPolicyField : public BitField<BasicPolicy, 3, 1> {}; 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class VirtualRegisterField : public BitField<unsigned, 4, 18> {}; 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // BitFields specific to BasicPolicy::FIXED_SLOT. 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class FixedSlotIndexField : public BitField<int, 22, 10> {}; 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // BitFields specific to BasicPolicy::EXTENDED_POLICY. 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class ExtendedPolicyField : public BitField<ExtendedPolicy, 22, 3> {}; 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class LifetimeField : public BitField<Lifetime, 25, 1> {}; 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class FixedRegisterField : public BitField<int, 26, 6> {}; 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1; 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize; 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1; 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1)); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Predicates for the operand policy. 1821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool HasAnyPolicy() const { 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == EXTENDED_POLICY && 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == ANY; 1851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool HasFixedPolicy() const { 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == FIXED_SLOT || 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == FIXED_REGISTER || 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == FIXED_DOUBLE_REGISTER; 1901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool HasRegisterPolicy() const { 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == EXTENDED_POLICY && ( 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == WRITABLE_REGISTER || 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == MUST_HAVE_REGISTER); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool HasDoubleRegisterPolicy() const { 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == EXTENDED_POLICY && 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == MUST_HAVE_DOUBLE_REGISTER; 1991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool HasSameAsInputPolicy() const { 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == EXTENDED_POLICY && 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == SAME_AS_FIRST_INPUT; 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool HasFixedSlotPolicy() const { 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == FIXED_SLOT; 2061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool HasFixedRegisterPolicy() const { 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == EXTENDED_POLICY && 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == FIXED_REGISTER; 2101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool HasFixedDoubleRegisterPolicy() const { 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == EXTENDED_POLICY && 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == FIXED_DOUBLE_REGISTER; 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool HasWritableRegisterPolicy() const { 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return basic_policy() == EXTENDED_POLICY && 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch extended_policy() == WRITABLE_REGISTER; 2181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicPolicy basic_policy() const { 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BasicPolicyField::decode(value_); 2231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExtendedPolicy extended_policy() const { 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(basic_policy() == EXTENDED_POLICY); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ExtendedPolicyField::decode(value_); 2291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [fixed_slot_index]: Only for FIXED_SLOT. 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int fixed_slot_index() const { 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HasFixedSlotPolicy()); 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<int>(value_) >> FixedSlotIndexField::kShift; 2351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER. 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int fixed_register_index() const { 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy()); 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FixedRegisterField::decode(value_); 2411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [virtual_register]: The virtual register ID for this operand. 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int virtual_register() const { 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VirtualRegisterField::decode(value_); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_virtual_register(unsigned id) { 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = VirtualRegisterField::update(value_, id); 2491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [lifetime]: Only for non-FIXED_SLOT. 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsUsedAtStart() { 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(basic_policy() == EXTENDED_POLICY); 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LifetimeField::decode(value_) == USED_AT_START; 2551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool TooManyParameters(int num_parameters) { 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int parameter_limit = -LUnallocated::kMinFixedSlotIndex; 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return num_parameters + 1 > parameter_limit; 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool TooManyParametersOrStackSlots(int num_parameters, 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int num_stack_slots) { 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int locals_limit = LUnallocated::kMaxFixedSlotIndex; 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return num_parameters + 1 + num_stack_slots > locals_limit; 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 2681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LMoveOperands final BASE_EMBEDDED { 2711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 2721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LMoveOperands(LOperand* source, LOperand* destination) 2731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block : source_(source), destination_(destination) { 2741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LOperand* source() const { return source_; } 2771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void set_source(LOperand* operand) { source_ = operand; } 2781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LOperand* destination() const { return destination_; } 2801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void set_destination(LOperand* operand) { destination_ = operand; } 2811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The gap resolver marks moves as "in-progress" by clearing the 2831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // destination (but not the source). 2841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool IsPending() const { 2851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return destination_ == NULL && source_ != NULL; 2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // True if this move a move into the given destination operand. 2891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool Blocks(LOperand* operand) const { 2901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return !IsEliminated() && source()->Equals(operand); 2911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // A move is redundant if it's been eliminated, if its source and 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // destination are the same, or if its destination is unneeded or constant. 2951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool IsRedundant() const { 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsEliminated() || source_->Equals(destination_) || IsIgnored() || 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (destination_ != NULL && destination_->IsConstantOperand()); 2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool IsIgnored() const { 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return destination_ != NULL && destination_->IsIgnored(); 3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 3031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // We clear both operands to indicate move that's been eliminated. 3051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void Eliminate() { source_ = destination_ = NULL; } 3061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool IsEliminated() const { 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(source_ != NULL || destination_ == NULL); 3081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return source_ == NULL; 3091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 3101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 3121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LOperand* source_; 3131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LOperand* destination_; 3141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 3151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <LOperand::Kind kOperandKind, int kNumCachedOperands> 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LSubKindOperand final : public LOperand { 3191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static LSubKindOperand* Create(int index, Zone* zone) { 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(index >= 0); 3221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (index < kNumCachedOperands) return &cache[index]; 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new(zone) LSubKindOperand(index); 3241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 3251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static LSubKindOperand* cast(LOperand* op) { 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(op->kind() == kOperandKind); 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<LSubKindOperand*>(op); 3291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 3301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void SetUpCache(); 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void TearDownCache(); 3331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static LSubKindOperand* cache; 3361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LSubKindOperand() : LOperand() { } 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit LSubKindOperand(int index) : LOperand(kOperandKind, index) { } 3391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 3401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS(name, type, number) \ 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef LSubKindOperand<LOperand::type, number> L##name; 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLITHIUM_OPERAND_LIST(LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS) 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef LITHIUM_TYPEDEF_SUBKIND_OPERAND_CLASS 3461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LParallelMove final : public ZoneObject { 349b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit LParallelMove(Zone* zone) : move_operands_(4, zone) { } 351b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddMove(LOperand* from, LOperand* to, Zone* zone) { 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch move_operands_.Add(LMoveOperands(from, to), zone); 354b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 355b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 356b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool IsRedundant() const; 357b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<LMoveOperands>* move_operands() { return &move_operands_; } 3599fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 360b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void PrintDataTo(StringStream* stream) const; 361b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 362b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 363b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<LMoveOperands> move_operands_; 364b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 365b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 366b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LPointerMap final : public ZoneObject { 368086aeeaae12517475c22695a200be45495516549Ben Murdoch public: 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit LPointerMap(Zone* zone) 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : pointer_operands_(8, zone), 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch untagged_operands_(0, zone), 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lithium_position_(-1) { } 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const ZoneList<LOperand*>* GetNormalizedOperands() { 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < untagged_operands_.length(); ++i) { 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RemovePointer(untagged_operands_[i]); 3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch untagged_operands_.Clear(); 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return &pointer_operands_; 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 381b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int lithium_position() const { return lithium_position_; } 382b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 383b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void set_lithium_position(int pos) { 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(lithium_position_ == -1); 385b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch lithium_position_ = pos; 386b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 387b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordPointer(LOperand* op, Zone* zone); 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void RemovePointer(LOperand* op); 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordUntagged(LOperand* op, Zone* zone); 391b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void PrintTo(StringStream* stream); 3929fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 393086aeeaae12517475c22695a200be45495516549Ben Murdoch private: 394b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<LOperand*> pointer_operands_; 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ZoneList<LOperand*> untagged_operands_; 396b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int lithium_position_; 397086aeeaae12517475c22695a200be45495516549Ben Murdoch}; 398086aeeaae12517475c22695a200be45495516549Ben Murdoch 399086aeeaae12517475c22695a200be45495516549Ben Murdoch 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LEnvironment final : public ZoneObject { 401b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 402b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LEnvironment(Handle<JSFunction> closure, 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameType frame_type, 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 405b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int parameter_count, 406b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int argument_count, 407b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int value_count, 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LEnvironment* outer, 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* entry, 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) 411b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : closure_(closure), 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_(frame_type), 413b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch arguments_stack_height_(argument_count), 414b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch deoptimization_index_(Safepoint::kNoDeoptimizationIndex), 415b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch translation_index_(-1), 416b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ast_id_(ast_id), 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch translation_size_(value_count), 418b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch parameter_count_(parameter_count), 4192b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch pc_offset_(-1), 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_(value_count, zone), 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_tagged_(value_count, zone), 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_uint32_(value_count, zone), 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_mapping_(0, zone), 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_(outer), 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(entry), 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone), 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_been_used_(false) { } 428b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 429b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<JSFunction> closure() const { return closure_; } 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameType frame_type() const { return frame_type_; } 431b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int arguments_stack_height() const { return arguments_stack_height_; } 432b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int deoptimization_index() const { return deoptimization_index_; } 433b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int translation_index() const { return translation_index_; } 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id() const { return ast_id_; } 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int translation_size() const { return translation_size_; } 436b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int parameter_count() const { return parameter_count_; } 4372b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int pc_offset() const { return pc_offset_; } 438b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const ZoneList<LOperand*>* values() const { return &values_; } 439b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LEnvironment* outer() const { return outer_; } 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* entry() { return entry_; } 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone() const { return zone_; } 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_been_used() const { return has_been_used_; } 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_has_been_used() { has_been_used_ = true; } 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddValue(LOperand* operand, 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation representation, 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_uint32) { 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_.Add(operand, zone()); 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (representation.IsSmiOrTagged()) { 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!is_uint32); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_tagged_.Add(values_.length() - 1, zone()); 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 454b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_uint32) { 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_uint32_.Add(values_.length() - 1, zone()); 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 458b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 459b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 460b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool HasTaggedValueAt(int index) const { 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return is_tagged_.Contains(index); 462b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 463b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool HasUint32ValueAt(int index) const { 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_uint32_.Contains(index); 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddNewObject(int length, bool is_arguments) { 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t encoded = LengthOrDupeField::encode(length) | 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsArgumentsField::encode(is_arguments) | 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsDuplicateField::encode(false); 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_mapping_.Add(encoded, zone()); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddDuplicateObject(int dupe_of) { 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t encoded = LengthOrDupeField::encode(dupe_of) | 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsDuplicateField::encode(true); 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_mapping_.Add(encoded, zone()); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ObjectDuplicateOfAt(int index) { 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ObjectIsDuplicateAt(index)); 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LengthOrDupeField::decode(object_mapping_[index]); 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ObjectLengthAt(int index) { 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!ObjectIsDuplicateAt(index)); 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LengthOrDupeField::decode(object_mapping_[index]); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ObjectIsArgumentsAt(int index) { 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!ObjectIsDuplicateAt(index)); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsArgumentsField::decode(object_mapping_[index]); 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ObjectIsDuplicateAt(int index) { 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsDuplicateField::decode(object_mapping_[index]); 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5002b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch void Register(int deoptimization_index, 5012b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int translation_index, 5022b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int pc_offset) { 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasBeenRegistered()); 504b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch deoptimization_index_ = deoptimization_index; 505b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch translation_index_ = translation_index; 5062b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch pc_offset_ = pc_offset; 507b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 508b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool HasBeenRegistered() const { 509b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex; 510b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 511b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 512b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void PrintTo(StringStream* stream); 513b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Marker value indicating a de-materialized object. 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static LOperand* materialization_marker() { return NULL; } 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Encoding used for the object_mapping map below. 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class LengthOrDupeField : public BitField<int, 0, 30> { }; 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class IsArgumentsField : public BitField<bool, 30, 1> { }; 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class IsDuplicateField : public BitField<bool, 31, 1> { }; 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 523b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<JSFunction> closure_; 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameType frame_type_; 525b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int arguments_stack_height_; 526b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int deoptimization_index_; 527b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int translation_index_; 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id_; 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int translation_size_; 530b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int parameter_count_; 5312b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch int pc_offset_; 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Value array: [parameters] [locals] [expression stack] [de-materialized]. 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |>--------- translation_size ---------<| 535b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<LOperand*> values_; 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GrowableBitVector is_tagged_; 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GrowableBitVector is_uint32_; 538b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Map with encoded information about materialization_marker operands. 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<uint32_t> object_mapping_; 541b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 542b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LEnvironment* outer_; 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* entry_; 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone_; 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_been_used_; 546b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 547b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 5481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Iterates over the non-null, non-constant operands in an environment. 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ShallowIterator final BASE_EMBEDDED { 5511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 5521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block explicit ShallowIterator(LEnvironment* env) 5531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block : env_(env), 5541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block limit_(env != NULL ? env->values()->length() : 0), 5551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block current_(0) { 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SkipUninteresting(); 5571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 5581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool Done() { return current_ >= limit_; } 5601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LOperand* Current() { 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!Done()); 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(env_->values()->at(current_) != NULL); 5641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return env_->values()->at(current_); 5651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 5661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Advance() { 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!Done()); 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current_; 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SkipUninteresting(); 5711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 5721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LEnvironment* env() { return env_; } 5741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 5763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool ShouldSkip(LOperand* op) { 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return op == NULL || op->IsConstantOperand(); 578e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 579e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Skip until something interesting, beginning with and including current_. 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SkipUninteresting() { 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (current_ < limit_ && ShouldSkip(env_->values()->at(current_))) { 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current_; 5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 5851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 5861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LEnvironment* env_; 5881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int limit_; 5891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int current_; 5901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 5911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Iterator for non-null, non-constant operands incl. outer environments. 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DeepIterator final BASE_EMBEDDED { 5951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 5961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block explicit DeepIterator(LEnvironment* env) 5973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : current_iterator_(env) { 5983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SkipUninteresting(); 5991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool Done() { return current_iterator_.Done(); } 6023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LOperand* Current() { 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!current_iterator_.Done()); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_iterator_.Current() != NULL); 6063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return current_iterator_.Current(); 6071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 6081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Advance() { 6103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch current_iterator_.Advance(); 6113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SkipUninteresting(); 6121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 6131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 6153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SkipUninteresting() { 6163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (current_iterator_.env() != NULL && current_iterator_.Done()) { 6173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch current_iterator_ = ShallowIterator(current_iterator_.env()->outer()); 6183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 6201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ShallowIterator current_iterator_; 6221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 6231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 624257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LPlatformChunk; 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LGap; 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LLabel; 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Superclass providing data and behavior common to all the 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// arch-specific LPlatformChunk classes. 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LChunk : public ZoneObject { 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static LChunk* NewChunk(HGraph* graph); 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddInstruction(LInstruction* instruction, HBasicBlock* block); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LConstantOperand* DefineConstantOperand(HConstant* constant); 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* LookupConstant(LConstantOperand* operand) const; 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation LookupLiteralRepresentation(LConstantOperand* operand) const; 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ParameterAt(int index); 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int GetParameterStackSlot(int index) const; 642342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch bool HasAllocatedStackSlots() const { 643342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return current_frame_slots_ != base_frame_slots_; 644342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 645342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch int GetSpillSlotCount() const { 646342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return current_frame_slots_ - base_frame_slots_; 647342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 648342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch int GetTotalFrameSlotCount() const { return current_frame_slots_; } 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationInfo* info() const { return info_; } 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGraph* graph() const { return graph_; } 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate() const { return graph_->isolate(); } 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<LInstruction*>* instructions() const { return &instructions_; } 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddGapMove(int index, LOperand* from, LOperand* to); 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LGap* GetGapAt(int index) const; 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsGapAt(int index) const; 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int NearestGapPos(int index) const; 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MarkEmptyBlocks(); 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; } 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LLabel* GetLabel(int block_id) const; 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int LookupDestination(int block_id) const; 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* GetAssemblyLabel(int block_id) const; 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ZoneList<Handle<SharedFunctionInfo>>& inlined_functions() const { 664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return inlined_functions_; 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AddInlinedFunction(Handle<SharedFunctionInfo> closure) { 668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_functions_.Add(closure, zone()); 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddDeprecationDependency(Handle<Map> map) { 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!map->is_deprecated()); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!map->CanBeDeprecated()) return; 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info_->IsStub()); 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch deprecation_dependencies_.Add(map, zone()); 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 677257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddStabilityDependency(Handle<Map> map) { 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map->is_stable()); 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!map->CanTransition()) return; 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info_->IsStub()); 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stability_dependencies_.Add(map, zone()); 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone() const { return info_->zone(); } 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> Codegen(); 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_allocated_double_registers(BitVector* allocated_registers); 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BitVector* allocated_double_registers() { 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return allocated_double_registers_; 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LChunk(CompilationInfo* info, HGraph* graph); 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 697342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch int base_frame_slots_; 698342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch int current_frame_slots_; 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CommitDependencies(Handle<Code> code) const; 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationInfo* info_; 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGraph* const graph_; 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BitVector* allocated_double_registers_; 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<LInstruction*> instructions_; 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<LPointerMap*> pointer_maps_; 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneList<Handle<SharedFunctionInfo>> inlined_functions_; 709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneList<Handle<Map>> deprecation_dependencies_; 710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneList<Handle<Map>> stability_dependencies_; 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LChunkBuilderBase BASE_EMBEDDED { 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit LChunkBuilderBase(CompilationInfo* info, HGraph* graph) 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : argument_count_(0), 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_(NULL), 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info_(info), 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph_(graph), 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status_(UNUSED), 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(graph->zone()) {} 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~LChunkBuilderBase() { } 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Abort(BailoutReason reason); 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Retry(BailoutReason reason); 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum Status { UNUSED, BUILDING, DONE, ABORTED }; 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LPlatformChunk* chunk() const { return chunk_; } 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationInfo* info() const { return info_; } 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGraph* graph() const { return graph_; } 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count() const { return argument_count_; } 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate() const { return graph_->isolate(); } 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap() const { return isolate()->heap(); } 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_unused() const { return status_ == UNUSED; } 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_building() const { return status_ == BUILDING; } 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_done() const { return status_ == DONE; } 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_aborted() const { return status_ == ABORTED; } 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // An input operand in register, stack slot or a constant operand. 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Will not be moved to a register even if one is freely available. 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) = 0; 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7481b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // Constructs proper environment for a lazy bailout point after call, creates 7491b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // LLazyBailout instruction and adds it to current block. 7501b268ca467c924004286c97bac133db489cf43d0Ben Murdoch void CreateLazyBailoutForCall(HBasicBlock* current_block, LInstruction* instr, 7511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch HInstruction* hydrogen_val); 7521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 7531b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // Assigns given environment to an instruction. An instruction which can 7541b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // deoptimize must have an environment. 7551b268ca467c924004286c97bac133db489cf43d0Ben Murdoch LInstruction* AssignEnvironment(LInstruction* instr, 7561b268ca467c924004286c97bac133db489cf43d0Ben Murdoch HEnvironment* hydrogen_env); 7571b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* argument_index_accumulator, 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HValue*>* objects_to_materialize); 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddObjectToMaterialize(HValue* value, 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HValue*>* objects_to_materialize, 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LEnvironment* result); 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone() const { return zone_; } 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count_; 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LPlatformChunk* chunk_; 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationInfo* info_; 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGraph* const graph_; 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Status status_; 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone_; 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum NumberUntagDMode { 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NUMBER_CANDIDATE_IS_SMI, 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NUMBER_CANDIDATE_IS_ANY_TAGGED 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LPhase : public CompilationPhase { 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LPhase(const char* name, LChunk* chunk) 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : CompilationPhase(name, chunk->info()), 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch chunk_(chunk) { } 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~LPhase(); 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LChunk* chunk_; 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(LPhase); 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A register-allocator view of a Lithium instruction. It contains the id of 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the output operand and a list of input operand uses. 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum RegisterKind { 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNALLOCATED_REGISTERS, 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GENERAL_REGISTERS, 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DOUBLE_REGISTERS 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Iterator for non-null temp operands. 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TempIterator BASE_EMBEDDED { 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit TempIterator(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 Murdoch// Iterator for non-constant input operands. 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass InputIterator BASE_EMBEDDED { 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit InputIterator(LInstruction* instr); 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool Done(); 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline LOperand* Current(); 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Advance(); 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void SkipUninteresting(); 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr_; 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int limit_; 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int current_; 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UseIterator BASE_EMBEDDED { 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline explicit UseIterator(LInstruction* instr); 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool Done(); 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline LOperand* Current(); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Advance(); 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InputIterator input_iterator_; 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeepIterator env_iterator_; 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LInstruction; 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LCodeGen; 853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 855086aeeaae12517475c22695a200be45495516549Ben Murdoch 856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_CRANKSHAFT_LITHIUM_H_ 857