1830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
5b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org#include "src/lithium.h"
6b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
84b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h"
11657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
12657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org#if V8_TARGET_ARCH_IA32
134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/ia32/lithium-ia32.h"  // NOLINT
144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/ia32/lithium-codegen-ia32.h"  // NOLINT
15657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org#elif V8_TARGET_ARCH_X64
164b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x64/lithium-x64.h"  // NOLINT
174b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x64/lithium-codegen-x64.h"  // NOLINT
18657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org#elif V8_TARGET_ARCH_ARM
194b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/arm/lithium-arm.h"  // NOLINT
204b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/arm/lithium-codegen-arm.h"  // NOLINT
21657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org#elif V8_TARGET_ARCH_MIPS
224b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/mips/lithium-mips.h"  // NOLINT
234b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/mips/lithium-codegen-mips.h"  // NOLINT
24fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#elif V8_TARGET_ARCH_ARM64
254b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/arm64/lithium-arm64.h"  // NOLINT
264b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/arm64/lithium-codegen-arm64.h"  // NOLINT
2712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#elif V8_TARGET_ARCH_MIPS64
2812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/mips64/lithium-mips64.h"  // NOLINT
2912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/mips64/lithium-codegen-mips64.h"  // NOLINT
30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#elif V8_TARGET_ARCH_X87
314b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x87/lithium-x87.h"  // NOLINT
324b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x87/lithium-codegen-x87.h"  // NOLINT
33657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org#else
34657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org#error "Unknown architecture."
35657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org#endif
36d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
37d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.orgnamespace v8 {
38d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.orgnamespace internal {
39d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
400a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
410a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid LOperand::PrintTo(StringStream* stream) {
420a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  LUnallocated* unalloc = NULL;
430a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  switch (kind()) {
440a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    case INVALID:
45659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      stream->Add("(0)");
460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    case UNALLOCATED:
480a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      unalloc = LUnallocated::cast(this);
490a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      stream->Add("v%d", unalloc->virtual_register());
5057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      if (unalloc->basic_policy() == LUnallocated::FIXED_SLOT) {
5157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        stream->Add("(=%dS)", unalloc->fixed_slot_index());
5257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        break;
5357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      }
5457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      switch (unalloc->extended_policy()) {
550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        case LUnallocated::NONE:
560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          break;
570a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        case LUnallocated::FIXED_REGISTER: {
5857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          int reg_index = unalloc->fixed_register_index();
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          if (reg_index < 0 ||
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org              reg_index >= Register::kMaxNumAllocatableRegisters) {
617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            stream->Add("(=invalid_reg#%d)", reg_index);
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          } else {
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            const char* register_name =
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                Register::AllocationIndexToString(reg_index);
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            stream->Add("(=%s)", register_name);
667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          }
670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          break;
680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        }
690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        case LUnallocated::FIXED_DOUBLE_REGISTER: {
7057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          int reg_index = unalloc->fixed_register_index();
717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          if (reg_index < 0 ||
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org              reg_index >= DoubleRegister::kMaxNumAllocatableRegisters) {
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            stream->Add("(=invalid_double_reg#%d)", reg_index);
747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          } else {
757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            const char* double_register_name =
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                DoubleRegister::AllocationIndexToString(reg_index);
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            stream->Add("(=%s)", double_register_name);
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          }
790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          break;
800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        }
810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        case LUnallocated::MUST_HAVE_REGISTER:
820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          stream->Add("(R)");
830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          break;
845924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org        case LUnallocated::MUST_HAVE_DOUBLE_REGISTER:
855924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org          stream->Add("(D)");
865924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org          break;
870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        case LUnallocated::WRITABLE_REGISTER:
880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          stream->Add("(WR)");
890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          break;
900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        case LUnallocated::SAME_AS_FIRST_INPUT:
910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          stream->Add("(1)");
920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          break;
930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        case LUnallocated::ANY:
940a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          stream->Add("(-)");
950a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org          break;
960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      }
970a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    case CONSTANT_OPERAND:
990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      stream->Add("[constant:%d]", index());
1000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
1010a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    case STACK_SLOT:
1020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      stream->Add("[stack:%d]", index());
1030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
1040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    case DOUBLE_STACK_SLOT:
1050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      stream->Add("[double_stack:%d]", index());
1060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case REGISTER: {
1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      int reg_index = index();
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (reg_index < 0 || reg_index >= Register::kMaxNumAllocatableRegisters) {
1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        stream->Add("(=invalid_reg#%d|R)", reg_index);
1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      } else {
1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        stream->Add("[%s|R]", Register::AllocationIndexToString(reg_index));
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case DOUBLE_REGISTER: {
1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      int reg_index = index();
1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (reg_index < 0 ||
1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          reg_index >= DoubleRegister::kMaxNumAllocatableRegisters) {
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        stream->Add("(=invalid_double_reg#%d|R)", reg_index);
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      } else {
1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        stream->Add("[%s|R]",
1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                    DoubleRegister::AllocationIndexToString(reg_index));
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1250a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1270a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
1280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
1290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
130bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
131bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgtemplate<LOperand::Kind kOperandKind, int kNumCachedOperands>
132bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgLSubKindOperand<kOperandKind, kNumCachedOperands>*
133bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgLSubKindOperand<kOperandKind, kNumCachedOperands>::cache = NULL;
134bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
135bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
136bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgtemplate<LOperand::Kind kOperandKind, int kNumCachedOperands>
137bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgvoid LSubKindOperand<kOperandKind, kNumCachedOperands>::SetUpCache() {
138bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  if (cache) return;
139bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  cache = new LSubKindOperand[kNumCachedOperands];
140bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  for (int i = 0; i < kNumCachedOperands; i++) {
141bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    cache[i].ConvertTo(kOperandKind, i);
1421456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  }
143bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
144bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
145bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
146bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgtemplate<LOperand::Kind kOperandKind, int kNumCachedOperands>
147bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgvoid LSubKindOperand<kOperandKind, kNumCachedOperands>::TearDownCache() {
148bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  delete[] cache;
149fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  cache = NULL;
150bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
1511456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1521456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LOperand::SetUpCaches() {
154bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org#define LITHIUM_OPERAND_SETUP(name, type, number) L##name::SetUpCache();
1551456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_SETUP)
1561456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#undef LITHIUM_OPERAND_SETUP
1571456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}
1581456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1591456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid LOperand::TearDownCaches() {
161bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org#define LITHIUM_OPERAND_TEARDOWN(name, type, number) L##name::TearDownCache();
1621456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_TEARDOWN)
1631456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#undef LITHIUM_OPERAND_TEARDOWN
1641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}
1651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
167c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgbool LParallelMove::IsRedundant() const {
168c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  for (int i = 0; i < move_operands_.length(); ++i) {
169c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (!move_operands_[i].IsRedundant()) return false;
170d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  }
171c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  return true;
172d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
173d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
174d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
175c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LParallelMove::PrintDataTo(StringStream* stream) const {
1760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  bool first = true;
1770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  for (int i = 0; i < move_operands_.length(); ++i) {
178c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (!move_operands_[i].IsEliminated()) {
1790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      LOperand* source = move_operands_[i].source();
1800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      LOperand* destination = move_operands_[i].destination();
1810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if (!first) stream->Add(" ");
1820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      first = false;
1830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      if (source->Equals(destination)) {
1840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        destination->PrintTo(stream);
185c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      } else {
1860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        destination->PrintTo(stream);
187c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org        stream->Add(" = ");
1880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com        source->PrintTo(stream);
189d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      }
1900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      stream->Add(";");
191d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    }
192d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  }
193d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
194d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
195d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
196c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LEnvironment::PrintTo(StringStream* stream) {
197471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  stream->Add("[id=%d|", ast_id().ToInt());
1987c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
1997c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    stream->Add("deopt_id=%d|", deoptimization_index());
2007c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
20132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  stream->Add("parameters=%d|", parameter_count());
20232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  stream->Add("arguments_stack_height=%d|", arguments_stack_height());
203c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  for (int i = 0; i < values_.length(); ++i) {
204c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (i != 0) stream->Add(";");
205c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (values_[i] == NULL) {
206c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      stream->Add("[hole]");
207c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    } else {
208c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      values_[i]->PrintTo(stream);
209c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    }
210d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  }
211c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  stream->Add("]");
212d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
213d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
214d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
2157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid LPointerMap::RecordPointer(LOperand* op, Zone* zone) {
216c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Do not record arguments as pointers.
217c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  if (op->IsStackSlot() && op->index() < 0) return;
218e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
2197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  pointer_operands_.Add(op, zone);
220d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
221d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
222d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid LPointerMap::RemovePointer(LOperand* op) {
224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Do not record arguments as pointers.
225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (op->IsStackSlot() && op->index() < 0) return;
226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < pointer_operands_.length(); ++i) {
228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (pointer_operands_[i]->Equals(op)) {
229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      pointer_operands_.Remove(i);
230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      --i;
231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid LPointerMap::RecordUntagged(LOperand* op, Zone* zone) {
237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Do not record arguments as pointers.
238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (op->IsStackSlot() && op->index() < 0) return;
239e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
2407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  untagged_operands_.Add(op, zone);
241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
244c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid LPointerMap::PrintTo(StringStream* stream) {
245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  stream->Add("{");
246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  for (int i = 0; i < pointer_operands_.length(); ++i) {
247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (i != 0) stream->Add(";");
248c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    pointer_operands_[i]->PrintTo(stream);
249d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  }
25071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  stream->Add("}");
251d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
252d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
253d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
254ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.orgint StackSlotOffset(int index) {
255ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org  if (index >= 0) {
256ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org    // Local or spill slot. Skip the frame pointer, function, and
257ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org    // context in the fixed part of the frame.
2587ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    return -(index + 1) * kPointerSize -
2597ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        StandardFrameConstants::kFixedFrameSizeFromFp;
260ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org  } else {
261ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org    // Incoming parameter. Skip the return address.
262c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    return -(index + 1) * kPointerSize + kFPOnStackSize + kPCOnStackSize;
263ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org  }
264ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org}
265ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org
266ac36071c9ef7e9284b15e25826dd7efb34157234jkummerow@chromium.org
26794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgLChunk::LChunk(CompilationInfo* info, HGraph* graph)
26894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    : spill_slot_count_(0),
26994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      info_(info),
27094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      graph_(graph),
2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      instructions_(32, info->zone()),
2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      pointer_maps_(8, info->zone()),
2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      inlined_closures_(1, info->zone()),
2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      deprecation_dependencies_(MapLess(), MapAllocator(info->zone())),
2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      stability_dependencies_(MapLess(), MapAllocator(info->zone())) {}
27694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
27794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
27828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgLLabel* LChunk::GetLabel(int block_id) const {
279657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  HBasicBlock* block = graph_->blocks()->at(block_id);
280657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  int first_instruction = block->first_instruction_index();
281657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return LLabel::cast(instructions_[first_instruction]);
282657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
283657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
284657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
28528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgint LChunk::LookupDestination(int block_id) const {
286657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  LLabel* cur = GetLabel(block_id);
287657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  while (cur->replacement() != NULL) {
288657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    cur = cur->replacement();
289657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  }
290657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return cur->block_id();
291657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
292657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
29328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgLabel* LChunk::GetAssemblyLabel(int block_id) const {
294657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  LLabel* label = GetLabel(block_id);
295e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!label->HasReplacement());
296657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return label->label();
297657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
298657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
299e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
30028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid LChunk::MarkEmptyBlocks() {
3011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  LPhase phase("L_Mark empty blocks", this);
302657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  for (int i = 0; i < graph()->blocks()->length(); ++i) {
303657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    HBasicBlock* block = graph()->blocks()->at(i);
304657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    int first = block->first_instruction_index();
305657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    int last = block->last_instruction_index();
306657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    LInstruction* first_instr = instructions()->at(first);
307657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    LInstruction* last_instr = instructions()->at(last);
308657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
309657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    LLabel* label = LLabel::cast(first_instr);
310657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    if (last_instr->IsGoto()) {
311657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      LGoto* goto_instr = LGoto::cast(last_instr);
312657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      if (label->IsRedundant() &&
313657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org          !label->is_loop_header()) {
314657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        bool can_eliminate = true;
315657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        for (int i = first + 1; i < last && can_eliminate; ++i) {
316657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org          LInstruction* cur = instructions()->at(i);
317657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org          if (cur->IsGap()) {
318657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org            LGap* gap = LGap::cast(cur);
319657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org            if (!gap->IsRedundant()) {
320657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org              can_eliminate = false;
321657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org            }
322657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org          } else {
323657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org            can_eliminate = false;
324657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org          }
325657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        }
326657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        if (can_eliminate) {
327657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org          label->set_replacement(GetLabel(goto_instr->block_id()));
328657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org        }
329657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      }
330657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    }
331657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  }
332657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
333657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
334657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
33528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  LInstructionGap* gap = new (zone()) LInstructionGap(block);
33732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  gap->set_hydrogen_value(instr->hydrogen_value());
338657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  int index = -1;
339657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  if (instr->IsControl()) {
340657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    instructions_.Add(gap, zone());
341657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    index = instructions_.length();
342657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    instructions_.Add(instr, zone());
343657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  } else {
344657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    index = instructions_.length();
345657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    instructions_.Add(instr, zone());
346657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    instructions_.Add(gap, zone());
347657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  }
348657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  if (instr->HasPointerMap()) {
349657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    pointer_maps_.Add(instr->pointer_map(), zone());
350657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    instr->pointer_map()->set_lithium_position(index);
351657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  }
352657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
353657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
354657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
35528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgLConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
356657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return LConstantOperand::Create(constant->id(), zone());
357657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
358657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
359657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
36028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgint LChunk::GetParameterStackSlot(int index) const {
361657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  // The receiver is at index 0, the first parameter at index 1, so we
362657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  // shift all parameter indexes down by the number of parameters, and
363657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  // make sure they end up negative so they are distinguishable from
364657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  // spill slots.
365ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int result = index - info()->num_parameters() - 1;
366ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
367e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(result < 0);
368657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return result;
369657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
370657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
371657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
372657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org// A parameter relative to ebp in the arguments stub.
37328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgint LChunk::ParameterAt(int index) {
374e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(-1 <= index);  // -1 is the receiver.
375657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return (1 + info()->scope()->num_parameters() - index) *
376657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      kPointerSize;
377657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
378657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
379657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
38028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgLGap* LChunk::GetGapAt(int index) const {
381657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return LGap::cast(instructions_[index]);
382657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
383657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
384657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
38528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgbool LChunk::IsGapAt(int index) const {
386657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return instructions_[index]->IsGap();
387657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
388657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
389657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
39028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgint LChunk::NearestGapPos(int index) const {
391657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  while (!IsGapAt(index)) index--;
392657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return index;
393657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
394657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
395657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
39628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
397657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  GetGapAt(index)->GetOrCreateParallelMove(
398657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org      LGap::START, zone())->AddMove(from, to, zone());
399657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
400657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
401657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
40228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgHConstant* LChunk::LookupConstant(LConstantOperand* operand) const {
403657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return HConstant::cast(graph_->LookupValue(operand->index()));
404657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
405657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
406657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
40728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgRepresentation LChunk::LookupLiteralRepresentation(
408657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    LConstantOperand* operand) const {
409657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return graph_->LookupValue(operand->index())->representation();
410657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
411657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
412657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
413c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgvoid LChunk::CommitDependencies(Handle<Code> code) const {
414c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
415c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org       iend = deprecation_dependencies_.end(); it != iend; ++it) {
416c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    Handle<Map> map = *it;
417e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!map->is_deprecated());
418e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(map->CanBeDeprecated());
419c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    Map::AddDependentCode(map, DependentCode::kTransitionGroup, code);
420c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  }
421c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
422af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  for (MapSet::const_iterator it = stability_dependencies_.begin(),
423af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org       iend = stability_dependencies_.end(); it != iend; ++it) {
424af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    Handle<Map> map = *it;
425e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(map->is_stable());
426e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(map->CanTransition());
427af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    Map::AddDependentCode(map, DependentCode::kPrototypeCheckGroup, code);
428af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  }
429af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
430c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  info_->CommitDependencies(code);
431c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
432c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
433c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
43428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgLChunk* LChunk::NewChunk(HGraph* graph) {
43579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHandleAllocation no_handles;
43679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
437935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  graph->DisallowAddingNewValues();
43828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  int values = graph->GetMaximumValueID();
43946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  CompilationInfo* info = graph->info();
44028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (values > LUnallocated::kMaxVirtualRegisters) {
441b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org    info->AbortOptimization(kNotEnoughVirtualRegistersForValues);
44228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    return NULL;
44328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  }
44428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  LAllocator allocator(values, graph);
44546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  LChunkBuilder builder(info, graph, &allocator);
44628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  LChunk* chunk = builder.Build();
44728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (chunk == NULL) return NULL;
44828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
44928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (!allocator.Allocate(chunk)) {
450b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org    info->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
45128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    return NULL;
45228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  }
45328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
45494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  chunk->set_allocated_double_registers(
45594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      allocator.assigned_double_registers());
45694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
45728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  return chunk;
45828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org}
45928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
46028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
461b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgHandle<Code> LChunk::Codegen() {
46228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  MacroAssembler assembler(info()->isolate(), NULL, 0);
463c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  LOG_CODE_EVENT(info()->isolate(),
464c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org                 CodeStartLinePosInfoRecordEvent(
465c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org                     assembler.positions_recorder()));
4662b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  // TODO(yangguo) remove this once the code serializer handles code stubs.
4672b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  if (info()->will_serialize()) assembler.enable_serializer();
46828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  LCodeGen generator(this, &assembler, info());
46928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
47028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  MarkEmptyBlocks();
47128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
47228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (generator.GenerateCode()) {
4734edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org    generator.CheckEnvironmentUsage();
474a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    CodeGenerator::MakeCodePrologue(info(), "optimized");
475b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Code::Flags flags = info()->flags();
47628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    Handle<Code> code =
47728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org        CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
47828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    generator.FinishCode(code);
479c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    CommitDependencies(code);
480b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    code->set_is_crankshafted(true);
481ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org    void* jit_handler_data =
482ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org        assembler.positions_recorder()->DetachJITHandlerData();
483ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org    LOG_CODE_EVENT(info()->isolate(),
484ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org                   CodeEndLinePosInfoRecordEvent(*code, jit_handler_data));
485c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org
48628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    CodeGenerator::PrintCode(code, info());
487e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!(info()->isolate()->serializer_enabled() &&
488a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org             info()->GetMustNotHaveEagerFrame() &&
489a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org             generator.NeedsEagerFrame()));
49028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    return code;
49128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  }
49286b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org  assembler.AbortedCodeGeneration();
49328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  return Handle<Code>::null();
49428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org}
49528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
49628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
49794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid LChunk::set_allocated_double_registers(BitVector* allocated_registers) {
49894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  allocated_double_registers_ = allocated_registers;
49994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  BitVector* doubles = allocated_double_registers();
50094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  BitVector::Iterator iterator(doubles);
50194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  while (!iterator.Done()) {
50294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (info()->saves_caller_doubles()) {
50394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      if (kDoubleSize == kPointerSize * 2) {
50494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        spill_slot_count_ += 2;
50594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      } else {
50694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org        spill_slot_count_++;
50794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      }
50894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
50994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    iterator.Advance();
51094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
51194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
51294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
51394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
514b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.orgvoid LChunkBuilderBase::Abort(BailoutReason reason) {
515b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  info()->AbortOptimization(reason);
516b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  status_ = ABORTED;
517b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org}
518b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org
519b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org
520b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.orgvoid LChunkBuilderBase::Retry(BailoutReason reason) {
521b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  info()->RetryOptimization(reason);
522b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  status_ = ABORTED;
523b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org}
524b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org
525b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org
5269cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgLEnvironment* LChunkBuilderBase::CreateEnvironment(
527ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    HEnvironment* hydrogen_env, int* argument_index_accumulator,
5289cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    ZoneList<HValue*>* objects_to_materialize) {
5299cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  if (hydrogen_env == NULL) return NULL;
5309cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
531ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  LEnvironment* outer =
532ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator,
533ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                        objects_to_materialize);
5349cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  BailoutId ast_id = hydrogen_env->ast_id();
535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!ast_id.IsNone() ||
5369cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org         hydrogen_env->frame_type() != JS_FUNCTION);
537ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
538ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  int omitted_count = (hydrogen_env->frame_type() == JS_FUNCTION)
539ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                          ? 0
540ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                          : hydrogen_env->specials_count();
541ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
542ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  int value_count = hydrogen_env->length() - omitted_count;
5439cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  LEnvironment* result =
5449cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      new(zone()) LEnvironment(hydrogen_env->closure(),
5459cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               hydrogen_env->frame_type(),
5469cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               ast_id,
5479cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               hydrogen_env->parameter_count(),
5489cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               argument_count_,
5499cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               value_count,
5509cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               outer,
5519cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               hydrogen_env->entry(),
5529cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                               zone());
5539cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  int argument_index = *argument_index_accumulator;
5549cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
5559cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // Store the environment description into the environment
5569cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // (with holes for nested objects)
5579cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  for (int i = 0; i < hydrogen_env->length(); ++i) {
558ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    if (hydrogen_env->is_special_index(i) &&
559ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        hydrogen_env->frame_type() != JS_FUNCTION) {
560ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      continue;
561ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    }
5629cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    LOperand* op;
5639cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    HValue* value = hydrogen_env->values()->at(i);
564011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    CHECK(!value->IsPushArguments());  // Do not deopt outgoing arguments
5659cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    if (value->IsArgumentsObject() || value->IsCapturedObject()) {
5669cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      op = LEnvironment::materialization_marker();
5679cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    } else {
5689cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      op = UseAny(value);
5699cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    }
5709cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    result->AddValue(op,
5719cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                     value->representation(),
5729cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                     value->CheckFlag(HInstruction::kUint32));
5739cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  }
5749cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
5759cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // Recursively store the nested objects into the environment
5769cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  for (int i = 0; i < hydrogen_env->length(); ++i) {
5779cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    if (hydrogen_env->is_special_index(i)) continue;
5789cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
5799cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    HValue* value = hydrogen_env->values()->at(i);
5809cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    if (value->IsArgumentsObject() || value->IsCapturedObject()) {
5819cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      AddObjectToMaterialize(value, objects_to_materialize, result);
5829cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    }
5839cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  }
5849cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
5859cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  if (hydrogen_env->frame_type() == JS_FUNCTION) {
5869cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    *argument_index_accumulator = argument_index;
5879cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  }
5889cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
5899cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  return result;
5909cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org}
5919cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
5929cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
5939cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org// Add an object to the supplied environment and object materialization list.
5949cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org//
5959cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org// Notes:
5969cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org//
5979cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org// We are building three lists here:
5989cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org//
5999cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org// 1. In the result->object_mapping_ list (added to by the
60057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    LEnvironment::Add*Object methods), we store the lengths (number
60157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    of fields) of the captured objects in depth-first traversal order, or
60257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    in case of duplicated objects, we store the index to the duplicate object
60357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    (with a tag to differentiate between captured and duplicated objects).
6049cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org//
6059cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org// 2. The object fields are stored in the result->values_ list
60657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    (added to by the LEnvironment.AddValue method) sequentially as lists
60757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    of fields with holes for nested objects (the holes will be expanded
60857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    later by LCodegen::AddToTranslation according to the
60957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org//    LEnvironment.object_mapping_ list).
6109cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org//
6119cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org// 3. The auxiliary objects_to_materialize array stores the hydrogen values
6129cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org//    in the same order as result->object_mapping_ list. This is used
6139cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org//    to detect duplicate values and calculate the corresponding object index.
6149cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgvoid LChunkBuilderBase::AddObjectToMaterialize(HValue* value,
6159cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    ZoneList<HValue*>* objects_to_materialize, LEnvironment* result) {
6169cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  int object_index = objects_to_materialize->length();
6179cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // Store the hydrogen value into the de-duplication array
6189cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  objects_to_materialize->Add(value, zone());
6199cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // Find out whether we are storing a duplicated value
6209cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  int previously_materialized_object = -1;
6219cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  for (int prev = 0; prev < object_index; ++prev) {
6229cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    if (objects_to_materialize->at(prev) == value) {
6239cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      previously_materialized_object = prev;
6249cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      break;
6259cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    }
6269cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  }
6279cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // Store the captured object length (or duplicated object index)
6289cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // into the environment. For duplicated objects, we stop here.
6299cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  int length = value->OperandCount();
6309cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  bool is_arguments = value->IsArgumentsObject();
6319cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  if (previously_materialized_object >= 0) {
6329cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    result->AddDuplicateObject(previously_materialized_object);
6339cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    return;
6349cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  } else {
6359cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    result->AddNewObject(is_arguments ? length - 1 : length, is_arguments);
6369cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  }
6379cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // Store the captured object's fields into the environment
6389cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  for (int i = is_arguments ? 1 : 0; i < length; ++i) {
6399cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    LOperand* op;
6409cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    HValue* arg_value = value->OperandAt(i);
6419cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
6429cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      // Insert a hole for nested objects
6439cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      op = LEnvironment::materialization_marker();
6449cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    } else {
645e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!arg_value->IsPushArguments());
6469cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      // For ordinary values, tell the register allocator we need the value
6479cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      // to be alive here
6489cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      op = UseAny(arg_value);
6499cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    }
6509cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    result->AddValue(op,
6519cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                     arg_value->representation(),
6529cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org                     arg_value->CheckFlag(HInstruction::kUint32));
6539cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  }
6549cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  // Recursively store all the nested captured objects into the environment
6559cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  for (int i = is_arguments ? 1 : 0; i < length; ++i) {
6569cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    HValue* arg_value = value->OperandAt(i);
6579cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
6589cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      AddObjectToMaterialize(arg_value, objects_to_materialize, result);
6599cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org    }
6609cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org  }
6619cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org}
6629cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
6639cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
6641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgLPhase::~LPhase() {
6651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (ShouldProduceTraceOutput()) {
6661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    isolate()->GetHTracer()->TraceLithium(name(), chunk_);
6671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
6681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
6691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
6701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
671d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org} }  // namespace v8::internal
672