1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen 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.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/lithium.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopes.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/serialize.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_IA32
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ia32/lithium-ia32.h"  // NOLINT
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ia32/lithium-codegen-ia32.h"  // NOLINT
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_X64
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/lithium-x64.h"  // NOLINT
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/lithium-codegen-x64.h"  // NOLINT
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_ARM
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/lithium-arm.h"  // NOLINT
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/lithium-codegen-arm.h"  // NOLINT
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_MIPS
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips/lithium-mips.h"  // NOLINT
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips/lithium-codegen-mips.h"  // NOLINT
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_ARM64
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm64/lithium-arm64.h"  // NOLINT
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm64/lithium-codegen-arm64.h"  // NOLINT
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_MIPS64
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/lithium-mips64.h"  // NOLINT
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/lithium-codegen-mips64.h"  // NOLINT
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_X87
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x87/lithium-x87.h"  // NOLINT
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x87/lithium-codegen-x87.h"  // NOLINT
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#error "Unknown architecture."
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
36086aeeaae12517475c22695a200be45495516549Ben Murdoch
37086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace v8 {
38086aeeaae12517475c22695a200be45495516549Ben Murdochnamespace internal {
39086aeeaae12517475c22695a200be45495516549Ben Murdoch
401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid LOperand::PrintTo(StringStream* stream) {
421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LUnallocated* unalloc = NULL;
431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  switch (kind()) {
441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case INVALID:
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      stream->Add("(0)");
461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      break;
471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case UNALLOCATED:
481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      unalloc = LUnallocated::cast(this);
491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      stream->Add("v%d", unalloc->virtual_register());
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (unalloc->basic_policy() == LUnallocated::FIXED_SLOT) {
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stream->Add("(=%dS)", unalloc->fixed_slot_index());
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      switch (unalloc->extended_policy()) {
551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        case LUnallocated::NONE:
561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          break;
571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        case LUnallocated::FIXED_REGISTER: {
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          int reg_index = unalloc->fixed_register_index();
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (reg_index < 0 ||
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              reg_index >= Register::kMaxNumAllocatableRegisters) {
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            stream->Add("(=invalid_reg#%d)", reg_index);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            const char* register_name =
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register::AllocationIndexToString(reg_index);
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            stream->Add("(=%s)", register_name);
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          break;
681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        }
691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        case LUnallocated::FIXED_DOUBLE_REGISTER: {
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          int reg_index = unalloc->fixed_register_index();
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (reg_index < 0 ||
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              reg_index >= DoubleRegister::kMaxNumAllocatableRegisters) {
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            stream->Add("(=invalid_double_reg#%d)", reg_index);
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            const char* double_register_name =
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                DoubleRegister::AllocationIndexToString(reg_index);
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            stream->Add("(=%s)", double_register_name);
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          break;
801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        }
811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        case LUnallocated::MUST_HAVE_REGISTER:
821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          stream->Add("(R)");
831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          break;
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case LUnallocated::MUST_HAVE_DOUBLE_REGISTER:
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          stream->Add("(D)");
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        case LUnallocated::WRITABLE_REGISTER:
881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          stream->Add("(WR)");
891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          break;
901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        case LUnallocated::SAME_AS_FIRST_INPUT:
911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          stream->Add("(1)");
921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          break;
931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        case LUnallocated::ANY:
941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          stream->Add("(-)");
951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          break;
961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      }
971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      break;
981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case CONSTANT_OPERAND:
991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      stream->Add("[constant:%d]", index());
1001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      break;
1011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case STACK_SLOT:
1021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      stream->Add("[stack:%d]", index());
1031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      break;
1041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    case DOUBLE_STACK_SLOT:
1051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      stream->Add("[double_stack:%d]", index());
1061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      break;
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case REGISTER: {
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int reg_index = index();
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (reg_index < 0 || reg_index >= Register::kMaxNumAllocatableRegisters) {
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stream->Add("(=invalid_reg#%d|R)", reg_index);
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stream->Add("[%s|R]", Register::AllocationIndexToString(reg_index));
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      break;
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DOUBLE_REGISTER: {
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int reg_index = index();
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (reg_index < 0 ||
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          reg_index >= DoubleRegister::kMaxNumAllocatableRegisters) {
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stream->Add("(=invalid_double_reg#%d|R)", reg_index);
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stream->Add("[%s|R]",
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    DoubleRegister::AllocationIndexToString(reg_index));
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      break;
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<LOperand::Kind kOperandKind, int kNumCachedOperands>
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLSubKindOperand<kOperandKind, kNumCachedOperands>*
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLSubKindOperand<kOperandKind, kNumCachedOperands>::cache = NULL;
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<LOperand::Kind kOperandKind, int kNumCachedOperands>
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LSubKindOperand<kOperandKind, kNumCachedOperands>::SetUpCache() {
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cache) return;
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cache = new LSubKindOperand[kNumCachedOperands];
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < kNumCachedOperands; i++) {
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cache[i].ConvertTo(kOperandKind, i);
1421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
1441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<LOperand::Kind kOperandKind, int kNumCachedOperands>
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LSubKindOperand<kOperandKind, kNumCachedOperands>::TearDownCache() {
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete[] cache;
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cache = NULL;
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LOperand::SetUpCaches() {
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_OPERAND_SETUP(name, type, number) L##name::SetUpCache();
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_SETUP)
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef LITHIUM_OPERAND_SETUP
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LOperand::TearDownCaches() {
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define LITHIUM_OPERAND_TEARDOWN(name, type, number) L##name::TearDownCache();
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_TEARDOWN)
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef LITHIUM_OPERAND_TEARDOWN
1645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
1651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochbool LParallelMove::IsRedundant() const {
168b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  for (int i = 0; i < move_operands_.length(); ++i) {
169b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (!move_operands_[i].IsRedundant()) return false;
170086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
171b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  return true;
172086aeeaae12517475c22695a200be45495516549Ben Murdoch}
173086aeeaae12517475c22695a200be45495516549Ben Murdoch
174086aeeaae12517475c22695a200be45495516549Ben Murdoch
175b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LParallelMove::PrintDataTo(StringStream* stream) const {
176b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool first = true;
177b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  for (int i = 0; i < move_operands_.length(); ++i) {
178b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (!move_operands_[i].IsEliminated()) {
179b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      LOperand* source = move_operands_[i].source();
180b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      LOperand* destination = move_operands_[i].destination();
181b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      if (!first) stream->Add(" ");
182b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      first = false;
183b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      if (source->Equals(destination)) {
184b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        destination->PrintTo(stream);
185b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      } else {
186b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        destination->PrintTo(stream);
187b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        stream->Add(" = ");
188b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        source->PrintTo(stream);
189086aeeaae12517475c22695a200be45495516549Ben Murdoch      }
190b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      stream->Add(";");
191086aeeaae12517475c22695a200be45495516549Ben Murdoch    }
192086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
193086aeeaae12517475c22695a200be45495516549Ben Murdoch}
194086aeeaae12517475c22695a200be45495516549Ben Murdoch
195086aeeaae12517475c22695a200be45495516549Ben Murdoch
196b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LEnvironment::PrintTo(StringStream* stream) {
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add("[id=%d|", ast_id().ToInt());
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream->Add("deopt_id=%d|", deoptimization_index());
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add("parameters=%d|", parameter_count());
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add("arguments_stack_height=%d|", arguments_stack_height());
203b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  for (int i = 0; i < values_.length(); ++i) {
204b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (i != 0) stream->Add(";");
205b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (values_[i] == NULL) {
206b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      stream->Add("[hole]");
207b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    } else {
208b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      values_[i]->PrintTo(stream);
209b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
210086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
211b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("]");
212086aeeaae12517475c22695a200be45495516549Ben Murdoch}
213086aeeaae12517475c22695a200be45495516549Ben Murdoch
214086aeeaae12517475c22695a200be45495516549Ben Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LPointerMap::RecordPointer(LOperand* op, Zone* zone) {
216b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Do not record arguments as pointers.
217b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (op->IsStackSlot() && op->index() < 0) return;
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pointer_operands_.Add(op, zone);
220086aeeaae12517475c22695a200be45495516549Ben Murdoch}
221086aeeaae12517475c22695a200be45495516549Ben Murdoch
222086aeeaae12517475c22695a200be45495516549Ben Murdoch
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LPointerMap::RemovePointer(LOperand* op) {
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Do not record arguments as pointers.
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (op->IsStackSlot() && op->index() < 0) return;
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < pointer_operands_.length(); ++i) {
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (pointer_operands_[i]->Equals(op)) {
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      pointer_operands_.Remove(i);
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      --i;
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LPointerMap::RecordUntagged(LOperand* op, Zone* zone) {
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Do not record arguments as pointers.
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (op->IsStackSlot() && op->index() < 0) return;
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  untagged_operands_.Add(op, zone);
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
244b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid LPointerMap::PrintTo(StringStream* stream) {
245b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  stream->Add("{");
246b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  for (int i = 0; i < pointer_operands_.length(); ++i) {
247b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (i != 0) stream->Add(";");
248b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    pointer_operands_[i]->PrintTo(stream);
249086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  stream->Add("}");
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint StackSlotOffset(int index) {
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (index >= 0) {
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Local or spill slot. Skip the frame pointer, function, and
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // context in the fixed part of the frame.
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return -(index + 1) * kPointerSize -
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StandardFrameConstants::kFixedFrameSizeFromFp;
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Incoming parameter. Skip the return address.
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return -(index + 1) * kPointerSize + kFPOnStackSize + kPCOnStackSize;
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLChunk::LChunk(CompilationInfo* info, HGraph* graph)
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : spill_slot_count_(0),
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      info_(info),
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      graph_(graph),
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instructions_(32, info->zone()),
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      pointer_maps_(8, info->zone()),
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      inlined_closures_(1, info->zone()),
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      deprecation_dependencies_(MapLess(), MapAllocator(info->zone())),
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stability_dependencies_(MapLess(), MapAllocator(info->zone())) {}
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLLabel* LChunk::GetLabel(int block_id) const {
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* block = graph_->blocks()->at(block_id);
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int first_instruction = block->first_instruction_index();
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LLabel::cast(instructions_[first_instruction]);
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint LChunk::LookupDestination(int block_id) const {
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LLabel* cur = GetLabel(block_id);
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (cur->replacement() != NULL) {
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cur = cur->replacement();
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return cur->block_id();
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLabel* LChunk::GetAssemblyLabel(int block_id) const {
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LLabel* label = GetLabel(block_id);
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!label->HasReplacement());
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return label->label();
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunk::MarkEmptyBlocks() {
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LPhase phase("L_Mark empty blocks", this);
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < graph()->blocks()->length(); ++i) {
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* block = graph()->blocks()->at(i);
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int first = block->first_instruction_index();
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int last = block->last_instruction_index();
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LInstruction* first_instr = instructions()->at(first);
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LInstruction* last_instr = instructions()->at(last);
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LLabel* label = LLabel::cast(first_instr);
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (last_instr->IsGoto()) {
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LGoto* goto_instr = LGoto::cast(last_instr);
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (label->IsRedundant() &&
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          !label->is_loop_header()) {
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        bool can_eliminate = true;
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int i = first + 1; i < last && can_eliminate; ++i) {
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          LInstruction* cur = instructions()->at(i);
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (cur->IsGap()) {
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            LGap* gap = LGap::cast(cur);
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (!gap->IsRedundant()) {
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              can_eliminate = false;
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            }
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            can_eliminate = false;
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (can_eliminate) {
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          label->set_replacement(GetLabel(goto_instr->block_id()));
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LInstructionGap* gap = new (zone()) LInstructionGap(block);
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gap->set_hydrogen_value(instr->hydrogen_value());
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index = -1;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->IsControl()) {
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instructions_.Add(gap, zone());
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    index = instructions_.length();
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instructions_.Add(instr, zone());
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    index = instructions_.length();
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instructions_.Add(instr, zone());
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instructions_.Add(gap, zone());
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr->HasPointerMap()) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pointer_maps_.Add(instr->pointer_map(), zone());
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->pointer_map()->set_lithium_position(index);
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LConstantOperand::Create(constant->id(), zone());
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint LChunk::GetParameterStackSlot(int index) const {
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The receiver is at index 0, the first parameter at index 1, so we
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // shift all parameter indexes down by the number of parameters, and
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // make sure they end up negative so they are distinguishable from
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // spill slots.
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int result = index - info()->num_parameters() - 1;
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(result < 0);
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A parameter relative to ebp in the arguments stub.
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint LChunk::ParameterAt(int index) {
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(-1 <= index);  // -1 is the receiver.
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (1 + info()->scope()->num_parameters() - index) *
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kPointerSize;
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLGap* LChunk::GetGapAt(int index) const {
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LGap::cast(instructions_[index]);
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LChunk::IsGapAt(int index) const {
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instructions_[index]->IsGap();
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint LChunk::NearestGapPos(int index) const {
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!IsGapAt(index)) index--;
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return index;
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GetGapAt(index)->GetOrCreateParallelMove(
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LGap::START, zone())->AddMove(from, to, zone());
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* LChunk::LookupConstant(LConstantOperand* operand) const {
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return HConstant::cast(graph_->LookupValue(operand->index()));
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRepresentation LChunk::LookupLiteralRepresentation(
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LConstantOperand* operand) const {
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return graph_->LookupValue(operand->index())->representation();
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunk::CommitDependencies(Handle<Code> code) const {
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       iend = deprecation_dependencies_.end(); it != iend; ++it) {
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Map> map = *it;
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!map->is_deprecated());
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(map->CanBeDeprecated());
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Map::AddDependentCode(map, DependentCode::kTransitionGroup, code);
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (MapSet::const_iterator it = stability_dependencies_.begin(),
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       iend = stability_dependencies_.end(); it != iend; ++it) {
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Map> map = *it;
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(map->is_stable());
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(map->CanTransition());
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Map::AddDependentCode(map, DependentCode::kPrototypeCheckGroup, code);
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info_->CommitDependencies(code);
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLChunk* LChunk::NewChunk(HGraph* graph) {
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHandleAllocation no_handles;
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  graph->DisallowAddingNewValues();
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int values = graph->GetMaximumValueID();
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info = graph->info();
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (values > LUnallocated::kMaxVirtualRegisters) {
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    info->AbortOptimization(kNotEnoughVirtualRegistersForValues);
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LAllocator allocator(values, graph);
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LChunkBuilder builder(info, graph, &allocator);
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LChunk* chunk = builder.Build();
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (chunk == NULL) return NULL;
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocator.Allocate(chunk)) {
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    info->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  chunk->set_allocated_double_registers(
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      allocator.assigned_double_registers());
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return chunk;
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> LChunk::Codegen() {
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MacroAssembler assembler(info()->isolate(), NULL, 0);
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_CODE_EVENT(info()->isolate(),
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 CodeStartLinePosInfoRecordEvent(
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     assembler.positions_recorder()));
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(yangguo) remove this once the code serializer handles code stubs.
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (info()->will_serialize()) assembler.enable_serializer();
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LCodeGen generator(this, &assembler, info());
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkEmptyBlocks();
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (generator.GenerateCode()) {
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    generator.CheckEnvironmentUsage();
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeGenerator::MakeCodePrologue(info(), "optimized");
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code::Flags flags = info()->flags();
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Code> code =
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    generator.FinishCode(code);
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CommitDependencies(code);
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code->set_is_crankshafted(true);
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void* jit_handler_data =
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assembler.positions_recorder()->DetachJITHandlerData();
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOG_CODE_EVENT(info()->isolate(),
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   CodeEndLinePosInfoRecordEvent(*code, jit_handler_data));
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeGenerator::PrintCode(code, info());
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!(info()->isolate()->serializer_enabled() &&
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             info()->GetMustNotHaveEagerFrame() &&
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             generator.NeedsEagerFrame()));
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return code;
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assembler.AbortedCodeGeneration();
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Code>::null();
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunk::set_allocated_double_registers(BitVector* allocated_registers) {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocated_double_registers_ = allocated_registers;
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector* doubles = allocated_double_registers();
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector::Iterator iterator(doubles);
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!iterator.Done()) {
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (info()->saves_caller_doubles()) {
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (kDoubleSize == kPointerSize * 2) {
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        spill_slot_count_ += 2;
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        spill_slot_count_++;
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    iterator.Advance();
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunkBuilderBase::Abort(BailoutReason reason) {
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info()->AbortOptimization(reason);
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  status_ = ABORTED;
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunkBuilderBase::Retry(BailoutReason reason) {
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info()->RetryOptimization(reason);
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  status_ = ABORTED;
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLEnvironment* LChunkBuilderBase::CreateEnvironment(
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HEnvironment* hydrogen_env, int* argument_index_accumulator,
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ZoneList<HValue*>* objects_to_materialize) {
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (hydrogen_env == NULL) return NULL;
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LEnvironment* outer =
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator,
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        objects_to_materialize);
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id = hydrogen_env->ast_id();
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!ast_id.IsNone() ||
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         hydrogen_env->frame_type() != JS_FUNCTION);
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int omitted_count = (hydrogen_env->frame_type() == JS_FUNCTION)
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          ? 0
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          : hydrogen_env->specials_count();
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int value_count = hydrogen_env->length() - omitted_count;
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LEnvironment* result =
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new(zone()) LEnvironment(hydrogen_env->closure(),
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               hydrogen_env->frame_type(),
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               ast_id,
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               hydrogen_env->parameter_count(),
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               argument_count_,
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               value_count,
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               outer,
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               hydrogen_env->entry(),
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               zone());
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int argument_index = *argument_index_accumulator;
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Store the environment description into the environment
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (with holes for nested objects)
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < hydrogen_env->length(); ++i) {
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (hydrogen_env->is_special_index(i) &&
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        hydrogen_env->frame_type() != JS_FUNCTION) {
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continue;
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* op;
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* value = hydrogen_env->values()->at(i);
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!value->IsPushArguments());  // Do not deopt outgoing arguments
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value->IsArgumentsObject() || value->IsCapturedObject()) {
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = LEnvironment::materialization_marker();
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = UseAny(value);
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->AddValue(op,
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     value->representation(),
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     value->CheckFlag(HInstruction::kUint32));
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Recursively store the nested objects into the environment
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < hydrogen_env->length(); ++i) {
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (hydrogen_env->is_special_index(i)) continue;
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* value = hydrogen_env->values()->at(i);
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value->IsArgumentsObject() || value->IsCapturedObject()) {
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddObjectToMaterialize(value, objects_to_materialize, result);
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (hydrogen_env->frame_type() == JS_FUNCTION) {
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *argument_index_accumulator = argument_index;
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Add an object to the supplied environment and object materialization list.
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Notes:
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We are building three lists here:
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 1. In the result->object_mapping_ list (added to by the
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    LEnvironment::Add*Object methods), we store the lengths (number
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    of fields) of the captured objects in depth-first traversal order, or
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    in case of duplicated objects, we store the index to the duplicate object
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    (with a tag to differentiate between captured and duplicated objects).
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 2. The object fields are stored in the result->values_ list
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    (added to by the LEnvironment.AddValue method) sequentially as lists
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    of fields with holes for nested objects (the holes will be expanded
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    later by LCodegen::AddToTranslation according to the
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    LEnvironment.object_mapping_ list).
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3. The auxiliary objects_to_materialize array stores the hydrogen values
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    in the same order as result->object_mapping_ list. This is used
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    to detect duplicate values and calculate the corresponding object index.
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LChunkBuilderBase::AddObjectToMaterialize(HValue* value,
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ZoneList<HValue*>* objects_to_materialize, LEnvironment* result) {
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int object_index = objects_to_materialize->length();
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Store the hydrogen value into the de-duplication array
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  objects_to_materialize->Add(value, zone());
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find out whether we are storing a duplicated value
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int previously_materialized_object = -1;
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int prev = 0; prev < object_index; ++prev) {
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (objects_to_materialize->at(prev) == value) {
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      previously_materialized_object = prev;
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Store the captured object length (or duplicated object index)
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // into the environment. For duplicated objects, we stop here.
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length = value->OperandCount();
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_arguments = value->IsArgumentsObject();
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (previously_materialized_object >= 0) {
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->AddDuplicateObject(previously_materialized_object);
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->AddNewObject(is_arguments ? length - 1 : length, is_arguments);
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Store the captured object's fields into the environment
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = is_arguments ? 1 : 0; i < length; ++i) {
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOperand* op;
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* arg_value = value->OperandAt(i);
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Insert a hole for nested objects
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = LEnvironment::materialization_marker();
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!arg_value->IsPushArguments());
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // For ordinary values, tell the register allocator we need the value
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // to be alive here
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = UseAny(arg_value);
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->AddValue(op,
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     arg_value->representation(),
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     arg_value->CheckFlag(HInstruction::kUint32));
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Recursively store all the nested captured objects into the environment
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = is_arguments ? 1 : 0; i < length; ++i) {
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* arg_value = value->OperandAt(i);
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddObjectToMaterialize(arg_value, objects_to_materialize, result);
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLPhase::~LPhase() {
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (ShouldProduceTraceOutput()) {
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate()->GetHTracer()->TraceLithium(name(), chunk_);
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
668257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
669257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
670257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
671086aeeaae12517475c22695a200be45495516549Ben Murdoch} }  // namespace v8::internal
672